From affe85fbc8a13d35960aa92ae87cbb6330ad253f Mon Sep 17 00:00:00 2001 From: Siyuan Wang Date: Thu, 25 Jul 2013 15:14:15 +0800 Subject: AMD Kabini: Add AGESA/PI code for new processor family Change-Id: Icb6f64e2e3cfd678fb4fb4f13f0e4b678d5acc4a Signed-off-by: Siyuan Wang Signed-off-by: Siyuan Wang Reviewed-by: Nick Dill Tested-by: Bruce Griffith Reviewed-on: http://review.coreboot.org/3836 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- .../f16kb/Proc/CPU/Family/0x16/KB/F16KbC6State.c | 198 + .../CPU/Family/0x16/KB/F16KbCacheFlushOnHalt.c | 150 + .../Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.c | 250 + .../Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.h | 78 + .../agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCpb.c | 195 + .../agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c | 369 + .../CPU/Family/0x16/KB/F16KbEquivalenceTable.c | 120 + .../agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbHtc.c | 178 + .../Proc/CPU/Family/0x16/KB/F16KbInitEarlyTable.c | 143 + .../f16kb/Proc/CPU/Family/0x16/KB/F16KbIoCstate.c | 371 + .../Proc/CPU/Family/0x16/KB/F16KbLogicalIdTables.c | 107 + .../0x16/KB/F16KbMicrocodePatch0700002A_Enc.c | 3539 ++ .../0x16/KB/F16KbMicrocodePatch07000106_Enc.c | 3539 ++ .../CPU/Family/0x16/KB/F16KbMicrocodePatchTables.c | 111 + .../f16kb/Proc/CPU/Family/0x16/KB/F16KbMsrTables.c | 264 + .../Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.c | 365 + .../Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.h | 78 + .../f16kb/Proc/CPU/Family/0x16/KB/F16KbPciTables.c | 1147 + .../Proc/CPU/Family/0x16/KB/F16KbPowerCheck.c | 500 + .../Proc/CPU/Family/0x16/KB/F16KbPowerCheck.h | 84 + .../f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmt.h | 535 + .../Family/0x16/KB/F16KbPowerMgmtSystemTables.c | 153 + .../agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPsi.c | 278 + .../f16kb/Proc/CPU/Family/0x16/KB/F16KbPstate.c | 613 + .../Proc/CPU/Family/0x16/KB/F16KbSharedMsrTable.c | 112 + .../f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.c | 1015 + .../f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.h | 152 + .../agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Apm.c | 124 + .../f16kb/Proc/CPU/Family/0x16/cpuF16BrandId.c | 166 + .../Proc/CPU/Family/0x16/cpuF16CacheDefaults.c | 129 + .../agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.c | 123 + .../agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.h | 76 + .../f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.c | 473 + .../f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.h | 90 + .../Proc/CPU/Family/0x16/cpuF16MsrUnknownTables.c | 104 + .../Proc/CPU/Family/0x16/cpuF16PciUnknownTables.c | 250 + .../f16kb/Proc/CPU/Family/0x16/cpuF16PowerMgmt.h | 294 + .../f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.c | 417 + .../f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.h | 144 + .../CPU/Family/0x16/cpuF16WheaInitDataTables.c | 127 + .../agesa/f16kb/Proc/CPU/Family/cpuFamRegisters.h | 125 + .../agesa/f16kb/Proc/CPU/Feature/PreserveMailbox.h | 97 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.c | 194 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.h | 127 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.c | 260 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.h | 156 + .../f16kb/Proc/CPU/Feature/cpuCacheFlushOnHalt.c | 199 + .../agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.c | 751 + .../agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.h | 138 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuCdit.c | 347 + .../agesa/f16kb/Proc/CPU/Feature/cpuCoreLeveling.c | 374 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.c | 175 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.h | 133 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.c | 513 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.h | 85 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuDmi.c | 872 + .../f16kb/Proc/CPU/Feature/cpuFeatureLeveling.c | 265 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.c | 283 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.h | 281 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.c | 201 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.h | 130 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.c | 207 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.h | 283 + .../agesa/f16kb/Proc/CPU/Feature/cpuL3Features.h | 399 + .../agesa/f16kb/Proc/CPU/Feature/cpuMsgBasedC1e.h | 127 + .../agesa/f16kb/Proc/CPU/Feature/cpuPrefetchMode.h | 110 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.c | 213 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.h | 130 + .../agesa/f16kb/Proc/CPU/Feature/cpuPstateGather.c | 410 + .../f16kb/Proc/CPU/Feature/cpuPstateHpcMode.h | 98 + .../f16kb/Proc/CPU/Feature/cpuPstateLeveling.c | 1100 + .../agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.c | 940 + .../agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.h | 314 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuSlit.c | 398 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuSrat.c | 618 + .../agesa/f16kb/Proc/CPU/Feature/cpuTdpLimiting.h | 129 + .../amd/agesa/f16kb/Proc/CPU/Feature/cpuWhea.c | 288 + src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.c | 1274 + src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.h | 399 + src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.c | 927 + src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h | 1314 + src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.asm | 367 + src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.c | 160 + .../amd/agesa/f16kb/Proc/CPU/cahalt64.asm | 173 + .../amd/agesa/f16kb/Proc/CPU/cahaltasm.S | 201 + .../amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.c | 1453 + .../amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.h | 303 + src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuBist.c | 171 + .../amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.c | 469 + .../amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.h | 290 + .../amd/agesa/f16kb/Proc/CPU/cpuEnvInit.h | 73 + .../amd/agesa/f16kb/Proc/CPU/cpuEventLog.c | 396 + .../agesa/f16kb/Proc/CPU/cpuFamilyTranslation.c | 485 + .../agesa/f16kb/Proc/CPU/cpuFamilyTranslation.h | 1052 + .../amd/agesa/f16kb/Proc/CPU/cpuGeneralServices.c | 1286 + .../amd/agesa/f16kb/Proc/CPU/cpuLateInit.c | 289 + .../amd/agesa/f16kb/Proc/CPU/cpuLateInit.h | 1137 + .../amd/agesa/f16kb/Proc/CPU/cpuMicrocodePatch.c | 431 + .../amd/agesa/f16kb/Proc/CPU/cpuPostInit.c | 416 + .../amd/agesa/f16kb/Proc/CPU/cpuPostInit.h | 233 + .../amd/agesa/f16kb/Proc/CPU/cpuPowerMgmt.c | 275 + .../f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.c | 332 + .../f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.h | 127 + .../f16kb/Proc/CPU/cpuPowerMgmtSystemTables.h | 93 + .../amd/agesa/f16kb/Proc/CPU/cpuRegisters.h | 498 + .../amd/agesa/f16kb/Proc/CPU/cpuServices.h | 342 + .../amd/agesa/f16kb/Proc/CPU/cpuWarmReset.c | 234 + .../amd/agesa/f16kb/Proc/CPU/heapManager.c | 889 + .../amd/agesa/f16kb/Proc/CPU/heapManager.h | 258 + .../amd/agesa/f16kb/Proc/CPU/mmioMapManager.h | 143 + .../amd/agesa/f16kb/Proc/Common/AmdFch.h | 65 + .../amd/agesa/f16kb/Proc/Common/AmdInitEarly.c | 323 + .../amd/agesa/f16kb/Proc/Common/AmdInitEnv.c | 188 + .../amd/agesa/f16kb/Proc/Common/AmdInitLate.c | 323 + .../amd/agesa/f16kb/Proc/Common/AmdInitMid.c | 178 + .../amd/agesa/f16kb/Proc/Common/AmdInitPost.c | 349 + .../amd/agesa/f16kb/Proc/Common/AmdInitReset.c | 257 + .../amd/agesa/f16kb/Proc/Common/AmdInitResume.c | 245 + .../amd/agesa/f16kb/Proc/Common/AmdLateRunApTask.c | 159 + .../amd/agesa/f16kb/Proc/Common/AmdS3LateRestore.c | 217 + .../amd/agesa/f16kb/Proc/Common/AmdS3Save.c | 424 + .../amd/agesa/f16kb/Proc/Common/CommonInits.c | 143 + .../amd/agesa/f16kb/Proc/Common/CommonInits.h | 65 + .../amd/agesa/f16kb/Proc/Common/CommonReturns.c | 262 + .../amd/agesa/f16kb/Proc/Common/CreateStruct.c | 313 + .../amd/agesa/f16kb/Proc/Common/CreateStruct.h | 195 + .../amd/agesa/f16kb/Proc/Common/S3RestoreState.c | 441 + .../amd/agesa/f16kb/Proc/Common/S3SaveState.c | 651 + .../amd/agesa/f16kb/Proc/Common/S3SaveState.h | 365 + .../amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaEnv.c | 80 + .../amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaLate.c | 59 + .../amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaMid.c | 509 + .../amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaReset.c | 61 + .../amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.c | 242 + .../amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.h | 91 + .../agesa/f16kb/Proc/Fch/Common/FchBiosRamUsage.h | 67 + .../amd/agesa/f16kb/Proc/Fch/Common/FchCommon.c | 47 + .../amd/agesa/f16kb/Proc/Fch/Common/FchCommonCfg.h | 1219 + .../amd/agesa/f16kb/Proc/Fch/Common/FchDef.h | 438 + .../amd/agesa/f16kb/Proc/Fch/Common/FchLib.c | 598 + .../amd/agesa/f16kb/Proc/Fch/Common/FchPeLib.c | 260 + .../amd/agesa/f16kb/Proc/Fch/Common/MemLib.c | 145 + .../amd/agesa/f16kb/Proc/Fch/Common/PciLib.c | 94 + src/vendorcode/amd/agesa/f16kb/Proc/Fch/Fch.h | 1624 + .../amd/agesa/f16kb/Proc/Fch/FchPlatform.h | 117 + .../Family/Yangtze/YangtzeHwAcpiEnvService.c | 485 + .../Family/Yangtze/YangtzeHwAcpiLateService.c | 152 + .../Family/Yangtze/YangtzeHwAcpiMidService.c | 48 + .../Fch/HwAcpi/Family/Yangtze/YangtzeSSService.c | 124 + .../amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiEnv.c | 102 + .../amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiLate.c | 167 + .../amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiMid.c | 64 + .../amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiReset.c | 213 + .../Fch/Hwm/Family/Yangtze/YangtzeHwmEnvService.c | 87 + .../Fch/Hwm/Family/Yangtze/YangtzeHwmLateService.c | 189 + .../amd/agesa/f16kb/Proc/Fch/Hwm/HwmLate.c | 74 + .../amd/agesa/f16kb/Proc/Fch/Ide/IdeEnv.c | 63 + .../amd/agesa/f16kb/Proc/Fch/Ide/IdeLate.c | 59 + .../amd/agesa/f16kb/Proc/Fch/Ide/IdeMid.c | 61 + .../Fch/Imc/Family/Yangtze/YangtzeImcService.c | 97 + .../amd/agesa/f16kb/Proc/Fch/Imc/FchEcEnv.c | 185 + .../amd/agesa/f16kb/Proc/Fch/Imc/FchEcLate.c | 61 + .../amd/agesa/f16kb/Proc/Fch/Imc/FchEcMid.c | 61 + .../amd/agesa/f16kb/Proc/Fch/Imc/ImcEnv.c | 140 + .../amd/agesa/f16kb/Proc/Fch/Imc/ImcLate.c | 81 + .../amd/agesa/f16kb/Proc/Fch/Imc/ImcLib.c | 314 + .../amd/agesa/f16kb/Proc/Fch/Imc/ImcMid.c | 62 + .../amd/agesa/f16kb/Proc/Fch/Imc/ImcReset.c | 67 + .../Fch/Interface/Family/Yangtze/EnvDefYangtze.c | 359 + .../Fch/Interface/Family/Yangtze/ResetDefYangtze.c | 185 + .../agesa/f16kb/Proc/Fch/Interface/FchInitEnv.c | 114 + .../agesa/f16kb/Proc/Fch/Interface/FchInitLate.c | 101 + .../agesa/f16kb/Proc/Fch/Interface/FchInitMid.c | 100 + .../agesa/f16kb/Proc/Fch/Interface/FchInitReset.c | 115 + .../amd/agesa/f16kb/Proc/Fch/Interface/FchInitS3.c | 102 + .../f16kb/Proc/Fch/Interface/FchTaskLauncher.c | 69 + .../f16kb/Proc/Fch/Interface/FchTaskLauncher.h | 62 + .../agesa/f16kb/Proc/Fch/Interface/InitEnvDef.c | 196 + .../agesa/f16kb/Proc/Fch/Interface/InitResetDef.c | 90 + .../amd/agesa/f16kb/Proc/Fch/Pcie/AbEnv.c | 79 + .../amd/agesa/f16kb/Proc/Fch/Pcie/AbLate.c | 67 + .../amd/agesa/f16kb/Proc/Fch/Pcie/AbMid.c | 62 + .../amd/agesa/f16kb/Proc/Fch/Pcie/AbReset.c | 64 + .../Fch/Pcie/Family/Yangtze/YangtzeAbEnvService.c | 253 + .../Pcie/Family/Yangtze/YangtzeAbResetService.c | 71 + .../Fch/Pcie/Family/Yangtze/YangtzeAbService.c | 68 + .../amd/agesa/f16kb/Proc/Fch/Pcie/PcieEnv.c | 67 + .../amd/agesa/f16kb/Proc/Fch/Pcie/PcieLate.c | 61 + .../amd/agesa/f16kb/Proc/Fch/Pcie/PcieMid.c | 61 + .../amd/agesa/f16kb/Proc/Fch/Pcie/PcieReset.c | 63 + .../amd/agesa/f16kb/Proc/Fch/Sata/AhciEnv.c | 86 + .../amd/agesa/f16kb/Proc/Fch/Sata/AhciLate.c | 67 + .../amd/agesa/f16kb/Proc/Fch/Sata/AhciLib.c | 68 + .../amd/agesa/f16kb/Proc/Fch/Sata/AhciMid.c | 67 + .../Sata/Family/Yangtze/YangtzeSataEnvService.c | 224 + .../Sata/Family/Yangtze/YangtzeSataResetService.c | 125 + .../Fch/Sata/Family/Yangtze/YangtzeSataService.c | 699 + .../amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciEnv.c | 82 + .../amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLate.c | 89 + .../amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLib.c | 67 + .../amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciMid.c | 76 + .../amd/agesa/f16kb/Proc/Fch/Sata/RaidEnv.c | 74 + .../amd/agesa/f16kb/Proc/Fch/Sata/RaidLate.c | 65 + .../amd/agesa/f16kb/Proc/Fch/Sata/RaidLib.c | 69 + .../amd/agesa/f16kb/Proc/Fch/Sata/RaidMid.c | 74 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataEnv.c | 104 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataEnvLib.c | 88 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataIdeEnv.c | 100 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLate.c | 71 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLib.c | 46 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataIdeMid.c | 75 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataLate.c | 116 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataLib.c | 258 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataMid.c | 196 + .../amd/agesa/f16kb/Proc/Fch/Sata/SataReset.c | 63 + .../Fch/Sd/Family/Yangtze/YangtzeSdEnvService.c | 129 + .../Fch/Sd/Family/Yangtze/YangtzeSdResetService.c | 47 + .../Proc/Fch/Sd/Family/Yangtze/YangtzeSdService.c | 47 + src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdEnv.c | 65 + .../amd/agesa/f16kb/Proc/Fch/Sd/SdLate.c | 60 + src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdMid.c | 61 + .../Fch/Spi/Family/Yangtze/YangtzeLpcEnvService.c | 89 + .../Spi/Family/Yangtze/YangtzeLpcResetService.c | 790 + .../amd/agesa/f16kb/Proc/Fch/Spi/LpcEnv.c | 94 + .../amd/agesa/f16kb/Proc/Fch/Spi/LpcLate.c | 58 + .../amd/agesa/f16kb/Proc/Fch/Spi/LpcMid.c | 60 + .../amd/agesa/f16kb/Proc/Fch/Spi/LpcReset.c | 70 + .../amd/agesa/f16kb/Proc/Fch/Spi/SpiEnv.c | 61 + .../amd/agesa/f16kb/Proc/Fch/Spi/SpiLate.c | 113 + .../amd/agesa/f16kb/Proc/Fch/Spi/SpiMid.c | 61 + .../amd/agesa/f16kb/Proc/Fch/Spi/SpiReset.c | 45 + .../amd/agesa/f16kb/Proc/Fch/Usb/EhciEnv.c | 60 + .../amd/agesa/f16kb/Proc/Fch/Usb/EhciLate.c | 60 + .../amd/agesa/f16kb/Proc/Fch/Usb/EhciMid.c | 158 + .../amd/agesa/f16kb/Proc/Fch/Usb/EhciReset.c | 62 + .../Fch/Usb/Family/Yangtze/YangtzeEhciEnvService.c | 44 + .../Usb/Family/Yangtze/YangtzeEhciLateService.c | 47 + .../Fch/Usb/Family/Yangtze/YangtzeEhciMidService.c | 188 + .../Fch/Usb/Family/Yangtze/YangtzeOhciEnvService.c | 96 + .../Usb/Family/Yangtze/YangtzeOhciLateService.c | 48 + .../Fch/Usb/Family/Yangtze/YangtzeOhciMidService.c | 107 + .../Fch/Usb/Family/Yangtze/YangtzeXhciEnvService.c | 482 + .../Usb/Family/Yangtze/YangtzeXhciLateService.c | 130 + .../Fch/Usb/Family/Yangtze/YangtzeXhciMidService.c | 48 + .../Usb/Family/Yangtze/YangtzeXhciResetService.c | 118 + .../amd/agesa/f16kb/Proc/Fch/Usb/OhciEnv.c | 60 + .../amd/agesa/f16kb/Proc/Fch/Usb/OhciLate.c | 60 + .../amd/agesa/f16kb/Proc/Fch/Usb/OhciMid.c | 213 + .../amd/agesa/f16kb/Proc/Fch/Usb/OhciReset.c | 62 + .../amd/agesa/f16kb/Proc/Fch/Usb/UsbEnv.c | 69 + .../amd/agesa/f16kb/Proc/Fch/Usb/UsbLate.c | 67 + .../amd/agesa/f16kb/Proc/Fch/Usb/UsbMid.c | 68 + .../amd/agesa/f16kb/Proc/Fch/Usb/UsbReset.c | 62 + .../amd/agesa/f16kb/Proc/Fch/Usb/XhciEnv.c | 115 + .../amd/agesa/f16kb/Proc/Fch/Usb/XhciLate.c | 62 + .../amd/agesa/f16kb/Proc/Fch/Usb/XhciMid.c | 77 + .../amd/agesa/f16kb/Proc/Fch/Usb/XhciReset.c | 83 + .../amd/agesa/f16kb/Proc/GNB/Common/Gnb.h | 171 + .../amd/agesa/f16kb/Proc/GNB/Common/GnbF1Table.h | 99 + .../agesa/f16kb/Proc/GNB/Common/GnbFamServices.h | 141 + .../amd/agesa/f16kb/Proc/GNB/Common/GnbGfx.h | 348 + .../f16kb/Proc/GNB/Common/GnbGfxFamServices.h | 102 + .../amd/agesa/f16kb/Proc/GNB/Common/GnbIommu.h | 195 + .../agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.c | 111 + .../agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.h | 55 + .../amd/agesa/f16kb/Proc/GNB/Common/GnbPcie.h | 398 + .../f16kb/Proc/GNB/Common/GnbPcieFamServices.h | 242 + .../f16kb/Proc/GNB/Common/GnbRegistersCommon.h | 1557 + .../f16kb/Proc/GNB/Common/GnbRegistersCommonV2.h | 1445 + .../agesa/f16kb/Proc/GNB/Common/GnbRegistersKB.h | 3954 +++ .../amd/agesa/f16kb/Proc/GNB/Common/GnbUra.h | 204 + .../agesa/f16kb/Proc/GNB/Common/GnbUraServices.h | 87 + .../amd/agesa/f16kb/Proc/GNB/Common/GnbUraToken.h | 103 + .../amd/agesa/f16kb/Proc/GNB/GnbInitAtEarly.c | 128 + .../amd/agesa/f16kb/Proc/GNB/GnbInitAtEnv.c | 138 + .../amd/agesa/f16kb/Proc/GNB/GnbInitAtLate.c | 136 + .../amd/agesa/f16kb/Proc/GNB/GnbInitAtMid.c | 118 + .../amd/agesa/f16kb/Proc/GNB/GnbInitAtPost.c | 150 + .../amd/agesa/f16kb/Proc/GNB/GnbInitAtReset.c | 93 + .../amd/agesa/f16kb/Proc/GNB/GnbInitAtS3Save.c | 94 + .../Proc/GNB/Modules/GnbCommonLib/GnbCommonLib.h | 57 + .../f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.c | 530 + .../f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.h | 156 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.c | 143 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.h | 65 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.c | 176 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.h | 69 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.c | 122 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.h | 66 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.c | 125 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.h | 73 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c | 403 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibPci.h | 166 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.c | 156 + .../Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.h | 73 + .../Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.c | 157 + .../Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.h | 73 + .../Modules/GnbFamTranslation/GnbPcieTranslation.c | 515 + .../GNB/Modules/GnbFamTranslation/GnbTranslation.c | 245 + .../Proc/GNB/Modules/GnbGfxConfig/GfxConfigEnv.c | 135 + .../Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.c | 264 + .../Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.h | 71 + .../Proc/GNB/Modules/GnbGfxConfig/GfxConfigMid.c | 113 + .../Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.c | 135 + .../Proc/GNB/Modules/GnbGfxConfig/GnbGfxConfig.h | 51 + .../Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.c | 184 + .../Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.h | 56 + .../Modules/GnbGfxInitLibV1/GfxEnumConnectors.c | 609 + .../Modules/GnbGfxInitLibV1/GfxEnumConnectors.h | 64 + .../GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.c | 217 + .../GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.h | 79 + .../GnbGfxIntTableV3/GfxIntegratedInfoTable.c | 504 + .../GnbGfxIntTableV3/GfxIntegratedInfoTable.h | 73 + .../Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c | 257 + .../Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h | 70 + .../GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c | 1233 + .../GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h | 321 + .../f16kb/Proc/GNB/Modules/GnbInitKB/AlibKB.c | 92 + .../f16kb/Proc/GNB/Modules/GnbInitKB/AlibSsdtKB.h | 3230 ++ .../Proc/GNB/Modules/GnbInitKB/GfxEnvInitKB.c | 229 + .../Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.c | 375 + .../Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.h | 55 + .../Modules/GnbInitKB/GfxIntegratedInfoTableKB.c | 526 + .../f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.c | 192 + .../f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.h | 53 + .../Proc/GNB/Modules/GnbInitKB/GfxMidInitKB.c | 161 + .../Proc/GNB/Modules/GnbInitKB/GfxPostInitKB.c | 153 + .../Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.c | 253 + .../Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.h | 53 + .../f16kb/Proc/GNB/Modules/GnbInitKB/GfxTablesKB.c | 479 + .../Proc/GNB/Modules/GnbInitKB/GnbEarlyInitKB.c | 459 + .../Proc/GNB/Modules/GnbInitKB/GnbEnvInitKB.c | 302 + .../Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.c | 1022 + .../Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.h | 78 + .../Proc/GNB/Modules/GnbInitKB/GnbInitKBInstall.h | 234 + .../Proc/GNB/Modules/GnbInitKB/GnbIommuTablesKB.c | 165 + .../Proc/GNB/Modules/GnbInitKB/GnbMidInitKB.c | 429 + .../Proc/GNB/Modules/GnbInitKB/GnbPostInitKB.c | 120 + .../Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.c | 585 + .../Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.h | 68 + .../Proc/GNB/Modules/GnbInitKB/GnbSamuPatchKB.h | 2103 ++ .../Proc/GNB/Modules/GnbInitKB/GnbSmuFirmwareKB.h | 32414 +++++++++++++++++++ .../f16kb/Proc/GNB/Modules/GnbInitKB/GnbTablesKB.c | 499 + .../f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraKB.c | 260 + .../Proc/GNB/Modules/GnbInitKB/GnbUraTokenMapKB.c | 122 + .../Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.c | 447 + .../Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.h | 157 + .../Proc/GNB/Modules/GnbInitKB/PcieConfigKB.c | 626 + .../Proc/GNB/Modules/GnbInitKB/PcieEarlyInitKB.c | 938 + .../Proc/GNB/Modules/GnbInitKB/PcieEnvInitKB.c | 94 + .../f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c | 463 + .../f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.h | 80 + .../Proc/GNB/Modules/GnbInitKB/PcieMidInitKB.c | 392 + .../Proc/GNB/Modules/GnbInitKB/PciePostInitKB.c | 470 + .../Proc/GNB/Modules/GnbInitKB/PcieTablesKB.c | 225 + .../f16kb/Proc/GNB/Modules/GnbInitKB/excel925.h | 113 + .../f16kb/Proc/GNB/Modules/GnbIoapic/GnbIoapic.c | 224 + .../GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.h | 99 + .../GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.c | 386 + .../GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.h | 122 + .../GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c | 348 + .../GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.h | 80 + .../Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c | 463 + .../Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.h | 107 + .../f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.c | 374 + .../f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.h | 63 + .../Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.c | 326 + .../Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.h | 54 + .../Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.c | 135 + .../Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.h | 74 + .../Proc/GNB/Modules/GnbPcieConfig/GnbPcieConfig.h | 54 + .../GNB/Modules/GnbPcieConfig/PcieConfigData.c | 533 + .../GNB/Modules/GnbPcieConfig/PcieConfigData.h | 57 + .../Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.c | 799 + .../Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.h | 221 + .../GNB/Modules/GnbPcieConfig/PcieInputParser.c | 277 + .../GNB/Modules/GnbPcieConfig/PcieInputParser.h | 83 + .../GNB/Modules/GnbPcieConfig/PcieMapTopology.c | 645 + .../GNB/Modules/GnbPcieConfig/PcieMapTopology.h | 57 + .../Modules/GnbPcieInitLibV1/GnbPcieInitLibV1.h | 60 + .../Modules/GnbPcieInitLibV1/PcieAspmBlackList.c | 173 + .../Modules/GnbPcieInitLibV1/PcieAspmBlackList.h | 55 + .../Modules/GnbPcieInitLibV1/PcieAspmExitLatency.h | 55 + .../GNB/Modules/GnbPcieInitLibV1/PciePhyServices.h | 73 + .../GNB/Modules/GnbPcieInitLibV1/PciePifServices.c | 622 + .../GNB/Modules/GnbPcieInitLibV1/PciePifServices.h | 120 + .../GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.c | 273 + .../GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.h | 94 + .../Modules/GnbPcieInitLibV1/PciePortServices.c | 396 + .../Modules/GnbPcieInitLibV1/PciePortServices.h | 118 + .../GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.h | 74 + .../Modules/GnbPcieInitLibV1/PcieSiliconServices.h | 72 + .../Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.c | 95 + .../Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.h | 55 + .../GnbPcieInitLibV1/PcieTopologyServices.c | 722 + .../GnbPcieInitLibV1/PcieTopologyServices.h | 135 + .../GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.c | 661 + .../GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.h | 131 + .../Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.c | 300 + .../Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.h | 127 + .../Modules/GnbPcieInitLibV4/GnbPcieInitLibV4.h | 52 + .../Modules/GnbPcieInitLibV4/PciePortServicesV4.c | 202 + .../Modules/GnbPcieInitLibV4/PciePortServicesV4.h | 64 + .../GNB/Modules/GnbPcieInitLibV4/PciePowerMgmtV4.h | 71 + .../GnbPcieInitLibV4/PcieWrapperServicesV4.c | 204 + .../GnbPcieInitLibV4/PcieWrapperServicesV4.h | 77 + .../Modules/GnbPcieInitLibV5/GnbPcieInitLibV5.h | 141 + .../Modules/GnbPcieInitLibV5/PciePhyServicesV5.c | 111 + .../Modules/GnbPcieInitLibV5/PciePifServicesV5.c | 269 + .../Modules/GnbPcieInitLibV5/PciePortServicesV5.c | 147 + .../GnbPcieInitLibV5/PcieSiliconServicesV5.c | 198 + .../GnbPcieInitLibV5/PcieTopologyServicesV5.c | 152 + .../GnbPcieInitLibV5/PcieWrapperServicesV5.c | 184 + .../GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.c | 376 + .../GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.h | 55 + .../Modules/GnbPcieTrainingV2/GnbPcieTrainingV2.h | 51 + .../GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.c | 801 + .../GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.h | 63 + .../Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.c | 375 + .../Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.h | 55 + .../Proc/GNB/Modules/GnbSSocketLib/GnbSSocketLib.c | 169 + .../f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.c | 143 + .../f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.h | 78 + .../f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbPcie.c | 142 + .../Proc/GNB/Modules/GnbScsLibV1/GnbScsLibV1.c | 198 + .../Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.c | 330 + .../Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.h | 123 + .../f16kb/Proc/GNB/Modules/GnbSview/GnbSview.c | 128 + .../f16kb/Proc/GNB/Modules/GnbTable/GnbTable.c | 357 + .../f16kb/Proc/GNB/Modules/GnbTable/GnbTable.h | 238 + .../Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c | 388 + .../amd/agesa/f16kb/Proc/HT/Fam16/htNbFam16.c | 150 + .../agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.c | 300 + .../agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.h | 110 + src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.c | 112 + src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.h | 579 + .../amd/agesa/f16kb/Proc/HT/htInterface.c | 262 + .../amd/agesa/f16kb/Proc/HT/htInterface.h | 489 + .../amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.c | 263 + .../amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.h | 114 + .../amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.c | 538 + .../amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.h | 161 + .../agesa/f16kb/Proc/HT/htInterfaceNonCoherent.c | 393 + .../agesa/f16kb/Proc/HT/htInterfaceNonCoherent.h | 137 + src/vendorcode/amd/agesa/f16kb/Proc/HT/htMain.c | 589 + src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.c | 251 + src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.h | 1200 + .../amd/agesa/f16kb/Proc/HT/htNbCommonHardware.h | 122 + src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.c | 669 + src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.h | 297 + .../amd/agesa/f16kb/Proc/HT/htTopologies.h | 71 + .../amd/agesa/f16kb/Proc/IDS/Control/IdsLib32.asm | 335 + .../amd/agesa/f16kb/Proc/IDS/Control/IdsLib64.asm | 342 + .../amd/agesa/f16kb/Proc/IDS/Debug/IdsDebug.c | 211 + .../amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.c | 654 + .../amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.h | 80 + .../amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.c | 755 + .../amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.h | 119 + .../amd/agesa/f16kb/Proc/IDS/Debug/IdsDpSerial.c | 185 + .../Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c | 308 + .../Proc/IDS/Family/0x16/KB/IdsF16KbAllService.h | 49 + .../f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbNvDef.h | 287 + src/vendorcode/amd/agesa/f16kb/Proc/IDS/IdsLib.h | 433 + .../amd/agesa/f16kb/Proc/IDS/Library/IdsLib.c | 1015 + .../amd/agesa/f16kb/Proc/IDS/Library/IdsRegAcc.h | 169 + .../amd/agesa/f16kb/Proc/IDS/OptionsIds.h | 92 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ardk/ma.c | 145 + .../amd/agesa/f16kb/Proc/Mem/Feat/CRAT/mfCrat.h | 95 + .../amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.c | 357 + .../amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.h | 80 + .../amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c | 721 + .../amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.c | 290 + .../amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.h | 80 + .../amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfemp.c | 177 + .../f16kb/Proc/Mem/Feat/EXCLUDIMM/mfdimmexclud.c | 206 + .../f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.c | 548 + .../f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.h | 72 + .../agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.c | 172 + .../agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.h | 78 + .../agesa/f16kb/Proc/Mem/Feat/MEMCLR/mfmemclr.c | 153 + .../f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.c | 179 + .../f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.h | 77 + .../Proc/Mem/Feat/PARTRN/mfParallelTraining.c | 288 + .../Proc/Mem/Feat/PARTRN/mfStandardTraining.c | 85 + .../Proc/Mem/Feat/RDWR2DTRAINING/KB/mfRdWr2DKb.c | 348 + .../Mem/Feat/RDWR2DTRAINING/mfRdDqs2DTraining.c | 115 + .../Mem/Feat/RDWR2DTRAINING/mfRdWr2DEyeRimSearch.c | 1112 + .../RDWR2DTRAINING/mfRdWr2DPatternGeneration.c | 424 + .../Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.c | 1368 + .../Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.h | 266 + .../amd/agesa/f16kb/Proc/Mem/Feat/S3/mfs3.c | 718 + .../amd/agesa/f16kb/Proc/Mem/Feat/TABLE/mftds.c | 401 + .../amd/agesa/f16kb/Proc/Mem/Main/KB/mmflowkb.c | 388 + .../amd/agesa/f16kb/Proc/Mem/Main/mdef.c | 155 + .../amd/agesa/f16kb/Proc/Mem/Main/merrhdl.c | 187 + .../amd/agesa/f16kb/Proc/Mem/Main/minit.c | 149 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mm.c | 253 + .../agesa/f16kb/Proc/Mem/Main/mmConditionalPso.c | 695 + .../amd/agesa/f16kb/Proc/Mem/Main/mmEcc.c | 186 + .../amd/agesa/f16kb/Proc/Mem/Main/mmExcludeDimm.c | 244 + .../amd/agesa/f16kb/Proc/Mem/Main/mmLvDdr3.c | 300 + .../amd/agesa/f16kb/Proc/Mem/Main/mmMemClr.c | 126 + .../amd/agesa/f16kb/Proc/Mem/Main/mmMemRestore.c | 750 + .../agesa/f16kb/Proc/Mem/Main/mmNodeInterleave.c | 146 + .../amd/agesa/f16kb/Proc/Mem/Main/mmOnlineSpare.c | 165 + .../agesa/f16kb/Proc/Mem/Main/mmParallelTraining.c | 288 + .../agesa/f16kb/Proc/Mem/Main/mmStandardTraining.c | 344 + .../amd/agesa/f16kb/Proc/Mem/Main/mmUmaAlloc.c | 262 + .../amd/agesa/f16kb/Proc/Mem/Main/mmflow.c | 406 + .../amd/agesa/f16kb/Proc/Mem/Main/mmlvddr3.h | 80 + .../amd/agesa/f16kb/Proc/Mem/Main/mu.asm | 496 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.c | 250 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/muc.c | 760 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnS3kb.h | 84 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mndctkb.c | 1217 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnflowkb.c | 129 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnidendimmkb.c | 147 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.c | 628 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.h | 410 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnmctkb.c | 551 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c | 268 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnphykb.c | 1078 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mnregkb.c | 847 + .../amd/agesa/f16kb/Proc/Mem/NB/KB/mns3kb.c | 1258 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mn.c | 608 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnS3.c | 949 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mndct.c | 1648 + .../amd/agesa/f16kb/Proc/Mem/NB/mnfeat.c | 1241 + .../amd/agesa/f16kb/Proc/Mem/NB/mnflow.c | 317 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnmct.c | 871 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnphy.c | 1345 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnreg.c | 601 + .../amd/agesa/f16kb/Proc/Mem/NB/mntrain3.c | 243 + .../amd/agesa/f16kb/Proc/Mem/Ps/KB/FT3/mpSkbft3.c | 130 + .../amd/agesa/f16kb/Proc/Mem/Ps/KB/mpSkb3.c | 345 + .../amd/agesa/f16kb/Proc/Mem/Ps/KB/mpUkb3.c | 180 + .../amd/agesa/f16kb/Proc/Mem/Ps/KB/mpkb3.c | 172 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mp.c | 1336 + .../amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c | 325 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmr0.c | 195 + .../amd/agesa/f16kb/Proc/Mem/Ps/mpodtpat.c | 216 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mprtt.c | 281 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mps2d.c | 233 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpsao.c | 239 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.c | 235 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.h | 134 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtlrdimm3.h | 132 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.c | 167 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.h | 90 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.c | 318 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.h | 87 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.c | 503 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.h | 96 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.c | 1202 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.h | 180 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttecc3.c | 163 + .../amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttwl3.c | 718 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mt.c | 262 + .../amd/agesa/f16kb/Proc/Mem/Tech/mthdi.c | 124 + .../amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.c | 906 + .../amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.h | 117 + .../f16kb/Proc/Mem/Tech/mttRdDqs2DEyeRimSearch.c | 996 + .../agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DTraining.c | 1185 + .../amd/agesa/f16kb/Proc/Mem/Tech/mttdimbt.c | 1478 + .../amd/agesa/f16kb/Proc/Mem/Tech/mttecc.c | 225 + .../amd/agesa/f16kb/Proc/Mem/Tech/mtthrc.c | 312 + .../agesa/f16kb/Proc/Mem/Tech/mtthrcSeedTrain.c | 623 + .../amd/agesa/f16kb/Proc/Mem/Tech/mttml.c | 263 + .../amd/agesa/f16kb/Proc/Mem/Tech/mttoptsrc.c | 425 + .../amd/agesa/f16kb/Proc/Mem/Tech/mttsrc.c | 345 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/ma.h | 162 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/merrhdl.h | 103 + .../amd/agesa/f16kb/Proc/Mem/mfParallelTraining.h | 113 + .../amd/agesa/f16kb/Proc/Mem/mfStandardTraining.h | 81 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfmemclr.h | 83 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfs3.h | 335 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mftds.h | 80 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mm.h | 1500 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mn.h | 1579 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mnpmu.h | 242 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mnreg.h | 533 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mp.h | 523 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mport.h | 70 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mt.h | 634 + src/vendorcode/amd/agesa/f16kb/Proc/Mem/mu.h | 272 + 585 files changed, 214084 insertions(+) create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbC6State.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCacheFlushOnHalt.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCpb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbEquivalenceTable.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbHtc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbInitEarlyTable.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbIoCstate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbLogicalIdTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatch0700002A_Enc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatch07000106_Enc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatchTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMsrTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPciTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerCheck.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerCheck.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmt.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmtSystemTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPsi.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPstate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbSharedMsrTable.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Apm.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16BrandId.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16CacheDefaults.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MsrUnknownTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16PciUnknownTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16PowerMgmt.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16WheaInitDataTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/cpuFamRegisters.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/PreserveMailbox.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheFlushOnHalt.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCdit.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCoreLeveling.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuDmi.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatureLeveling.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuL3Features.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuMsgBasedC1e.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPrefetchMode.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateGather.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateHpcMode.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateLeveling.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuSlit.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuSrat.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuTdpLimiting.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuWhea.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.asm create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt64.asm create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahaltasm.S create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuBist.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEnvInit.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEventLog.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuFamilyTranslation.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuFamilyTranslation.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuGeneralServices.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuLateInit.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuLateInit.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuMicrocodePatch.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPostInit.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPostInit.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmt.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSystemTables.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuRegisters.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuWarmReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/heapManager.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/heapManager.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/CPU/mmioMapManager.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdFch.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitEarly.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitPost.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitResume.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdLateRunApTask.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdS3LateRestore.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdS3Save.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonInits.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonInits.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonReturns.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/CreateStruct.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/CreateStruct.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/S3RestoreState.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/S3SaveState.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Common/S3SaveState.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchBiosRamUsage.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchCommon.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchCommonCfg.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchDef.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchPeLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/MemLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/PciLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Fch.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/FchPlatform.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiLateService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiMidService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeSSService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/Family/Yangtze/YangtzeHwmEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/Family/Yangtze/YangtzeHwmLateService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/HwmLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/Family/Yangtze/YangtzeImcService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/Family/Yangtze/EnvDefYangtze.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/Family/Yangtze/ResetDefYangtze.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitS3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchTaskLauncher.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchTaskLauncher.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/InitEnvDef.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/InitResetDef.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbResetService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataResetService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataEnvLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdResetService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciLateService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciMidService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciLateService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciMidService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciEnvService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciLateService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciMidService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciResetService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/Gnb.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbF1Table.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbFamServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbGfx.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbGfxFamServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbIommu.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbPcie.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbPcieFamServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersCommon.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersCommonV2.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUra.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUraServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUraToken.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtEarly.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtLate.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtPost.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtReset.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtS3Save.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbCommonLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbFamTranslation/GnbPcieTranslation.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbFamTranslation/GnbTranslation.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigEnv.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigMid.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GnbGfxConfig.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibSsdtKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxEnvInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxMidInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxPostInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxTablesKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbEarlyInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbEnvInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbInitKBInstall.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbIommuTablesKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbMidInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbPostInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSamuPatchKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSmuFirmwareKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbTablesKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraTokenMapKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieConfigKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieEarlyInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieEnvInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieMidInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PciePostInitKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieTablesKB.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/excel925.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbIoapic/GnbIoapic.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbPcieConfig.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/GnbPcieInitLibV1.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/GnbPcieInitLibV4.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePortServicesV4.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePortServicesV4.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePowerMgmtV4.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PcieWrapperServicesV4.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PcieWrapperServicesV4.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/GnbPcieInitLibV5.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePhyServicesV5.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePifServicesV5.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePortServicesV5.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieSiliconServicesV5.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieTopologyServicesV5.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieWrapperServicesV5.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/GnbPcieTrainingV2.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSSocketLib/GnbSSocketLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbPcie.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbScsLibV1/GnbScsLibV1.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSview/GnbSview.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbTable/GnbTable.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbTable/GnbTable.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbFam16.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterface.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterface.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceNonCoherent.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceNonCoherent.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htMain.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htNbCommonHardware.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/HT/htTopologies.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Control/IdsLib32.asm create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Control/IdsLib64.asm create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebug.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpSerial.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbNvDef.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/IdsLib.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Library/IdsLib.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/Library/IdsRegAcc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/IDS/OptionsIds.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ardk/ma.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CRAT/mfCrat.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfemp.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/EXCLUDIMM/mfdimmexclud.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/MEMCLR/mfmemclr.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/PARTRN/mfParallelTraining.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/PARTRN/mfStandardTraining.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/KB/mfRdWr2DKb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdDqs2DTraining.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DEyeRimSearch.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DPatternGeneration.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/S3/mfs3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/TABLE/mftds.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/KB/mmflowkb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mdef.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/merrhdl.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/minit.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mm.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmConditionalPso.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmEcc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmExcludeDimm.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmLvDdr3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmMemClr.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmMemRestore.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmNodeInterleave.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmOnlineSpare.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmParallelTraining.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmStandardTraining.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmUmaAlloc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmflow.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmlvddr3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.asm create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/muc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnS3kb.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mndctkb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnflowkb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnidendimmkb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnmctkb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnphykb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnregkb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mns3kb.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mn.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnS3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mndct.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnfeat.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnflow.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnmct.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnphy.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnreg.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mntrain3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/FT3/mpSkbft3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpSkb3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpUkb3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpkb3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mp.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmr0.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpodtpat.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mprtt.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mps2d.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpsao.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtlrdimm3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttecc3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttwl3.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mt.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mthdi.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DEyeRimSearch.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DTraining.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttdimbt.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttecc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mtthrc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mtthrcSeedTrain.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttml.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttoptsrc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttsrc.c create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/ma.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/merrhdl.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfParallelTraining.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfStandardTraining.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfmemclr.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfs3.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mftds.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mm.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mn.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mnpmu.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mnreg.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mp.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mport.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mt.h create mode 100644 src/vendorcode/amd/agesa/f16kb/Proc/Mem/mu.h (limited to 'src/vendorcode/amd/agesa/f16kb/Proc') diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbC6State.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbC6State.c new file mode 100644 index 0000000000..b923fec5bd --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbC6State.c @@ -0,0 +1,198 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini C6 C-state feature support functions. + * + * Provides the functions necessary to initialize the C6 feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuFeatures.h" +#include "cpuC6State.h" +#include "cpuApicUtilities.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBC6STATE_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +F16KbIsC6Supported ( + IN C6_FAMILY_SERVICES *C6Services, + IN UINT32 Socket, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +STATIC +F16KbInitializeC6 ( + IN C6_FAMILY_SERVICES *C6Services, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Is C6 supported on this CPU + * + * @param[in] C6Services Pointer to this CPU's C6 family services. + * @param[in] Socket This core's zero-based socket number. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE C6 state is supported. + * @retval FALSE C6 state is not supported. + * + */ +BOOLEAN +STATIC +F16KbIsC6Supported ( + IN C6_FAMILY_SERVICES *C6Services, + IN UINT32 Socket, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return (IsFeatureEnabled (IoCstate, PlatformConfig, StdHeader)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable C6 on a family 16h Kabini CPU. + * + * @param[in] C6Services Pointer to this CPU's C6 family services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +F16KbInitializeC6 ( + IN C6_FAMILY_SERVICES *C6Services, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + CSTATE_CTRL1_REGISTER CstateCtrl1; + POPUP_PSTATE_REGISTER PopDownPstate; + CLK_PWR_TIMING_CTRL2_REGISTER ClkPwrTimingCtrl2; + + if ((EntryPoint & CPU_FEAT_AFTER_PM_INIT) != 0) { + // Initialize F4x118 + PciAddress.AddressValue = CSTATE_CTRL1_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); + // Set C-state Action Field 0 + // bits[8] PwrGateEnCstAct0 = 0x1 + // bits[9] PwrOffEnCstAct0 = 0x1 + CstateCtrl1.PwrGateEnCstAct0 = 1; + CstateCtrl1.PwrOffEnCstAct0 = 1; + // Set C-state Action Field 1 + // bits[24] PwrGateEnCstAct1 = 0x1 + // bits[25] PwrOffEnCstAct1 = 0x1 + CstateCtrl1.PwrGateEnCstAct1 = 1; + CstateCtrl1.PwrOffEnCstAct1 = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); + + // Initialize F3xA8[PopDownPstate] = F3xDC[HwPstateMaxVal] + PciAddress.AddressValue = CPTC2_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader); + PciAddress.AddressValue = POPUP_PSTATE_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &PopDownPstate, StdHeader); + PopDownPstate.PopDownPstate = ClkPwrTimingCtrl2.HwPstateMaxVal; + LibAmdPciWrite (AccessWidth32, PciAddress, &PopDownPstate, StdHeader); + } else if ((EntryPoint & (CPU_FEAT_AFTER_RESUME_MTRR_SYNC | CPU_FEAT_BEFORE_RELINQUISH_AP)) != 0) { + // Initialize F4x118 + PciAddress.AddressValue = CSTATE_CTRL1_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); + // Set C-state Action Field 0 + // bits[1] CacheFlushEnCstAct0 = 0x1 + CstateCtrl1.CacheFlushEnCstAct0 = 1; + // Set C-state Action Field 1 + // bits[17] CacheFlushEnCstAct1 = 0x1 + CstateCtrl1.CacheFlushEnCstAct1 = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); + } + return AGESA_SUCCESS; +} + +CONST C6_FAMILY_SERVICES ROMDATA F16KbC6Support = +{ + 0, + F16KbIsC6Supported, + F16KbInitializeC6, + ReloadMicrocodePatchAfterMemInit +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCacheFlushOnHalt.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCacheFlushOnHalt.c new file mode 100644 index 0000000000..95c3a5ab96 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCacheFlushOnHalt.c @@ -0,0 +1,150 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Cache Flush On Halt Function for Family 16h Kabini. + * + * Contains code to initialize Cache Flush On Halt feature for Family 16h Kabini. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuPostInit.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuFeatures.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBCACHEFLUSHONHALT_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +VOID +SetF16KbCacheFlushOnHaltRegister ( + IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * P U B L I C F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * Enable Cpu Cache Flush On Halt Function + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + */ +VOID +SetF16KbCacheFlushOnHaltRegister ( + IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + CSTATE_CTRL1_REGISTER CstateCtrl1; + + if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { + // Set F4x118 + PciAddress.AddressValue = CSTATE_CTRL1_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); + // Set C-state Action Field 0 + // bits[11] NbClkGate0 = 0x1 + // bits[12] SelfRefr0 = 0x1 + CstateCtrl1.NbClkGate0 = 1; + CstateCtrl1.SelfRefr0 = 1; + // Set C-state Action Field 1 + // bits[27] NbClkGate1 = 0x1 + // bits[28] SelfRefr1 = 0x1 + CstateCtrl1.NbClkGate1 = 1; + CstateCtrl1.SelfRefr1 = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); + + //Override the default setting + IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, NULL, StdHeader); + } + +} + +CONST CPU_CFOH_FAMILY_SERVICES ROMDATA F16KbCacheFlushOnHalt = +{ + 0, + SetF16KbCacheFlushOnHaltRegister +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.c new file mode 100644 index 0000000000..0ae46c605e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.c @@ -0,0 +1,250 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini after warm reset sequence for core P-states + * + * Performs the "Core Minimum P-State Transition Sequence After Warm Reset" + * as described in the BKDG. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "F16KbCoreAfterReset.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBCOREAFTERRESET_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +F16KbPmCoreAfterResetPhase1OnCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F16KbPmCoreAfterResetPhase2OnCore ( + IN VOID *HwPsMaxVal, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family 16h Kabini core 0 entry point for performing the necessary steps for core + * P-states after a warm reset has occurred. + * + * The steps are as follows: + * 1. Write 0 to MSRC001_0062[PstateCmd] on all cores in the processor. + * 2. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from + * MSRC001_00[6B:64] indexed by MSRC001_0071[CurPstateLimit]. + * 3. Write MSRC001_0061[PstateMaxVal] to MSRC001_0062[PstateCmd] on all + * cores in the processor. + * 4. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from + * MSRC001_00[6B:64] indexed by MSRC001_0061[PstateMaxVal]. + * 5. If MSRC001_0071[CurPstateLimit] != MSRC001_0071[CurPstate], wait for + * MSRC001_0071[CurCpuVid] = [CpuVid] from MSRC001_00[6B:64] indexed by + * MSRC001_0061[PstateMaxVal]. + * 6. Wait for MSRC001_0063[CurPstate] = MSRC001_0062[PstateCmd]. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParamsPtr Service parameters + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F16KbPmCoreAfterReset ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Core; + UINT32 HwPsMaxVal; + PCI_ADDR PciAddress; + AP_TASK TaskPtr; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbPmCoreAfterReset\n"); + + GetCurrentCore (&Core, StdHeader); + ASSERT (Core == 0); + + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, FUNC_3, CPTC2_REG); + LibAmdPciRead (AccessWidth32, PciAddress, &HwPsMaxVal, StdHeader); + HwPsMaxVal = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &HwPsMaxVal)->HwPstateMaxVal; + + // Launch each local core to perform steps 1 through 3. + TaskPtr.FuncAddress.PfApTask = F16KbPmCoreAfterResetPhase1OnCore; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); + + // Launch each local core to perform steps 4 through 6. + TaskPtr.FuncAddress.PfApTaskI = F16KbPmCoreAfterResetPhase2OnCore; + TaskPtr.DataTransfer.DataSizeInDwords = 1; + TaskPtr.DataTransfer.DataPtr = &HwPsMaxVal; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); +} + + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F16KbPmCoreAfterReset to perform MSR initialization on all + * cores of a family 16h socket. + * + * This function implements steps 1 - 3 on each core. + * + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F16KbPmCoreAfterResetPhase1OnCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 CofvidSts; + UINT64 LocalMsrRegister; + UINT64 PstateCtrl; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbPmCoreAfterResetPhase1OnCore\n"); + + // 1. Write 0 to MSRC001_0062[PstateCmd] on all cores in the processor. + PstateCtrl = 0; + LibAmdMsrWrite (MSR_PSTATE_CTL, &PstateCtrl, StdHeader); + + // 2. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from + // MSRC001_00[6B:64] indexed by MSRC001_0071[CurPstateLimit]. + do { + LibAmdMsrRead (MSR_COFVID_STS, &CofvidSts, StdHeader); + LibAmdMsrRead ((UINT32) (MSR_PSTATE_0 + (UINT32) (((COFVID_STS_MSR *) &CofvidSts)->CurPstateLimit)), &LocalMsrRegister, StdHeader); + } while ((((COFVID_STS_MSR *) &CofvidSts)->CurCpuFid != ((PSTATE_MSR *) &LocalMsrRegister)->CpuFid) || + (((COFVID_STS_MSR *) &CofvidSts)->CurCpuDid != ((PSTATE_MSR *) &LocalMsrRegister)->CpuDid)); + + // 3. Write MSRC001_0061[PstateMaxVal] to MSRC001_0062[PstateCmd] on all + // cores in the processor. + LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &LocalMsrRegister, StdHeader); + ((PSTATE_CTRL_MSR *) &PstateCtrl)->PstateCmd = ((PSTATE_CURLIM_MSR *) &LocalMsrRegister)->PstateMaxVal; + LibAmdMsrWrite (MSR_PSTATE_CTL, &PstateCtrl, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F16KbPmCoreAfterReset to perform MSR initialization on all + * cores of a family 16h socket. + * + * This function implements steps 4 - 6 on each core. + * + * @param[in] HwPsMaxVal Index of the highest enabled HW P-state. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F16KbPmCoreAfterResetPhase2OnCore ( + IN VOID *HwPsMaxVal, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 TargetPsMsr; + UINT64 LocalMsrRegister; + UINT64 PstateCtrl; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbPmCoreAfterResetPhase2OnCore\n"); + + // 4. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from + // MSRC001_00[6B:64] indexed by D18F3xDC[PstateMaxVal]. + LibAmdMsrRead ((*(UINT32 *) HwPsMaxVal) + MSR_PSTATE_0, &TargetPsMsr, StdHeader); + do { + LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader); + } while ((((COFVID_STS_MSR *) &LocalMsrRegister)->CurCpuFid != ((PSTATE_MSR *) &TargetPsMsr)->CpuFid) || + (((COFVID_STS_MSR *) &LocalMsrRegister)->CurCpuDid != ((PSTATE_MSR *) &TargetPsMsr)->CpuDid)); + + // 5. If MSRC001_0071[CurPstateLimit] != MSRC001_0071[CurPstate], wait for + // MSRC001_0071[CurCpuVid] = [CpuVid] from MSRC001_00[6B:64] indexed by + // MSRC001_0061[PstateMaxVal]. + if (((COFVID_STS_MSR *) &LocalMsrRegister)->CurPstateLimit != ((COFVID_STS_MSR *) &LocalMsrRegister)->CurPstate) { + do { + LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader); + } while (GetF16KbCurCpuVid (&LocalMsrRegister) != GetF16KbCpuVid (&TargetPsMsr)); + } + + // 6. Wait for MSRC001_0063[CurPstate] = MSRC001_0062[PstateCmd]. + LibAmdMsrRead (MSR_PSTATE_CTL, &PstateCtrl, StdHeader); + do { + LibAmdMsrRead (MSR_PSTATE_STS, &LocalMsrRegister, StdHeader); + } while (((PSTATE_STS_MSR *) &LocalMsrRegister)->CurPstate != ((PSTATE_CTRL_MSR *) &PstateCtrl)->PstateCmd); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.h new file mode 100644 index 0000000000..2f986286ad --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCoreAfterReset.h @@ -0,0 +1,78 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini after warm reset sequence for core P-states + * + * Contains code that provide power management functionality + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _F16_KB_CORE_AFTER_RESET_H_ +#define _F16_KB_CORE_AFTER_RESET_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +VOID +F16KbPmCoreAfterReset ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _F16_KB_CORE_AFTER_RESET_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCpb.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCpb.c new file mode 100644 index 0000000000..db00c58e95 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbCpb.c @@ -0,0 +1,195 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 CPB Initialization + * + * Enables core performance boost. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuFeatures.h" +#include "cpuCpb.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBCPB_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +F16KbIsCpbSupported ( + IN CPB_FAMILY_SERVICES *CpbServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +STATIC +F16KbInitializeCpb ( + IN CPB_FAMILY_SERVICES *CpbServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT64 EntryPoint, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * BSC entry point for checking whether or not CPB is supported. + * + * @param[in] CpbServices The current CPU's family services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] Socket Zero based socket number to check. + * @param[in] StdHeader Config handle for library and services. + * + * @retval TRUE CPB is supported. + * @retval FALSE CPB is not supported. + * + */ +BOOLEAN +STATIC +F16KbIsCpbSupported ( + IN CPB_FAMILY_SERVICES *CpbServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrData; + BOOLEAN CpbSupported; + CPB_CTRL_REGISTER CpbControl; + PCI_ADDR PciAddress; + + CpbSupported = FALSE; + + PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl, StdHeader); + if (CpbControl.NumBoostStates != 0) { + LibAmdMsrRead (MSR_PSTATE_0, &MsrData, StdHeader); + if (((PSTATE_MSR *) &MsrData)->PsEnable == 1) { + CpbSupported = TRUE; + } + } + return CpbSupported; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * BSC entry point for for enabling Core Performance Boost. + * + * Set up D18F4x15C[BoostSrc] and start the PDMs according to the BKDG. + * + * @param[in] CpbServices The current CPU's family services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] EntryPoint Current CPU feature dispatch point. + * @param[in] Socket Zero based socket number to check. + * @param[in] StdHeader Config handle for library and services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +F16KbInitializeCpb ( + IN CPB_FAMILY_SERVICES *CpbServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT64 EntryPoint, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPB_CTRL_REGISTER CpbControl; + PCI_ADDR PciAddress; + F16_PSTATE_MSR PstateMsrData; + UINT32 Pbx; + + if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { + PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl, StdHeader); + if ((CpbControl.BoostSrc == 0) && (CpbControl.NumBoostStates != 0)) { + // If any boosted P-state is still enabled, set BoostSrc = 1. + for (Pbx = 0; Pbx < CpbControl.NumBoostStates; Pbx++) { + LibAmdMsrRead (PS_REG_BASE + Pbx, (UINT64 *)&PstateMsrData, StdHeader); + if (PstateMsrData.PsEnable == 1) { + CpbControl.BoostSrc = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &CpbControl, StdHeader); + break; + } + } + } + } + return AGESA_SUCCESS; +} + +CONST CPB_FAMILY_SERVICES ROMDATA F16KbCpbSupport = +{ + 0, + F16KbIsCpbSupported, + F16KbInitializeCpb +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c new file mode 100644 index 0000000000..37d0aa0ea3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c @@ -0,0 +1,369 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD DMI Record Creation API, and related functions for Family16h Kabini. + * + * Contains code that produce the DMI related information. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 87400 $ @e \$Date: 2013-02-01 12:14:44 -0600 (Fri, 01 Feb 2013) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuPstateTables.h" +#include "cpuLateInit.h" +#include "cpuF16Dmi.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuServices.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBDMI_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------------------- + * Processor Family Table + * + *-------------------------------------------------------------------------------------*/ +CONST CHAR8 ROMDATA str_A6[] = "AMD A6-"; +CONST CHAR8 ROMDATA str_A4[] = "AMD A4-"; +CONST CHAR8 ROMDATA str_E2[] = "AMD E2-"; +CONST CHAR8 ROMDATA str_E1[] = "AMD E1-"; +CONST CHAR8 ROMDATA str_GX[] = "AMD GX-"; +/*--------------------------------------------------------------------------------------- + * Processor Family Table + * + * 047h = "E-Series" + * 048h = "A-Series" + * 049h = "GX-Series" + *-------------------------------------------------------------------------------------*/ +CONST CPU_T4_PROC_FAMILY ROMDATA F16KbFT3T4ProcFamily[] = +{ + {str_A6, 0x48}, + {str_A4, 0x48}, + {str_E2, 0x47}, + {str_E1, 0x47}, + {str_GX, 0x49}, +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +DmiF16KbGetInfo ( + IN OUT CPU_TYPE_INFO *CpuInfoPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +DmiF16KbGetT4ProcFamily ( + IN OUT UINT8 *T4ProcFamily, + IN PROC_FAMILY_TABLE *CpuDmiProcFamilyTable, + IN CPU_TYPE_INFO *CpuInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +DmiF16KbGetVoltage ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +DmiF16KbGetMemInfo ( + IN OUT CPU_GET_MEM_INFO *CpuGetMemInfoPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT16 +DmiF16KbGetExtClock ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF16KbGetInfo + * + * Get CPU type information + * + * @param[in,out] CpuInfoPtr Pointer to CPU_TYPE_INFO struct. + * @param[in] StdHeader Standard Head Pointer + * + */ +VOID +DmiF16KbGetInfo ( + IN OUT CPU_TYPE_INFO *CpuInfoPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPUID_DATA CpuId; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + LibAmdCpuidRead (AMD_CPUID_FMF, &CpuId, StdHeader); + CpuInfoPtr->ExtendedFamily = (UINT8) (CpuId.EAX_Reg >> 20) & 0xFF; // bit 27:20 + CpuInfoPtr->ExtendedModel = (UINT8) (CpuId.EAX_Reg >> 16) & 0xF; // bit 19:16 + CpuInfoPtr->BaseFamily = (UINT8) (CpuId.EAX_Reg >> 8) & 0xF; // bit 11:8 + CpuInfoPtr->BaseModel = (UINT8) (CpuId.EAX_Reg >> 4) & 0xF; // bit 7:4 + CpuInfoPtr->Stepping = (UINT8) (CpuId.EAX_Reg & 0xF); // bit 3:0 + + CpuInfoPtr->PackageType = (UINT8) (CpuId.EBX_Reg >> 28) & 0xF; // bit 31:28 + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + CpuInfoPtr->TotalCoreNumber = FamilySpecificServices->GetNumberOfPhysicalCores (FamilySpecificServices, StdHeader); + CpuInfoPtr->TotalCoreNumber--; + + LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuId, StdHeader); + CpuInfoPtr->EnabledCoreNumber = (UINT8) (CpuId.ECX_Reg & 0xFF); // bit 7:0 + + switch (CpuInfoPtr->PackageType) { + case KB_SOCKET_FT3: + /// Use 'NONE' for BGA package + CpuInfoPtr->ProcUpgrade = P_UPGRADE_NONE; + break; + default: + CpuInfoPtr->ProcUpgrade = P_UPGRADE_UNKNOWN; + break; + } + + // L1 Size & Associativity + LibAmdCpuidRead (AMD_CPUID_TLB_L1Cache, &CpuId, StdHeader); + CpuInfoPtr->CacheInfo.L1CacheSize = (UINT32) (((CpuId.ECX_Reg >> 24) + (CpuId.EDX_Reg >> 24)) * (CpuInfoPtr->TotalCoreNumber + 1)); + + CpuInfoPtr->CacheInfo.L1CacheAssoc = DMI_ASSOCIATIVE_2_WAY; // Per the BKDG, this is hard-coded to 2-Way. + + // L2 Size & Associativity + LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuId, StdHeader); + CpuInfoPtr->CacheInfo.L2CacheSize = (UINT32) (CpuId.ECX_Reg >> 16); + + CpuInfoPtr->CacheInfo.L2CacheAssoc = DMI_ASSOCIATIVE_16_WAY; // Per the BKDG, this is hard-coded to 16-Way. + + // L3 Size & Associativity + CpuInfoPtr->CacheInfo.L3CacheSize = 0; + CpuInfoPtr->CacheInfo.L3CacheAssoc = DMI_ASSOCIATIVE_UNKNOWN; + } + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF16KbGetT4ProcFamily + * + * Get type 4 processor family information + * + * @param[in,out] T4ProcFamily Pointer to type 4 processor family information. + * @param[in] *CpuDmiProcFamilyTable Pointer to DMI family special service + * @param[in] *CpuInfo Pointer to CPU_TYPE_INFO struct + * @param[in] StdHeader Standard Head Pointer + * + */ +VOID +DmiF16KbGetT4ProcFamily ( + IN OUT UINT8 *T4ProcFamily, + IN PROC_FAMILY_TABLE *CpuDmiProcFamilyTable, + IN CPU_TYPE_INFO *CpuInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CHAR8 NameString[49]; + CONST CHAR8 *DmiString; + CONST VOID *DmiStringTable; + UINT8 NumberOfDmiString; + UINT8 i; + + // Get name string from MSR_C001_00[30:35] + GetNameString (NameString, StdHeader); + // Get DMI String + DmiStringTable = NULL; + switch (CpuInfo->PackageType) { + case KB_SOCKET_FT3: + DmiStringTable = (CONST VOID *) &F16KbFT3T4ProcFamily[0]; + NumberOfDmiString = sizeof (F16KbFT3T4ProcFamily) / sizeof (CPU_T4_PROC_FAMILY); + break; + default: + DmiStringTable = NULL; + NumberOfDmiString = 0; + break; + } + + // Find out which DMI string matches current processor's name string + *T4ProcFamily = P_FAMILY_UNKNOWN; + if ((DmiStringTable != NULL) && (NumberOfDmiString != 0)) { + for (i = 0; i < NumberOfDmiString; i++) { + DmiString = (((CPU_T4_PROC_FAMILY *) DmiStringTable)[i]).Stringstart; + if (IsSourceStrContainTargetStr (NameString, DmiString, StdHeader)) { + *T4ProcFamily = (((CPU_T4_PROC_FAMILY *) DmiStringTable)[i]).T4ProcFamilySetting; + break; + } + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF16KbGetVoltage + * + * Get the voltage value according to SMBIOS SPEC's requirement. + * + * @param[in] StdHeader Standard Head Pointer + * + * @retval Voltage - CPU Voltage. + * + */ +UINT8 +DmiF16KbGetVoltage ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxVid; + UINT8 Voltage; + UINT8 NumberBoostStates; + UINT64 MsrData; + PCI_ADDR TempAddr; + CPB_CTRL_REGISTER CpbCtrl; + + // Voltage = 0x80 + (voltage at boot time * 10) + TempAddr.AddressValue = CPB_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, TempAddr, &CpbCtrl, StdHeader); // F4x15C + NumberBoostStates = (UINT8) CpbCtrl.NumBoostStates; + + LibAmdMsrRead ((MSR_PSTATE_0 + NumberBoostStates), &MsrData, StdHeader); + MaxVid = (UINT8) (((PSTATE_MSR *)&MsrData)->CpuVid); + + if ((MaxVid >= 0xF8) && (MaxVid <= 0xFF)) { + Voltage = 0; + } else { + Voltage = (UINT8) ((155000L - (625 * MaxVid) + 5000) / 10000); + } + + Voltage += 0x80; + return (Voltage); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF16KbGetMemInfo + * + * Get memory information. + * + * @param[in,out] CpuGetMemInfoPtr Pointer to CPU_GET_MEM_INFO struct. + * @param[in] StdHeader Standard Head Pointer + * + */ +VOID +DmiF16KbGetMemInfo ( + IN OUT CPU_GET_MEM_INFO *CpuGetMemInfoPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PciData; + PCI_ADDR PciAddress; + + CpuGetMemInfoPtr->EccCapable = FALSE; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_2, 0x90); + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + // Check if F2x90[DimmEccEn] is set + if ((PciData & 0x00080000) != 0) { + CpuGetMemInfoPtr->EccCapable = TRUE; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF16KbGetExtClock + * + * Get the external clock Speed + * + * @param[in] StdHeader Standard Head Pointer + * + * @retval ExtClock - CPU external clock Speed. + * + */ +UINT16 +DmiF16KbGetExtClock ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return (EXTERNAL_CLOCK_DFLT); +} + +/* -----------------------------------------------------------------------------*/ +CONST PROC_FAMILY_TABLE ROMDATA ProcFamily16KbDmiTable = +{ +// This table is for Processor family 16h Kabini + AMD_FAMILY_16_KB, // ID for Family 16h Kabini + DmiF16KbGetInfo, // Transfer vectors for family + DmiF16KbGetT4ProcFamily, // Get type 4 processor family information + DmiF16KbGetVoltage, // specific routines (above) + DmiF16GetMaxSpeed, + DmiF16KbGetExtClock, + DmiF16KbGetMemInfo, // Get memory information + 0, + NULL +}; + + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbEquivalenceTable.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbEquivalenceTable.c new file mode 100644 index 0000000000..02e5df92af --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbEquivalenceTable.c @@ -0,0 +1,120 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini Equivalence Table related data + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#include "amdlib.h" +#include "cpuRegisters.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBEQUIVALENCETABLE_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GetF16KbMicrocodeEquivalenceTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **KbEquivalenceTablePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +STATIC CONST UINT16 ROMDATA stu1[] = +{ + 0x7001, 0x7001, + 0x7000, 0x7000 +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the appropriate microcode patch equivalent ID table. + * + * @CpuServiceMethod{::F_CPU_GET_FAMILY_SPECIFIC_ARRAY}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] KbEquivalenceTablePtr Points to the first entry in the table. + * @param[out] NumberOfElements Number of valid entries in the table. + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetF16KbMicrocodeEquivalenceTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **KbEquivalenceTablePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrDeCfg; + + LibAmdMsrRead (0xC0011029, &MsrDeCfg, StdHeader); + if ((MsrDeCfg & BIT12) == 0) { + } else { + *NumberOfElements = ((sizeof (stu1) / sizeof (UINT16)) / 2); + *KbEquivalenceTablePtr = stu1; + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbHtc.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbHtc.c new file mode 100644 index 0000000000..9b93e4512d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbHtc.c @@ -0,0 +1,178 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini thermal initialization + * + * Performs processor thermal initialization. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 85817 $ @e \$Date: 2013-01-11 16:58:12 -0600 (Fri, 11 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "CommonReturns.h" +#include "cpuFeatures.h" +#include "cpuHtc.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "GnbHandleLib.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBHTC_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +STATIC +F16KbInitializeHtc ( + IN HTC_FAMILY_SERVICES *HtcServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Main entry point for initializing the Thermal Control + * safety net feature. + * + * This must be run by all Family 16h Kabini core 0s in the system. + * + * @param[in] HtcServices The current CPU's family services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] StdHeader Config handle for library and services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +F16KbInitializeHtc ( + IN HTC_FAMILY_SERVICES *HtcServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 HtcTempLimit; + NB_CAPS_REGISTER NbCaps; + HTC_REGISTER HtcReg; + CLK_PWR_TIMING_CTRL2_REGISTER Cptc2; + POPUP_PSTATE_REGISTER PopUpPstate; + PCI_ADDR PciAddress; + UINT32 D0F0xBC_xC0107097; + + if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { + PciAddress.AddressValue = NB_CAPS_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbCaps, StdHeader); + if (NbCaps.HtcCapable == 1) { + // Enable HTC + PciAddress.Address.Register = HTC_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &HtcReg, StdHeader); + GnbRegisterReadKB (GnbGetHandle (StdHeader), 0x4, 0xC0107097, &D0F0xBC_xC0107097, 0, StdHeader); + HtcReg.HtcTmpLmt = (D0F0xBC_xC0107097 >> 3) & 0x7F; + if (HtcReg.HtcTmpLmt != 0) { + // Enable HTC + HtcReg.HtcEn = 1; + PciAddress.Address.Register = CPTC2_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &Cptc2, StdHeader); + if (HtcReg.HtcPstateLimit > Cptc2.HwPstateMaxVal) { + // F3xDC[HwPstateMaxVal] = F3x64[HtcPstateLimit] + Cptc2.HwPstateMaxVal = HtcReg.HtcPstateLimit; + LibAmdPciWrite (AccessWidth32, PciAddress, &Cptc2, StdHeader); + // F3xA8[PopDownPstate] = F3xDC[HwPstateMaxVal] + PciAddress.Address.Register = POPUP_PSTATE_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PopUpPstate, StdHeader); + PopUpPstate.PopDownPstate = Cptc2.HwPstateMaxVal; + LibAmdPciWrite (AccessWidth32, PciAddress, &PopUpPstate, StdHeader); + } + if ((PlatformConfig->HtcTemperatureLimit >= 520) && (PlatformConfig->LhtcTemperatureLimit != 0)) { + HtcTempLimit = ((PlatformConfig->HtcTemperatureLimit - 520) / 5); + if (HtcTempLimit < HtcReg.HtcTmpLmt) { + HtcReg.HtcTmpLmt = HtcTempLimit; + } + } + } else { + // Disable HTC + HtcReg.HtcEn = 0; + } + PciAddress.Address.Register = HTC_REG; + IDS_OPTION_HOOK (IDS_HTC_CTRL, &HtcReg, StdHeader); + LibAmdPciWrite (AccessWidth32, PciAddress, &HtcReg, StdHeader); + } + } + return AGESA_SUCCESS; +} + +CONST HTC_FAMILY_SERVICES ROMDATA F16KbHtcSupport = +{ + 0, + (PF_HTC_IS_SUPPORTED) CommonReturnTrue, + F16KbInitializeHtc +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbInitEarlyTable.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbInitEarlyTable.c new file mode 100644 index 0000000000..9c0e54baca --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbInitEarlyTable.c @@ -0,0 +1,143 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize the Family 16h Kabini specific way of running early initialization. + * + * Returns the table of initialization steps to perform at + * AmdInitEarly. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x16/KB + * @e \$Revision: 86705 $ @e \$Date: 2013-01-24 17:34:21 -0600 (Thu, 24 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#include "cpuEarlyInit.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBINITEARLYTABLE_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern CONST S_PERFORM_EARLY_INIT_ON_CORE ROMDATA F16KbEarlyInitBeforeApLaunchOnCoreTable[]; +extern CONST S_PERFORM_EARLY_INIT_ON_CORE ROMDATA F16KbEarlyInitAfterApLaunchOnCoreTable[]; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +GetF16KbEarlyInitBeforeApLaunchOnCoreTable ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST S_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetF16KbEarlyInitAfterApLaunchOnCoreTable ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST S_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------------------*/ +/** + * Initializer routine that may be invoked at AmdCpuEarly (Before AP launch) to return the steps that a + * processor that uses the standard initialization steps should take. + * + * @CpuServiceMethod{::F_GET_EARLY_INIT_TABLE}. + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[out] Table Table of appropriate init steps for the executing core. + * @param[in] EarlyParams Service Interface structure to initialize. + * @param[in] StdHeader Opaque handle to standard config header. + * + */ +VOID +GetF16KbEarlyInitBeforeApLaunchOnCoreTable ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST S_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *Table = F16KbEarlyInitBeforeApLaunchOnCoreTable; +} + +/*------------------------------------------------------------------------------------*/ +/** + * Initializer routine that may be invoked at AmdCpuEarly (After AP launch) to return the steps that a + * processor that uses the standard initialization steps should take. + * + * @CpuServiceMethod{::F_GET_EARLY_INIT_TABLE}. + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[out] Table Table of appropriate init steps for the executing core. + * @param[in] EarlyParams Service Interface structure to initialize. + * @param[in] StdHeader Opaque handle to standard config header. + * + */ +VOID +GetF16KbEarlyInitAfterApLaunchOnCoreTable ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST S_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *Table = F16KbEarlyInitAfterApLaunchOnCoreTable; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbIoCstate.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbIoCstate.c new file mode 100644 index 0000000000..d3923d6a75 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbIoCstate.c @@ -0,0 +1,371 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini IO C-state feature support functions. + * + * Provides the functions necessary to initialize the IO C-state feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuFeatures.h" +#include "cpuIoCstate.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "CommonReturns.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBIOCSTATE_FILECODE + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +F16KbInitializeIoCstateOnCore ( + IN VOID *CstateBaseMsr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16KbIsCsdObjGenerated ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE IoCstateFamilyServiceTable; + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable IO Cstate on a family 16h Kabini CPU. + * Implement BIOS Requirements for Initialization of C-states + * + * @param[in] IoCstateServices Pointer to this CPU's IO Cstate family services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +F16KbInitializeIoCstate ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 LocalMsrRegister; + AP_TASK TaskPtr; + PCI_ADDR PciAddress; + CSTATE_POLICY_CTRL1_REGISTER CstatePolicyCtrl1; + + if ((EntryPoint & CPU_FEAT_AFTER_PM_INIT) != 0) { + // Initialize F4x128 + // bit[4:2] HaltCstateIndex = 0 + PciAddress.AddressValue = CSTATE_POLICY_CTRL1_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &CstatePolicyCtrl1, StdHeader); + CstatePolicyCtrl1.HaltCstateIndex = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &CstatePolicyCtrl1, StdHeader); + + // Initialize MSRC001_0073[CstateAddr] on each core to a region of + // the IO address map with 8 consecutive available addresses. + LocalMsrRegister = 0; + + IDS_HDT_CONSOLE (CPU_TRACE, " Init IO C-state Base at 0x%x\n", PlatformConfig->CStateIoBaseAddress); + ((CSTATE_ADDRESS_MSR *) &LocalMsrRegister)->CstateAddr = PlatformConfig->CStateIoBaseAddress; + + TaskPtr.FuncAddress.PfApTaskI = F16KbInitializeIoCstateOnCore; + TaskPtr.DataTransfer.DataSizeInDwords = 2; + TaskPtr.DataTransfer.DataPtr = &LocalMsrRegister; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL); + } + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable CState on a family 16h Kabini core. + * + * @param[in] CstateBaseMsr MSR value to write to C001_0073 as determined by core 0. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +STATIC +F16KbInitializeIoCstateOnCore ( + IN VOID *CstateBaseMsr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // Initialize MSRC001_0073[CstateAddr] on each core + LibAmdMsrWrite (MSR_CSTATE_ADDRESS, (UINT64 *) CstateBaseMsr, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the size of CST object + * + * @param[in] IoCstateServices IO Cstate services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data + * @param[in] StdHeader Config Handle for library, services. + * + * @retval CstObjSize Size of CST Object + * + */ +UINT32 +STATIC +F16KbGetAcpiCstObj ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN GenerateCsdObj; + UINT32 CStateAcpiObjSize; + IO_CSTATE_FAMILY_SERVICES *FamilyServices; + ACPI_CST_GET_INPUT CstGetInput; + + CstGetInput.IoCstateServices = IoCstateServices; + CstGetInput.PlatformConfig = PlatformConfig; + CstGetInput.CStateAcpiObjSizePtr = &CStateAcpiObjSize; + + IDS_SKIP_HOOK (IDS_CST_SIZE, &CstGetInput, StdHeader) { + CStateAcpiObjSize = CST_HEADER_SIZE + CST_BODY_SIZE; + + // If CSD Object is generated, add the size of CSD Object to the total size of + // CState ACPI Object size + GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + GenerateCsdObj = FamilyServices->IsCsdObjGenerated (FamilyServices, StdHeader); + + if (GenerateCsdObj) { + CStateAcpiObjSize += CSD_HEADER_SIZE + CSD_BODY_SIZE; + } + } + return CStateAcpiObjSize; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Routine to generate the C-State ACPI objects + * + * @param[in] IoCstateServices IO Cstate services. + * @param[in] LocalApicId Local Apic Id for each core. + * @param[in, out] **PstateAcpiBufferPtr Pointer to the Acpi Buffer Pointer. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +STATIC +F16KbCreateAcpiCstObj ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN UINT8 LocalApicId, + IN OUT VOID **PstateAcpiBufferPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrData; + BOOLEAN GenerateCsdObj; + CST_HEADER_STRUCT *CstHeaderPtr; + CST_BODY_STRUCT *CstBodyPtr; + CSD_HEADER_STRUCT *CsdHeaderPtr; + CSD_BODY_STRUCT *CsdBodyPtr; + IO_CSTATE_FAMILY_SERVICES *FamilyServices; + ACPI_CST_CREATE_INPUT CstInput; + + CstInput.IoCstateServices = IoCstateServices; + CstInput.LocalApicId = LocalApicId; + CstInput.PstateAcpiBufferPtr = PstateAcpiBufferPtr; + + IDS_SKIP_HOOK (IDS_CST_CREATE, &CstInput, StdHeader) { + // Read from MSR C0010073 to obtain CstateAddr + LibAmdMsrRead (MSR_CSTATE_ADDRESS, &MsrData, StdHeader); + + // Typecast the pointer + CstHeaderPtr = (CST_HEADER_STRUCT *) *PstateAcpiBufferPtr; + + // Set CST Header + CstHeaderPtr->NameOpcode = NAME_OPCODE; + CstHeaderPtr->CstName_a__ = CST_NAME__; + CstHeaderPtr->CstName_a_C = CST_NAME_C; + CstHeaderPtr->CstName_a_S = CST_NAME_S; + CstHeaderPtr->CstName_a_T = CST_NAME_T; + + // Typecast the pointer + CstHeaderPtr++; + CstBodyPtr = (CST_BODY_STRUCT *) CstHeaderPtr; + + // Set CST Body + CstBodyPtr->PkgOpcode = PACKAGE_OPCODE; + CstBodyPtr->PkgLength = CST_LENGTH; + CstBodyPtr->PkgElements = CST_NUM_OF_ELEMENTS; + CstBodyPtr->BytePrefix = BYTE_PREFIX_OPCODE; + CstBodyPtr->Count = CST_COUNT; + CstBodyPtr->PkgOpcode2 = PACKAGE_OPCODE; + CstBodyPtr->PkgLength2 = CST_PKG_LENGTH; + CstBodyPtr->PkgElements2 = CST_PKG_ELEMENTS; + CstBodyPtr->BufferOpcode = BUFFER_OPCODE; + CstBodyPtr->BufferLength = CST_SUBPKG_LENGTH; + CstBodyPtr->BufferElements = CST_SUBPKG_ELEMENTS; + CstBodyPtr->BufferOpcode2 = BUFFER_OPCODE; + CstBodyPtr->GdrOpcode = GENERIC_REG_DESCRIPTION; + CstBodyPtr->GdrLength = CST_GDR_LENGTH; + CstBodyPtr->AddrSpaceId = GDR_ASI_SYSTEM_IO; + CstBodyPtr->RegBitWidth = 0x08; + CstBodyPtr->RegBitOffset = 0x00; + CstBodyPtr->AddressSize = GDR_ASZ_BYTE_ACCESS; + CstBodyPtr->RegisterAddr = ((CSTATE_ADDRESS_MSR *) &MsrData)->CstateAddr + 1; + CstBodyPtr->EndTag = 0x0079; + CstBodyPtr->BytePrefix2 = BYTE_PREFIX_OPCODE; + CstBodyPtr->Type = CST_C2_TYPE; + CstBodyPtr->WordPrefix = WORD_PREFIX_OPCODE; + CstBodyPtr->Latency = 400; + CstBodyPtr->DWordPrefix = DWORD_PREFIX_OPCODE; + CstBodyPtr->Power = 0; + + CstBodyPtr++; + //Update the pointer + *PstateAcpiBufferPtr = CstBodyPtr; + + + // Check whether CSD object should be generated + GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + GenerateCsdObj = FamilyServices->IsCsdObjGenerated (FamilyServices, StdHeader); + + if (GenerateCsdObj) { + CsdHeaderPtr = (CSD_HEADER_STRUCT *) *PstateAcpiBufferPtr; + + // Set CSD Header + CsdHeaderPtr->NameOpcode = NAME_OPCODE; + CsdHeaderPtr->CsdName_a__ = CST_NAME__; + CsdHeaderPtr->CsdName_a_C = CST_NAME_C; + CsdHeaderPtr->CsdName_a_S = CST_NAME_S; + CsdHeaderPtr->CsdName_a_D = CSD_NAME_D; + + CsdHeaderPtr++; + CsdBodyPtr = (CSD_BODY_STRUCT *) CsdHeaderPtr; + + // Set CSD Body + CsdBodyPtr->PkgOpcode = PACKAGE_OPCODE; + CsdBodyPtr->PkgLength = CSD_BODY_SIZE - 1; + CsdBodyPtr->PkgElements = 1; + CsdBodyPtr->PkgOpcode2 = PACKAGE_OPCODE; + CsdBodyPtr->PkgLength2 = CSD_BODY_SIZE - 4; // CSD_BODY_SIZE - Package() - Package Opcode + CsdBodyPtr->PkgElements2 = 6; + CsdBodyPtr->BytePrefix = BYTE_PREFIX_OPCODE; + CsdBodyPtr->NumEntries = 6; + CsdBodyPtr->BytePrefix2 = BYTE_PREFIX_OPCODE; + CsdBodyPtr->Revision = 0; + CsdBodyPtr->DWordPrefix = DWORD_PREFIX_OPCODE; + CsdBodyPtr->Domain = (LocalApicId & 0xFE) >> 1; + CsdBodyPtr->DWordPrefix2 = DWORD_PREFIX_OPCODE; + CsdBodyPtr->CoordType = CSD_COORD_TYPE_HW_ALL; + CsdBodyPtr->DWordPrefix3 = DWORD_PREFIX_OPCODE; + CsdBodyPtr->NumProcessors = 0x2; + CsdBodyPtr->DWordPrefix4 = DWORD_PREFIX_OPCODE; + CsdBodyPtr->Index = 0x0; + + CsdBodyPtr++; + + // Update the pointer + *PstateAcpiBufferPtr = CsdBodyPtr; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Routine to check whether CSD object should be created. + * + * @param[in] IoCstateServices IO Cstate services. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE CSD Object should be created. + * @retval FALSE CSD Object should not be created. + * + */ +BOOLEAN +F16KbIsCsdObjGenerated ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // CSD Object should only be created when there are two cores per compute unit + if (GetComputeUnitMapping (StdHeader) == EvenCoresMapping) { + return TRUE; + } + return FALSE; +} + +CONST IO_CSTATE_FAMILY_SERVICES ROMDATA F16KbIoCstateSupport = +{ + 0, + (PF_IO_CSTATE_IS_SUPPORTED) CommonReturnTrue, + F16KbInitializeIoCstate, + F16KbGetAcpiCstObj, + F16KbCreateAcpiCstObj, + F16KbIsCsdObjGenerated +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbLogicalIdTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbLogicalIdTables.c new file mode 100644 index 0000000000..97affa017c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbLogicalIdTables.c @@ -0,0 +1,107 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini Logical ID Table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuRegisters.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBLOGICALIDTABLES_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GetF16KbLogicalIdAndRev ( + OUT CONST CPU_LOGICAL_ID_XLAT **KbIdPtr, + OUT UINT8 *NumberOfElements, + OUT UINT64 *LogicalFamily, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +STATIC CONST CPU_LOGICAL_ID_XLAT ROMDATA CpuF16KbLogicalIdAndRevArray[] = +{ + { + 0x7001, + AMD_F16_KB_A1 + }, + { + 0x7000, + AMD_F16_KB_A0 + }, +}; + +VOID +GetF16KbLogicalIdAndRev ( + OUT CONST CPU_LOGICAL_ID_XLAT **KbIdPtr, + OUT UINT8 *NumberOfElements, + OUT UINT64 *LogicalFamily, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = (sizeof (CpuF16KbLogicalIdAndRevArray) / sizeof (CPU_LOGICAL_ID_XLAT)); + *KbIdPtr = CpuF16KbLogicalIdAndRevArray; + *LogicalFamily = AMD_FAMILY_16_KB; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatch0700002A_Enc.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatch0700002A_Enc.c new file mode 100644 index 0000000000..5a010ae1a4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatch0700002A_Enc.c @@ -0,0 +1,3539 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD F16Kb Microcode patch. + * + * F16Kb Microcode Patch rev 0700002A for 7000 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84798 $ @e \$Date: 2012-12-19 21:26:23 -0600 (Wed, 19 Dec 2012) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuEarlyInit.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +// Encrypt Patch code 0700002A for 7000 and equivalent + +CONST UINT8 ROMDATA arr1 [IDS_PAD_4K] = +{ + 0x12, + 0x20, + 0x18, + 0x12, + 0x2a, + 0x00, + 0x00, + 0x07, + 0x03, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x70, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xaa, + 0xaa, + 0x49, + 0x98, + 0x47, + 0x92, + 0x9e, + 0x94, + 0x1c, + 0x90, + 0x43, + 0x82, + 0xfb, + 0x61, + 0x5c, + 0xc3, + 0x8a, + 0xb1, + 0xd7, + 0x77, + 0xc5, + 0x2f, + 0xe2, + 0x32, + 0x8e, + 0xa2, + 0xfe, + 0x17, + 0x86, + 0x8b, + 0xea, + 0xf8, + 0x9c, + 0x9a, + 0xdb, + 0x75, + 0x44, + 0x1c, + 0x12, + 0xd5, + 0x0f, + 0x64, + 0x9f, + 0x29, + 0x38, + 0x9c, + 0xec, + 0xfd, + 0x20, + 0xb9, + 0x5c, + 0x11, + 0xfa, + 0xac, + 0xde, + 0xa7, + 0xaf, + 0xb2, + 0x71, + 0x1b, + 0x5d, + 0x8d, + 0x0a, + 0x84, + 0xff, + 0xae, + 0x77, + 0xef, + 0xee, + 0xe8, + 0xb9, + 0xe4, + 0x4c, + 0xcf, + 0x43, + 0x69, + 0xda, + 0x62, + 0x85, + 0x56, + 0x75, + 0xf4, + 0xa9, + 0x9e, + 0x2a, + 0x63, + 0x6d, + 0xdd, + 0xcb, + 0x04, + 0x18, + 0xeb, + 0xa5, + 0xab, + 0x8d, + 0xd7, + 0x03, + 0x48, + 0x71, + 0x18, + 0x18, + 0x3e, + 0xff, + 0x33, + 0x60, + 0xb0, + 0x43, + 0x6c, + 0xa3, + 0xc6, + 0x78, + 0x0a, + 0xc8, + 0x88, + 0x0b, + 0x85, + 0x34, + 0x41, + 0x72, + 0xe7, + 0x2f, + 0xac, + 0x22, + 0x75, + 0x9c, + 0xe3, + 0x58, + 0xa0, + 0xf4, + 0xa7, + 0x39, + 0x42, + 0x6c, + 0x39, + 0xe6, + 0x8e, + 0xd2, + 0xbc, + 0x6d, + 0xea, + 0x84, + 0xb6, + 0x83, + 0xdf, + 0xfa, + 0x39, + 0xf8, + 0x22, + 0x55, + 0xd4, + 0x69, + 0x89, + 0x6a, + 0xcd, + 0xb0, + 0x3d, + 0xdc, + 0x2e, + 0x16, + 0xcd, + 0xd6, + 0xeb, + 0x66, + 0x67, + 0x74, + 0xc1, + 0x3c, + 0x7c, + 0xed, + 0xce, + 0x4c, + 0x15, + 0xdf, + 0x64, + 0x80, + 0xbc, + 0x7f, + 0xee, + 0x45, + 0x2f, + 0xa2, + 0x64, + 0x3b, + 0xed, + 0x26, + 0xdd, + 0xb5, + 0xb7, + 0xef, + 0xa2, + 0x7d, + 0x9b, + 0x05, + 0x67, + 0xbe, + 0x6e, + 0xbd, + 0xb4, + 0x7d, + 0x22, + 0x9f, + 0xea, + 0x5b, + 0xe5, + 0xf2, + 0x4b, + 0x5c, + 0xfa, + 0xad, + 0xcc, + 0x41, + 0x10, + 0x63, + 0x1a, + 0xc3, + 0x7a, + 0x8a, + 0x1e, + 0xc2, + 0x41, + 0x3f, + 0xde, + 0x82, + 0x7c, + 0xa9, + 0x49, + 0x43, + 0xd2, + 0x05, + 0x83, + 0xe6, + 0x2c, + 0x3f, + 0xb1, + 0x61, + 0xac, + 0x78, + 0x8a, + 0x03, + 0xe9, + 0xda, + 0x54, + 0xfd, + 0x80, + 0x93, + 0x32, + 0x84, + 0xf6, + 0xee, + 0xb1, + 0x5b, + 0xa4, + 0x3e, + 0x0d, + 0x7a, + 0x6a, + 0x53, + 0x85, + 0x61, + 0x29, + 0x17, + 0xb6, + 0xd3, + 0xaa, + 0x02, + 0x2e, + 0xef, + 0x99, + 0x23, + 0x88, + 0x70, + 0xa8, + 0xfa, + 0xbf, + 0x0a, + 0xac, + 0x41, + 0x1f, + 0x38, + 0x03, + 0x12, + 0x9f, + 0x87, + 0xd8, + 0x74, + 0xdb, + 0xf5, + 0x51, + 0x53, + 0xb0, + 0x57, + 0x74, + 0x1d, + 0xcd, + 0x21, + 0x0e, + 0xa8, + 0x0f, + 0x3e, + 0x0c, + 0x40, + 0x09, + 0xd2, + 0x1d, + 0xd7, + 0xb1, + 0x85, + 0x0d, + 0x1f, + 0x47, + 0x3e, + 0x59, + 0x67, + 0x09, + 0x95, + 0xbb, + 0x05, + 0x52, + 0x7f, + 0xf3, + 0xc2, + 0xf5, + 0x1a, + 0x80, + 0x6d, + 0x31, + 0x18, + 0x9d, + 0xc4, + 0x47, + 0xb4, + 0x5f, + 0x3c, + 0xbb, + 0x20, + 0x51, + 0x02, + 0x5a, + 0x32, + 0x13, + 0x8d, + 0x25, + 0x99, + 0x8d, + 0xa1, + 0x87, + 0x53, + 0xff, + 0x0b, + 0x74, + 0x68, + 0x85, + 0x34, + 0x3a, + 0x56, + 0xfd, + 0x68, + 0x0c, + 0x15, + 0xd2, + 0x67, + 0x4b, + 0x45, + 0xa5, + 0x1b, + 0x5c, + 0x5b, + 0xc9, + 0x08, + 0x73, + 0x99, + 0xd4, + 0xbb, + 0xca, + 0x5c, + 0x96, + 0x39, + 0x9c, + 0xbb, + 0xfe, + 0x1d, + 0xff, + 0x70, + 0xe1, + 0xdd, + 0xfb, + 0xb7, + 0x5a, + 0xce, + 0x1f, + 0x16, + 0xc8, + 0x2b, + 0x2d, + 0xa5, + 0xdc, + 0xbf, + 0x08, + 0xfe, + 0x8a, + 0xf8, + 0xd6, + 0xd7, + 0xf5, + 0x0e, + 0x5e, + 0xcf, + 0xb1, + 0x0f, + 0xf8, + 0x0c, + 0x89, + 0xb4, + 0x36, + 0xd3, + 0x81, + 0xe4, + 0xd5, + 0x16, + 0x23, + 0xe3, + 0x1c, + 0xb3, + 0xe1, + 0x82, + 0x41, + 0x81, + 0xd4, + 0x6b, + 0xc2, + 0x51, + 0xfb, + 0x26, + 0x59, + 0x9c, + 0x01, + 0xc2, + 0xc7, + 0xc1, + 0x60, + 0xf9, + 0xe0, + 0xfc, + 0x46, + 0xc0, + 0xd1, + 0xf7, + 0xc7, + 0xe1, + 0x44, + 0x23, + 0x3c, + 0x9d, + 0xec, + 0xbb, + 0x6e, + 0x88, + 0xae, + 0x2c, + 0xec, + 0xfb, + 0x5f, + 0xf4, + 0x12, + 0x35, + 0xff, + 0x09, + 0x81, + 0x66, + 0x81, + 0x56, + 0xcd, + 0xee, + 0x62, + 0x61, + 0x4d, + 0xc3, + 0xb7, + 0x45, + 0xa4, + 0xec, + 0x07, + 0xca, + 0x49, + 0xce, + 0x34, + 0x56, + 0x33, + 0xdf, + 0xaa, + 0xcb, + 0xf4, + 0xf8, + 0x00, + 0x29, + 0x2f, + 0x30, + 0xf4, + 0xb9, + 0x7a, + 0x5b, + 0x1b, + 0xb5, + 0xe4, + 0x14, + 0x78, + 0x04, + 0x04, + 0xb6, + 0x51, + 0xd2, + 0xf6, + 0xf1, + 0xf4, + 0x09, + 0xca, + 0x66, + 0xe5, + 0x79, + 0xda, + 0xff, + 0xbd, + 0x23, + 0x3e, + 0xb9, + 0xcb, + 0x81, + 0x4b, + 0x32, + 0xff, + 0x3d, + 0x64, + 0x5b, + 0xf3, + 0x78, + 0xe7, + 0x91, + 0x40, + 0x89, + 0xf4, + 0xdc, + 0x50, + 0xa7, + 0xd7, + 0x2c, + 0xd1, + 0x93, + 0x4d, + 0x7f, + 0x35, + 0xa7, + 0xd1, + 0xd1, + 0x17, + 0x99, + 0x63, + 0xae, + 0x8a, + 0x4c, + 0x5a, + 0x50, + 0x47, + 0xa7, + 0x15, + 0x5e, + 0xbc, + 0x09, + 0xce, + 0x7f, + 0x54, + 0x70, + 0xfc, + 0x22, + 0xef, + 0x86, + 0x57, + 0xa7, + 0x68, + 0x01, + 0x00, + 0x00, + 0x00, + 0x2a, + 0x00, + 0x00, + 0x07, + 0x0c, + 0x1b, + 0xae, + 0x1d, + 0x63, + 0x04, + 0x5d, + 0x04, + 0x05, + 0x1a, + 0xd4, + 0x06, + 0xa0, + 0x0d, + 0x0e, + 0x13, + 0xec, + 0x0f, + 0x1b, + 0x10, + 0xe7, + 0x13, + 0x40, + 0x1f, + 0x70, + 0x10, + 0x3e, + 0x11, + 0xe2, + 0x13, + 0x93, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xf7, + 0x7f, + 0x22, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0x43, + 0x0c, + 0xfe, + 0x00, + 0xe1, + 0xcf, + 0x43, + 0xd7, + 0xf1, + 0xa4, + 0x06, + 0x00, + 0x65, + 0xd1, + 0x38, + 0x80, + 0xc1, + 0x1f, + 0x10, + 0xe0, + 0xf7, + 0xff, + 0xff, + 0x80, + 0xe1, + 0x1b, + 0x8a, + 0xfa, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xff, + 0xbf, + 0x2e, + 0xe0, + 0x9f, + 0xab, + 0xff, + 0xff, + 0x7f, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xbf, + 0xf8, + 0xb9, + 0x06, + 0x00, + 0x5a, + 0x5c, + 0x39, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xdf, + 0xff, + 0xff, + 0x2e, + 0xe0, + 0x1f, + 0xab, + 0xfa, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x9d, + 0x4b, + 0xe1, + 0x0a, + 0xa0, + 0x06, + 0x00, + 0x8e, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xcf, + 0x43, + 0xd7, + 0x70, + 0x5c, + 0x39, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xa3, + 0xdb, + 0x38, + 0x00, + 0xc1, + 0xdf, + 0xd9, + 0xeb, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xda, + 0xb8, + 0x06, + 0x00, + 0x00, + 0xff, + 0xff, + 0x3c, + 0xe1, + 0x5f, + 0xeb, + 0xfe, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xdb, + 0x7a, + 0x00, + 0xc0, + 0x1f, + 0xdb, + 0xeb, + 0xf4, + 0x01, + 0x39, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0x4d, + 0xa0, + 0x06, + 0x00, + 0x5b, + 0xd4, + 0x38, + 0x00, + 0x80, + 0x1f, + 0xc0, + 0xff, + 0x9f, + 0xfa, + 0xff, + 0xac, + 0xe1, + 0x1f, + 0xeb, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf8, + 0xff, + 0xff, + 0x2c, + 0xe1, + 0x1f, + 0xeb, + 0xfe, + 0xe2, + 0xff, + 0xff, + 0x2e, + 0xe1, + 0x9f, + 0xab, + 0xfa, + 0x27, + 0xb9, + 0x06, + 0x00, + 0x0d, + 0xdd, + 0x38, + 0xc0, + 0xa1, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x26, + 0xb9, + 0x06, + 0x00, + 0xfd, + 0xff, + 0xff, + 0x2c, + 0xe0, + 0x9f, + 0x6b, + 0xf1, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xf3, + 0xb8, + 0x06, + 0x00, + 0xf0, + 0x58, + 0x39, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xf0, + 0x5c, + 0x39, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x43, + 0xdc, + 0x38, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0x3f, + 0xdc, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0x1f, + 0xa3, + 0x06, + 0x00, + 0xff, + 0x7f, + 0xff, + 0x2e, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0x8d, + 0xdf, + 0x38, + 0x00, + 0xc1, + 0x1f, + 0x10, + 0xe0, + 0xff, + 0xbd, + 0x07, + 0x00, + 0x38, + 0xdd, + 0x38, + 0xc0, + 0xa1, + 0x1f, + 0xc0, + 0xe7, + 0xb1, + 0xfe, + 0x38, + 0xc0, + 0xa1, + 0x1f, + 0xc0, + 0xe7, + 0xe6, + 0x2f, + 0x06, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x56, + 0x5f, + 0x06, + 0x00, + 0xf8, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0x5f, + 0xeb, + 0xfe, + 0xf0, + 0xff, + 0xff, + 0x2e, + 0xe1, + 0x9f, + 0xeb, + 0xfe, + 0x56, + 0xb8, + 0x06, + 0x00, + 0xff, + 0xdd, + 0x7f, + 0x00, + 0xe1, + 0x5d, + 0x8b, + 0xfe, + 0xff, + 0xdb, + 0x7f, + 0x2e, + 0xe1, + 0x8f, + 0x6b, + 0xcb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x67, + 0xd9, + 0x3a, + 0x00, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x42, + 0xa0, + 0x06, + 0x00, + 0x9d, + 0xf1, + 0xef, + 0x2b, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xe0, + 0xff, + 0xff, + 0x2f, + 0xe1, + 0x1f, + 0xe0, + 0xac, + 0xdf, + 0xfb, + 0xff, + 0x2c, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0x2c, + 0xa0, + 0x06, + 0x00, + 0xf7, + 0x63, + 0x3f, + 0x00, + 0xc0, + 0x9f, + 0xd9, + 0xeb, + 0xef, + 0x61, + 0x3f, + 0x00, + 0xc0, + 0x9f, + 0xd9, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd7, + 0x7a, + 0x00, + 0xc0, + 0xdf, + 0xda, + 0xeb, + 0xe7, + 0xff, + 0xff, + 0x00, + 0xe0, + 0xdd, + 0x0a, + 0xf9, + 0x81, + 0xaf, + 0x06, + 0x00, + 0xef, + 0x56, + 0x39, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0xdf, + 0xff, + 0xff, + 0x2f, + 0xe0, + 0xdf, + 0xab, + 0xfa, + 0x80, + 0xaf, + 0x06, + 0x00, + 0x7f, + 0xfd, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0x67, + 0xf9, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0x0d, + 0xa0, + 0x06, + 0x00, + 0x77, + 0xd5, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0xd9, + 0x7f, + 0x3f, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x6f, + 0xd7, + 0x3a, + 0x00, + 0xc0, + 0x9f, + 0xdb, + 0xeb, + 0xff, + 0x57, + 0x7f, + 0x29, + 0xa0, + 0x9f, + 0xc9, + 0xe7, + 0x0c, + 0xa0, + 0x06, + 0x00, + 0x67, + 0xd9, + 0x3a, + 0x00, + 0xc0, + 0x9f, + 0xdb, + 0xeb, + 0xc0, + 0xff, + 0xff, + 0x28, + 0xe0, + 0x1f, + 0xe0, + 0xac, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf9, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0x9f, + 0xaf, + 0xfe, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x6b, + 0xb8, + 0x06, + 0x00, + 0xf5, + 0xff, + 0xff, + 0x28, + 0xe1, + 0x9f, + 0xaf, + 0xfe, + 0x90, + 0xff, + 0xff, + 0x29, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x0b, + 0xd0, + 0x38, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0x7b, + 0xfa, + 0xff, + 0xa8, + 0xe1, + 0x1f, + 0xea, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xdb, + 0x7a, + 0x00, + 0xc1, + 0x1f, + 0x1a, + 0xe0, + 0x00, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0x5b, + 0xeb, + 0xfe, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x07, + 0xd0, + 0x38, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0x6f, + 0xfc, + 0xff, + 0xa8, + 0xe1, + 0x1f, + 0xea, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd9, + 0x7a, + 0x00, + 0xc1, + 0x1f, + 0x1a, + 0xe0, + 0xff, + 0xff, + 0xff, + 0xac, + 0xe1, + 0x1f, + 0xeb, + 0xe1, + 0x5b, + 0x92, + 0x06, + 0x00, + 0xff, + 0xd9, + 0x7f, + 0x2d, + 0xe1, + 0x5f, + 0xab, + 0xfe, + 0xa1, + 0xdb, + 0x38, + 0x00, + 0xa1, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf9, + 0xff, + 0xff, + 0x2f, + 0xe1, + 0xdf, + 0xab, + 0xfa, + 0xfc, + 0xff, + 0xff, + 0x2f, + 0xe1, + 0xdf, + 0xeb, + 0xfe, + 0x1e, + 0xa0, + 0x06, + 0x00, + 0xfe, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xdb, + 0x8b, + 0xfe, + 0xff, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xd7, + 0xc3, + 0xd6, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xfb, + 0xff, + 0x26, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xa3, + 0xdf, + 0x38, + 0x00, + 0xc1, + 0x9f, + 0xd9, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xe7, + 0xff, + 0xff, + 0x2f, + 0xe1, + 0xdf, + 0xeb, + 0xfa, + 0xf7, + 0xff, + 0xff, + 0x2f, + 0xe1, + 0xdf, + 0xeb, + 0xff, + 0x1e, + 0xa0, + 0x06, + 0x00, + 0xef, + 0xdf, + 0x3a, + 0x00, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd5, + 0x7a, + 0x00, + 0xc1, + 0x1f, + 0xdb, + 0xeb, + 0x81, + 0xff, + 0xff, + 0x2c, + 0xe1, + 0x9f, + 0xea, + 0xfe, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf7, + 0xff, + 0xff, + 0x2c, + 0xe1, + 0x1f, + 0xeb, + 0xff, + 0xf8, + 0xff, + 0xff, + 0x2a, + 0xe1, + 0x9f, + 0xaa, + 0xfa, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xfe, + 0xff, + 0xff, + 0x2a, + 0xe1, + 0x9f, + 0xea, + 0xfe, + 0xff, + 0xd5, + 0x7f, + 0x2c, + 0xe1, + 0x1f, + 0xab, + 0xfa, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe0, + 0x1f, + 0x4b, + 0xe6, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe0, + 0xdf, + 0x79, + 0xe4, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xab, + 0xdb, + 0x38, + 0x00, + 0xc0, + 0x5f, + 0x9a, + 0xfc, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x2a, + 0xe0, + 0x1f, + 0xe0, + 0xe2, + 0xff, + 0xcf, + 0x7f, + 0x27, + 0xe0, + 0x5f, + 0x6b, + 0xe3, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xdc, + 0xff, + 0xff, + 0x27, + 0xe0, + 0xdd, + 0xa9, + 0xfa, + 0xe2, + 0xff, + 0xff, + 0x2a, + 0xe0, + 0x9f, + 0xea, + 0xfa, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd5, + 0x7f, + 0x2c, + 0xe0, + 0xcf, + 0x69, + 0xff, + 0x4f, + 0xd8, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x2e, + 0xe0, + 0x1f, + 0xe0, + 0xe2, + 0xff, + 0xd9, + 0x7f, + 0x2c, + 0xe0, + 0x9f, + 0x6b, + 0xe3, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xdf, + 0xff, + 0xff, + 0x2c, + 0xe0, + 0x1d, + 0xab, + 0xfa, + 0xdf, + 0xff, + 0xff, + 0x2e, + 0xe0, + 0x9f, + 0xeb, + 0xfa, + 0xef, + 0xa5, + 0x06, + 0x00, + 0xff, + 0xdd, + 0x7f, + 0x2c, + 0xe0, + 0x0f, + 0x6b, + 0xff, + 0x2b, + 0xce, + 0x38, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0x94, + 0xbb, + 0x06, + 0x00, + 0xdf, + 0xfb, + 0xff, + 0x2c, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xdf, + 0x7a, + 0x2c, + 0xc0, + 0x9f, + 0xdb, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf7, + 0x5f, + 0x3f, + 0x00, + 0xa0, + 0x9f, + 0xc9, + 0xe7, + 0xf7, + 0xdf, + 0x3a, + 0x2c, + 0xc0, + 0x9f, + 0xdb, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xef, + 0x5f, + 0x3f, + 0x00, + 0xa0, + 0x9f, + 0xc9, + 0xe7, + 0x2f, + 0xcc, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xf7, + 0xdf, + 0x3a, + 0x2c, + 0xc0, + 0x9f, + 0xdb, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xdd, + 0x0b, + 0xf9, + 0xfe, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0x4b, + 0x6b, + 0xcb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x5b, + 0x7f, + 0x00, + 0xa0, + 0x9f, + 0xc9, + 0xe7, + 0xe7, + 0xff, + 0xff, + 0x26, + 0xe0, + 0x9f, + 0xe9, + 0xff, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf3, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xd7, + 0xc3, + 0xd6, + 0x7f, + 0x5e, + 0x3f, + 0x00, + 0xa0, + 0x9f, + 0xc9, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xff, + 0xbf, + 0x2d, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0x0f, + 0xff, + 0xfe, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xdb, + 0x7f, + 0x2d, + 0xe0, + 0xdf, + 0x6b, + 0xf1, + 0xcc, + 0xff, + 0xff, + 0x2b, + 0xe0, + 0x1f, + 0xe0, + 0xac, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xe0, + 0xff, + 0xff, + 0x28, + 0xe1, + 0x1f, + 0xe0, + 0xac, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd7, + 0x7f, + 0x2d, + 0xe0, + 0x5f, + 0xab, + 0xff, + 0xf7, + 0xdb, + 0x3a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd1, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x00, + 0x00, + 0xfe, + 0x2b, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0x00, + 0x00, + 0xfe, + 0x2d, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0x49, + 0x9d, + 0x06, + 0x00, + 0x00, + 0x00, + 0xbf, + 0x2a, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0x00, + 0x80, + 0xff, + 0x7f, + 0x80, + 0x3e, + 0xce, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xdf, + 0xbf, + 0x2a, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0x5d, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xbf, + 0x49, + 0x3d, + 0x06, + 0x00, + 0xb0, + 0xff, + 0xff, + 0x2b, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xc0, + 0xff, + 0xff, + 0x2a, + 0xe0, + 0x1f, + 0xe0, + 0xac, + 0x49, + 0x3d, + 0x06, + 0x00, + 0x2f, + 0xd4, + 0x38, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0x67, + 0x5e, + 0x3f, + 0x00, + 0xc0, + 0x9f, + 0xda, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xdf, + 0xfb, + 0xff, + 0x2c, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xf7, + 0xdf, + 0x3a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd1, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x2f, + 0xd4, + 0x38, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0xf7, + 0x5f, + 0x3f, + 0x00, + 0xc0, + 0x9f, + 0xda, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xef, + 0x5b, + 0x3f, + 0x00, + 0xc0, + 0x9f, + 0xda, + 0xeb, + 0x00, + 0xff, + 0xff, + 0x2f, + 0xe1, + 0xdf, + 0xeb, + 0xfe, + 0x48, + 0xba, + 0x06, + 0x00, + 0xff, + 0xdf, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xf7, + 0xdb, + 0x3a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0x47, + 0xba, + 0x06, + 0x00, + 0xe7, + 0xff, + 0xff, + 0x26, + 0xe0, + 0x9f, + 0xe9, + 0xff, + 0xf4, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xcf, + 0x03, + 0xd7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf7, + 0x81, + 0x3a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xdf, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x2b, + 0xe0, + 0xdf, + 0xeb, + 0xf3, + 0x00, + 0x00, + 0xfe, + 0x2d, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0x49, + 0x9d, + 0x06, + 0x00, + 0x00, + 0x00, + 0xbf, + 0x2a, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0x00, + 0x80, + 0xff, + 0x7f, + 0x80, + 0x3e, + 0xce, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xdf, + 0xbf, + 0x2a, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0x5d, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xbf, + 0x49, + 0x3d, + 0x06, + 0x00, + 0xb0, + 0xff, + 0xff, + 0x2b, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xc0, + 0xff, + 0xff, + 0x2a, + 0xe0, + 0x1f, + 0xe0, + 0xac, + 0x49, + 0x3d, + 0x06, + 0x00, + 0xcc, + 0xff, + 0xff, + 0x2d, + 0xe0, + 0x1f, + 0xe0, + 0xac, + 0xff, + 0xe5, + 0x7f, + 0x2a, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x67, + 0x5e, + 0x3f, + 0x00, + 0xc0, + 0x9f, + 0xda, + 0xeb, + 0xff, + 0xdb, + 0x7f, + 0x2d, + 0xe0, + 0xdf, + 0xab, + 0xff, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xfe, + 0xff, + 0xff, + 0x2a, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xd5, + 0x7f, + 0x2d, + 0xe0, + 0x5f, + 0x6b, + 0xf1, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xdf, + 0xfb, + 0xff, + 0x2c, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xe0, + 0xff, + 0xff, + 0x29, + 0xe1, + 0x1f, + 0xe0, + 0xac, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf7, + 0xdb, + 0x3a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xd3, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xf7, + 0xdf, + 0x3a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xd3, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x00, + 0xff, + 0xff, + 0x31, + 0xe1, + 0x5f, + 0xec, + 0xfe, + 0xff, + 0xe3, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xc3, + 0xb2, + 0x06, + 0x00, + 0xf7, + 0xe1, + 0x3a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xc2, + 0xb2, + 0x06, + 0x00, + 0x0a, + 0x02, + 0xff, + 0x2e, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0x7f, + 0xfd, + 0xff, + 0x2c, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xfa, + 0x3a, + 0x06, + 0x00, + 0x39, + 0x1f, + 0xfe, + 0x00, + 0xe1, + 0xcf, + 0x03, + 0xd7, + 0xe7, + 0xff, + 0xff, + 0x2e, + 0xe0, + 0x9f, + 0xeb, + 0xfa, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xee, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0x1f, + 0xe0, + 0xac, + 0xff, + 0xdb, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x2b, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x2d, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0x11, + 0x20, + 0x06, + 0x00, + 0x17, + 0xfc, + 0xbf, + 0x2d, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xcf, + 0xbf, + 0x11, + 0x80, + 0x06, + 0x00, + 0xfc, + 0xff, + 0xff, + 0x2b, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xe3, + 0xff, + 0xff, + 0x2b, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xee, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0x11, + 0x20, + 0x06, + 0x00, + 0xff, + 0xff, + 0xbf, + 0x2d, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xff, + 0xef, + 0xff, + 0xaa, + 0xff, + 0xcf, + 0xbf, + 0x11, + 0x80, + 0x06, + 0x00, + 0xf1, + 0xff, + 0xff, + 0x2b, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xff, + 0xbf, + 0x2d, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xff, + 0x9f, + 0xef, + 0xd5, + 0xfe, + 0xcf, + 0xbf, + 0x11, + 0x80, + 0x06, + 0x00, + 0xf0, + 0xff, + 0xff, + 0x2b, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x2b, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xfe, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0x11, + 0x20, + 0x06, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x56, + 0x5f, + 0x06, + 0x00, + 0x0a, + 0x02, + 0xff, + 0x2e, + 0xe0, + 0x1f, + 0xe0, + 0xe7, + 0xe7, + 0xff, + 0xff, + 0x2e, + 0xe0, + 0x9f, + 0xeb, + 0xfa, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xe0, + 0xff, + 0xff, + 0x29, + 0xe1, + 0x1f, + 0xe0, + 0xac, + 0xdf, + 0xfb, + 0xff, + 0x2c, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd7, + 0x7f, + 0x2b, + 0xe1, + 0x5f, + 0xaa, + 0xff, + 0xf7, + 0xdb, + 0x3a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xfb, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd7, + 0x7a, + 0x2c, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xdb, + 0xf7, + 0xff, + 0x3e, + 0xe0, + 0x1f, + 0x2b, + 0xfb, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xe6, + 0x58, + 0x06, + 0x00, + 0xff, + 0xd1, + 0x7f, + 0x28, + 0xe0, + 0x1f, + 0x6b, + 0xf1, + 0x67, + 0xd1, + 0x3a, + 0x00, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0x46, + 0xa1, + 0x06, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x45, + 0xa1, + 0x06, + 0x00, + 0xf8, + 0xff, + 0xff, + 0x00, + 0xe1, + 0x9d, + 0x0b, + 0xf9, + 0xfe, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xcf, + 0x43, + 0xd7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x2b, + 0xce, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x97, + 0x5b, + 0x02, + 0x00, + 0x57, + 0xdc, + 0x38, + 0x00, + 0xc0, + 0xdf, + 0xdb, + 0xeb, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x9b, + 0x5b, + 0x06, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xbc, + 0xa8, + 0x3e, + 0x11, + 0x69, + 0xce, + 0x06, + 0x3f, + 0xb9, + 0x87, + 0xd7, + 0xdd, + 0xc6, + 0x12, + 0xb6, + 0xe2, + 0xc2, + 0x53, + 0x20, + 0xfb, + 0xea, + 0x71, + 0x72, + 0xb5, + 0xe1, + 0xa6, + 0xd8, + 0xee, + 0x9d, + 0x97, + 0xe6, + 0x72, + 0x3f, + 0x73, + 0x88, + 0xed, + 0x14, + 0x8c, + 0xdf, + 0x5d, + 0x8f, + 0x0d, + 0xd0, + 0x70, + 0x64, + 0x1c, + 0x06, + 0x7f, + 0x59, + 0x93, + 0x32, + 0x55, + 0x2a, + 0x10, + 0x61, + 0xde, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatch07000106_Enc.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatch07000106_Enc.c new file mode 100644 index 0000000000..85bdc4e582 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatch07000106_Enc.c @@ -0,0 +1,3539 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD F16Kb Microcode patch. + * + * F16Kb Microcode Patch rev 07000106 for 7001 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 86822 $ @e \$Date: 2013-01-28 00:17:14 -0500 (Mon, 28 Jan 2013) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuEarlyInit.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +// Encrypt Patch code 07000106 for 7001 and equivalent + +CONST UINT8 ROMDATA arr2 [IDS_PAD_4K] = +{ + 0x13, + 0x20, + 0x22, + 0x01, + 0x06, + 0x01, + 0x00, + 0x07, + 0x03, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x70, + 0x00, + 0x00, + 0x00, + 0xaa, + 0xaa, + 0xaa, + 0x49, + 0x66, + 0xa8, + 0x8e, + 0x7a, + 0x20, + 0xc7, + 0xae, + 0xe4, + 0xf4, + 0xb4, + 0x4a, + 0x32, + 0x58, + 0xbb, + 0x8b, + 0x60, + 0x57, + 0x0e, + 0x35, + 0x36, + 0xda, + 0x53, + 0x69, + 0xb7, + 0xaf, + 0x84, + 0xe0, + 0x66, + 0x54, + 0x71, + 0x2a, + 0xef, + 0x0f, + 0xf0, + 0x0e, + 0x9d, + 0x5a, + 0xbe, + 0xbe, + 0x19, + 0x2a, + 0xe1, + 0x53, + 0xdf, + 0x30, + 0x15, + 0xe9, + 0x9e, + 0xa2, + 0xb4, + 0x74, + 0x0f, + 0xfa, + 0x38, + 0x6e, + 0x5c, + 0x08, + 0xa5, + 0xe5, + 0xd7, + 0xc3, + 0x24, + 0x04, + 0x5c, + 0x6e, + 0xf5, + 0x57, + 0xb6, + 0x2e, + 0x41, + 0x1d, + 0x5d, + 0xa2, + 0x62, + 0x9c, + 0xce, + 0x79, + 0xfb, + 0xd8, + 0xda, + 0x01, + 0x36, + 0xfe, + 0xcf, + 0x18, + 0x78, + 0xcd, + 0x8b, + 0x49, + 0x92, + 0x0a, + 0x59, + 0x40, + 0x8f, + 0xc9, + 0x3e, + 0xf6, + 0xd7, + 0xea, + 0x78, + 0x89, + 0xc1, + 0xea, + 0xf8, + 0x2e, + 0x35, + 0xf8, + 0xfb, + 0x15, + 0x48, + 0x8f, + 0x07, + 0xd4, + 0x3f, + 0x1f, + 0x85, + 0x38, + 0x87, + 0x17, + 0x38, + 0x23, + 0x9b, + 0xcc, + 0x4a, + 0xea, + 0xfd, + 0x49, + 0x5a, + 0xfe, + 0xb6, + 0x11, + 0x21, + 0xa6, + 0x5d, + 0x26, + 0x5a, + 0x2e, + 0xc9, + 0x49, + 0x4a, + 0x2a, + 0x5b, + 0xc7, + 0x8f, + 0xde, + 0x65, + 0x27, + 0xfd, + 0x9d, + 0x59, + 0x02, + 0xf9, + 0xad, + 0x13, + 0x4a, + 0x19, + 0xb9, + 0x63, + 0x1b, + 0x94, + 0xd8, + 0x24, + 0x87, + 0xd2, + 0xfc, + 0x1d, + 0x4f, + 0xa2, + 0xf1, + 0xf1, + 0x4e, + 0x1a, + 0x8e, + 0x7a, + 0xbd, + 0xaf, + 0xd4, + 0x24, + 0x07, + 0x3b, + 0x43, + 0x2d, + 0xe3, + 0xbf, + 0xc3, + 0x03, + 0x4c, + 0x81, + 0x9b, + 0xec, + 0x8a, + 0x91, + 0x7b, + 0x1c, + 0xe0, + 0x70, + 0xa4, + 0x3f, + 0x83, + 0x4d, + 0xa5, + 0x4b, + 0x9d, + 0xbe, + 0xfe, + 0xdf, + 0xed, + 0xb8, + 0xa9, + 0x0e, + 0xe1, + 0x11, + 0x71, + 0x4d, + 0xfa, + 0x27, + 0x32, + 0x5c, + 0xd1, + 0xe9, + 0x84, + 0xbb, + 0xeb, + 0x65, + 0x19, + 0x09, + 0xc9, + 0x2f, + 0x0c, + 0x80, + 0x14, + 0x3f, + 0x94, + 0x1f, + 0xcd, + 0xaf, + 0x29, + 0x51, + 0x7c, + 0x88, + 0x36, + 0xf3, + 0xcb, + 0x41, + 0x20, + 0xcb, + 0x4c, + 0x1c, + 0x4b, + 0xb2, + 0xaa, + 0x6c, + 0x2c, + 0xab, + 0x37, + 0x5b, + 0x2a, + 0x58, + 0x44, + 0x53, + 0xdf, + 0x59, + 0xbc, + 0x14, + 0xe3, + 0x7f, + 0xd6, + 0x4a, + 0xd6, + 0x98, + 0x59, + 0x8c, + 0xbb, + 0xce, + 0xe6, + 0x86, + 0xdb, + 0x66, + 0xbd, + 0xeb, + 0x51, + 0xf1, + 0xce, + 0x80, + 0x0f, + 0xd9, + 0x83, + 0x86, + 0x17, + 0xed, + 0x78, + 0x3e, + 0x5d, + 0xac, + 0xd1, + 0x13, + 0xfa, + 0x01, + 0x58, + 0x35, + 0xe9, + 0x66, + 0x16, + 0x5d, + 0xa8, + 0x70, + 0x08, + 0x0e, + 0xa3, + 0xab, + 0x3b, + 0xd1, + 0x75, + 0xbf, + 0x2f, + 0xb2, + 0x9a, + 0x7c, + 0xd8, + 0x84, + 0x66, + 0x1a, + 0x07, + 0x00, + 0xe0, + 0x04, + 0xbf, + 0x0e, + 0x04, + 0xaa, + 0x0e, + 0x91, + 0x6f, + 0xb4, + 0xb8, + 0xff, + 0xfa, + 0xad, + 0xb0, + 0xd8, + 0x41, + 0x65, + 0xf5, + 0xd5, + 0x0d, + 0x12, + 0x15, + 0xbf, + 0x40, + 0x5b, + 0xed, + 0xeb, + 0x81, + 0x2a, + 0x1f, + 0x48, + 0x00, + 0x5b, + 0xf7, + 0x08, + 0x35, + 0x86, + 0x8d, + 0xe4, + 0x15, + 0x52, + 0x40, + 0x1b, + 0x88, + 0x5a, + 0x8f, + 0xd0, + 0x4f, + 0xb5, + 0xbc, + 0xdb, + 0x45, + 0x30, + 0xc5, + 0x89, + 0x32, + 0x98, + 0xf9, + 0xa7, + 0x18, + 0x27, + 0xf1, + 0x0b, + 0xc7, + 0x6d, + 0xeb, + 0x7f, + 0x39, + 0xd2, + 0x25, + 0x99, + 0x6d, + 0x3a, + 0x1b, + 0x24, + 0xa4, + 0xc5, + 0x7c, + 0xdf, + 0x33, + 0x3d, + 0x7c, + 0x43, + 0x40, + 0x5b, + 0x8d, + 0xd1, + 0xec, + 0x0c, + 0xca, + 0x76, + 0xd9, + 0x1a, + 0x32, + 0xee, + 0x45, + 0xee, + 0xb6, + 0x30, + 0x21, + 0xf8, + 0x66, + 0xb5, + 0xbf, + 0xfb, + 0x66, + 0x13, + 0x9c, + 0xf0, + 0xcf, + 0xae, + 0xca, + 0x54, + 0xbc, + 0xf1, + 0xce, + 0x76, + 0x57, + 0x8d, + 0xf5, + 0xee, + 0x02, + 0x14, + 0xc0, + 0x62, + 0x3f, + 0xa1, + 0xad, + 0x9d, + 0xbb, + 0x83, + 0x3d, + 0x8f, + 0xf2, + 0xe9, + 0x41, + 0x42, + 0xca, + 0x04, + 0xf9, + 0xf7, + 0x4f, + 0xf7, + 0xc6, + 0x77, + 0xf0, + 0x0e, + 0x8c, + 0xea, + 0xb6, + 0x6c, + 0x47, + 0xae, + 0xd1, + 0x1b, + 0x2c, + 0x89, + 0xbf, + 0x4b, + 0x61, + 0xdc, + 0x2d, + 0x06, + 0x6d, + 0x79, + 0x5c, + 0x5e, + 0x82, + 0xc0, + 0x4f, + 0x54, + 0x5d, + 0x68, + 0x55, + 0x5b, + 0x1c, + 0x75, + 0xb6, + 0xcc, + 0x4b, + 0xb6, + 0x3e, + 0x2b, + 0xec, + 0x30, + 0xa7, + 0x90, + 0xd8, + 0x99, + 0x44, + 0x85, + 0xe7, + 0x21, + 0x33, + 0x00, + 0x48, + 0xf3, + 0xbb, + 0x92, + 0xe9, + 0x48, + 0x99, + 0x45, + 0x66, + 0xd5, + 0xe6, + 0xd9, + 0x9e, + 0x92, + 0x8b, + 0x42, + 0x94, + 0xa3, + 0x2f, + 0x44, + 0xb1, + 0x5e, + 0x07, + 0xd7, + 0x0a, + 0xb4, + 0x7b, + 0x49, + 0x7e, + 0x15, + 0xab, + 0x34, + 0x6b, + 0xff, + 0x1f, + 0xcf, + 0x84, + 0x7f, + 0x57, + 0x6c, + 0xdb, + 0xc3, + 0x3e, + 0xc1, + 0xef, + 0x05, + 0xea, + 0x39, + 0xe0, + 0xe6, + 0x15, + 0x4f, + 0x9a, + 0xdd, + 0x93, + 0x01, + 0x00, + 0x00, + 0x00, + 0x06, + 0x01, + 0x00, + 0x07, + 0xe2, + 0x13, + 0xe7, + 0x13, + 0x93, + 0x07, + 0x66, + 0x04, + 0x60, + 0x04, + 0xd7, + 0x19, + 0x04, + 0x07, + 0xf0, + 0x0c, + 0xf0, + 0x0c, + 0xf0, + 0x0c, + 0xf0, + 0x0c, + 0xf0, + 0x0c, + 0xf0, + 0x0c, + 0xf0, + 0x0c, + 0xf0, + 0x0c, + 0xf0, + 0x0c, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x6f, + 0xd7, + 0x3a, + 0x00, + 0xc0, + 0x9f, + 0xdb, + 0xeb, + 0xff, + 0x57, + 0x7f, + 0x29, + 0xa0, + 0x9f, + 0xc9, + 0xe7, + 0x55, + 0xa0, + 0x06, + 0x00, + 0x67, + 0xd9, + 0x3a, + 0x00, + 0xc0, + 0x9f, + 0xdb, + 0xeb, + 0xc0, + 0xff, + 0xff, + 0x28, + 0xe0, + 0x1f, + 0xe0, + 0xac, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x67, + 0xd9, + 0x3a, + 0x00, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x17, + 0xac, + 0x06, + 0x00, + 0x9d, + 0xf1, + 0xef, + 0x2b, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x16, + 0xac, + 0x06, + 0x00, + 0xf9, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0x9f, + 0xaf, + 0xfe, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x6b, + 0xb8, + 0x06, + 0x00, + 0xf5, + 0xff, + 0xff, + 0x28, + 0xe1, + 0x9f, + 0xaf, + 0xfe, + 0x90, + 0xff, + 0xff, + 0x29, + 0xe1, + 0x1f, + 0xe0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xdf, + 0xff, + 0xff, + 0x2e, + 0xe0, + 0x1f, + 0xab, + 0xfa, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x9d, + 0x4b, + 0xe1, + 0x53, + 0xa0, + 0x06, + 0x00, + 0xd9, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xcf, + 0x43, + 0xd7, + 0x70, + 0x5c, + 0x39, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xa3, + 0xdb, + 0x38, + 0x00, + 0xc1, + 0xdf, + 0xd9, + 0xeb, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xd7, + 0xb8, + 0x06, + 0x00, + 0x00, + 0xff, + 0xff, + 0x3c, + 0xe1, + 0x5f, + 0xeb, + 0xfe, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xdd, + 0x7f, + 0x2c, + 0xe0, + 0x0f, + 0x6b, + 0xff, + 0x4b, + 0xd8, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0x91, + 0xbb, + 0x06, + 0x00, + 0x2b, + 0xce, + 0x38, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x90, + 0xbb, + 0x06, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x29, + 0xe1, + 0x4f, + 0x2a, + 0xca, + 0xff, + 0x81, + 0x7f, + 0x2d, + 0xe1, + 0x4f, + 0x2b, + 0xca, + 0xfa, + 0xb8, + 0x06, + 0x00, + 0xfb, + 0xff, + 0xff, + 0x2d, + 0xe1, + 0xdf, + 0xab, + 0xfe, + 0x23, + 0xd3, + 0x38, + 0x00, + 0xc1, + 0x1d, + 0x00, + 0xf9, + 0x19, + 0xa1, + 0x06, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x76, + 0x5e, + 0x39, + 0x00, + 0xc0, + 0x1f, + 0xd0, + 0xeb, + 0xf5, + 0xff, + 0xff, + 0x2e, + 0xe1, + 0x1f, + 0xe0, + 0xac, + 0x93, + 0xbf, + 0x06, + 0x00, + 0xff, + 0xdd, + 0x7f, + 0x2f, + 0xe0, + 0xdf, + 0xab, + 0xff, + 0x76, + 0x5e, + 0x39, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0xd1, + 0x7f, + 0x28, + 0xe0, + 0x1f, + 0x6b, + 0xf1, + 0x67, + 0xd1, + 0x3a, + 0x00, + 0xa0, + 0x9f, + 0xcb, + 0xe7, + 0x33, + 0xa1, + 0x06, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x32, + 0xa1, + 0x06, + 0x00, + 0xf8, + 0xff, + 0xff, + 0x00, + 0xe1, + 0x9d, + 0x0b, + 0xf9, + 0xfe, + 0xff, + 0xff, + 0x00, + 0xe1, + 0xcf, + 0x43, + 0xd7, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x2b, + 0xce, + 0x38, + 0x00, + 0xa0, + 0x1f, + 0xc0, + 0xe7, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x94, + 0x5b, + 0x02, + 0x00, + 0x57, + 0xdc, + 0x38, + 0x00, + 0xc0, + 0xdf, + 0xdb, + 0xeb, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0x98, + 0x5b, + 0x06, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0x81, + 0x7f, + 0x00, + 0xe1, + 0x1f, + 0xc0, + 0xbf, + 0xff, + 0xbf, + 0x07, + 0x00, + 0x13, + 0x42, + 0x99, + 0xf4, + 0x9c, + 0x43, + 0x10, + 0xb9, + 0x93, + 0x17, + 0x40, + 0x75, + 0x1b, + 0x3d, + 0x9e, + 0xa9, + 0x4f, + 0xbf, + 0xac, + 0x60, + 0x92, + 0x6b, + 0xbb, + 0x51, + 0x50, + 0x1a, + 0x56, + 0xc0, + 0x34, + 0x59, + 0xb6, + 0x4a, + 0x30, + 0x0a, + 0x21, + 0xa2, + 0x14, + 0x1f, + 0x8d, + 0x89, + 0xc4, + 0x82, + 0xb0, + 0x5c, + 0x8d, + 0x49, + 0x3d, + 0xb8, + 0x34, + 0x7a, + 0x54, + 0xb2, + 0xc2, + 0x0e, + 0x5b, + 0xbc, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatchTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatchTables.c new file mode 100644 index 0000000000..4790709618 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMicrocodePatchTables.c @@ -0,0 +1,111 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini microcode patches + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBMICROCODEPATCHTABLES_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +extern CONST MICROCODE_PATCHES_4K ROMDATA *CpuF16KbMicroCodePatchArray[]; +extern CONST UINT8 ROMDATA CpuF16KbNumberOfMicrocodePatches; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GetF16KbMicroCodePatchesStruct ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **KbUcodePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns a table containing the appropriate microcode patches. + * + * @CpuServiceMethod{::F_CPU_GET_FAMILY_SPECIFIC_ARRAY}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] KbUcodePtr Points to the first entry in the table. + * @param[out] NumberOfElements Number of valid entries in the table. + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetF16KbMicroCodePatchesStruct ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **KbUcodePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = CpuF16KbNumberOfMicrocodePatches; + *KbUcodePtr = &CpuF16KbMicroCodePatchArray[0]; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMsrTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMsrTables.c new file mode 100644 index 0000000000..12dd300f70 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbMsrTables.c @@ -0,0 +1,264 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 KB MSR tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x16/KB + * @e \$Revision: 87267 $ @e \$Date: 2013-01-31 09:34:00 -0600 (Thu, 31 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "F16KbPowerMgmt.h" +#include "Table.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBMSRTABLES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +NbMcaLock ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +// M S R T a b l e s +// ---------------------- + +STATIC CONST MSR_TYPE_ENTRY_INITIALIZER ROMDATA F16KbMsrRegisters[] = +{ +// MSR_TOM2 (0xC001001D) +// bits[39:23] TOP_MEM2 = 0x0 + { + MsrRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MSR_TOM2, // Address + 0x0000000000000000, // RegData + 0xFFFFFFFFFF800000, // RegMask + }} + }, + +// MSR_SYS_CFG (0xC0010010) +// bits[21] MtrrTom2En = 0x1 + { + MsrRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MSR_SYS_CFG, // Address + (1 << 21), // RegData + (1 << 21), // RegMask + }} + }, +// MC4_MISC_1 (0xC0000408) +// Clear to 0 + { + MsrRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + 0xC0000408, // Address + 0x0000000000000000, // RegData + 0xFF0FFFFFFFFFFFFF, // RegMask + }} + }, +// MSR_LS_CFG (C0011020) +// bits[26] = 0x1 + { + MsrRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MSR_LS_CFG, // Address + 0x0000000004000000, // RegData + 0x0000000004000000, // RegMask + }} + }, +// MSR_IC_CFG (C0011021) +// bits[26] DIS_WIDEREAD_PWR_SAVE = 0x1 + { + MsrRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MSR_IC_CFG, // Address + 0x0000000004000000, // RegData + 0x0000000004000000, // RegMask + }} + }, +// Processor Feedback Constants 0 (C0011090) +// bits[15:8] RefCountScale = 0x64 +// bits[7:0] ActualCountScale = 0xA5 + { + MsrRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + 0xC0011090, // Address + 0x00000000000064A5, // RegData + 0x000000000000FFFF, // RegMask + }} + }, +// MSR_L2I_CFG (C00110A0) +// bits[56:45] L2ScrubberInterval = 0x100 +// bits[44] PbDisObeysThrottleNb = 0x1 +// bits[43:40] ThrottleNbInterface = 0x0 +// bits[19] McaToMstCoreEn = 0x1 + { + MsrRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MSR_L2I_CFG, // Address + 0x0020100000080000, // RegData + 0x01FFFF0000080000, // RegMask + }} + }, +}; + +// MSR with Special Programming Requirements Table +// ---------------------- + +STATIC CONST FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_INITIALIZER ROMDATA F16KbMsrWorkarounds[] = +{ +// MSR_0000_0413 + { + FamSpecificWorkaround, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + NbMcaLock, // Function call + 0x00000000, // Data + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F16KbMsrRegisterTable = { + AllCores, + PERFORM_TP_AFTER_AP_LAUNCH, + (sizeof (F16KbMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F16KbMsrRegisters, +}; + +CONST REGISTER_TABLE ROMDATA F16KbMsrWorkaroundTable = { + AllCores, + PERFORM_TP_AFTER_AP_LAUNCH, + (sizeof (F16KbMsrWorkarounds) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) F16KbMsrWorkarounds, +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * MSR special programming requirements for MSR_0000_0413 + * + * + * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +NbMcaLock ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + MC4_MISC0_MSR Mc4Misc0; + + LibAmdMsrRead (MSR_MC4_MISC, (UINT64 *) &Mc4Misc0, StdHeader); + + if (Mc4Misc0.IntType == 0x2) { + Mc4Misc0.Locked = 1; + } else { + Mc4Misc0.Locked = 0; + } + LibAmdMsrWrite (MSR_MC4_MISC, (UINT64 *) &Mc4Misc0, StdHeader); + + return; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.c new file mode 100644 index 0000000000..0ab9896db4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.c @@ -0,0 +1,365 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini after warm reset sequence for NB P-states + * + * Performs the "NB COF and VID Transition Sequence After Warm Reset" + * as described in the BKDG. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "F16KbNbAfterReset.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbHandleLib.h" +#include "GnbRegisterAccKB.h" +#include "GnbRegistersKB.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBNBAFTERRESET_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +F16KbPmNbAfterResetOnCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +TransitionToNbLow ( + IN PCI_ADDR PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +TransitionToNbHigh ( + IN PCI_ADDR PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +WaitForNbTransitionToComplete ( + IN PCI_ADDR PciAddress, + IN UINT32 PstateIndex, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family 16h Kabini core 0 entry point for performing the necessary steps after + * a warm reset has occurred. + * + * The steps are as follows: + * + * 1. Temp1=D18F5x170[SwNbPstateLoDis]. + * 2. Temp2=D18F5x170[NbPstateDisOnP0]. + * 3. Temp3=D18F5x170[NbPstateThreshold]. + * 4. Temp4=D18F5x170[NbPstateGnbSlowDis]. + * 5. If MSRC001_0070[NbPstate]=0, go to step 6. If MSRC001_0070[NbPstate]=1, go to step 11. + * 6. Write 1 to D18F5x170[NbPstateGnbSlowDis]. + * 7. Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold]. + * 8. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, CurNb- + * Did]=[NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo]. + * 9. Set D18F5x170[SwNbPstateLoDis]=1. + * 10. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, CurNb- + * Did]=[NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi]. Go to step 15. + * 11. Write 1 to D18F5x170[SwNbPstateLoDis]. + * 12. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, CurNb- + * Did]=[NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi]. + * 13. Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold]. + * 14. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, CurNb- + * Did]=[NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo]. + * 15. Set D18F5x170[SwNbPstateLoDis]=Temp1, D18F5x170[NbPstateDisOnP0]=Temp2, D18F5x170[NbP- + * stateThreshold]=Temp3, and D18F5x170[NbPstateGnbSlowDis]=Temp4. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParamsPtr Service parameters + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F16KbPmNbAfterReset ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 Core; + UINT32 TaskedCore; + UINT32 Ignored; + AP_TASK TaskPtr; + AGESA_STATUS IgnoredSts; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbPmNbAfterReset\n"); + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + + ASSERT (Core == 0); + + // Launch one core per node. + TaskPtr.FuncAddress.PfApTask = F16KbPmNbAfterResetOnCore; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetGivenModuleCoreRange (Socket, Module, &TaskedCore, &Ignored, StdHeader)) { + if (TaskedCore != 0) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) TaskedCore, &TaskPtr, StdHeader); + } + } + } + ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, (VOID *) CpuEarlyParamsPtr); +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F16KbPmNbAfterReset to perform MSR initialization on one + * core of each die in a family 16h socket. + * + * This function implements steps 1 - 15 on each core. + * + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F16KbPmNbAfterResetOnCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 NbPsCtrlOnEntry; + UINT32 NbPsCtrlOnExit; + UINT64 LocalMsrRegister; + PCI_ADDR PciAddress; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbPmNbAfterResetOnCore\n"); + + // 1. Temp1 = D18F5x170[SwNbPstateLoDis]. + // 2. Temp2 = D18F5x170[NbPstateDisOnP0]. + // 3. Temp3 = D18F5x170[NbPstateThreshold]. + // 4. Temp4 = D18F5x170[NbPstateGnbSlowDis]. + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrlOnEntry, StdHeader); + + // Check if NB P-states were disabled, and if so, prevent any changes from occurring. + if (((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->SwNbPstateLoDis == 0) { + // 5. If MSRC001_0070[NbPstate] = 1, go to step 11 + LibAmdMsrRead (MSR_COFVID_CTL, &LocalMsrRegister, StdHeader); + if (((COFVID_CTRL_MSR *) &LocalMsrRegister)->NbPstate == 0) { + // 6. Write 1 to D18F5x170[NbPstateGnbSlowDis]. + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrlOnExit, StdHeader); + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnExit)->NbPstateGnbSlowDis = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrlOnExit, StdHeader); + + // 7. Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold]. + // 8. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, + // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo]. + TransitionToNbLow (PciAddress, StdHeader); + + // 9. Set D18F5x170[SwNbPstateLoDis] = 1. + // 10. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, + // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi]. + // Go to step 15. + TransitionToNbHigh (PciAddress, StdHeader); + } else { + // 11. Set D18F5x170[SwNbPstateLoDis] = 1. + // 12. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, + // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi]. + TransitionToNbHigh (PciAddress, StdHeader); + + // 13. Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold]. + // 14. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, + // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo]. + TransitionToNbLow (PciAddress, StdHeader); + } + + // 15. Set D18F5x170[SwNbPstateLoDis]=Temp1, D18F5x170[NbPstateDisOnP0]=Temp2, D18F5x170[NbP- + // stateThreshold]=Temp3, and D18F5x170[NbPstateGnbSlowDis]=Temp4. + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrlOnExit, StdHeader); + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnExit)->SwNbPstateLoDis = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->SwNbPstateLoDis; + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnExit)->NbPstateDisOnP0 = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->NbPstateDisOnP0; + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnExit)->NbPstateThreshold = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->NbPstateThreshold; + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnExit)->NbPstateGnbSlowDis = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->NbPstateGnbSlowDis; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrlOnExit, StdHeader); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F16KbPmNbAfterResetOnCore to transition to the low NB P-state. + * + * This function implements steps 7, 8, 13, and 14 as needed. + * + * @param[in] PciAddress Segment, bus, device number of the node to transition. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +TransitionToNbLow ( + IN PCI_ADDR PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + NB_PSTATE_CTRL_REGISTER NbPsCtrl; + + IDS_HDT_CONSOLE (CPU_TRACE, " TransitionToNbLow\n"); + + // 7/13. Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold]. + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + NbPsCtrl.SwNbPstateLoDis = 0; + NbPsCtrl.NbPstateDisOnP0 = 0; + NbPsCtrl.NbPstateThreshold = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + + // 8/14. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, + // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo]. + WaitForNbTransitionToComplete (PciAddress, NbPsCtrl.NbPstateLo, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F16KbPmNbAfterResetOnCore to transition to the high NB P-state. + * + * This function implements steps 9, 10, 11, and 12 as needed. + * + * @param[in] PciAddress Segment, bus, device number of the node to transition. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +TransitionToNbHigh ( + IN PCI_ADDR PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + NB_PSTATE_CTRL_REGISTER NbPsCtrl; + + IDS_HDT_CONSOLE (CPU_TRACE, " TransitionToNbHigh\n"); + + // 9/10. Set D18F5x170[SwNbPstateLoDis] = 1. + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + NbPsCtrl.SwNbPstateLoDis = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + + // 11/12. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, + // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi]. + WaitForNbTransitionToComplete (PciAddress, NbPsCtrl.NbPstateHi, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F16KbPmAfterResetCore to wait for NB FID and DID to + * match a specific P-state. + * + * This function implements steps 8, 10, 12, and 14 as needed. + * + * @param[in] PciAddress Segment, bus, device number of the node to transition. + * @param[in] PstateIndex P-state settings to match. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +WaitForNbTransitionToComplete ( + IN PCI_ADDR PciAddress, + IN UINT32 PstateIndex, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + NB_PSTATE_REGISTER TargetNbPs; + NB_PSTATE_STS_REGISTER NbPsSts; + + IDS_HDT_CONSOLE (CPU_TRACE, " WaitForNbTransitionToComplete\n"); + + PciAddress.Address.Function = FUNC_5; + PciAddress.Address.Register = NB_PSTATE_0 + (PstateIndex << 2); + LibAmdPciRead (AccessWidth32, PciAddress, &TargetNbPs, StdHeader); + PciAddress.Address.Register = NB_PSTATE_STATUS; + do { + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsSts, StdHeader); + } while ((NbPsSts.CurNbPstate != PstateIndex || + (NbPsSts.CurNbFid != TargetNbPs.NbFid)) || + (NbPsSts.CurNbDid != TargetNbPs.NbDid)); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.h new file mode 100644 index 0000000000..0d2c7bcd72 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbNbAfterReset.h @@ -0,0 +1,78 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini after warm reset sequence for NB P-states + * + * Contains code that provide power management functionality + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_F16_KB_NB_AFTER_RESET_H_ +#define _CPU_F16_KB_NB_AFTER_RESET_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +VOID +F16KbPmNbAfterReset ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F16_KB_NB_AFTER_RESET_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPciTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPciTables.c new file mode 100644 index 0000000000..4cd445e349 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPciTables.c @@ -0,0 +1,1147 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 KB PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x16/KB + * @e \$Revision: 86705 $ @e \$Date: 2013-01-24 17:34:21 -0600 (Thu, 24 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "F16KbPowerMgmt.h" +#include "Table.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBPCITABLES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +SetDisCstateBoostBlockPstateUp ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +ScalingApmParamBaseOnCSampleTimer ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SetTdpLimitDis ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +// P C I T a b l e s +// ---------------------- + +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F16KbPciRegistersAfterApLaunch[] = +{ +// D18F0x6C - Link Initialization Control +// bits[0] RouteTblDis = 0x0 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x6C), // Address + 0x00000000, // RegData + 0x00000001, // RegMask + }} + }, +// D18F0x84 - Link Control +// bits[12] IsocEn = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x84), // Address + 0x00001000, // RegData + 0x00001000, // RegMask + }} + }, +// D18F0x90 - Link Base Channel Buffer Count +// bits[30] PReq[3] = 0x0 +// bits[29:28] NpReqData[3:2] = 0x0 +// bits[27:25] FreeData = 0x0 +// bits[24:20] FreeCmd = 0x0 +// bits[19:18] RspData = 0x1 +// bits[17:16] NpReqData[1:0] = 0x1 +// bits[15:12] ProbeCmd = 0x0 +// bits[11:8] RspCmd = 0x1 +// bits[7:5] PReq[2:0] = 0x5 +// bits[4:0] NpReqCmd = 0x5 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x90), // Address + 0x000501A5, // RegData + 0x7FFFFFFF, // RegMask + }} + }, +// D18F0x94 - Link Isochronous Channel Buffer Count +// bits[28:27] IsocRspData = 0x0 +// bits[26:25] IsocNpReqData = 0x1 +// bits[24:22] IsocRspCmd = 0x0 +// bits[21:19] IsocPReq = 0x0 +// bits[18:16] IsocNpReqCmd = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x94), // Address + 0x02010000, // RegData + 0x1FFF0000, + }} + }, +// D18F0x90 - Link Base Channel Buffer Count +// bit [31] LockBc = 0x1 +// +// NOTE: The entry is intended to be programmed after other bits of D18F0x[90, 94] is programmed. + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x90), // Address + 0x80000000, // regData + 0x80000000, // regMask + }} + }, +// D18F0x110 - Link Clumping Enable +// bits [31:1] ClumpEn = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x110), // Address + 0x00000002, // regData + 0xFFFFFFFE, // regMask + }} + }, +// D18F0x168 - Extended Link Transaction Control +// bits[20] = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x168), // Address + 0x00100000, // RegData + 0x00100000, // RegMask + }} + }, + +// D18F2x118 - Memory Controller Configuration Low +// bits[31:28] MctVarPriCntLmt = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x118), // Address + 0x10000000, // RegData + 0xF0000000, // RegMask + }} + }, +// D18F3x44 - MCA NB Configuration +// bits[30] SyncFloodOnDramAdrParErr = 0x1 +// bits[27] NbMcaToMstCpuEn = 0x1 +// bits[21] SyncFloodOnAnyUcErr = 0x1 +// bits[20] SyncFloodOnWDT = 0x1 +// bits[6] CpuErrDis = 0x1 +// bits[4] SyncPktPropDis = 0x0 +// bits[3] SyncPktGenDis = 0x0 +// bits[2] SyncFloodOnDramUcEcc = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x44), // Address + 0x48300044, // RegData + 0x4830005C, // RegMask + }} + }, +// D18F3x6C - Data Buffer Count +// bits[30:28] IsocRspDBC = 0x1 +// bits[18:16] UpRspDBC = 0x1 +// bits[7:6] DnRspDBC = 0x1 +// bits[5:4] DnReqDBC = 0x1 +// bits[2:0] UpReqDBC = 0x2 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x6C), // Address + 0x10010052, // RegData + 0x700700F7, // RegMask + }} + }, +// D18F3x70 - SRI to XBAR Command Buffer Count +// bits[30:28] IsocRspCBC = 0x1 +// bits[26:24] IsocPreqCBC = 0x0 +// bits[22:20] IsocReqCBC = 0x1 +// bits[18:16] UpRspCBC = 0x3 +// bits[14:12] DnPreqCBC = 0x1 +// bits[10:8] UpPreqCBC = 0x1 +// bits[7:6] DnRspCBC = 0x1 +// bits[5:4] DnReqCBC = 0x1 +// bits[2:0] UpReqCBC = 0x3 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x70), // Address + 0x10131153, // RegData + 0x777777F7, // RegMask + }} + }, +// D18F3x74 - XBAR to SRI Command Buffer Count +// bits[31:28] DRReqCBC = 0x0 +// bits[26:24] IsocPreqCBC = 0x1 +// bits[23:20] IsocReqCBC = 0x1 +// bits[19:16] ProbeCBC = 0xC +// bits[14:12] DnPreqCBC = 0x0 +// bits[10:8] UpPreqCBC = 0x1 +// bits[6:4] DnReqCBC = 0x0 +// bits[2:0] UpReqCBC = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0x011C0101, // RegData + 0xF7FF7777, // RegMask + }} + }, +// D18F3x78 - MCT to XBAR Buffer Count +// bits[12:8] ProbeCBC = 0x8 +// bits[5:0] RspCBC = 0x10 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x78), // Address + 0x00000810, // RegData + 0x00001F3F, // RegMask + }} + }, + +// D18F3x7C - Free List Buffer Count +// bits[22:20] Sri2XbarFreeRspDBC = 0x0 +// bits[19:16] Sri2XbarFreeXreqDBC = 0x5 +// bits[15:12] Sri2XbarFreeRspCBC = 0x0 +// bits[11:8] Sri2XbarFreeXreqCBC = 0x6 +// bits[5:0] Xbar2SriFreeListCBC = 0x1B + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x0005061B, // RegData + 0x007FFF3F, // RegMask + }} + }, +// D18F3x84 - ACPI Power State Control High +// bits[1] NbLowPwrEnSmafAct4 = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x84), // Address + 0x00000002, // RegData + 0x00000002, // RegMask + }} + }, +// D18F3xA0 - Power Control Miscellaneous +// bits[13:11] PllLockTime = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x00000800, // RegData + 0x00003800, // RegMask + }} + }, +// D18F3xA0 - Power Control Miscellaneous +// bits[14] Svi2HighFreqSel = 0x1, if PERFORMANCE_VRM_HIGH_SPEED_ENABLE == TRUE + { + ProfileFixup, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_VRM_HIGH_SPEED_ENABLE, // PerformanceFeatures + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x00004000, // regData + 0x00004000, // regMask + }} + }, +// D18F3xA4 - Reported Temperature Control +// bits[12:8] PerStepTimeDn = 0xF +// bits[7] TmpSlewDnEn = 0x1 +// bits[6:5] TmpMaxDiffUp = 0x3 +// bits[4:0] PerStepTimeUp = 0xF + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA4), // Address + 0x00000FEF, // RegData + 0x00001FFF, // RegMask + }} + }, +// D18F3xD4 - Clock Power/Timing Control 0 +// bits[31] NbClkDivApplyAll = 0x1 +// bits[30:28] NbClkDiv = 0x1 +// bits[27:24] PowerStepUp = 0x8 +// bits[23:20] PowerStepDown = 0x8 +// bits[11:8] ClkRampHystSel = 0xF + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xD4), // Address + 0x98800F00, // RegData + 0xFFF00F00, // RegMask + }} + }, +// D18F3xD8 - Clock Power/Timing Control 1 +// bits[6:4] VSRampSlamTime = 0x4 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xD8), // Address + 0x00000040, // RegData + 0x00000070, // RegMask + }} + }, +// D18F3xDC - Clock Power/Timing Control 2 +// bits[29:27] NbsynPtrAdjLo = 0x5 +// bits[26] IgnCpuPrbEn = 0x0 +// bits[25:19] CacheFlushOnHaltTmr = 0xF +// bits[18:16] CacheFlushOnHaltCtl = 0x0 +// bits[14:12] NbsynPtrAdj = 0x6 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xDC), // Address + 0x28786000, // RegData + 0x3FFF7000, // RegMask + }} + }, +// D18F3x140 - SRI to XCS Token Count +// bits[24:20] FreeTok = 0xF +// bits[17:16] IsocRspTok = 0x1 +// bits[15:14] IsocPreqTok = 0x0 +// bits[13:12] IsocReqTok = 0x1 +// bits[11:10] DnRspTok = 0x1 +// bits[9:8] UpRspTok = 0x1 +// bits[7:6] DnPreqTok = 0x1 +// bits[5:4] UpPreqTok = 0x2 +// bits[3:2] DnReqTok = 0x1 +// bits[1:0] UpReqTok = 0x2 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00F11566, // RegData + 0x01F3FFFF, // RegMask + }} + }, +// D18F3x144 - MCT to XCS Token Count +// bits[7:4] ProbeTok = 0x4 +// bits[3:0] RspTok = 0x7 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000047, // RegData + 0x000000FF, // RegMask + }} + }, +// D18F3x148 - Link to XCS Token Count - Link 0 +// bits[31:30] FreeTok[3:2] = 0x0 +// bits[28] IsocRspTok1 = 0x0 +// bits[26] IsocPreqTok1 = 0x0 +// bits[24] IsocReqTok1 = 0x0 +// bits[23:22] ProbeTok1 = 0x0 +// bits[21:20] RspTok1 = 0x0 +// bits[19:18] PReqTok1 = 0x0 +// bits[17:16] ReqTok1 = 0x0 +// bits[15:14] FreeTok[1:0] = 0x0 +// bits[13:12] IsocRspTok0 = 0x0 +// bits[11:10] IsocPreqTok0 = 0x1 +// bits[9:8] IsocReqTok0 = 0x1 +// bits[7:6] ProbeTok0 = 0x0 +// bits[5:4] RspTok0 = 0x2 +// bits[3:2] PReqTok0 = 0x2 +// bits[1:0] ReqTok0 = 0x2 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x148), // Address + 0x0000052A, // RegData + 0xD5FFFFFF, // RegMask + }} + }, +// D18F3x160 - NB Machine Check Misc (DRAM Thresholding) 0 (MC4_MISC0) +// bits[23:20] LvtOffset = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x160), // Address + 0x00100000, // RegData + 0x00F00000, // RegMask + }} + }, +// D18F3x168 - NB Machine Check Misc (Link Thresholding) 1 (MC4_MISC1) +// bits[23:20] LvtOffset = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x168), // Address + 0x00100000, // RegData + 0x00F00000, // RegMask + }} + }, +// D18F3x17C - Extended Freelist Buffer Count +// bits[3:0] SPQPrbFreeCBC = 0x8 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x17C), // Address + 0x00000008, // RegData + 0x0000000F, // RegMask + }} + }, +// D18F3x180 - Extended NB MCA Configuration +// bits[28] SyncFloodOnCC6DramUcErr = 0x1 +// bits[24] McaLogErrAddrWdtErr = 0x1 +// bits[21] SyncFloodOnCpuLeakErr = 0x1 +// bits[17] SyncFloodOnDeferErrToIO = 0x1 +// bits[9] SyncFloodOnUCNbAry = 0x1 +// bits[8] SyncFloodOnProtErr = 0x1 +// bits[7] SyncFloodOnTgtAbortErr = 0x1 +// bits[6] SyncFloodOnDatErr = 0x1 +// bits[5] DisPciCfgCpuMstAbortRsp = 0x1 +// bits[1] SyncFloodOnUsPwDatErr = 0x1 +// bits[0] McaLogUsPwDatErrEn = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x180), // Address + 0x112203E3, // RegData + 0x112203E3, // RegMask + }} + }, +// bits[9] = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x188), // Address + 0x00000200, // RegData + 0x00000200, // RegMask + }} + }, +// D18F3x1A0 - Core Interface Buffer Count +// bits[18:16] CpuToNbFreeBufCnt = 0x3 +// bits[2:0] CpuCmdBufCnt = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1A0), // Address + 0x00030001, // RegData + 0x00070007, // RegMask + }} + }, +// D18F3x1CC - IBS Control +// bits[8] LvtOffsetVal = 0x1 +// bits[3:0] LvtOffset = 0x0 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1CC), // Address + 0x00000100, // RegData + 0x0000010F, // RegMask + }} + }, +// D18F3x1E4 - SBI Control +// bits[11:8] LvtOffset = 0x3 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1E4), // Address + 0x00000300, // RegData + 0x00000F00, // RegMask + }} + }, +// D18F0x6C - Link Initialization Control +// bit [30] RlsLnkFullTokCntImm = 0x1 +// bit [28] RlsIntFullTokCntImm = 0x1 +// +// NOTE: The entry is intended to be after D18F0x[90, 94] and D18F3x[6C, 70, 74, 78, 7C, 140, 144, 148, 14C, 17C, 1A0] are programmed. + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x6C), // Address + 0x50000000, // RegData + 0x50000000, // RegMask + }} + }, +// D18F0x6C - Link Initialization Control +// bits[27] ApplyIsocModeEnNow = 0x1 +// +// NOTE: The entry is intended to be after RlsLnkFullTokCntImm and RlsIntFullTokCntImm have been set. + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x6C), // Address + 0x08000000, // RegData + 0x08000000, // RegMask + }} + }, +// D18F3x200 - Performance Mode Control Register +// bits[3] EnMcqPrbPickThrottle = 0x1 +// bits[2] EnDctOddToNcLnkDatXfr = 0x1 +// bits[1] EnDctEvnToNcLnkDatXfr = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x200), // Address + 0x0000000E, // RegData + 0x0000000E, // RegMask + }} + }, +// D18F4x118 - C-state Control 1 +// bits[23:21] ClkDivisorCstAct1 = 0x0 +// bits[19:18] CacheFlushTmrSelCstAct1 = 0x2 +// bits[16] CpuPrbEnCstAct1 = 0x1 +// bits[7:5] ClkDivisorCstAct0 = 0x0 +// bits[3:2] CacheFlushTmrSelCstAct0 = 0x2 +// bits[0] CpuPrbEnCstAct0 = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x118), // Address + 0x00090009, // RegData + 0x00ED00ED, // RegMask + }} + }, +// D18F4x128 - C-state Policy Control 1 +// bits[24:23] CacheFlushSucMonMispredictAct = 0x1 +// bits[22:21] CacheFlushSucMonTmrSel = 0x1 +// bits[20:18] CacheFlushSucMonThreshold = 0x4 +// bits[11:5] CacheFlushTmr = 0x7F +// bits[4:2] HaltCstateIndex = 0x0 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x128), // Address + 0x00B00FE0, // RegData + 0x01FC0FFC, // RegMask + }} + }, +// D18F4x15C - Core Performance Boost Control +// bits[8] CstatePowerEn = 0x1 +// bits[1:0] BoostSrc = 0x0 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x15C), // Address + 0x00000100, // RegData + 0x00000103, // RegMask + }} + }, +// D18F4x16C - APM TDP Control +// bits[14] CacUpC1 = 0x0 +// bits[4] ApmTdpLimitIntEn = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x16C), // Address + 0x00000010, // RegData + 0x00004010, // RegMask + }} + }, + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x210), // Address + 0x0000B41F, // RegData + 0x0000F7FF, // RegMask + }} + }, +// D18F5x88 - NB Configuration 4 (NB_CFG4) +// bits[24] DisHbNpReqBusLock = 0x1 +// bits[0] CC6PstateWakeUpDis = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_5, 0x88), // Address + 0x01000001, // RegData + 0x01000001, // RegMask + }} + }, +// D18F5x8C +// bits[15] = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_5, 0x8C), // Address + 0x00008000, // RegData + 0x00008000, // RegMask + }} + }, +// D18F5xE0 - Processor TDP Running Average +// bits[3:0] RunAvgRange = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_5, 0xE0), // Address + 0x00000001, // RegData + 0x0000000F, // RegMask + }} + }, +// D18F5x128 - Clock Power/Timing Control 3 +// bits[13:12] PwrGateTmr = 0x0 +// bits[9] FastSlamTimeDown = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_5, 0x128), // Address + 0x00000200, // RegData + 0x00003200, // RegMask + }} + }, +// D18F5x12C - Clock Power/Timing Control 4 +// bits[5] CorePsi1En = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_5, 0x12C), // Address + 0x00000020, // RegData + 0x00000020, // RegMask + }} + }, +// D18F5x170 - Northbridge P-state Control +// bits[12:9] NbPstateThreshold = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_5, 0x170), // Address + 0x00000200, // RegData + 0x00001E00, // RegMask + }} + }, +// D18F5x178 - Northbridge Fusion Configuration +// bits[18] CstateFusionHsDis = 0x1 +// bits[17] = 0x1 +// bits[16] ProcHotToGnbEn = 0x1 +// bits[11] = 0x1 +// bits[10] = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_5, 0x178), // Address + 0x00070C00, // RegData + 0x00070C00, // RegMask + }} + }, +}; + +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F16KbPciRegistersBeforeApLaunch[] = +{ +// D18F0x68 - Link Transaction Control +// bits[22:21] DsNpReqLmt = 0x2 +// bits[19] ApicExtSpur = 0x1 +// bits[18] ApicExtId = 0x1 +// bits[17] ApicExtBrdCst = 0x1 +// bits[15] LimitCldtCfg = 0x1 +// bits[11] RespPassPW = 0x1 +// bits[10] DisFillP = 0x0 +// bits[4] DisMTS = 0x1 +// bits[3] DisWrDwP = 0x1 +// bits[2] DisWrBP = 0x1 +// bits[1] DisRdDwP = 0x1 +// bits[0] DisRdBP = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x68), // Address + 0x004E881F, // RegData + 0x006E8C1F, // RegMask + }} + }, +// D18F3x8C - NB Configuration 1 High (NB_CFG1_HI) +// bits[30] MSRC001_001F[DisStpClkAbortFlush] = 0x1 +// bits[23] MSRC001_001F[EnaDiv1CpuLowPwr] = 0x1 +// bits[22] MSRC001_001F[InitApicIdCpuIdLo] = 0x1 +// bits[19] MSRC001_001F[DisDatFwdVic] = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x8C), // Address + 0x40C80000, // RegData + 0x40C80000, // RegMask + }} + }, +}; + +// PCI with Special Programming Requirements Table +// ---------------------- + +STATIC CONST FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_INITIALIZER ROMDATA F16KbPciWorkarounds[] = +{ +// D18F3x88 + { + FamSpecificWorkaround, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + SetDisCstateBoostBlockPstateUp, // function call + 0x00000000, // data + }} + }, +// D18F4x110 + { + FamSpecificWorkaround, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + ScalingApmParamBaseOnCSampleTimer, // function call + 0x00000000, // data + }} + }, +// D18F4x16C + { + FamSpecificWorkaround, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_KB_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + SetTdpLimitDis, // function call + 0x00000000, // data + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F16KbPciRegisterTableAfterApLaunch = { + PrimaryCores, + PERFORM_TP_AFTER_AP_LAUNCH, + (sizeof (F16KbPciRegistersAfterApLaunch) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) F16KbPciRegistersAfterApLaunch, +}; + +CONST REGISTER_TABLE ROMDATA F16KbPciRegisterTableBeforeApLaunch = { + PrimaryCores, + PERFORM_TP_BEFORE_AP_LAUNCH, + (sizeof (F16KbPciRegistersBeforeApLaunch) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) F16KbPciRegistersBeforeApLaunch, +}; + +CONST REGISTER_TABLE ROMDATA F16KbPciWorkaroundTable = { + PrimaryCores, + PERFORM_TP_AFTER_AP_LAUNCH, + (sizeof (F16KbPciWorkarounds) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) F16KbPciWorkarounds, +}; + +/*---------------------------------------------------------------------------------------*/ +/** + * Workaround for Kabini processors. + * + * + * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetDisCstateBoostBlockPstateUp ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + NB_CFG1_LOW_REG_REGISTER NbCfg1Low; + NB_CFG_4_REGISTER NbCfg4; + + PciAddress.AddressValue = NB_CFG_REG4_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&NbCfg4, StdHeader); + + PciAddress.AddressValue = NB_CFG1_LOW_REG_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&NbCfg1Low, StdHeader); + + NbCfg1Low.DisCstateBoostBlockPstateUp = NbCfg4.EnCstateBoostBlockCC6Exit; + LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&NbCfg1Low, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Workaround for Kabini processors. + * + * AGESA should program F4x110[11:0][CSampleTimer] to 2, and update below registers as: + * The following should be ROUNDED-NEAREST: + * + * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +ScalingApmParamBaseOnCSampleTimer ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + pmgmt_str0 var0; + pmgmt_str1 var1; + SAMPLE_RESIDENCY_TIMER_REGISTER SampleResidencyTimer; + + PciAddress.AddressValue = SAMPLE_RESIDENCY_TIMER_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&SampleResidencyTimer, StdHeader); + + SampleResidencyTimer.CSampleTimer = 20; + IDS_OPTION_HOOK (IDS_CSAMPLE_TIMER, (VOID *) (&SampleResidencyTimer), StdHeader); + ASSERT (SampleResidencyTimer.CSampleTimer != 0); + LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&SampleResidencyTimer, StdHeader); + + // The following should be ROUNDED-NEAREST: + // F5xB8[19:0] = F5xB8[19:0] * 2 / F4x110[CSampleTimer] + // F5xBC[19:0] = F5xBC[19:0] * 2 / F4x110[CSampleTimer] + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, FUNC_5, 0xB8); + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&var0, StdHeader); + var0.Bits_19_0 = ((var0.Bits_19_0 * 2) + (SampleResidencyTimer.CSampleTimer / 2)) / SampleResidencyTimer.CSampleTimer; + LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&var0, StdHeader); + + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, FUNC_5, 0xBC); + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&var1, StdHeader); + var1.Bits_19_0 = ((var1.Bits_19_0 * 2) + (SampleResidencyTimer.CSampleTimer / 2)) / SampleResidencyTimer.CSampleTimer; + LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&var1, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Workaround for Kabini processors. + * + * AGESA should program F4x16C[TdpLimitDis] in some case + * + * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetTdpLimitDis ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PciData; + PCI_ADDR PciAddress; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, FUNC_0, 0xB8); + PciData = 0xC010408C; + LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&PciData, StdHeader); + PciAddress.Address.Register = 0xBC; + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&PciData, StdHeader); + + if ((PciData & BIT2) == BIT2) { + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, FUNC_4, 0x16C); + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&PciData, StdHeader); + PciData |= BIT3; + LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&PciData, StdHeader); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerCheck.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerCheck.c new file mode 100644 index 0000000000..2017f8b548 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerCheck.c @@ -0,0 +1,500 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 P-State power check + * + * Performs the "Processor-Systemboard Power Delivery Compatibility Check" as + * described in the BKDG. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 86879 $ @e \$Date: 2013-01-28 11:11:12 -0600 (Mon, 28 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuF16PowerMgmt.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "F16KbPowerCheck.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFeatures.h" +#include "cpuApicUtilities.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBPOWERCHECK_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +F16KbPmPwrCheckErrorHandler ( + IN VOID *ErrorData, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F16KbPmPwrChkCopyPstate ( + IN UINT8 Dest, + IN UINT8 Src, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F16KbTransitionPstateCore ( + IN VOID *StateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * Family 16h Kabini core 0 entry point for performing the family 16h Processor- + * Systemboard Power Delivery Check. + * + * The steps are as follows: + * 1. Starting with P0, loop through all P-states until a passing state is + * found. A passing state is one in which the current required by the + * CPU is less than the maximum amount of current that the system can + * provide to the CPU. If P0 is under the limit, no further action is + * necessary. + * 2. If at least one P-State is under the limit & at least one P-State is + * over the limit, the BIOS must: + * a. If the processor's current P-State is disabled by the power check, + * then the BIOS must request a transition to an enabled P-state + * using MSRC001_0062[PstateCmd] and wait for MSRC001_0063[CurPstate] + * to reflect the new value. + * b. Copy the contents of the enabled P-state MSRs to the highest + * performance P-state locations. + * c. Request a P-state transition to the P-state MSR containing the + * COF/VID values currently applied. + * d. If a subset of boosted P-states are disabled, then copy the contents + * of the highest performance boosted P-state still enabled to the + * boosted P-states that have been disabled. + * e. If all boosted P-states are disabled, then program D18F4x15C[BoostSrc] + * to zero. + * f. Adjust the following P-state parameters affected by the P-state + * MSR copy by subtracting the number of P-states that are disabled + * by the power check. + * 1. F3x64[HtcPstateLimit] + * 2. F3x68[SwPstateLimit] + * 3. F3xDC[PstateMaxVal] + * 3. If all P-States are over the limit, the BIOS must: + * a. If the processor's current P-State is !=F3xDC[PstateMaxVal], then + * write F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] and wait for + * MSRC001_0063[CurPstate] to reflect the new value. + * b. If MSRC001_0061[PstateMaxVal]!=000b, copy the contents of the P-state + * MSR pointed to by F3xDC[PstateMaxVal] to the software P0 MSR. + * Write 000b to MSRC001_0062[PstateCmd] and wait for MSRC001_0063 + * [CurPstate] to reflect the new value. + * c. Adjust the following P-state parameters to zero: + * 1. F3x64[HtcPstateLimit] + * 2. F3x68[SwPstateLimit] + * 3. F3xDC[PstateMaxVal] + * d. Program D18F4x15C[BoostSrc] to zero. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParams Service parameters + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F16KbPmPwrCheck ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 DisPsNum; + UINT8 PsMaxVal; + UINT8 Pstate; + UINT32 ProcIddMax; + UINT32 LocalPciRegister; + UINT32 PstateLimit; + UINT32 SwPstateAdjust; + PCI_ADDR PciAddress; + UINT64 LocalMsrRegister; + PWRCHK_ERROR_DATA ErrorData; + + ErrorData.SocketNumber = 0; + // get the Max P-state value + for (PsMaxVal = NM_PS_REG - 1; PsMaxVal != 0; --PsMaxVal) { + LibAmdMsrRead (PS_REG_BASE + PsMaxVal, &LocalMsrRegister, StdHeader); + if (((F16_PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1) { + break; + } + } + + ErrorData.HwPstateNumber = (UINT8) (PsMaxVal + 1); + + // Starting with P0, loop through all P-states until a passing state is + // found. A passing state is one in which the current required by the + // CPU is less than the maximum amount of current that the system can + // provide to the CPU. If P0 is under the limit, no further action is + // necessary. + DisPsNum = 0; + for (Pstate = 0; Pstate < ErrorData.HwPstateNumber; Pstate++) { + if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, Pstate, &ProcIddMax, StdHeader)) { + if (ProcIddMax > CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].MaximumCurrentLimit) { + // Add to event log the Pstate that exceeded the current limit + PutEventLog (AGESA_WARNING, + CPU_EVENT_PM_PSTATE_OVERCURRENT, + 0, Pstate, 0, 0, StdHeader); + DisPsNum++; + } else { + break; + } + } + } + + ErrorData.AllowablePstateNumber = ((PsMaxVal + 1) - DisPsNum); + + if (ErrorData.AllowablePstateNumber == 0) { + PutEventLog (AGESA_FATAL, + CPU_EVENT_PM_ALL_PSTATE_OVERCURRENT, + 0, 0, 0, 0, StdHeader); + } + + if (DisPsNum != 0) { + PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F4x15C + ErrorData.NumberOfBoostStates = (UINT8) ((F16_CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates; + + if (DisPsNum >= ErrorData.NumberOfBoostStates) { + // If all boosted P-states are disabled, then program D18F4x15C[BoostSrc] to zero. + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + ((F16_CPB_CTRL_REGISTER *) (&LocalPciRegister))->BoostSrc = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + // Update the result of isFeatureEnabled in heap. + UpdateFeatureStatusInHeap (CoreBoost, FALSE, StdHeader); + + ErrorData.NumberOfSwPstatesDisabled = DisPsNum - ErrorData.NumberOfBoostStates; + } else { + ErrorData.NumberOfSwPstatesDisabled = 0; + } + + PciAddress.AddressValue = HTC_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F3x64 + ErrorData.HtcPstate = (UINT8) (((HTC_REGISTER *) (&LocalPciRegister))->HtcPstateLimit); + + F16KbPmPwrCheckErrorHandler (&ErrorData, StdHeader); + + // Final Step + // F3x64[HtcPstatelimit] -= disPsNum + // F3x68[SwPstateLimit] -= disPsNum + // F3xDC[HwPstateMaxVal] -= disPsNum + if (ErrorData.NumberOfSwPstatesDisabled != 0) { + PstateLimit = ((HTC_REGISTER *) &LocalPciRegister)->HtcPstateLimit; + if (PstateLimit > PsMaxVal) { + SwPstateAdjust = PstateLimit - PsMaxVal; + } else { + SwPstateAdjust = 0; + } + if (PstateLimit > ErrorData.NumberOfSwPstatesDisabled) { + PstateLimit -= ErrorData.NumberOfSwPstatesDisabled; + } else { + PstateLimit = ErrorData.NumberOfBoostStates; + } + if (PstateLimit <= ErrorData.NumberOfBoostStates) { + PstateLimit = ErrorData.NumberOfBoostStates + SwPstateAdjust; + } + ((HTC_REGISTER *) (&LocalPciRegister))->HtcPstateLimit = PstateLimit; + LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + + PciAddress.Address.Register = SW_PS_LIMIT_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F3x68 + PstateLimit = ((SW_PS_LIMIT_REGISTER *) &LocalPciRegister)->SwPstateLimit; + if (PstateLimit > PsMaxVal) { + SwPstateAdjust = PstateLimit - PsMaxVal; + } else { + SwPstateAdjust = 0; + } + if (PstateLimit > ErrorData.NumberOfSwPstatesDisabled) { + PstateLimit -= ErrorData.NumberOfSwPstatesDisabled; + } else { + PstateLimit = ErrorData.NumberOfBoostStates; + } + if (PstateLimit <= ErrorData.NumberOfBoostStates) { + PstateLimit = ErrorData.NumberOfBoostStates + SwPstateAdjust; + } + ((SW_PS_LIMIT_REGISTER *) (&LocalPciRegister))->SwPstateLimit = PstateLimit; + LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + + PciAddress.Address.Register = CPTC2_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F3xDC + PstateLimit = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->HwPstateMaxVal; + if (PstateLimit > ErrorData.NumberOfSwPstatesDisabled) { + PstateLimit -= ErrorData.NumberOfSwPstatesDisabled; + } else { + PstateLimit = ErrorData.NumberOfBoostStates; + } + if (PstateLimit < ErrorData.NumberOfBoostStates) { + PstateLimit = ErrorData.NumberOfBoostStates; + } + + ((CLK_PWR_TIMING_CTRL2_REGISTER *) (&LocalPciRegister))->HwPstateMaxVal = PstateLimit; + LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Error handler called if any p-states were determined to be out + * of range for the mother board. + * + * This function implements steps 2a-c and 3a-c on each core. + * + * @param[in] ErrorData Details about the error condition. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F16KbPmPwrCheckErrorHandler ( + IN VOID *ErrorData, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 HwPsMaxVal; + UINT8 SwPsMaxVal; + UINT8 HwDisPsNum; + UINT8 CurrentSwPs; + UINT8 ShiftIndex; + UINT8 PsDisableCount; + UINT8 NewSwP0; + UINT8 StateNumber; + UINT8 Core; + UINT32 ActiveCores; + UINT64 LocalMsrRegister; + BOOLEAN DisableAllBoostPstates; + AP_TASK ApTask; + AGESA_STATUS IgnoreStatus; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + if (IsBsp (StdHeader, &IgnoreStatus)) { + // P-state MSRs are shared, so only BSC needs to perform this + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + GetActiveCoresInCurrentSocket (&ActiveCores, StdHeader); + + HwPsMaxVal = (((PWRCHK_ERROR_DATA *) ErrorData)->HwPstateNumber - 1); + HwDisPsNum = (((PWRCHK_ERROR_DATA *) ErrorData)->HwPstateNumber - + ((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber); + + LibAmdMsrRead (MSR_PSTATE_STS, &LocalMsrRegister, StdHeader); + CurrentSwPs = (UINT8) (((PSTATE_STS_MSR *) &LocalMsrRegister)->CurPstate); + LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &LocalMsrRegister, StdHeader); + SwPsMaxVal = (UINT8) (((PSTATE_CURLIM_MSR *) &LocalMsrRegister)->PstateMaxVal); + PsDisableCount = 0; + if (((PWRCHK_ERROR_DATA *) ErrorData)->HtcPstate > HwPsMaxVal) { + ShiftIndex = ((PWRCHK_ERROR_DATA *) ErrorData)->HtcPstate; + } else { + ShiftIndex = HwPsMaxVal; + } + + DisableAllBoostPstates = FALSE; + + // Prepare ApTask + ApTask.FuncAddress.PfApTaskI = F16KbTransitionPstateCore; + ApTask.DataTransfer.DataSizeInDwords = 1; + ApTask.DataTransfer.DataPtr = &StateNumber; + ApTask.DataTransfer.DataTransferFlags = 0; + ApTask.ExeFlags = 0; + if (((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber == 0) { + // All P-States are over the limit. + + // Step 1 + // Transition to Pstate Max if not there already + if (CurrentSwPs != SwPsMaxVal) { + StateNumber = SwPsMaxVal; + for (Core = 1; Core < (UINT8) ActiveCores; ++Core) { + ApUtilRunCodeOnSocketCore (0, Core, &ApTask, StdHeader); + } + ApUtilTaskOnExecutingCore (&ApTask, StdHeader, (VOID *) NULL); + } + + // Step 2 + // If Pstate Max is not P0, copy Pstate max contents to P0 and switch + // to P0. + for (i = 0; i <= (ShiftIndex - HwPsMaxVal); i++) { + F16KbPmPwrChkCopyPstate ((((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfBoostStates + i), (HwPsMaxVal + i), StdHeader); + } + StateNumber = 0; + for (Core = 1; Core < (UINT8) ActiveCores; ++Core) { + ApUtilRunCodeOnSocketCore (0, Core, &ApTask, StdHeader); + } + ApUtilTaskOnExecutingCore (&ApTask, StdHeader, (VOID *) NULL); + + + // Disable all SW P-states except P0 + PsDisableCount = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled - 1; + + // Set a flag to disable all boost P-states + DisableAllBoostPstates = TRUE; + } else { + // At least one P-State is under the limit & at least one P-State is + // over the limit. + if (((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfBoostStates > HwDisPsNum) { + // A subset of boosted P-states are disabled. Copy the contents of the + // highest performance boosted P-state still enabled to the boosted + // P-states that have been disabled. + for (i = 0; i < HwDisPsNum; i++) { + F16KbPmPwrChkCopyPstate (i, HwDisPsNum, StdHeader); + } + } else { + // Set a flag to disable all boost P-states + DisableAllBoostPstates = TRUE; + + if (((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled != 0) { + // Move remaining P-state register(s) up + // Step 1 + // Transition to a valid Pstate if current Pstate has been disabled + if (CurrentSwPs < ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled) { + StateNumber = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled; + for (Core = 1; Core < (UINT8) ActiveCores; ++Core) { + ApUtilRunCodeOnSocketCore (0, Core, &ApTask, StdHeader); + } + ApUtilTaskOnExecutingCore (&ApTask, StdHeader, (VOID *) NULL); + + CurrentSwPs = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled; + } + + // Step 2 + // Move enabled Pstates up and disable the remainder + NewSwP0 = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfBoostStates + ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled; + for (i = 0; i <= (ShiftIndex - NewSwP0); i++) { + F16KbPmPwrChkCopyPstate ((i + ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfBoostStates), (i + NewSwP0), StdHeader); + } + + // Step 3 + // Transition to current COF/VID at shifted location + CurrentSwPs = (CurrentSwPs - ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled); + StateNumber = CurrentSwPs; + for (Core = 1; Core < (UINT8) ActiveCores; ++Core) { + ApUtilRunCodeOnSocketCore (0, Core, &ApTask, StdHeader); + } + ApUtilTaskOnExecutingCore (&ApTask, StdHeader, (VOID *) NULL); + + // Disable the appropriate number of P-states + PsDisableCount = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled; + } + } + } + // Disable all boost P-states + if (DisableAllBoostPstates) { + for (i = 0; i < ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfBoostStates; i++) { + FamilySpecificServices->DisablePstate (FamilySpecificServices, i, StdHeader); + } + } + // Disable the appropriate P-states if any, starting from HW Pmin + for (i = 0; i < PsDisableCount; i++) { + FamilySpecificServices->DisablePstate (FamilySpecificServices, (HwPsMaxVal - i), StdHeader); + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Copies the contents of one P-State MSR to another. + * + * @param[in] Dest Destination p-state number + * @param[in] Src Source p-state number + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +STATIC +F16KbPmPwrChkCopyPstate ( + IN UINT8 Dest, + IN UINT8 Src, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 LocalMsrRegister; + + LibAmdMsrRead ((UINT32) (PS_REG_BASE + Src), &LocalMsrRegister, StdHeader); + LibAmdMsrWrite ((UINT32) (PS_REG_BASE + Dest), &LocalMsrRegister, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Core-level transition Pstate + * + * Transitions the executing core to the desired P-state. + * + * @param[in] StateNumber The new P-State to make effective. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F16KbTransitionPstateCore ( + IN VOID *StateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + + FamilySpecificServices->TransitionPstate (FamilySpecificServices, *((UINT8 *) StateNumber), (BOOLEAN) TRUE, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerCheck.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerCheck.h new file mode 100644 index 0000000000..078a539226 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerCheck.h @@ -0,0 +1,84 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini Power related functions and structures + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _F16_KB_POWER_CHECK_H_ +#define _F16_KB_POWER_CHECK_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +/// Power Check Error Data +typedef struct { + UINT8 SocketNumber; ///< Socket Number + UINT8 HwPstateNumber; ///< Number of hardware P-states + UINT8 AllowablePstateNumber; ///< Number of allowable P-states + UINT8 NumberOfBoostStates; ///< Number of boosted P-states + UINT8 NumberOfSwPstatesDisabled; ///< Number of software P-states disabled + UINT8 HtcPstate; ///< HTC Pstate Limit Pstate +} PWRCHK_ERROR_DATA; + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +VOID +F16KbPmPwrCheck ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _F16_KB_POWER_CHECK_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmt.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmt.h new file mode 100644 index 0000000000..497b4d4fdb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmt.h @@ -0,0 +1,535 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini Power Management related registers defination + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_F16_KB_POWERMGMT_H_ +#define _CPU_F16_KB_POWERMGMT_H_ + +/* + * Family 16h Kabini CPU Power Management MSR definitions + * + */ + + +/* NB Machine Check Misc 4 MSR Register 0x00000413 */ +#define MC4_MISC0 0x00000413ul + +/// Interrupt Pending and CMP-Halt MSR Register +typedef struct { + UINT64 :24; ///< Reserved + UINT64 BlkPtr:8; ///< Block pointer for additional MISC registers + UINT64 ErrCnt:12; ///< Error counter + UINT64 :4; ///< Reserved + UINT64 Ovrflw:1; ///< Overflow + UINT64 IntType:2; ///< Interrupt type + UINT64 CntEn:1; ///< Counter enable + UINT64 LvtOffset:4; ///< LVT offset + UINT64 :5; ///< Reserved + UINT64 Locked:1; ///< Locked + UINT64 CntP:1; ///< Counter present + UINT64 Valid:1; ///< Valid +} MC4_MISC0_MSR; + +/* P-state Registers 0xC00100[6B:64] */ + +/// P-state MSR +typedef struct { + UINT64 CpuFid:6; ///< CpuFid + UINT64 CpuDid:3; ///< CpuDid + UINT64 CpuVid:8; ///< CpuVid + UINT64 :5; ///< Reserved + UINT64 NbPstate:1; ///< NbPstate + UINT64 :9; ///< Reserved + UINT64 IddValue:8; ///< IddValue + UINT64 IddDiv:2; ///< IddDiv + UINT64 :21; ///< Reserved + UINT64 PsEnable:1; ///< Pstate Enable +} PSTATE_MSR; + +#define GetF16KbCpuVid(PstateMsr) (((PSTATE_MSR *) PstateMsr)->CpuVid) + + +/* VID operation related macros */ +#define ConvertVidInuV(Vid) (1550000 - (6250 * Vid)) ///< Convert VID in uV. + +/* COFVID Control Register 0xC0010070 */ +#define MSR_COFVID_CTL 0xC0010070ul + +/// COFVID Control MSR Register +typedef struct { + UINT64 CpuFid:6; ///< CpuFid + UINT64 CpuDid:3; ///< CpuDid + UINT64 CpuVid_6_0:7; ///< CpuVid[6:0] + UINT64 PstateId:3; ///< Pstate ID + UINT64 :1; ///< Reserved + UINT64 CpuVid_7:1; ///< CpuVid[7] + UINT64 :1; ///< Reserved + UINT64 NbPstate:1; ///< Northbridge P-state + UINT64 :1; ///< Reserved + UINT64 NbVid:8; ///< NbVid + UINT64 :32; ///< Reserved +} COFVID_CTRL_MSR; + +#define COFVID_CTRL_MSR_CurCpuVid_6_0_OFFSET 9 +#define COFVID_CTRL_MSR_CurCpuVid_6_0_WIDTH 7 +#define COFVID_CTRL_MSR_CurCpuVid_6_0_MASK 0xfe00 +#define COFVID_CTRL_MSR_CurCpuVid_7_OFFSET 20 +#define COFVID_CTRL_MSR_CurCpuVid_7_WIDTH 1 +#define COFVID_CTRL_MSR_CurCpuVid_7_MASK 0x100000ul + +/* SVI VID Encoding */ + +///< Union structure of VID in SVI1/SVI2 modes +typedef union { + UINT32 RawVid; ///< Raw VID value + struct { ///< SVI2 mode VID structure + UINT32 Vid_6_0:7; ///< Vid[6:0] of SVI2 mode + UINT32 Vid_7:1; ///< Vid[7] of SVI2 mode + } SVI2; + struct { ///< SVI1 mode VID structure + UINT32 Vid_LSB_Ignore:1; ///< Ignored LSB of 8bit VID encoding in SVI1 mode + UINT32 Vid_6_0:1; ///< Vid[6:0] of SVI mode + } SVI1; +} SVI_VID; + + +#define SetF16KbCpuVid(CofVidStsMsr, NewCpuVid) ( \ + ((COFVID_CTRL_MSR *) CofVidStsMsr)->CurCpuVid_6_0) = ((SVI_VID *) NewCpuVid)->SVI2.Vid_6_0; \ + ((COFVID_CTRL_MSR *) CofVidStsMsr)->CurCpuVid_7) = ((SVI_VID *) NewCpuVid)->SVI2.Vid_7; \ +) + + +/* COFVID Status Register 0xC0010071 */ +#define MSR_COFVID_STS 0xC0010071ul + +/// COFVID Status MSR Register +typedef struct { + UINT64 CurCpuFid:6; ///< Current CpuFid + UINT64 CurCpuDid:3; ///< Current CpuDid + UINT64 CurCpuVid_6_0:7; ///< Current CpuVid[6:0] + UINT64 CurPstate:3; ///< Current Pstate + UINT64 :1; ///< Reserved + UINT64 CurCpuVid_7:1; ///< Current CpuVid[7] + UINT64 :2; ///< Reserved + UINT64 NbPstateDis:1; ///< NbPstate Disable + UINT64 :8; + UINT64 StartupPstate:3; ///< Startup Pstate + UINT64 :14; ///< Reserved + UINT64 MaxCpuCof:6; ///< MaxCpuCof + UINT64 :1; ///< Reserved + UINT64 CurPstateLimit:3; ///< Current Pstate Limit + UINT64 MaxNbCof:5; ///< MaxNbCof +} COFVID_STS_MSR; + +#define COFVID_STS_MSR_CurCpuVid_6_0_OFFSET 9 +#define COFVID_STS_MSR_CurCpuVid_6_0_WIDTH 7 +#define COFVID_STS_MSR_CurCpuVid_6_0_MASK 0xfe00 +#define COFVID_STS_MSR_CurCpuVid_7_OFFSET 20 +#define COFVID_STS_MSR_CurCpuVid_7_WIDTH 1 +#define COFVID_STS_MSR_CurCpuVid_7_MASK 0x100000ul + +#define GetF16KbCurCpuVid(CofVidStsMsr) ( \ + (((COFVID_STS_MSR *) CofVidStsMsr)->CurCpuVid_7 << COFVID_STS_MSR_CurCpuVid_6_0_WIDTH) \ + | ((COFVID_STS_MSR *) CofVidStsMsr)->CurCpuVid_6_0) + + +/* + * Family 16h Kabini CPU Power Management PCI definitions + * + */ +/* Link Initialization Status D18F0x1A0 */ +#define LINK_INIT_STATUS_REG 0x1A0 +#define LINK_INIT_STATUS_REG_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_0, LINK_INIT_STATUS_REG)) + +/// Link Initialization Status +typedef struct { + UINT32 InitComplete0:2; ///< Initialization complete for link 0 + UINT32 InitComplete1:2; ///< Initialization complete for link 1 + UINT32 :20; ///< Reserved + UINT32 IntNbExtCap:4; ///< Internal NB extneded capability + UINT32 :3; ///< Reserved + UINT32 InitStatusValid:1; ///< Initialization status valid +} LINK_INIT_STATUS_REGISTER; + +/* NB Configuration 1 Low F3x88 */ +#define NB_CFG1_LOW_REG 0x88 +#define NB_CFG1_LOW_REG_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_3, NB_CFG1_LOW_REG)) + +/// Power Control Miscellaneous PCI Register +typedef struct { + UINT32 :18; ///< Reserved + UINT32 DisCstateBoostBlockPstateUp:1; ///< DisCstateBoostBlockPstateUp + UINT32 :12; ///< Reserved + UINT32 DisCohLdtCfg:1; ///< Disable coherent link configuration accesses +} NB_CFG1_LOW_REG_REGISTER; + +/* Power Control Miscellaneous Register F3xA0 */ +#define PW_CTL_MISC_REG 0xA0 +#define PW_CTL_MISC_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_3, PW_CTL_MISC_REG)) + +/// Power Control Miscellaneous PCI Register +typedef struct { + UINT32 PsiVid:7; ///< PSI_L VID threshold VID[6:0] + UINT32 PsiVidEn:1; ///< PSI_L VID enable + UINT32 PsiVid_7:1; ///< PSI_L VID threshold VID[7] + UINT32 :1; ///< Reserved + UINT32 IdleExitEn:1; ///< Idle exit enable + UINT32 PllLockTime:3; ///< PLL synchronization lock time + UINT32 Svi2HighFreqSel:1; ///< SVI2 high frequency select + UINT32 :1; ///< Reserved + UINT32 ConfigId:12; ///< Configuration ID + UINT32 :3; ///< Reserved + UINT32 CofVidProg:1; ///< COF and VID of Pstate programmed +} POWER_CTRL_MISC_REGISTER; + + +/* Clock Power/Timing Control 0 Register F3xD4 */ +#define CPTC0_REG 0xD4 +#define CPTC0_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_3, CPTC0_REG)) + +/// Clock Power Timing Control PCI Register +typedef struct { + UINT32 MaxSwPstateCpuCof:6; ///< Maximum software P-state core COF + UINT32 :2; ///< Reserved + UINT32 ClkRampHystSel:4; ///< Clock Ramp Hysteresis Select + UINT32 ClkRampHystCtl:1; ///< Clock Ramp Hysteresis Control + UINT32 :1; ///< Reserved + UINT32 CacheFlushImmOnAllHalt:1; ///< Cache Flush Immediate on All Halt + UINT32 :5; ///< Reserved + UINT32 PowerStepDown:4; ///< Power Step Down + UINT32 PowerStepUp:4; ///< Power Step Up + UINT32 NbClkDiv:3; ///< NbClkDiv + UINT32 NbClkDivApplyAll:1; ///< NbClkDivApplyAll +} CLK_PWR_TIMING_CTRL_REGISTER; + + +/* Clock Power/Timing Control 1 Register F3xD8 */ +#define CPTC1_REG 0xD8 +#define CPTC1_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_3, CPTC1_REG)) + +/// Clock Power Timing Control 1 PCI Register +typedef struct { + UINT32 :4; ///< Reserved + UINT32 VSRampSlamTime:3; ///< Voltage stabilization ramp time + UINT32 :25; ///< Reserved +} CLK_PWR_TIMING_CTRL1_REGISTER; + + +/* Northbridge Capabilities Register F3xE8 */ +#define NB_CAPS_REG 0xE8 +#define NB_CAPS_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_3, NB_CAPS_REG)) + +/// Northbridge Capabilities PCI Register +typedef struct { + UINT32 :1; ///< Reserved + UINT32 DualNode:1; ///< Dual-node multi-processor capable + UINT32 EightNode:1; ///< Eight-node multi-processor capable + UINT32 Ecc:1; ///< ECC capable + UINT32 Chipkill:1; ///< Chipkill ECC capable + UINT32 :3; ///< Reserved + UINT32 MctCap:1; ///< Memory controller capable + UINT32 SvmCapable:1; ///< SVM capable + UINT32 HtcCapable:1; ///< HTC capable + UINT32 :3; ///< Reserved + UINT32 MultVidPlane:1; ///< Multiple VID plane capable + UINT32 :4; ///< Reserved + UINT32 x2Apic:1; ///< x2Apic capability + UINT32 :4; ///< Reserved + UINT32 MemPstateCap:1; ///< Memory P-state capable + UINT32 :3; ///< Reserved + UINT32 Succor:1; ///< SUCCOR + UINT32 :3; ///< Reserved +} NB_CAPS_REGISTER; + +/* Sample and Residency Timers Register D18F4x110 */ +#define SAMPLE_RESIDENCY_TIMER_REG 0x110 +#define SAMPLE_RESIDENCY_TIMER_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_4, SAMPLE_RESIDENCY_TIMER_REG)) + +/// Sample and Residency Timers Register +typedef struct { + UINT32 CSampleTimer:12; ///< CSampleTimer + UINT32 FastCSampleTimer:1; ///< FastCSampleTimer + UINT32 MinResTmr:8; ///< Minimum residency timer + UINT32 :11; ///< Reserved +} SAMPLE_RESIDENCY_TIMER_REGISTER; + +/* C-state Control 1 Register D18F4x118 */ +#define CSTATE_CTRL1_REG 0x118 +#define CSTATE_CTRL1_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_4, CSTATE_CTRL1_REG)) + +/// C-state Control 1 Register +typedef struct { + UINT32 CpuPrbEnCstAct0:1; ///< Core direct probe enable + UINT32 CacheFlushEnCstAct0:1; ///< Cache flush enable + UINT32 CacheFlushTmrSelCstAct0:2; ///< Cache flush timer select + UINT32 :1; ///< Reserved + UINT32 ClkDivisorCstAct0:3; ///< Clock divisor + UINT32 PwrGateEnCstAct0:1; ///< Power gate enable + UINT32 PwrOffEnCstAct0:1; ///< C-state action field 3 + UINT32 NbPwrGate0:1; ///< NB power-gating 0 + UINT32 NbClkGate0:1; ///< NB clock-gating 0 + UINT32 SelfRefr0:1; ///< Self-refresh 0 + UINT32 SelfRefrEarly0:1; ///< Allow early self-refresh 0 + UINT32 :2; ///< Reserved + UINT32 CpuPrbEnCstAct1:1; ///< Core direct probe enable + UINT32 CacheFlushEnCstAct1:1; ///< Cache flush eable + UINT32 CacheFlushTmrSelCstAct1:2; ///< Cache flush timer select + UINT32 :1; ///< Reserved + UINT32 ClkDivisorCstAct1:3; ///< Clock divisor + UINT32 PwrGateEnCstAct1:1; ///< Power gate enable + UINT32 PwrOffEnCstAct1:1; ///< C-state action field 3 + UINT32 NbPwrGate1:1; ///< NB power-gating 1 + UINT32 NbClkGate1:1; ///< NB clock-gating 1 + UINT32 SelfRefr1:1; ///< Self-refresh 1 + UINT32 SelfRefrEarly1:1; ///< Allow early self-refresh 1 + UINT32 :2; ///< Reserved +} CSTATE_CTRL1_REGISTER; + + +/* C-state Control 2 Register D18F4x11C */ +#define CSTATE_CTRL2_REG 0x11C +#define CSTATE_CTRL2_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_4, CSTATE_CTRL2_REG)) + +/// C-state Control 2 Register +typedef struct { + UINT32 CpuPrbEnCstAct2:1; ///< Core direct probe enable + UINT32 CacheFlushEnCstAct2:1; ///< Cache flush eable + UINT32 CacheFlushTmrSelCstAct2:2; ///< Cache flush timer select + UINT32 :1; ///< Reserved + UINT32 ClkDivisorCstAct2:3; ///< Clock divisor + UINT32 PwrGateEnCstAct2:1; ///< Power gate enable + UINT32 PwrOffEnCstAct2:1; ///< C-state action field 3 + UINT32 NbPwrGate2:1; ///< NB power-gating 2 + UINT32 NbClkGate2:1; ///< NB clock-gating 2 + UINT32 SelfRefr2:1; ///< Self-refresh 2 + UINT32 SelfRefrEarly2:1; ///< Allow early self-refresh 2 + UINT32 :18; ///< Reserved +} CSTATE_CTRL2_REGISTER; + + +/* Cstate Policy Control 1 Register D18F4x128 */ +#define CSTATE_POLICY_CTRL1_REG 0x128 +#define CSTATE_POLICY_CTRL1_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_4, CSTATE_POLICY_CTRL1_REG)) + +/// Cstate Policy Control 1 Register +typedef struct { + UINT32 :2; ///< Reserved + UINT32 HaltCstateIndex:3; ///< Specifies the IO-based C-state that is invoked by a HLT instruction + UINT32 CacheFlushTmr:7; ///< Cache flush timer + UINT32 :6; ///< Reserved + UINT32 CacheFlushSucMonThreshold:3; ///< Cache flush success monitor threshold + UINT32 CacheFlushSucMonTmrSel:2; ///< Cache flush success monitor timer select + UINT32 CacheFlushSucMonMispredictAct:2; ///< Cache flush success monitor mispredict action + UINT32 :6; ///< Reserved + UINT32 CstateMsgDis:1; ///< C-state messaging disable +} CSTATE_POLICY_CTRL1_REGISTER; + + +/* Core Performance Boost Control Register D18F4x15C */ + +/// Core Performance Boost Control Register +typedef struct { + UINT32 BoostSrc:2; ///< Boost source + UINT32 NumBoostStates:3; ///< Number of boosted states + UINT32 :2; ///< Reserved + UINT32 ApmMasterEn:1; ///< APM master enable + UINT32 CstatePowerEn:1; ///< C-state Power Enable + UINT32 :22; ///< Reserved + UINT32 BoostLock:1; ///< +} CPB_CTRL_REGISTER; + + +/* Northbridge Capabilities 2 F5x84*/ +#define NB_CAPS_REG2 0x84 +#define NB_CAPS_REG2_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, NB_CAPS_REG2)) + +/// Northbridge Capabilities 2 PCI Register +typedef struct { + UINT32 CmpCap:8; ///< CMP capable + UINT32 :4; ///< Reserved + UINT32 DctEn:4; ///< DCT enabled + UINT32 DdrMaxRate:5; ///< maximum DDR rate + UINT32 :3; ///< Reserved + UINT32 DdrMaxRateEnf:5; ///< enforced maximum DDR rate: + UINT32 :3; ///< Reserved +} NB_CAPS_2_REGISTER; + +/* Northbridge Configuration 4 F5x88*/ +#define NB_CFG_REG4 0x88 +#define NB_CFG_REG4_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, NB_CFG_REG4)) + +/// Northbridge Configuration 4 PCI Register +typedef struct { + UINT32 CC6PstateWakeUpDis:1; ///< CC6PstateWakeUpDis + UINT32 :17; ///< Reserved + UINT32 EnCstateBoostBlockCC6Exit:1;///< EnCstateBoostBlockCC6Exit + UINT32 :5; ///< Reserved + UINT32 DisHbNpReqBusLock:1; ///< DisHbNpReqBusLock + UINT32 :7; ///< Reserved +} NB_CFG_4_REGISTER; + +typedef struct { + UINT32 Bits_19_0:20; ///< Bits[19:0] + UINT32 Bits_31_20:12; ///< Reserved +} pmgmt_str0; + +typedef struct { + UINT32 Bits_19_0:20; ///< Bits[19:0] + UINT32 Bits_31_20:12; ///< Reserved +} pmgmt_str1; + +/* Northbridge P-state [3:0] F5x1[6C:60] */ + +/// Northbridge P-state Register +typedef struct { + UINT32 NbPstateEn:1; ///< NB P-state enable + UINT32 NbFid:6; ///< NB frequency ID + UINT32 NbDid:1; ///< NB divisor ID + UINT32 :2; ///< Reserved + UINT32 NbVid_6_0:7; ///< NB VID[6:0] + UINT32 :1; ///< Reserved + UINT32 MemPstate:1; ///< Memory P-State + UINT32 :2; ///< Reserved + UINT32 NbVid_7:1; ///< NB VID[7] + UINT32 NbIddDiv:2; ///< northbridge current divisor + UINT32 NbIddValue:8; ///< northbridge current value +} NB_PSTATE_REGISTER; + +#define NB_PSTATE_REGISTER_NbVid_6_0_OFFSET 10 +#define NB_PSTATE_REGISTER_NbVid_6_0_WIDTH 7 +#define NB_PSTATE_REGISTER_NbVid_6_0_MASK 0x0001FC00ul +#define NB_PSTATE_REGISTER_NbVid_7_OFFSET 21 +#define NB_PSTATE_REGISTER_NbVid_7_WIDTH 1 +#define NB_PSTATE_REGISTER_NbVid_7_MASK 0x00200000ul + +#define GetF16KbNbVid(NbPstateRegister) ( \ + (((NB_PSTATE_REGISTER *) NbPstateRegister)->NbVid_7 << NB_PSTATE_REGISTER_NbVid_6_0_WIDTH) \ + | ((NB_PSTATE_REGISTER *) NbPstateRegister)->NbVid_6_0) + +#define SetF16KbNbVid(NbPstateRegister, NewNbVid) { \ + ((NB_PSTATE_REGISTER *) NbPstateRegister)->NbVid_6_0 = ((SVI_VID *) NewNbVid)->SVI2.Vid_6_0; \ + ((NB_PSTATE_REGISTER *) NbPstateRegister)->NbVid_7 = ((SVI_VID *) NewNbVid)->SVI2.Vid_7; \ +} + +/* Northbridge P-state Status */ +#define NB_PSTATE_CTRL 0x170 +#define NB_PSTATE_CTRL_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, NB_PSTATE_CTRL)) + +/// Northbridge P-state Control Register +typedef struct { + UINT32 NbPstateMaxVal:2; ///< NB P-state maximum value + UINT32 :1; ///< Reserved + UINT32 NbPstateLo:2; ///< NB P-state low + UINT32 :1; ///< Reserved + UINT32 NbPstateHi:2; ///< NB P-state high + UINT32 :1; ///< Reserved + UINT32 NbPstateThreshold:4; ///< NB P-state threshold + UINT32 NbPstateDisOnP0:1; ///< NB P-state disable on P0 + UINT32 SwNbPstateLoDis:1; ///< Software NB P-state low disable + UINT32 :8; ///< Reserved + UINT32 NbPstateGnbSlowDis:1; ///< NbPstateGnbSlowDis + UINT32 NbPstateLoRes:3; ///< NB P-state low residency timer + UINT32 NbPstateHiRes:3; ///< NB P-state high residency timer + UINT32 NbPstateFidVidSbcEn:1; ///< NbPstateFidVidSbcEn + UINT32 MemPstateDis:1; ///< Memory P-state disable +} NB_PSTATE_CTRL_REGISTER; + + +/* Northbridge P-state Status */ +#define NB_PSTATE_STATUS 0x174 +#define NB_PSTATE_STATUS_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, NB_PSTATE_STATUS)) + +/// Northbridge P-state Status Register +typedef struct { + UINT32 NbPstateDis:1; ///< Nb pstate disable + UINT32 StartupNbPstate:2; ///< startup northbridge Pstate number + UINT32 CurNbFid:6; ///< Current NB FID + UINT32 CurNbDid:1; ///< Current NB DID + UINT32 :2; ///< Reserved + UINT32 CurNbVid_6_0:7; ///< Current NB VID[6:0] + UINT32 CurNbPstate:2; ///< Current NB Pstate + UINT32 :1; ///< Reserved + UINT32 CurNbPstateLo:1; ///< Current NB Pstate maps to Lo or Hi + UINT32 CurNbVid_7:1; ///< Current NB VID[7] + UINT32 CurMemPstate:1; ///< Current memory P-state + UINT32 :7; ///< Reserved +} NB_PSTATE_STS_REGISTER; + +#define NB_PSTATE_STS_REGISTER_CurNbVid_6_0_OFFSET 12 +#define NB_PSTATE_STS_REGISTER_CurNbVid_6_0_WIDTH 7 +#define NB_PSTATE_STS_REGISTER_CurNbVid_6_0_MASK 0x0007F000ul +#define NB_PSTATE_STS_REGISTER_CurNbVid_7_OFFSET 23 +#define NB_PSTATE_STS_REGISTER_CurNbVid_7_WIDTH 1 +#define NB_PSTATE_STS_REGISTER_CurNbVid_7_MASK 0x00800000ul + +#define GetF16KbCurNbVid(NbPstateStsRegister) ( \ + (((NB_PSTATE_STS_REGISTER *) NbPstateStsRegister)->CurNbVid_7 << NB_PSTATE_STS_REGISTER_CurNbVid_6_0_WIDTH) \ + | ((NB_PSTATE_STS_REGISTER *) NbPstateStsRegister)->CurNbVid_6_0) + +/* Miscellaneous Voltages */ +#define MISC_VOLTAGES 0x17C +#define MISC_VOLTAGES_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, MISC_VOLTAGES)) + +/// Miscellaneous Voltages Register +typedef struct { + UINT32 MaxVid:8; ///< Maximum Voltage + UINT32 :2; ///< Reserved + UINT32 MinVid:8; ///< Minimum Voltage + UINT32 :5; ///< Reserved + UINT32 NbPsi0Vid:8; ///< Northbridge PSI0_L VID threshold + UINT32 NbPsi0VidEn:1; ///< Northbridge PSI0_L VID enable +} MISC_VOLTAGE_REGISTER; + + +/* Clock Power/Timing Control 5 Register F5x188 */ +#define CPTC5_REG 0x188 +#define CPTC5_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, CPTC5_REG)) + +/// Clock Power Timing Control 5 Register +typedef struct { + UINT32 NbOffsetTrim:2; ///< Northbridge offset trim + UINT32 NbLoadLineTrim:3; ///< Northbridge load line trim + UINT32 NbPsi1:1; ///< Northbridge PSI1_L + UINT32 :1; ///< Northbridge telemetry functionality. + UINT32 :25; ///< Reserved +} CLK_PWR_TIMING_CTRL_5_REGISTER; + +#endif /* _CPU_F16_KB_POWERMGMT_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmtSystemTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmtSystemTables.c new file mode 100644 index 0000000000..fac228848f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPowerMgmtSystemTables.c @@ -0,0 +1,153 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Models 0x00 - 0x0F Kabini Power Management related initialization table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "cpuPowerMgmtSystemTables.h" +#include "F16KbUtilities.h" +#include "F16KbCoreAfterReset.h" +#include "F16KbNbAfterReset.h" +#include "F16KbPowerCheck.h" +#include "IdsF16KbAllService.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBPOWERMGMTSYSTEMTABLES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GetF16KbSysPmTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **SysPmTblPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* Family 16h Kabini Only Table */ +/* ---------------------- */ +CONST SYS_PM_TBL_STEP ROMDATA CpuF16KbSysPmTableArray[] = +{ + /// @todo + IDS_INITIAL_F16_KB_PM_STEP + // Step 1 - Configure F3x[84:80]. Handled by PCI register table. + + // Step 2 - Disable NB Pstate, if required + // Execute both cold & warm + { + 0, // ExeFlags + F16KbNbPstateDis // Function Pointer + }, + + // Step 3 - Core Minimum P-state Transition Sequence After Warm Reset + // Execute only after warm reset + { + PM_EXEFLAGS_WARM_ONLY, // ExeFlags + F16KbPmCoreAfterReset // Function Pointer + }, + + // Step 4 - NB P-state COF and VID Synchronization After Warm Reset + // Execute only after warm reset + { + PM_EXEFLAGS_WARM_ONLY, // ExeFlags + F16KbPmNbAfterReset // Function Pointer + }, + + // Step 5 - Power Check + // Execute only after warm reset + { + 0, // ExeFlags + F16KbPmPwrCheck // Function Pointer + }, + + IDS_F16_KB_PM_CUSTOM_STEP +}; + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the appropriate table of steps to perform to initialize the power management + * subsystem. + * + * @CpuServiceMethod{::F_CPU_GET_FAMILY_SPECIFIC_ARRAY}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] SysPmTblPtr Points to the first entry in the table. + * @param[out] NumberOfElements Number of valid entries in the table. + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetF16KbSysPmTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **SysPmTblPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = (sizeof (CpuF16KbSysPmTableArray) / sizeof (SYS_PM_TBL_STEP)); + *SysPmTblPtr = CpuF16KbSysPmTableArray; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPsi.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPsi.c new file mode 100644 index 0000000000..7d9d4d2a96 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPsi.c @@ -0,0 +1,278 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini PSI Initialization + * + * Enables Power Status Indicator (PSI) feature + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuFeatures.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "CommonReturns.h" +#include "cpuPsi.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBPSI_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +STATIC +F16KbPmVrmLowPowerModeEnable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PCI_ADDR PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Entry point for enabling Power Status Indicator + * + * This function must be run after all P-State routines have been executed + * + * @param[in] PsiServices The current CPU's family services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config handle for library and services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +F16KbInitializePsi ( + IN PSI_FAMILY_SERVICES *PsiServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); + // Configure PsiVid + F16KbPmVrmLowPowerModeEnable (FamilySpecificServices, PlatformConfig, PciAddress, StdHeader); + } + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Sets up PSI_L operation. + * + * This function implements the LowPowerThreshold parameter. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] PciAddress Segment, bus, device number of the node to transition. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F16KbPmVrmLowPowerModeEnable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PCI_ADDR PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PSTATE_MSR PstateMsr; + CLK_PWR_TIMING_CTRL2_REGISTER ClkPwrTimingCtrl2; + POWER_CTRL_MISC_REGISTER PwrCtrlMisc; + UINT32 CoreVrmLowPowerThreshold; + UINT32 Pstate; + UINT32 HwPstateMaxVal; + UINT32 PstateCurrent; + UINT32 NextPstateCurrent; + UINT32 PreviousVid; + UINT32 CurrentVid; + + NB_PSTATE_REGISTER NbPstateReg; + NB_PSTATE_CTRL_REGISTER NbPsCtrl; + MISC_VOLTAGE_REGISTER MiscVoltageReg; + UINT32 NbVrmLowPowerThreshold; + UINT32 NbPstate; + UINT32 NbPstateMaxVal; + UINT32 NbPstateCurrent; + UINT32 NextNbPstateCurrent; + UINT32 PreviousNbVid; + UINT32 CurrentNbVid; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbPmVrmLowPowerModeEnable\n"); + + if (PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold != 0) { + // Set up PSI0_L for VDD + CoreVrmLowPowerThreshold = PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold; + IDS_HDT_CONSOLE (CPU_TRACE, " Core VRM - LowPowerThreshold: %d\n", CoreVrmLowPowerThreshold); + PreviousVid = 0xFF; + CurrentVid = 0xFF; + + PciAddress.AddressValue = CPTC2_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader); + HwPstateMaxVal = ClkPwrTimingCtrl2.HwPstateMaxVal; + ASSERT (HwPstateMaxVal < NM_PS_REG); + + IDS_HDT_CONSOLE (CPU_TRACE, " HwPstateMaxVal %d\n", HwPstateMaxVal); + // Check P-state from P0 to HwPstateMaxVal + for (Pstate = 0; Pstate <= HwPstateMaxVal; Pstate++) { + FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) Pstate, &PstateCurrent, StdHeader); + + LibAmdMsrRead ((UINT32) (Pstate + PS_REG_BASE), (UINT64 *) &PstateMsr, StdHeader); + CurrentVid = (UINT32) PstateMsr.CpuVid; + + if (Pstate == HwPstateMaxVal) { + NextPstateCurrent = 0; + } else { + // Check P-state from P1 to HwPstateMaxVal + FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrent, StdHeader); + } + + if ((PstateCurrent <= CoreVrmLowPowerThreshold) && + (NextPstateCurrent <= CoreVrmLowPowerThreshold) && + (CurrentVid != PreviousVid)) { + // Program PsiVid and PsiVidEn if PSI state is found and stop searching. + PciAddress.AddressValue = PW_CTL_MISC_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &PwrCtrlMisc, StdHeader); + PwrCtrlMisc.PsiVid = CurrentVid; + PwrCtrlMisc.PsiVidEn = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &PwrCtrlMisc, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " PsiVid is enabled at P-state %d. PsiVid: %d\n", Pstate, CurrentVid); + break; + } else { + PstateCurrent = NextPstateCurrent; + PreviousVid = CurrentVid; + } + } + } + + if (PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold != 0) { + // Set up NBPSI0_L for VDDNB + NbVrmLowPowerThreshold = PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold; + IDS_HDT_CONSOLE (CPU_TRACE, " NB VRM - LowPowerThreshold: %d\n", NbVrmLowPowerThreshold); + PreviousNbVid = 0xFF; + CurrentNbVid = 0xFF; + + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + NbPstateMaxVal = NbPsCtrl.NbPstateMaxVal; + ASSERT (NbPstateMaxVal < NM_NB_PS_REG); + + IDS_HDT_CONSOLE (CPU_TRACE, " NbPstateMaxVal %d\n", NbPstateMaxVal); + for (NbPstate = 0; NbPstate <= NbPstateMaxVal; NbPstate++) { + // Check only valid NB P-state + if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) NbPstate, &NbPstateCurrent, StdHeader) != TRUE) { + continue; + } + + PciAddress.Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate)); + LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateReg, StdHeader); + CurrentNbVid = (UINT32) GetF16KbNbVid (&NbPstateReg); + + if (NbPstate == NbPstateMaxVal) { + NextNbPstateCurrent = 0; + } else { + // Check only valid NB P-state + if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) (NbPstate + 1), &NextNbPstateCurrent, StdHeader) != TRUE) { + continue; + } + } + + if ((NbPstateCurrent <= NbVrmLowPowerThreshold) && + (NextNbPstateCurrent <= NbVrmLowPowerThreshold) && + (CurrentNbVid != PreviousNbVid)) { + // Program NbPsi0Vid and NbPsi0VidEn if PSI state is found and stop searching. + PciAddress.AddressValue = MISC_VOLTAGES_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &MiscVoltageReg, StdHeader); + MiscVoltageReg.NbPsi0Vid = CurrentNbVid; + MiscVoltageReg.NbPsi0VidEn = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &MiscVoltageReg, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " NbPsi0Vid is enabled at NB P-state %d. NbPsi0Vid: %d\n", NbPstate, CurrentNbVid); + break; + } else { + PreviousNbVid = CurrentNbVid; + } + } + } +} + + +CONST PSI_FAMILY_SERVICES ROMDATA F16KbPsiSupport = +{ + 0, + (PF_PSI_IS_SUPPORTED) CommonReturnTrue, + F16KbInitializePsi +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPstate.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPstate.c new file mode 100644 index 0000000000..38913c1d7a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbPstate.c @@ -0,0 +1,613 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini Pstate feature support functions. + * + * Provides the functions necessary to initialize the Pstate feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "GeneralServices.h" +#include "cpuPstateTables.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "cpuFamilyTranslation.h" +#include "cpuFamRegisters.h" +#include "cpuF16Utilities.h" +#include "F16KbUtilities.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "CommonReturns.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBPSTATE_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +F16KbGetPowerStepValueInTime ( + IN OUT UINT32 *PowerStepPtr + ); + +VOID +STATIC +F16KbGetPllValueInTime ( + IN OUT UINT32 *PllLockTimePtr + ); + + +AGESA_STATUS +F16KbGetPstateTransLatency ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN PSTATE_LEVELING *PStateLevelingBufferStructPtr, + IN PCI_ADDR *PciAddress, + OUT UINT32 *TransitionLatency, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F16KbGetPstateFrequency ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT8 StateNumber, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F16KbGetPstatePower ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT8 StateNumber, + OUT UINT32 *PowerInMw, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F16KbGetPstateMaxState ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + OUT UINT32 *MaxPStateNumber, + OUT UINT8 *NumberOfBoostStates, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F16KbGetPstateRegisterInfo ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT32 PState, + OUT BOOLEAN *PStateEnabled, + IN OUT UINT32 *IddVal, + IN OUT UINT32 *IddDiv, + OUT UINT32 *SwPstateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if Pstate PSD is dependent. + * + * @param[in] PstateCpuServices Pstate CPU services. + * @param[in,out] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE PSD is dependent. + * @retval FALSE PSD is independent. + * + */ +BOOLEAN +STATIC +F16KbIsPstatePsdDependent ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbIsPstatePsdDependent\n"); + // Family 16h KB defaults to independent PSD + IDS_HDT_CONSOLE (CPU_TRACE, " P-state PSD is independent.\n"); + return FALSE; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to get Pstate Transition Latency. + * + * Calculate TransitionLatency by power step value and pll value. + * + * @param[in] PstateCpuServices Pstate CPU services. + * @param[in] PStateLevelingBufferStructPtr Pstate row data buffer pointer + * @param[in] PciAddress Pci address + * @param[out] TransitionLatency The transition latency. + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F16KbGetPstateTransLatency ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN PSTATE_LEVELING *PStateLevelingBufferStructPtr, + IN PCI_ADDR *PciAddress, + OUT UINT32 *TransitionLatency, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CpuFid; + UINT32 HwP0CpuFid; + UINT32 PowerStepDown; + UINT32 PowerStepUp; + UINT32 PllLockTime; + UINT32 LocalPciRegister; + UINT32 k; + UINT32 PStateMaxValueOnCurrentCore; + UINT32 TransAndBusMastLatency; + UINT64 MsrData; + BOOLEAN CpuFidSameFlag; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetPstateTransLatency\n"); + + CpuFidSameFlag = TRUE; + HwP0CpuFid = 0; + + // Get PStateMaxValue + PciAddress->Address.Register = CPTC2_REG; + PciAddress->Address.Function = FUNC_3; + LibAmdPciRead (AccessWidth32, *PciAddress, &LocalPciRegister, StdHeader); + PStateMaxValueOnCurrentCore = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->HwPstateMaxVal; + + // + //Check if MSRC001_00[6B:64][CpuFid] is the same value for all P-states + // + for (k = 0; k <= PStateMaxValueOnCurrentCore; k++) { + LibAmdMsrRead ((MSR_PSTATE_0 + k), &MsrData, StdHeader); + CpuFid = (UINT32) (((PSTATE_MSR *) &MsrData)->CpuFid); + if (k == 0) { + HwP0CpuFid = CpuFid; + } + if (HwP0CpuFid != CpuFid) { + CpuFidSameFlag = FALSE; + break; + } + } + + PciAddress->Address.Register = CPTC0_REG; + PciAddress->Address.Function = FUNC_3; + LibAmdPciRead (AccessWidth32, *PciAddress, &LocalPciRegister, StdHeader); + + // PowerStepDown - Bits 20:23 + PowerStepDown = ((CLK_PWR_TIMING_CTRL_REGISTER *) &LocalPciRegister)->PowerStepDown; + + // PowerStepUp - Bits 24:27 + PowerStepUp = ((CLK_PWR_TIMING_CTRL_REGISTER *) &LocalPciRegister)->PowerStepUp; + + // Convert the raw numbers in TempVar8_a and TempVar8_b into time + F16KbGetPowerStepValueInTime (&PowerStepDown); + F16KbGetPowerStepValueInTime (&PowerStepUp); + + // + //(15 * (F3xD4[PowerStepDown] + F3xD4[PowerStepUp]) /1000) us + // + TransAndBusMastLatency = + (15 * (PowerStepDown + PowerStepUp) + 999) / 1000; + + if (!CpuFidSameFlag) { + // + //+ F3xA0[PllLockTime] + // + PciAddress->Address.Register = PW_CTL_MISC_REG; + LibAmdPciRead (AccessWidth32, *PciAddress, &LocalPciRegister, StdHeader); + + PllLockTime = ((POWER_CTRL_MISC_REGISTER *) &LocalPciRegister)->PllLockTime; + F16KbGetPllValueInTime (&PllLockTime); + TransAndBusMastLatency += PllLockTime; + } + + *TransitionLatency = TransAndBusMastLatency; + + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to calculates the frequency in megahertz of the desired P-state. + * + * @param[in] PstateCpuServices Pstate CPU services. + * @param[in] StateNumber The P-State to analyze. + * @param[out] FrequencyInMHz The P-State's frequency in MegaHertz + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS Always Succeeds. + */ +AGESA_STATUS +F16KbGetPstateFrequency ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT8 StateNumber, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 TempValue; + UINT32 CpuDid; + UINT32 CpuFid; + UINT64 LocalMsrRegister; + PCI_ADDR PciAddress; + HTC_REGISTER HtcReg; + CLK_PWR_TIMING_CTRL2_REGISTER ClkPwrTimingCtrl2; + + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetPstateFrequency - P%d\n", StateNumber); + + PciAddress.AddressValue = CPTC2_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader); + + PciAddress.AddressValue = HTC_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &HtcReg, StdHeader); + + ASSERT ((StateNumber <= ClkPwrTimingCtrl2.HwPstateMaxVal) || ((StateNumber == HtcReg.HtcPstateLimit))); + + LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader); + + CpuDid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuDid); + CpuFid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuFid); + + switch (CpuDid) { + case 0: + TempValue = 1; + break; + case 1: + TempValue = 2; + break; + case 2: + TempValue = 4; + break; + case 3: + TempValue = 8; + break; + case 4: + TempValue = 16; + break; + default: + // CpuDid is set to an undefined value. This is due to either a misfused CPU, or + // an invalid P-state MSR write. + ASSERT (FALSE); + TempValue = 1; + break; + } + *FrequencyInMHz = (100 * (CpuFid + 0x10) / TempValue); + IDS_HDT_CONSOLE (CPU_TRACE, " FrequencyInMHz=%d, CpuFid=%d, CpuDid=%d\n", *FrequencyInMHz, CpuFid, CpuDid); + + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to calculates the power in milliWatts of the desired P-state. + * + * @param[in] PstateCpuServices Pstate CPU services. + * @param[in] StateNumber Which P-state to analyze + * @param[out] PowerInMw The Power in milliWatts of that P-State + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F16KbGetPstatePower ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT8 StateNumber, + OUT UINT32 *PowerInMw, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CpuVid; + UINT32 IddValue; + UINT32 IddDiv; + UINT32 V_x100000; + UINT32 Power; + UINT64 LocalMsrRegister; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetPstatePower - P%d\n", StateNumber); + + ASSERT (StateNumber < NM_PS_REG); + LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader); + ASSERT (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1); + CpuVid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuVid); + IddValue = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->IddValue); + IddDiv = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->IddDiv); + + if (CpuVid >= 0xF8) { + V_x100000 = 0; + } else { + V_x100000 = 155000L - (625L * CpuVid); + } + + Power = V_x100000 * IddValue; + + switch (IddDiv) { + case 0: + *PowerInMw = Power / 100L; + break; + case 1: + *PowerInMw = Power / 1000L; + break; + case 2: + *PowerInMw = Power / 10000L; + break; + default: + // IddDiv is set to an undefined value. This is due to either a misfused CPU, or + // an invalid P-state MSR write. + ASSERT (FALSE); + *PowerInMw = 0; + break; + } + IDS_HDT_CONSOLE (CPU_TRACE, " PowerInMw=%d, CpuVid=%d, IddValue=%d, IddDiv=%d\n", *PowerInMw, CpuVid, IddValue, IddDiv); + + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to get CPU pstate max state. + * + * @param[in] PstateCpuServices Pstate CPU services. + * @param[out] MaxPStateNumber The max hw pstate value on the current socket. + * @param[out] NumberOfBoostStates The number of boosted P-states on the current socket. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F16KbGetPstateMaxState ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + OUT UINT32 *MaxPStateNumber, + OUT UINT8 *NumberOfBoostStates, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 NumBoostStates; + UINT64 MsrValue; + UINT32 LocalPciRegister; + PCI_ADDR PciAddress; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetPstateMaxState\n"); + + LocalPciRegister = 0; + + // For F16 Kabini CPU, skip boosted p-state. The boosted p-state number = F4x15C[NumBoostStates]. + PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F4x15C + + NumBoostStates = ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates; + *NumberOfBoostStates = (UINT8) NumBoostStates; + + // + // Read PstateMaxVal [6:4] from MSR C001_0061 + // So, we will know the max pstate state in this socket. + // + LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &MsrValue, StdHeader); + *MaxPStateNumber = (UINT32) (((PSTATE_CURLIM_MSR *) &MsrValue)->PstateMaxVal) + NumBoostStates; + IDS_HDT_CONSOLE (CPU_TRACE, " MaxPStateNumber=%d, NumBoostStates=%d\n", *MaxPStateNumber, NumBoostStates); + + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to get CPU pstate register information. + * + * @param[in] PstateCpuServices Pstate CPU services. + * @param[in] PState Input Pstate number for query. + * @param[out] PStateEnabled Boolean flag return pstate enable. + * @param[in,out] IddVal Pstate current value. + * @param[in,out] IddDiv Pstate current divisor. + * @param[out] SwPstateNumber Software P-state number. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F16KbGetPstateRegisterInfo ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT32 PState, + OUT BOOLEAN *PStateEnabled, + IN OUT UINT32 *IddVal, + IN OUT UINT32 *IddDiv, + OUT UINT32 *SwPstateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 LocalPciRegister; + UINT64 LocalMsrRegister; + PCI_ADDR PciAddress; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetPstateRegisterInfo - P%d\n", PState); + + ASSERT (PState < NM_PS_REG); + + // For F16 Kabini CPU, skip boosted p-state. The boosted p-state number = F4x15C[NumBoostStates]. + PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F4x15C + + // Read PSTATE MSRs + LibAmdMsrRead (PS_REG_BASE + (UINT32) PState, &LocalMsrRegister, StdHeader); + + *SwPstateNumber = PState; + + if (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1) { + // PState enable = bit 63 + *PStateEnabled = TRUE; + // + // Check input pstate belongs to Boosted-Pstate, if yes, return *PStateEnabled = FALSE. + // + if (PState < ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates) { + *PStateEnabled = FALSE; + } else { + *SwPstateNumber = PState - ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates; + } + IDS_HDT_CONSOLE (CPU_TRACE, " Pstate %d is enabled. SwPstateNumber=%d\n", PState, *SwPstateNumber); + } else { + *PStateEnabled = FALSE; + } + + // Bits 39:32 (high 32 bits [7:0]) + *IddVal = (UINT32) ((PSTATE_MSR *) &LocalMsrRegister)->IddValue; + // Bits 41:40 (high 32 bits [9:8]) + *IddDiv = (UINT32) ((PSTATE_MSR *) &LocalMsrRegister)->IddDiv; + + IDS_HDT_CONSOLE (CPU_TRACE, " IddVal=%d, IddDiv=%d\n", *IddVal, *IddDiv); + return (AGESA_SUCCESS); +} + + +CONST PSTATE_CPU_FAMILY_SERVICES ROMDATA F16KbPstateServices = +{ + 0, + (PF_PSTATE_PSD_IS_NEEDED) CommonReturnTrue, + F16KbIsPstatePsdDependent, + F16KbGetPstateTransLatency, + F16KbGetPstateFrequency, + (PF_CPU_SET_PSTATE_LEVELING_REG) CommonReturnAgesaSuccess, + F16KbGetPstatePower, + F16KbGetPstateMaxState, + F16KbGetPstateRegisterInfo +}; + + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + + +/** + *--------------------------------------------------------------------------------------- + * + * F16KbGetPowerStepValueInTime + * + * Description: + * Convert power step value in time + * + * Parameters: + * @param[out] *PowerStepPtr + * + * @retval VOID + * + *--------------------------------------------------------------------------------------- + **/ +VOID +STATIC +F16KbGetPowerStepValueInTime ( + IN OUT UINT32 *PowerStepPtr + ) +{ + UINT32 TempVar_a; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetPowerStepValueInTime\n"); + + TempVar_a = *PowerStepPtr; + + if (TempVar_a < 0x4) { + *PowerStepPtr = 400 - (TempVar_a * 100); + } else if (TempVar_a < 0x9) { + *PowerStepPtr = 130 - (TempVar_a * 10); + } else { + *PowerStepPtr = 90 - (TempVar_a * 5); + } + IDS_HDT_CONSOLE (CPU_TRACE, " PowerStepPtr=%d\n", *PowerStepPtr); +} + +/** + *--------------------------------------------------------------------------------------- + * + * F16KbGetPllValueInTime + * + * Description: + * Convert PLL Value in time + * + * Parameters: + * @param[out] *PllLockTimePtr + * + * @retval VOID + * + *--------------------------------------------------------------------------------------- + **/ +VOID +STATIC +F16KbGetPllValueInTime ( + IN OUT UINT32 *PllLockTimePtr + ) +{ + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetPllValueInTime\n"); + + if (*PllLockTimePtr < 4) { + *PllLockTimePtr = *PllLockTimePtr + 1; + } else if (*PllLockTimePtr == 4) { + *PllLockTimePtr = 8; + } else if (*PllLockTimePtr == 5) { + *PllLockTimePtr = 16; + } else + *PllLockTimePtr = 0; + IDS_HDT_CONSOLE (CPU_TRACE, " PllLockTimePtr=%d\n", *PllLockTimePtr); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbSharedMsrTable.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbSharedMsrTable.c new file mode 100644 index 0000000000..a953793c3d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbSharedMsrTable.c @@ -0,0 +1,112 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini Shared MSR table with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 86705 $ @e \$Date: 2013-01-24 17:34:21 -0600 (Thu, 24 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBSHAREDMSRTABLE_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +// M S R T a b l e s +// ---------------------- + +STATIC CONST MSR_TYPE_ENTRY_INITIALIZER ROMDATA F16KbSharedMsrRegisters[] = +{ + // When there's a entry, change the number of entries below from 0 to (sizeof (F16KbSharedMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)) + {0}, +}; + +// Shared MSRs with Special Programming Requirements Table +// ---------------------- +STATIC CONST FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_INITIALIZER ROMDATA F16KbSharedMsrWorkarounds[] = +{ + // When there's a entry, change the number of entries below from 0 to (sizeof (F16KbSharedMsrWorkarounds) / sizeof (TABLE_ENTRY_FIELDS)) + {0}, +}; + + +CONST REGISTER_TABLE ROMDATA F16KbSharedMsrRegisterTable = { + ComputeUnitPrimary, + PERFORM_TP_AFTER_AP_LAUNCH, + 0, + //(sizeof (F16KbSharedMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F16KbSharedMsrRegisters, +}; + +CONST REGISTER_TABLE ROMDATA F16KbSharedMsrWorkaroundTable = { + ComputeUnitPrimary, + PERFORM_TP_AFTER_AP_LAUNCH, + 0, + //(sizeof (F16KbSharedMsrWorkarounds) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F16KbSharedMsrWorkarounds, +}; + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.c new file mode 100644 index 0000000000..ed94e79f78 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.c @@ -0,0 +1,1015 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 models 00h - 0Fh Kabini specific utility functions. + * + * Provides numerous utility functions specific to family 16h Kabini. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuFamilyTranslation.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "cpuEarlyInit.h" +#include "GeneralServices.h" +#include "F16KbUtilities.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) +#define FILECODE PROC_CPU_FAMILY_0X16_KB_F16KBUTILITIES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +STATIC +F16KbNbPstateDisCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F16KbGetNbFreqNumeratorInMHz ( + IN UINT32 NbFid, + OUT UINT32 *FreqNumeratorInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F16KbGetNbFreqDivisor ( + IN UINT32 NbDid, + OUT UINT32 *FreqDivisor, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +STATIC +F16KbCalculateNbFrequencyInMHz ( + IN UINT32 NbFid, + IN UINT32 NbDid, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F16KbCovertVidInuV ( + IN UINT32 Vid, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F16KbCmnGetIddDivisor ( + IN UINT32 IddDiv, + OUT UINT32 *IddDivisor, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F16KbCmnCalculateCurrentInmA ( + IN UINT32 IddValue, + IN UINT32 IddDiv, + OUT UINT32 *CurrentInmA, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16KbSetDownCoreRegister ( + IN CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices, + IN UINT32 *Socket, + IN UINT32 *Module, + IN UINT32 *LeveledCores, + IN CORE_LEVELING_TYPE CoreLevelMode, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Get CPU pstate current. + * + * @CpuServiceMethod{::F_CPU_GET_IDD_MAX}. + * + * This function returns the ProcIddMax. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] Pstate The P-state to check. + * @param[out] ProcIddMax P-state current in mA. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE P-state is enabled + * @retval FALSE P-state is disabled + */ +BOOLEAN +F16KbGetProcIddMax ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 Pstate, + OUT UINT32 *ProcIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MsrAddress; + PSTATE_MSR PstateMsr; + BOOLEAN IsPstateEnabled; + PCI_ADDR PciAddress; + NB_CAPS_2_REGISTER NbCap2; + UINT32 ProcIddMaxPerCore; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetProcIddMax - P%d\n", Pstate); + + IsPstateEnabled = FALSE; + + MsrAddress = (UINT32) (Pstate + PS_REG_BASE); + ASSERT (MsrAddress <= PS_MAX_REG); + + LibAmdMsrRead (MsrAddress, (UINT64 *) &PstateMsr, StdHeader); + F16KbCmnCalculateCurrentInmA ((UINT32) PstateMsr.IddValue, (UINT32) PstateMsr.IddDiv, &ProcIddMaxPerCore, StdHeader); + PciAddress.AddressValue = NB_CAPS_REG2_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbCap2, StdHeader); + *ProcIddMax = (UINT32) ProcIddMaxPerCore * (NbCap2.CmpCap + 1); + IDS_HDT_CONSOLE (CPU_TRACE, " Pstate %d ProcIddMax %d CmpCap %d\n", Pstate, *ProcIddMax, NbCap2.CmpCap); + + if (PstateMsr.PsEnable == 1) { + IsPstateEnabled = TRUE; + } + return IsPstateEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Set down core register on Kabini + * + * This function set F3x190 Downcore Control Register[5:0] + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] Socket Socket ID. + * @param[in] Module Module ID in socket. + * @param[in] LeveledCores Number of core. + * @param[in] CoreLevelMode Core level mode. + * @param[in] StdHeader Header for library and services. + * + * @retval TRUE Down Core register is updated. + * @retval FALSE Down Core register is not updated. + */ +BOOLEAN +F16KbSetDownCoreRegister ( + IN CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices, + IN UINT32 *Socket, + IN UINT32 *Module, + IN UINT32 *LeveledCores, + IN CORE_LEVELING_TYPE CoreLevelMode, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NumOfComputeUnit; + UINT8 CoresPerComputeUnit; + UINT32 LocalPciRegister; + UINT32 CoreDisableBits; + UINT32 TempVar32_a; + PCI_ADDR PciAddress; + BOOLEAN IsUpdated; + AGESA_STATUS AgesaStatus; + + IsUpdated = FALSE; + CoreDisableBits = 0; + TempVar32_a = 1; + CoresPerComputeUnit = 1; + + switch (CoreLevelMode) { + // There's no 'break' except 'case CORE_LEVEL_COMPUTE_UNIT'. + // It's for generating CoreDisableBits and CoresPerComputeUnit + case CORE_LEVEL_COMPUTE_UNIT_THREE: + TempVar32_a = TempVar32_a << 1; + CoresPerComputeUnit++; + case CORE_LEVEL_COMPUTE_UNIT_TWO: + TempVar32_a = TempVar32_a << 1; + CoresPerComputeUnit++; + case CORE_LEVEL_COMPUTE_UNIT: + TempVar32_a = (TempVar32_a << 1) - 1; + TempVar32_a = FOUR_CORE_COMPUTE_UNIT_BITMAP & (~TempVar32_a); + NumOfComputeUnit = (UINT8) ((*LeveledCores) / CoresPerComputeUnit); + for (CoreDisableBits = 0; NumOfComputeUnit > 0; NumOfComputeUnit--) { + CoreDisableBits <<= FOUR_CORE_COMPUTE_UNIT_BITWIDTH; + CoreDisableBits |= TempVar32_a; + } + break; + default: + TempVar32_a = *LeveledCores; + if (TempVar32_a == 1) { + CoreDisableBits = DOWNCORE_MASK_SINGLE; + } else { + CoreDisableBits = ALL_CORES_DISABLE_BITMAP; + TempVar32_a = ((1 << TempVar32_a) - 1); + CoreDisableBits &= ~TempVar32_a; + } + } + + if (CoreDisableBits != 0) { + if (GetPciAddress (StdHeader, (UINT8) *Socket, (UINT8) *Module, &PciAddress, &AgesaStatus)) { + PciAddress.Address.Function = FUNC_5; + PciAddress.Address.Register = NORTH_BRIDGE_CAPABILITIES_2_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + LocalPciRegister = (LocalPciRegister & 0xFF) + 1; + LocalPciRegister = (1 << LocalPciRegister) - 1; + CoreDisableBits &= LocalPciRegister; + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = DOWNCORE_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + if ((LocalPciRegister | CoreDisableBits) != LocalPciRegister) { + LocalPciRegister |= CoreDisableBits; + LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + IsUpdated = TRUE; + } + } + } + + return IsUpdated; +} + + +CONST CPU_CORE_LEVELING_FAMILY_SERVICES ROMDATA F16KbCoreLeveling = +{ + 0, + F16KbSetDownCoreRegister +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the NB clock on the desired node. + * + * @CpuServiceMethod{::F_CPU_GET_NB_FREQ}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] FrequencyInMHz Northbridge clock frequency in MHz. + * @param[in] StdHeader Header for library and services. + * + * @return AGESA_SUCCESS FrequencyInMHz is valid. + */ +AGESA_STATUS +F16KbGetCurrentNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + NB_PSTATE_STS_REGISTER NbPstateStsReg; + PCI_ADDR PciAddress; + AGESA_STATUS ReturnCode; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetCurrentNbFrequency\n"); + + PciAddress.AddressValue = NB_PSTATE_STATUS_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateStsReg, StdHeader); + ReturnCode = F16KbCalculateNbFrequencyInMHz ( + NbPstateStsReg.CurNbFid, + NbPstateStsReg.CurNbDid, + FrequencyInMHz, + StdHeader + ); + return ReturnCode; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the node's minimum and maximum northbridge frequency. + * + * @CpuServiceMethod{::F_CPU_GET_MIN_MAX_NB_FREQ}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] PciAddress The segment, bus, and device numbers of the CPU in question. + * @param[out] MaxFreqInMHz The node's maximum northbridge frequency. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_SUCCESS Northbridge frequency is valid + */ +AGESA_STATUS +F16KbGetMinMaxNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PCI_ADDR *PciAddress, + OUT UINT32 *var3, + OUT UINT32 *MaxFreqInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + INT8 NbPsMaxVal; + UINT8 i; + UINT32 LocalPciRegister; + AGESA_STATUS AgesaStatus; + + AgesaStatus = AGESA_ERROR; + + // Obtain the max NB frequency on the node + PciAddress->Address.Function = FUNC_5; + PciAddress->Address.Register = NB_PSTATE_CTRL; + LibAmdPciRead (AccessWidth32, *PciAddress, &LocalPciRegister, StdHeader); + NbPsMaxVal = (INT8) ((NB_PSTATE_CTRL_REGISTER *) &LocalPciRegister)->NbPstateMaxVal; + + // Starting from NB Pmax + for (i = 0; i <= NbPsMaxVal; i++) { + PciAddress->Address.Function = FUNC_5; + PciAddress->Address.Register = (NB_PSTATE_0 + (4 * i)); + LibAmdPciRead (AccessWidth32, *PciAddress, &LocalPciRegister, StdHeader); + + // Ensure that the NB Pstate is enabled + if (((NB_PSTATE_REGISTER *) &LocalPciRegister)->NbPstateEn == 1) { + AgesaStatus = F16KbCalculateNbFrequencyInMHz (((NB_PSTATE_REGISTER *) &LocalPciRegister)->NbFid, + ((NB_PSTATE_REGISTER *) &LocalPciRegister)->NbDid, + MaxFreqInMHz, + StdHeader); + break; + } + } + // If all of NbPstates are disabled, get MaxFreqInMHz from CurNbPstate + if (i > NbPsMaxVal) { + PciAddress->Address.Register = NB_PSTATE_STATUS; + LibAmdPciRead (AccessWidth32, *PciAddress, &LocalPciRegister, StdHeader); + F16KbCalculateNbFrequencyInMHz (((NB_PSTATE_STS_REGISTER *) &LocalPciRegister)->CurNbFid, + ((NB_PSTATE_STS_REGISTER *) &LocalPciRegister)->CurNbDid, + MaxFreqInMHz, + StdHeader); + *var3 = *MaxFreqInMHz; + ASSERT (FALSE); + } else { + // If platform configuration disable NB P-states, return the NB P0 frequency + // as both the min and max frequency on the node. + if (PlatformConfig->PlatformProfile.PlatformPowerPolicy == Performance) { + *var3 = *MaxFreqInMHz; + } else { + PciAddress->Address.Function = FUNC_5; + PciAddress->Address.Register = NB_PSTATE_CTRL; + LibAmdPciRead (AccessWidth32, *PciAddress, &LocalPciRegister, StdHeader); + NbPsMaxVal = (INT8) ((NB_PSTATE_CTRL_REGISTER *) &LocalPciRegister)->NbPstateMaxVal; + + // Obtain the min NB frequency on the node, starting from NB Pmin + for (; NbPsMaxVal >= 0; NbPsMaxVal--) { + PciAddress->Address.Function = FUNC_5; + PciAddress->Address.Register = (NB_PSTATE_0 + (4 * NbPsMaxVal)); + LibAmdPciRead (AccessWidth32, *PciAddress, &LocalPciRegister, StdHeader); + + // Ensure that the NB Pstate is enabled + if (((NB_PSTATE_REGISTER *) &LocalPciRegister)->NbPstateEn == 1) { + AgesaStatus = F16KbCalculateNbFrequencyInMHz (((NB_PSTATE_REGISTER *) &LocalPciRegister)->NbFid, + ((NB_PSTATE_REGISTER *) &LocalPciRegister)->NbDid, + var3, + StdHeader); + break; + } + } + } + } + IDS_OPTION_HOOK (IDS_NBPS_MIN_FREQ, var3, StdHeader); + + return AgesaStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the NB clock on the desired node. + * + * @CpuServiceMethod{::F_CPU_GET_NB_PSTATE_INFO}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] PciAddress The segment, bus, and device numbers of the CPU in question. + * @param[in] NbPstate The NB P-state number to check. + * @param[out] FreqNumeratorInMHz The desired node's frequency numerator in megahertz. + * @param[out] FreqDivisor The desired node's frequency divisor. + * @param[out] VoltageInuV The desired node's voltage in microvolts. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE NbPstate is valid + * @retval FALSE NbPstate is disabled or invalid + */ +BOOLEAN +F16KbGetNbPstateInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PCI_ADDR *PciAddress, + IN UINT32 NbPstate, + OUT UINT32 *FreqNumeratorInMHz, + OUT UINT32 *FreqDivisor, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 NbVid; + BOOLEAN PstateIsValid; + NB_PSTATE_CTRL_REGISTER NbPstateCtrlReg; + NB_PSTATE_REGISTER NbPstateReg; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetNbPstateInfo - NB P%d\n", NbPstate); + + ASSERT ((PciAddress->Address.Segment == 0) && (PciAddress->Address.Bus == 0) && (PciAddress->Address.Device == 0x18)); + + PstateIsValid = FALSE; + + // If NB P1, P2, or P3 is requested, make sure that NB Pstate is enabled + if ((NbPstate == 0) || (FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, PlatformConfig, StdHeader))) { + PciAddress->AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, *PciAddress, &NbPstateCtrlReg, StdHeader); + + ASSERT ((NbPstate < NM_NB_PS_REG) && (NbPstateCtrlReg.NbPstateMaxVal < NM_NB_PS_REG)); + if (NbPstate <= NbPstateCtrlReg.NbPstateMaxVal) { + PciAddress->Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate)); + LibAmdPciRead (AccessWidth32, *PciAddress, &NbPstateReg, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " En:%d Fid:%x Did:%x Vid:%x\n", NbPstateReg.NbPstateEn, NbPstateReg.NbFid, NbPstateReg.NbDid, GetF16KbNbVid (&NbPstateReg)); + + // Check if at least NB P0 is enabled. + ASSERT ((NbPstate == 0) ? (NbPstateReg.NbPstateEn == 1) : TRUE); + // Ensure that requested NbPstate is enabled + if (NbPstateReg.NbPstateEn == 1) { + F16KbGetNbFreqNumeratorInMHz (NbPstateReg.NbFid, FreqNumeratorInMHz, StdHeader); + F16KbGetNbFreqDivisor (NbPstateReg.NbDid, FreqDivisor, StdHeader); + + NbVid = GetF16KbNbVid (&NbPstateReg); + F16KbCovertVidInuV (NbVid, VoltageInuV, StdHeader); + PstateIsValid = TRUE; + } + } + } + return PstateIsValid; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Get NB pstate current. + * + * @CpuServiceMethod{::F_CPU_GET_NB_IDD_MAX}. + * + * This function returns the NbIddMax. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] NbPstate The NB P-state to check. + * @param[out] NbIddMax NB P-state current in mA. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE NB P-state is enabled, and NbIddMax is valid. + * @retval FALSE NB P-state is disabled + */ +BOOLEAN +F16KbGetNbIddMax ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 NbPstate, + OUT UINT32 *NbIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN IsNbPsEnabled; + PCI_ADDR PciAddress; + NB_PSTATE_CTRL_REGISTER NbPstateCtrlReg; + NB_PSTATE_REGISTER NbPstateReg; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetNbIddMax - NB P%d\n", NbPstate); + + IsNbPsEnabled = FALSE; + + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateCtrlReg, StdHeader); + + ASSERT (NbPstate < NM_NB_PS_REG); + if (NbPstate <= NbPstateCtrlReg.NbPstateMaxVal) { + PciAddress.Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate)); + LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateReg, StdHeader); + + // Ensure that requested NbPstate is enabled + if (NbPstateReg.NbPstateEn == 1) { + F16KbCmnCalculateCurrentInmA (NbPstateReg.NbIddValue, NbPstateReg.NbIddDiv, NbIddMax, StdHeader); + IsNbPsEnabled = TRUE; + IDS_HDT_CONSOLE (CPU_TRACE, " NB Pstate %d is Valid. NbIddMax %d\n", NbPstate, *NbIddMax); + } + } + return IsNbPsEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get the number of physical cores of current processor. + * + * @CpuServiceMethod{::F_CPU_NUMBER_OF_PHYSICAL_CORES}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @return The number of physical cores. + */ +UINT8 +F16KbGetNumberOfPhysicalCores ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPUID_DATA CpuId; + + // + //CPUID.80000008h.ECX.NC + 1, 000b = 1, 001b = 2, etc. + // + LibAmdCpuidRead (CPUID_LONG_MODE_ADDR, &CpuId, StdHeader); + return ((UINT8) ((CpuId.ECX_Reg & 0xff) + 1)); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Use the Mailbox Register to get the Ap Mailbox info for the current core. + * + * @CpuServiceMethod{::F_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE}. + * + * Access the mailbox register used with this NB family. This is valid until the + * point that some init code initializes the mailbox register for its normal use. + * The Machine Check Misc (Thresholding) register is available as both a PCI config + * register and a MSR, so it can be used as a mailbox from HT to other functions. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] ApMailboxInfo The AP Mailbox info + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +F16KbGetApMailboxFromHardware ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT AP_MAILBOXES *ApMailboxInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // For Family 16h Kabini, we will return socket 0, node 0, module 0, module type 0, and 0 for + // the system degree + ApMailboxInfo->ApMailInfo.Info = (UINT32) 0x00000000; + ApMailboxInfo->ApMailExtInfo.Info = (UINT32) 0x00000000; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Get this AP's system core number from hardware. + * + * @CpuServiceMethod{::F_CPU_GET_AP_CORE_NUMBER}. + * + * Returns the system core number from the scratch MSR, where + * it was saved at heap initialization. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @return The AP's unique core number + */ +UINT32 +F16KbGetApCoreNumber ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPUID_DATA Cpuid; + + LibAmdCpuidRead (0x1, &Cpuid, StdHeader); + return ((Cpuid.EBX_Reg >> 24) & 0xFF); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Is the Northbridge PState feature enabled? + * + * @CpuServiceMethod{::F_IS_NB_PSTATE_ENABLED}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE The NB PState feature is enabled. + * @retval FALSE The NB PState feature is not enabled. + */ +BOOLEAN +F16KbIsNbPstateEnabled ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + BOOLEAN NbPstatesSupported; + BOOLEAN SkipHwCfg; + NB_PSTATE_STS_REGISTER NbPstateSts; + NB_PSTATE_CTRL_REGISTER NbPstateCtrl; + + + PciAddress.AddressValue = NB_PSTATE_STATUS_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *) &NbPstateSts, StdHeader); + if (NbPstateSts.NbPstateDis == 1) { + return FALSE; + } + + SkipHwCfg = FALSE; + IDS_OPTION_HOOK (IDS_NBPSDIS_OVERRIDE, &SkipHwCfg, StdHeader); + + // NbPstates is supported by default + NbPstatesSupported = TRUE; + + // Get user options + if (!PlatformConfig->PlatformProfile.NbPstatesSupported) { + NbPstatesSupported = FALSE; + } + + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, (VOID *) &NbPstateCtrl, StdHeader); + if (((NbPstateCtrl.NbPstateMaxVal != 0) || SkipHwCfg) && (NbPstatesSupported)) { + return TRUE; + } + return FALSE; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Disable NB P-state. + * - clear F5x1[6C:64] + * - clear F5x170[NbPstateMaxVal] + * - set F5x170[SwNbPstateLoDis] + * - clear MSRC001_00[6B:64][NbPstate] + * + * @param[in] FamilySpecificServices The current Family Specific Services + * @param[in] CpuEarlyParamsPtr Service Parameters + * @param[in] StdHeader Handle of Header for calling lib functions and services. + */ +VOID +F16KbNbPstateDis ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 i; + UINT32 PciData; + UINT32 NbPsCtrl; + UINT32 NbPsCtrlOrg; + BOOLEAN SkipNbPsLoPart; + PCI_ADDR PciAddress; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbNbPstateDis\n"); + + // D18F5x170[30, NbPstateFidVidSbcEn] = 1 + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateFidVidSbcEn = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + + // Check whether NB P-state is disabled + if (!FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, &CpuEarlyParamsPtr->PlatformConfig, StdHeader)) { + + IDS_HDT_CONSOLE (CPU_TRACE, " NB Pstates disabled\n"); + + PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + NbPsCtrlOrg = NbPsCtrl; + + // If CurNbPstate is not NB P0, get the Pstate pointed to by CurNbPstate and copy it's value to NB P0 to P3 and clear NbPstateHi + PciAddress.Address.Register = NB_PSTATE_STATUS; + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + + SkipNbPsLoPart = FALSE; + if ((((NB_PSTATE_STS_REGISTER *) &PciData)->StartupNbPstate != ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateHi) && + (((NB_PSTATE_STS_REGISTER *) &PciData)->StartupNbPstate != ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateLo)) { + SkipNbPsLoPart = TRUE; + } + + if (((NB_PSTATE_STS_REGISTER *) &PciData)->CurNbPstate != 0) { + PciAddress.Address.Register = NB_PSTATE_0 + (((NB_PSTATE_STS_REGISTER *) &PciData)->CurNbPstate * 4); + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + + for (i = 1; i < NM_NB_PS_REG; i++) { + PciAddress.Address.Register = NB_PSTATE_0 + (i * 4); + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + } + + if (!SkipNbPsLoPart) { + // Program D18F5x170 to transition the NB P-state: + // 1) NbPstateLo = NbPstateMaxVal. + // 2) SwNbPstateLoDis = NbPstateDisOnP0 = NbPstateThreshold = 0. + + PciAddress.Address.Register = NB_PSTATE_CTRL; + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateLo = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateMaxVal; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->SwNbPstateLoDis = 0; + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateDisOnP0 = 0; + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateThreshold = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + + // Wait for D18F5x174[CurNbPstate] to equal NbPstateLo. + PciAddress.Address.Register = NB_PSTATE_STATUS; + do { + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + } while (((NB_PSTATE_STS_REGISTER *) &PciData)->CurNbPstate != ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateLo); + } + } + + // Program D18F5x170 to force the NB P-state: + // 1) NbPstateHi = target NB P-state. + // 2) SwNbPstateLoDis = 1 + // And clear F5x170[NbPstateMaxVal] + PciAddress.Address.Register = NB_PSTATE_CTRL; + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateHi = 0; + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->NbPstateMaxVal = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrl)->SwNbPstateLoDis = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); + + // Wait for D18F5x174[CurNbPstate] to equal the target NB P-state. + PciAddress.Address.Register = NB_PSTATE_STATUS; + do { + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + } while (((NB_PSTATE_STS_REGISTER *) &PciData)->CurNbPstate != 0); + + // Clear F5x1[6C:64] + PciData = 0x00000000; + for (i = 1; i < NM_NB_PS_REG; i++) { + PciAddress.Address.Register = NB_PSTATE_0 + (i * 4); + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + + } + + // Clear MSRC001_00[6B:64][NbPstate] on cores + F16KbNbPstateDisCore (StdHeader); + + // BIOS performs the following to release the NB P-state force: + // 1. Restore the initial D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateLo] values. + // 2. Restore the initial D18F5x170[NbPstateThreshold, NbPstateHi] values. + PciAddress.Address.Register = NB_PSTATE_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + ((NB_PSTATE_CTRL_REGISTER *) &PciData)->NbPstateLo = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + ((NB_PSTATE_CTRL_REGISTER *) &PciData)->SwNbPstateLoDis = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOrg)->SwNbPstateLoDis; + ((NB_PSTATE_CTRL_REGISTER *) &PciData)->NbPstateDisOnP0 = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOrg)->NbPstateDisOnP0; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + + ((NB_PSTATE_CTRL_REGISTER *) &PciData)->NbPstateHi = 0; + ((NB_PSTATE_CTRL_REGISTER *) &PciData)->NbPstateMaxVal = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + ((NB_PSTATE_CTRL_REGISTER *) &PciData)->NbPstateThreshold = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOrg)->NbPstateThreshold; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Disable NB P-state on core. + * - clear MSRC001_00[6B:64][NbPstate]. + * + * @param[in] StdHeader Handle of Header for calling lib functions and services. + */ +VOID +STATIC +F16KbNbPstateDisCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 i; + UINT64 MsrData; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbNbPstateDisCore\n"); + + // Only one core per compute unit needs to clear NbPstate in P-state MSRs + if (IsCoreComputeUnitPrimary (FirstCoreIsComputeUnitPrimary, StdHeader)) { + for (i = MSR_PSTATE_0; i <= MSR_PSTATE_7; i++) { + LibAmdMsrRead (i, &MsrData, StdHeader); + ((PSTATE_MSR *) &MsrData)->NbPstate = 0; + LibAmdMsrWrite (i, &MsrData, StdHeader); + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Get NB Frequency Numerator in MHz + * + * @param[in] NbFid NB Frequency ID to convert + * @param[out] FreqNumeratorInMHz The desire NB FID's frequency numerator in megahertz. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + */ +VOID +STATIC +F16KbGetNbFreqNumeratorInMHz ( + IN UINT32 NbFid, + OUT UINT32 *FreqNumeratorInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetNbFreqNumeratorInMHz - NbFid=%d\n", NbFid); + *FreqNumeratorInMHz = (NbFid + 4) * 100; + IDS_HDT_CONSOLE (CPU_TRACE, " FreqNumeratorInMHz=%d\n", *FreqNumeratorInMHz); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Get NB Frequency Divisor + * + * @param[in] NbDid NB Divisor ID to convert. + * @param[out] FreqDivisor The desire NB DID's frequency divisor. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + */ +VOID +STATIC +F16KbGetNbFreqDivisor ( + IN UINT32 NbDid, + OUT UINT32 *FreqDivisor, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbGetNbFreqDivisor - NbDid=%d\n", NbDid); + *FreqDivisor = (1 << NbDid); + IDS_HDT_CONSOLE (CPU_TRACE, " FreqDivisor=%d\n", *FreqDivisor); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Calculate NB Frequency in MHz + * + * @param[in] NbFid NB Frequency ID to convert + * @param[in] NbDid NB Divisor ID to convert. + * @param[out] FrequencyInMHz The Northbridge clock frequency in megahertz. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @return AGESA_SUCCESS FrequencyInMHz is valid. + */ +AGESA_STATUS +STATIC +F16KbCalculateNbFrequencyInMHz ( + IN UINT32 NbFid, + IN UINT32 NbDid, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 FreqNumeratorInMHz; + UINT32 FreqDivisor; + AGESA_STATUS ReturnStatus; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbCalculateNbFrequencyInMHz - NbFid=%x, NbDid=%x\n", NbFid, NbDid); + + ReturnStatus = AGESA_SUCCESS; + F16KbGetNbFreqNumeratorInMHz (NbFid, &FreqNumeratorInMHz, StdHeader); + F16KbGetNbFreqDivisor (NbDid, &FreqDivisor, StdHeader); + *FrequencyInMHz = FreqNumeratorInMHz / FreqDivisor; + IDS_HDT_CONSOLE (CPU_TRACE, " FrequencyInMHz=%d\n", *FrequencyInMHz); + + return ReturnStatus; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Convert VID to microvolts(uV) + * + * @param[in] Vid The voltage ID of SVI2 encoding to be converted. + * @param[out] VoltageInuV The voltage in microvolts. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + */ +VOID +STATIC +F16KbCovertVidInuV ( + IN UINT32 Vid, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbCovertVidInuV\n"); + // Maximum 1.55V, 6.25mV per stpe + *VoltageInuV = ConvertVidInuV(Vid); + IDS_HDT_CONSOLE (CPU_TRACE, " Vid=%x, VoltageInuV=%d\n", Vid, *VoltageInuV); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Get Core/NB Idd Divisor + * + * @param[in] IddDiv Core/NB current divisor to convert. + * @param[out] IddDivisor The desire Core/NB current divisor. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +STATIC +F16KbCmnGetIddDivisor ( + IN UINT32 IddDiv, + OUT UINT32 *IddDivisor, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbCmnGetIddDivisor - IddDiv=%d\n", IddDiv); + + switch (IddDiv) { + case 0: + *IddDivisor = 1000; + break; + case 1: + *IddDivisor = 100; + break; + case 2: + *IddDivisor = 10; + break; + default: // IddDiv = 3 is reserved. Use 10 + *IddDivisor = 10; + ASSERT (FALSE); + break; + } + IDS_HDT_CONSOLE (CPU_TRACE, " IddDivisor=%d\n", *IddDivisor); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Calculate Core/NB current in mA + * + * @param[in] IddValue Core/NB current value. + * @param[in] IddDiv Core/NB current divisor. + * @param[out] CurrentInmA The Core/NB current in milliampere. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +STATIC +F16KbCmnCalculateCurrentInmA ( + IN UINT32 IddValue, + IN UINT32 IddDiv, + OUT UINT32 *CurrentInmA, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 IddDivisor; + + IDS_HDT_CONSOLE (CPU_TRACE, " F16KbCmnCalculateCurrentInmA - IddValue=%x, IddDiv=%x\n", IddValue, IddDiv); + + F16KbCmnGetIddDivisor (IddDiv, &IddDivisor, StdHeader); + *CurrentInmA = IddValue * IddDivisor; + + IDS_HDT_CONSOLE (CPU_TRACE, " CurrentInmA=%d\n", *CurrentInmA); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.h new file mode 100644 index 0000000000..4565ccef0d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbUtilities.h @@ -0,0 +1,152 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Kabini specific utility functions. + * + * Provides numerous utility functions specific to family 16h Kabini. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16/KB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _F16_KB_UTILITES_H_ +#define _F16_KB_UTILITES_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +#define FOUR_CORE_COMPUTE_UNIT_BITMAP 0xF +#define FOUR_CORE_COMPUTE_UNIT_BITWIDTH 0x4 +#define ALL_CORES_DISABLE_BITMAP 0xFFFFFFFFul + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +UINT8 +F16KbGetNumberOfPhysicalCores ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F16KbGetApMailboxFromHardware ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT AP_MAILBOXES *ApMailboxInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16KbIsNbPstateEnabled ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F16KbNbPstateDis ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16KbGetProcIddMax ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 Pstate, + OUT UINT32 *ProcIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16KbGetNbIddMax ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 NbPstate, + OUT UINT32 *NbIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F16KbGetCurrentNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F16KbGetMinMaxNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PCI_ADDR *PciAddress, + OUT UINT32 *var3, + OUT UINT32 *MaxFreqInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16KbGetNbPstateInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PCI_ADDR *PciAddress, + IN UINT32 NbPstate, + OUT UINT32 *FreqNumeratorInMHz, + OUT UINT32 *FreqDivisor, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +F16KbGetApCoreNumber ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _F16_KB_UTILITES_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Apm.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Apm.c new file mode 100644 index 0000000000..2330f18309 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Apm.c @@ -0,0 +1,124 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 APM Initialization + * + * Enables Application Power Management feature + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuF16PowerMgmt.h" +#include "CommonReturns.h" +#include "cpuApm.h" +#include "OptionMultiSocket.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16APM_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * Entry point for enabling Application Power Management + * + * This function must be run after all P-State routines have been executed + * + * @param[in] ApmServices The current CPU's family services. + * @param[in] StdHeader Config handle for library and services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +STATIC AGESA_STATUS +F16InitializeApm ( + IN APM_FAMILY_SERVICES *ApmServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + F16_CPB_CTRL_REGISTER CpbControl; + PCI_ADDR PciAddress; + + PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl, StdHeader); + if (CpbControl.NumBoostStates == 0) { + CpbControl.ApmMasterEn = 0; + } else { + CpbControl.ApmMasterEn = 1; + } + LibAmdPciWrite (AccessWidth32, PciAddress, &CpbControl, StdHeader); + return AGESA_SUCCESS; +} + + + +CONST APM_FAMILY_SERVICES ROMDATA F16ApmSupport = +{ + 0, + (PF_APM_IS_SUPPORTED) CommonReturnTrue, + F16InitializeApm +}; + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16BrandId.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16BrandId.c new file mode 100644 index 0000000000..444315ac9e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16BrandId.c @@ -0,0 +1,166 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU BrandId related functions and structures. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuEarlyInit.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16BRANDID_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +#define NAME_STRING_ADDRESS_PORT 0x194 +#define NAME_STRING_DATA_PORT 0x198 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +/// FAM16_BRAND_STRING_MSR +typedef struct _PROCESSOR_NAME_STRING { + UINT32 lo; ///< lower 32-bits of 64-bit value + UINT32 hi; ///< highest 32-bits of 64-bit value +} PROCESSOR_NAME_STRING; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +F16SetBrandIdRegistersAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +CONST CHAR8 ROMDATA str_Unprogrammed_Sample[48] = "AMD Unprogrammed Engineering Sample"; +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * Set the Processor Name String register based on F5x194/198 + * + * This function copies F5x198_x[B:0] to MSR_C001_00[35:30] + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[in] EarlyParams Service parameters. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F16SetBrandIdRegistersAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PciData; + UINT32 MsrIndex; + UINT64 MsrData; + UINT64 *MsrNameStringPtrPtr; + PCI_ADDR PciAddress; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, FUNC_5, 0); + PciAddress.Address.Register = NAME_STRING_ADDRESS_PORT; + // check if D18F5x198_x0 is 00000000h. + PciData = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + PciAddress.Address.Register = NAME_STRING_DATA_PORT; + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + if (PciData != 0) { + for (MsrIndex = 0; MsrIndex <= (MSR_CPUID_NAME_STRING5 - MSR_CPUID_NAME_STRING0); MsrIndex++) { + PciAddress.Address.Register = NAME_STRING_ADDRESS_PORT; + PciData = MsrIndex * 2; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + PciAddress.Address.Register = NAME_STRING_DATA_PORT; + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + ((PROCESSOR_NAME_STRING *) (&MsrData))->lo = PciData; + + PciAddress.Address.Register = NAME_STRING_ADDRESS_PORT; + PciData = (MsrIndex * 2) + 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); + PciAddress.Address.Register = NAME_STRING_DATA_PORT; + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + ((PROCESSOR_NAME_STRING *) (&MsrData))->hi = PciData; + + LibAmdMsrWrite ((MsrIndex + MSR_CPUID_NAME_STRING0), &MsrData, StdHeader); + } + } else { + // It is unprogrammed (unfused) parts and use a name string of "AMD Unprogrammed Engineering Sample" + MsrNameStringPtrPtr = (UINT64 *) str_Unprogrammed_Sample; + // Put values into name MSRs, Always write the full 48 bytes + for (MsrIndex = MSR_CPUID_NAME_STRING0; MsrIndex <= MSR_CPUID_NAME_STRING5; MsrIndex++) { + LibAmdMsrWrite (MsrIndex, MsrNameStringPtrPtr, StdHeader); + MsrNameStringPtrPtr++; + } + } + return; +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16CacheDefaults.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16CacheDefaults.c new file mode 100644 index 0000000000..b89daaabdb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16CacheDefaults.c @@ -0,0 +1,129 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 ROM Execution Cache Defaults + * + * Contains default values for ROM execution cache setup + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuCacheInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16CACHEDEFAULTS_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GetF16CacheInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **CacheInfoPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +#define MEM_TRAINING_BUFFER_SIZE 16384 +#define VAR_MTRR_MASK 0x000000FFFFFFFFFFul + +#define HEAP_BASE_MASK 0x000000FFFFFFFFFFul + +#define SHARED_MEM_SIZE 0 + +CONST CACHE_INFO ROMDATA CpuF16CacheInfo = +{ + BSP_STACK_SIZE_64K, + CORE0_STACK_SIZE, + CORE1_STACK_SIZE, + MEM_TRAINING_BUFFER_SIZE, + SHARED_MEM_SIZE, + VAR_MTRR_MASK, + VAR_MTRR_MASK, + HEAP_BASE_MASK, + InfiniteExe +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the family specific properties of the cache, and its usage. + * + * @CpuServiceMethod{::F_CPU_GET_FAMILY_SPECIFIC_ARRAY}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] CacheInfoPtr Points to the cache info properties on exit. + * @param[out] NumberOfElements Will be one to indicate one entry. + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetF16CacheInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **CacheInfoPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = 1; + *CacheInfoPtr = &CpuF16CacheInfo; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.c new file mode 100644 index 0000000000..df81dcd255 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.c @@ -0,0 +1,123 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD DMI Record Creation API, and related functions for Family 16h. + * + * Contains code that produce the DMI related information. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuPstateTables.h" +#include "cpuLateInit.h" +#include "cpuF16PowerMgmt.h" +#include "cpuServices.h" +#include "cpuF16Dmi.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16DMI_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF16GetMaxSpeed + * + * Get the Max Speed + * + * @param[in] StdHeader Standard Head Pointer + * + * @retval MaxSpeed - CPU Max Speed. + * + */ +UINT16 +DmiF16GetMaxSpeed ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PP_FUSE_ARRAY_V2_fld36; + UINT32 P0Frequency; + UINT32 PciData; + PCI_ADDR PciAddress; + PSTATE_CPU_FAMILY_SERVICES *FamilyServices; + + FamilyServices = NULL; + GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_4, 0x15C); + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + PP_FUSE_ARRAY_V2_fld36 = (UINT8) ((PciData >> 2) & 7); + + FamilyServices->GetPstateFrequency (FamilyServices, PP_FUSE_ARRAY_V2_fld36, &P0Frequency, StdHeader); + return ((UINT16) P0Frequency); +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.h new file mode 100644 index 0000000000..c687c3b38e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Dmi.h @@ -0,0 +1,76 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD DMI Record Creation API, and related functions for Family 16h. + * + * Contains code that produce the DMI related information. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_F16_DMI_H_ +#define _CPU_F16_DMI_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +UINT16 +DmiF16GetMaxSpeed ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F16_DMI_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.c new file mode 100644 index 0000000000..cf1d0d8ee9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.c @@ -0,0 +1,473 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 MMIO map manager + * + * manage MMIO base/limit registers. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "mmioMapManager.h" +#include "cpuF16MmioMap.h" +#include "S3SaveState.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16MMIOMAP_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +STATIC CONST UINT16 ROMDATA MmioBaseLowRegOffset[MMIO_REG_PAIR_NUM] = {0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0x1A0, 0x1A8, 0x1B0, 0x1B8}; +STATIC CONST UINT16 ROMDATA MmioLimitLowRegOffset[MMIO_REG_PAIR_NUM] = {0x84, 0x8C, 0x94, 0x9C, 0xA4, 0xAC, 0xB4, 0xBC, 0x1A4, 0x1AC, 0x1B4, 0x1BC}; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +#define F16_MMIO_ALIGN 0x10000l + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * BSC entry point for for adding MMIO map + * + * program MMIO base/limit registers + * + * @param[in] MmioMapServices MMIO map manager services. + * @param[in] AmdAddMmioParams Pointer to a data structure containing the parameter information. + * + * @retval AGESA_STATUS AGESA_ERROR - The requested range could not be added because there are not + * enough mapping resources. + * AGESA_BOUNDS_CHK - One or more input parameters are invalid. For example, the + * TargetAddress does not correspond to any device in the system. + * AGESA_SUCCESS - Adding MMIO map succeeds + */ +AGESA_STATUS +STATIC +cpuF16AddingMmioMap ( + IN MMIO_MAP_FAMILY_SERVICES *MmioMapServices, + IN AMD_ADD_MMIO_PARAMS AmdAddMmioParams + ) +{ + UINT8 i; + UINT8 j; + UINT8 UnusedMmioPair; + UINT8 Socket; + UINT8 Module; + UINT8 MmioPair; + AGESA_STATUS IgnoredSts; + PCI_ADDR PciAddress; + MMIO_BASE_LOW MmioBaseLow; + MMIO_LIMIT_LOW MmioLimitLow; + MMIO_RANGE MmioRange[MMIO_REG_PAIR_NUM]; + MMIO_RANGE MmioRangeTemp; + MMIO_RANGE NewMmioRange; + MMIO_RANGE FragmentMmioRange; + BOOLEAN Overlap; + BOOLEAN NewMmioIncluded; + + UnusedMmioPair = 0; + // FragmentMMioRange is used for record the MMIO range which is splitted by overriding. + FragmentMmioRange.Attribute.MmioReadableRange = 0; + FragmentMmioRange.Attribute.MmioWritableRange = 0; + FragmentMmioRange.Base = 0; + FragmentMmioRange.Limit = F16_MMIO_ALIGN; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, FUNC_1, MmioBaseLowRegOffset[0]); + IDS_HDT_CONSOLE (MAIN_FLOW, "MMIO map configuration before merging:\n"); + IDS_HDT_CONSOLE (MAIN_FLOW, " Base Limit NP RE WE Lock DstNode DstLink DstSubLink\n"); + for (MmioPair = 0; MmioPair < MMIO_REG_PAIR_NUM; MmioPair++) { + // MMIO base low + PciAddress.Address.Register = MmioBaseLowRegOffset[MmioPair]; + LibAmdPciRead (AccessWidth32, PciAddress, &MmioBaseLow, &(AmdAddMmioParams.StdHeader)); + // MMIO limit low + PciAddress.Address.Register = MmioLimitLowRegOffset[MmioPair]; + LibAmdPciRead (AccessWidth32, PciAddress, &MmioLimitLow, &(AmdAddMmioParams.StdHeader)); + // get MMIO info + MmioRange[MmioPair].Base = (MmioBaseLow.MmioBase << 16); + MmioRange[MmioPair].Limit = (MmioLimitLow.MmioLimit << 16) + F16_MMIO_ALIGN; + MmioRange[MmioPair].Attribute.MmioPostedRange = (UINT8) MmioLimitLow.NP; + MmioRange[MmioPair].Attribute.MmioReadableRange = (UINT8) MmioBaseLow.RE; + MmioRange[MmioPair].Attribute.MmioWritableRange = (UINT8) MmioBaseLow.WE; + MmioRange[MmioPair].Attribute.MmioSecuredRange = (UINT8) MmioBaseLow.Lock; + MmioRange[MmioPair].Destination.DstNode = MmioLimitLow.DstNode; + MmioRange[MmioPair].Destination.DstLink = MmioLimitLow.DstLink; + MmioRange[MmioPair].Destination.DstSubLink = MmioLimitLow.DstSubLink; + MmioRange[MmioPair].RangeNum = MmioPair; + MmioRange[MmioPair].Modified = FALSE; + if ((MmioRange[MmioPair].Attribute.MmioReadableRange == 0) && (MmioRange[MmioPair].Attribute.MmioWritableRange == 0)) { + UnusedMmioPair++; + } + IDS_HDT_CONSOLE (MAIN_FLOW, " %02d ", MmioPair); + IDS_HDT_CONSOLE (MAIN_FLOW, "%08x%08x %08x%08x", (MmioRange[MmioPair].Base >> 32) & 0xFFFFFFFF, + MmioRange[MmioPair].Base & 0xFFFFFFFF, + (MmioRange[MmioPair].Limit >> 32) & 0xFFFFFFFF, + MmioRange[MmioPair].Limit & 0xFFFFFFFF); + IDS_HDT_CONSOLE (MAIN_FLOW, " %s %s %s %s", MmioRange[MmioPair].Attribute.MmioPostedRange ? "Y" : "N", + MmioRange[MmioPair].Attribute.MmioReadableRange ? "Y" : "N", + MmioRange[MmioPair].Attribute.MmioWritableRange ? "Y" : "N", + MmioRange[MmioPair].Attribute.MmioSecuredRange ? "Y" : "N"); + IDS_HDT_CONSOLE (MAIN_FLOW, " %02d %02d %02d\n", MmioRange[MmioPair].Destination.DstNode, + MmioRange[MmioPair].Destination.DstLink, + MmioRange[MmioPair].Destination.DstSubLink); + } + + // parse requirement + NewMmioRange.Base = AmdAddMmioParams.BaseAddress; + NewMmioRange.Limit = AmdAddMmioParams.BaseAddress + AmdAddMmioParams.Length; + NewMmioRange.Attribute = AmdAddMmioParams.Attributes; + IDS_HDT_CONSOLE (MAIN_FLOW, "req %08x%08x %08x%08x\n", (NewMmioRange.Base >> 32) & 0xFFFFFFFF, + NewMmioRange.Base & 0xFFFFFFFF, + (NewMmioRange.Limit >> 32) & 0xFFFFFFFF, + NewMmioRange.Limit & 0xFFFFFFFF); + + + // sort by base address + // range0, range1, range2, non used, non used... + for (i = 0; i < (MMIO_REG_PAIR_NUM - 1); i++) { + for (j = 0; j < (MMIO_REG_PAIR_NUM - i - 1); j++) { + if (((MmioRange[j].Base > MmioRange[j + 1].Base) && ((MmioRange[j + 1].Attribute.MmioReadableRange != 0) || (MmioRange[j + 1].Attribute.MmioWritableRange != 0))) || + (((MmioRange[j].Attribute.MmioReadableRange == 0) && (MmioRange[j].Attribute.MmioWritableRange == 0)) && + ((MmioRange[j + 1].Attribute.MmioReadableRange != 0) || (MmioRange[j + 1].Attribute.MmioWritableRange != 0)))) { + MmioRangeTemp = MmioRange[j]; + MmioRange[j] = MmioRange[j + 1]; + MmioRange[j + 1] = MmioRangeTemp; + } + } + } + + // merge the request to current setting + Overlap = FALSE; + NewMmioIncluded = FALSE; + for (MmioPair = 0; MmioPair < MMIO_REG_PAIR_NUM; MmioPair++) { + if (MmioRange[MmioPair].Attribute.MmioReadableRange != 0 || MmioRange[MmioPair].Attribute.MmioWritableRange != 0) { + if (((NewMmioRange.Base <= MmioRange[MmioPair].Base) && (NewMmioRange.Limit >= MmioRange[MmioPair].Base)) || + ((MmioRange[MmioPair].Base <= NewMmioRange.Base) && (MmioRange[MmioPair].Limit > NewMmioRange.Base))) { + if ((NewMmioRange.Attribute.MmioPostedRange == MmioRange[MmioPair].Attribute.MmioPostedRange) && + (NewMmioRange.Attribute.MmioReadableRange == MmioRange[MmioPair].Attribute.MmioReadableRange) && + (NewMmioRange.Attribute.MmioWritableRange == MmioRange[MmioPair].Attribute.MmioWritableRange) && + (NewMmioRange.Attribute.MmioSecuredRange == MmioRange[MmioPair].Attribute.MmioSecuredRange)) { + +// Original sorted MMIO register pair defined ranges: +// ____________ ________ ____________ +// | | | | | | +// base0 limit0 base1 limit1 base2 limit2 +// Requested MMIO range: +// case 1: +// ((NewMmioRange.Base <= MmioRange[MmioPair].Base) && (NewMmioRange.Limit >= MmioRange[MmioPair].Base)) +// __________ +// | | +// new base new limit +// ____________________ +// | | +// new base new limit +// case 2: +// ((MmioRange[MmioPair].Base <= NewMmioRange.Base) && (MmioRange[MmioPair].Limit >= NewMmioRange.Base)) +// ____________ +// | | +// new base new limit + + MmioRange[MmioPair].Base = (MmioRange[MmioPair].Base <= NewMmioRange.Base) ? MmioRange[MmioPair].Base : NewMmioRange.Base; + MmioRange[MmioPair].Modified = TRUE; + for (i = 1; NewMmioRange.Limit >= MmioRange[MmioPair + i].Base; i++) { + if ((NewMmioRange.Attribute.MmioPostedRange == MmioRange[MmioPair + i].Attribute.MmioPostedRange) && + (NewMmioRange.Attribute.MmioReadableRange == MmioRange[MmioPair + i].Attribute.MmioReadableRange) && + (NewMmioRange.Attribute.MmioWritableRange == MmioRange[MmioPair + i].Attribute.MmioWritableRange) && + (NewMmioRange.Attribute.MmioSecuredRange == MmioRange[MmioPair + i].Attribute.MmioSecuredRange)) { + MmioRange[MmioPair].Limit = MmioRange[MmioPair + i].Limit; + MmioRange[MmioPair + i].Base = 0; + MmioRange[MmioPair + i].Limit = F16_MMIO_ALIGN; + MmioRange[MmioPair + i].Attribute.MmioReadableRange = 0; + MmioRange[MmioPair + i].Attribute.MmioWritableRange = 0; + MmioRange[MmioPair + i].Modified = TRUE; + UnusedMmioPair++; + } else if (MmioRange[MmioPair + i].Attribute.MmioReadableRange != 0 || MmioRange[MmioPair + i].Attribute.MmioWritableRange != 0) { + // Overlapped MMIO regions with different attributes + MmioRange[MmioPair].Limit = (MmioRange[MmioPair].Limit >= NewMmioRange.Limit) ? MmioRange[MmioPair].Limit : NewMmioRange.Limit; + NewMmioIncluded = TRUE; + Overlap = TRUE; + break; + } + } + MmioRange[MmioPair].Limit = (MmioRange[MmioPair + i - 1].Limit >= NewMmioRange.Limit) ? MmioRange[MmioPair + i - 1].Limit : NewMmioRange.Limit; + break; + } else { + // Overlapped MMIO regions with different attributes + Overlap = TRUE; + break; + } + } + } else { + +// Original sorted MMIO register pair defined ranges: +// ____________ ________ ____________ +// | | | | | | +// base0 limit0 base1 limit1 base2 limit2 +// Requested MMIO range: +// case 3: +// No overlapping area with the original ranges +// ____________ +// | | +// new base new limit +// ______________ +// | | +// new base new limit + + MmioRange[MmioPair].Base = NewMmioRange.Base; + MmioRange[MmioPair].Limit = NewMmioRange.Limit; + MmioRange[MmioPair].Attribute = NewMmioRange.Attribute; + MmioRange[MmioPair].Modified = TRUE; + + break; + } + } + + if (MmioPair == MMIO_REG_PAIR_NUM) { + IDS_HDT_CONSOLE (MAIN_FLOW, " [ERROR] Not enough MMIO register pairs to hold the request.\n"); + return AGESA_ERROR; + } + + if (Overlap) { + if (NewMmioRange.Attribute.OverrideExisting) { + // First loop, to see which existing MMIO range should be overrided + for (MmioPair = 0; MmioPair < MMIO_REG_PAIR_NUM; MmioPair++) { + if ((MmioRange[MmioPair].Modified == TRUE) || (NewMmioRange.Limit < MmioRange[MmioPair].Base) || (NewMmioRange.Base > MmioRange[MmioPair].Limit)) { + continue; + } else { + // There's an overlap between NewMmio and MmioRange[MmioPair] + + // ____________________ + // | | + // base0 limit0 + // __________ + // | | + // new base new limit + if ((NewMmioRange.Base >= MmioRange[MmioPair].Base) && (NewMmioRange.Limit <= MmioRange[MmioPair].Limit)) { + if ((MmioRange[MmioPair].Limit - NewMmioRange.Limit) >= F16_MMIO_ALIGN) { + FragmentMmioRange.Base = NewMmioRange.Limit; + FragmentMmioRange.Limit = MmioRange[MmioPair].Limit; + FragmentMmioRange.Attribute = MmioRange[MmioPair].Attribute; + FragmentMmioRange.Destination = MmioRange[MmioPair].Destination; + } + if ((NewMmioRange.Base - MmioRange[MmioPair].Base) < F16_MMIO_ALIGN) { + MmioRange[MmioPair].Attribute.MmioReadableRange = 0; + MmioRange[MmioPair].Attribute.MmioWritableRange = 0; + UnusedMmioPair++; + } + MmioRange[MmioPair].Limit = NewMmioRange.Base; + MmioRange[MmioPair].Modified = TRUE; + } + // ____________________ + // | | + // base0 limit0 + // ______________ + // | | + // new base new limit + if ((NewMmioRange.Base < MmioRange[MmioPair].Base) && (NewMmioRange.Limit <= MmioRange[MmioPair].Limit) && (NewMmioRange.Limit > MmioRange[MmioPair].Base)) { + MmioRange[MmioPair].Base = NewMmioRange.Limit; + MmioRange[MmioPair].Modified = TRUE; + if ((MmioRange[MmioPair].Limit - NewMmioRange.Limit) < F16_MMIO_ALIGN) { + MmioRange[MmioPair].Attribute.MmioReadableRange = 0; + MmioRange[MmioPair].Attribute.MmioWritableRange = 0; + UnusedMmioPair++; + } + } + // ____________________ + // | | + // base0 limit0 + // ______________ + // | | + // new base new limit + if ((NewMmioRange.Base >= MmioRange[MmioPair].Base) && (NewMmioRange.Base < MmioRange[MmioPair].Limit) && (NewMmioRange.Limit > MmioRange[MmioPair].Limit)) { + MmioRange[MmioPair].Limit = NewMmioRange.Base; + MmioRange[MmioPair].Modified = TRUE; + if ((NewMmioRange.Base - MmioRange[MmioPair].Base) < F16_MMIO_ALIGN) { + MmioRange[MmioPair].Attribute.MmioReadableRange = 0; + MmioRange[MmioPair].Attribute.MmioWritableRange = 0; + UnusedMmioPair++; + } + } + // _________ + // | | + // base0 limit0 + // ___________________ + // | | + // new base new limit + if ((NewMmioRange.Base <= MmioRange[MmioPair].Base) && (NewMmioRange.Limit >= MmioRange[MmioPair].Limit)) { + MmioRange[MmioPair].Base = 0; + MmioRange[MmioPair].Limit = F16_MMIO_ALIGN; + MmioRange[MmioPair].Attribute.MmioReadableRange = 0; + MmioRange[MmioPair].Attribute.MmioWritableRange = 0; + MmioRange[MmioPair].Attribute.MmioPostedRange = 0; + MmioRange[MmioPair].Attribute.MmioSecuredRange = 0; + MmioRange[MmioPair].Modified = TRUE; + UnusedMmioPair++; + } + } + } + // Let's see if there's enough MMIO registers for NewMmioRange and FragmentMmioRange + if (!NewMmioIncluded) { + UnusedMmioPair--; + } + if ((FragmentMmioRange.Attribute.MmioReadableRange != 0) && (FragmentMmioRange.Attribute.MmioWritableRange != 0)) { + UnusedMmioPair--; + } + + if ((UnusedMmioPair != 0) && (UnusedMmioPair <= MMIO_REG_PAIR_NUM)) { + // Set MMIO for NewMmioRange and FragmentMmioRange + for (MmioPair = 0; MmioPair < MMIO_REG_PAIR_NUM; MmioPair++) { + if ((MmioRange[MmioPair].Attribute.MmioReadableRange == 0) && (MmioRange[MmioPair].Attribute.MmioWritableRange == 0)) { + if (!NewMmioIncluded) { + MmioRange[MmioPair].Base = NewMmioRange.Base; + MmioRange[MmioPair].Limit = NewMmioRange.Limit; + MmioRange[MmioPair].Attribute = NewMmioRange.Attribute; + MmioRange[MmioPair].Modified = TRUE; + NewMmioIncluded = TRUE; + } else if ((FragmentMmioRange.Attribute.MmioReadableRange != 0) && (FragmentMmioRange.Attribute.MmioWritableRange != 0)) { + MmioRange[MmioPair].Base = FragmentMmioRange.Base; + MmioRange[MmioPair].Limit = FragmentMmioRange.Limit; + MmioRange[MmioPair].Attribute = FragmentMmioRange.Attribute; + MmioRange[MmioPair].Destination = FragmentMmioRange.Destination; + MmioRange[MmioPair].Modified = TRUE; + FragmentMmioRange.Attribute.MmioReadableRange = 0; + FragmentMmioRange.Attribute.MmioWritableRange = 0; + } else { + break; + } + } + } + } else { + // We don't have enough MMIO registers. + IDS_HDT_CONSOLE (MAIN_FLOW, " [ERROR] Not enough MMIO register pairs to hold the request.\n"); + return AGESA_ERROR; + } + } else { + // Overlapped MMIO regions with different attributes + // and the caller doesn't want to override existing MMIO setting. + IDS_HDT_CONSOLE (MAIN_FLOW, " [ERROR] Overlapped MMIO regions with different attributes.\n"); + return AGESA_ERROR; + } + } + // write back MMIO base/limit + IDS_HDT_CONSOLE (MAIN_FLOW, "MMIO map configuration after merging:\n"); + IDS_HDT_CONSOLE (MAIN_FLOW, " Base Limit NP RE WE Lock DstNode DstLink DstSubLink\n"); + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, &(AmdAddMmioParams.StdHeader))) { + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (&(AmdAddMmioParams.StdHeader), Socket, Module, &PciAddress, &IgnoredSts)) { + PciAddress.Address.Function = FUNC_1; + for (MmioPair = 0; MmioPair < MMIO_REG_PAIR_NUM; MmioPair++) { + IDS_HDT_CONSOLE (MAIN_FLOW, " %02d ", MmioPair); + IDS_HDT_CONSOLE (MAIN_FLOW, "%08x%08x %08x%08x", (MmioRange[MmioPair].Base >> 32) & 0xFFFFFFFF, + MmioRange[MmioPair].Base & 0xFFFFFFFF, + (MmioRange[MmioPair].Limit >> 32) & 0xFFFFFFFF, + MmioRange[MmioPair].Limit & 0xFFFFFFFF); + IDS_HDT_CONSOLE (MAIN_FLOW, " %s %s %s %s", MmioRange[MmioPair].Attribute.MmioPostedRange ? "Y" : "N", + MmioRange[MmioPair].Attribute.MmioReadableRange ? "Y" : "N", + MmioRange[MmioPair].Attribute.MmioWritableRange ? "Y" : "N", + MmioRange[MmioPair].Attribute.MmioSecuredRange ? "Y" : "N"); + IDS_HDT_CONSOLE (MAIN_FLOW, " %02d %02d %02d\n", MmioRange[MmioPair].Destination.DstNode, + MmioRange[MmioPair].Destination.DstLink, + MmioRange[MmioPair].Destination.DstSubLink); + if (MmioRange[MmioPair].Modified) { + // MMIO base low + PciAddress.Address.Register = MmioBaseLowRegOffset[MmioRange[MmioPair].RangeNum]; + LibAmdPciRead (AccessWidth32, PciAddress, &MmioBaseLow, &(AmdAddMmioParams.StdHeader)); + if (MmioBaseLow.Lock == 1) { + IDS_HDT_CONSOLE (MAIN_FLOW, " [ERROR] MMIO register pair locked.\n"); + return AGESA_ERROR; + } + // Disable RE/WE before changing the address range + MmioBaseLow.RE = 0; + MmioBaseLow.WE = 0; + S3_SAVE_PCI_WRITE (&(AmdAddMmioParams.StdHeader), PciAddress, AccessWidth32, &MmioBaseLow); + LibAmdPciWrite (AccessWidth32, PciAddress, &MmioBaseLow, &(AmdAddMmioParams.StdHeader)); + + IDS_HDT_CONSOLE (MAIN_FLOW, " Reconfiguring offset %X\n", MmioBaseLowRegOffset[MmioRange[MmioPair].RangeNum]); + MmioBaseLow.MmioBase = (UINT32) (MmioRange[MmioPair].Base >> 16) & 0xFFFFFFul; + MmioBaseLow.RE = MmioRange[MmioPair].Attribute.MmioReadableRange; + MmioBaseLow.WE = MmioRange[MmioPair].Attribute.MmioWritableRange; + S3_SAVE_PCI_WRITE (&(AmdAddMmioParams.StdHeader), PciAddress, AccessWidth32, &MmioBaseLow); + LibAmdPciWrite (AccessWidth32, PciAddress, &MmioBaseLow, &(AmdAddMmioParams.StdHeader)); + + // MMIO limit low + IDS_HDT_CONSOLE (MAIN_FLOW, " Reconfiguring offset %X\n", MmioLimitLowRegOffset[MmioRange[MmioPair].RangeNum]); + PciAddress.Address.Register = MmioLimitLowRegOffset[MmioRange[MmioPair].RangeNum]; + LibAmdPciRead (AccessWidth32, PciAddress, &MmioLimitLow, &(AmdAddMmioParams.StdHeader)); + MmioLimitLow.MmioLimit = (UINT32) ((MmioRange[MmioPair].Limit - 1) >> 16) & 0xFFFFFFul; + MmioLimitLow.NP = MmioRange[MmioPair].Attribute.MmioPostedRange; + MmioLimitLow.DstNode = MmioRange[MmioPair].Destination.DstNode; + MmioLimitLow.DstLink = MmioRange[MmioPair].Destination.DstLink; + MmioLimitLow.DstSubLink = MmioRange[MmioPair].Destination.DstSubLink; + S3_SAVE_PCI_WRITE (&(AmdAddMmioParams.StdHeader), PciAddress, AccessWidth32, &MmioLimitLow); + LibAmdPciWrite (AccessWidth32, PciAddress, &MmioLimitLow, &(AmdAddMmioParams.StdHeader)); + } + } + } + } + } + } + return AGESA_SUCCESS; +} + +CONST MMIO_MAP_FAMILY_SERVICES ROMDATA F16MmioMapSupport = +{ + 0, + cpuF16AddingMmioMap +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.h new file mode 100644 index 0000000000..d202dfbaa0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MmioMap.h @@ -0,0 +1,90 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 MMIO map manager + * + * manage MMIO base/limit registers. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_F16_MMIO_MAP_H_ +#define _CPU_F16_MMIO_MAP_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ +#define MMIO_REG_PAIR_NUM 12 + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +/// MMIO base low +typedef struct { + UINT32 RE:1; ///< Read enable + UINT32 WE:1; ///< Write enable + UINT32 :1; ///< Reserved + UINT32 Lock:1; ///< Lock + UINT32 :4; ///< Reserved + UINT32 MmioBase:24; ///< MMIO base address register bits[39:16] +} MMIO_BASE_LOW; + +/// MMIO limit low +typedef struct { + UINT32 DstNode:3; ///< Destination node ID bits + UINT32 :1; ///< Reserved + UINT32 DstLink:2; ///< Destination link ID + UINT32 DstSubLink:1; ///< Destination sublink + UINT32 NP:1; ///< Non-posted + UINT32 MmioLimit:24; ///< MMIO limit address register bits[39:16] +} MMIO_LIMIT_LOW; + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +#endif // _CPU_F16_MMIO_MAP_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MsrUnknownTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MsrUnknownTables.c new file mode 100644 index 0000000000..5299228dcd --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16MsrUnknownTables.c @@ -0,0 +1,104 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 MSR tables for unknown processor + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16MSRUNKNOWNTABLES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +STATIC CONST MSR_TYPE_ENTRY_INITIALIZER ROMDATA F16MsrUnknownRegisters[] = +{ +// M S R T a b l e s +// ---------------------- + +// MSR_NB_CFG1 (C001001F) +// bits[54] InitApicIdCpuIdLo = 0x1 + { + MsrRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MSR_NB_CFG, // Address + 0x0040000000000000, // RegData + 0x0040000000000000, // RegMask + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F16MsrUnknownRegisterTable = { + AllCores, + PERFORM_TP_BEFORE_AP_LAUNCH, + (sizeof (F16MsrUnknownRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *)F16MsrUnknownRegisters, +}; + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16PciUnknownTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16PciUnknownTables.c new file mode 100644 index 0000000000..f4bd703d69 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16PciUnknownTables.c @@ -0,0 +1,250 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 PCI tables for unknown processor + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16PCIUNKNOWNTABLES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +// P C I T a b l e s +// ---------------------- + +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F16PciUnknownRegisters[] = +{ +// D18F0x68 - Link Transaction Control +// bits[22:21] DsNpReqLmt = 0x2 +// bits[19] ApicExtSpur = 0x1 +// bits[18] ApicExtId = 0x1 +// bits[17] ApicExtBrdCst = 0x1 +// bits[15] LimitCldtCfg = 0x1 +// bits[11] RespPassPW = 0x1 +// bits[10] DisFillP = 0x0 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x68), // Address + 0x004E8800, // RegData + 0x006E8C00, // RegMask + }} + }, +// D18F0x6C - Link Initialization Control +// bits[0] RouteTblDis = 0x0 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x6C), // Address + 0x00000000, // RegData + 0x00000001, // RegMask + }} + }, +// D18F0x90 - Upstream Base Channel Buffer Count +// bits[27:25] FreeData = 0x0 +// bits[24:20] FreeCmd = 0x0 +// bits[19:18] RspData = 0x1 +// bits[17:16] NpReqData = 0x1 +// bits[15:12] ProbeCmd = 0x0 +// bits[11:8] RspCmd = 0x2 +// bits[7:5] PReq = 0x5 +// bits[4:0] NpReqCmd = 0x8 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x90), // Address + 0x000502A8, // RegData + 0x0FFFFFFF, // RegMask + }} + }, +// D18F0x94 - Link Isochronous Channel Buffer Count +// bits[28:27] IsocRspData = 0x0 +// bits[26:25] IsocNpReqData = 0x1 +// bits[24:22] IsocRspCmd = 0x0 +// bits[21:19] IsocPReq = 0x0 +// bits[18:16] IsocNpReqCmd = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x94), // Address + 0x02010000, // RegData + 0x1FFF0000, // RegMask + }} + }, +// D18F3x6C - Data Buffer Count +// bits[30:28] IsocRspDBC = 0x1 +// bits[18:16] UpRspDBC = 0x1 +// bits[7:6] DnRspDBC = 0x1 +// bits[5:4] DnReqDBC = 0x1 +// bits[2:0] UpReqDBC = 0x2 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x6C), // Address + 0x10010052, // RegData + 0x700700F7, // RegMask + }} + }, +// D18F3xA0 - Power Control Miscellaneous +// bits[13:11] PllLockTime = 0x1 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x00000800, // RegData + 0x00003800, // RegMask + }} + }, +// D18F3xA4 - Reported Temperature Control +// bits[20] TcenPwrDnCc6En = 0x1 +// bits[12:8] PerStepTimeDn = 0xF +// bits[7] TmpSlewDnEn = 0x1 +// bits[6:5] TmpMaxDiffUp = 0x3 +// bits[4:0] PerStepTimeUp = 0xF + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA4), // Address + 0x00100FEF, // RegData + 0x00101FFF, // RegMask + }} + }, +// D18F3x1CC - IBS Control +// bits[8] LvtOffsetVal = 0x1 +// bits[3:0] LvtOffset = 0x0 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1CC), // Address + 0x00000100, // RegData + 0x0000010F, // RegMask + }} + }, +// D18F4x15C - Core Performance Boost Control +// bits[1:0] BoostSrc = 0 + { + PciRegister, + { + AMD_FAMILY_16, // CpuFamily + AMD_F16_ALL // CpuRevision + }, + {AMD_PF_ALL}, // PlatformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x15C), // Address + 0x00000000, // RegData + 0x00000003, // RegMask + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F16PciUnknownRegisterTable = { + PrimaryCores, + PERFORM_TP_BEFORE_AP_LAUNCH, + (sizeof (F16PciUnknownRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F16PciUnknownRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16PowerMgmt.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16PowerMgmt.h new file mode 100644 index 0000000000..72ca5b84d6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16PowerMgmt.h @@ -0,0 +1,294 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 Power Management related registers defination + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPUF16POWERMGMT_H_ +#define _CPUF16POWERMGMT_H_ + +/* + * Family 16h CPU Power Management MSR definitions + * + */ + + +/* Last Branch From IP Register 0x000001DB */ +#define MSR_BR_FROM 0x000001DBul + +/* P-state Current Limit Register 0xC0010061 */ +#define MSR_PSTATE_CURRENT_LIMIT 0xC0010061ul // F16 Shared + +/// Pstate Current Limit MSR Register +typedef struct { + UINT64 CurPstateLimit:3; ///< Current Pstate Limit + UINT64 :1; ///< Reserved + UINT64 PstateMaxVal:3; ///< Pstate Max Value + UINT64 :57; ///< Reserved +} PSTATE_CURLIM_MSR; + + +/* P-state Control Register 0xC0010062 */ +#define MSR_PSTATE_CTL 0xC0010062ul // F16 Shared + +/// Pstate Control MSR Register +typedef struct { + UINT64 PstateCmd:3; ///< Pstate change command + UINT64 :61; ///< Reserved +} PSTATE_CTRL_MSR; + + +/* P-state Status Register 0xC0010063 */ +#define MSR_PSTATE_STS 0xC0010063ul + +/// Pstate Status MSR Register +typedef struct { + UINT64 CurPstate:3; ///< Current Pstate + UINT64 :61; ///< Reserved +} PSTATE_STS_MSR; + + +/* P-state Registers 0xC001006[B:4] */ +#define MSR_PSTATE_0 0xC0010064ul +#define MSR_PSTATE_1 0xC0010065ul +#define MSR_PSTATE_2 0xC0010066ul +#define MSR_PSTATE_3 0xC0010067ul +#define MSR_PSTATE_4 0xC0010068ul +#define MSR_PSTATE_5 0xC0010069ul +#define MSR_PSTATE_6 0xC001006Aul +#define MSR_PSTATE_7 0xC001006Bul + +#define PS_REG_BASE MSR_PSTATE_0 /* P-state Register base */ +#define PS_MAX_REG MSR_PSTATE_7 /* Maximum P-State Register */ +#define PS_MIN_REG MSR_PSTATE_0 /* Minimum P-State Register */ +#define NM_PS_REG 8 /* number of P-state MSR registers */ + +/// P-state MSR with common field +typedef struct { + UINT64 :63; ///< CpuFid + UINT64 PsEnable:1; ///< Pstate Enable +} F16_PSTATE_MSR; + + +/* C-state Address Register 0xC0010073 */ +#define MSR_CSTATE_ADDRESS 0xC0010073ul + +/// C-state Address MSR Register +typedef struct { + UINT64 CstateAddr:16; ///< C-state address + UINT64 :48; ///< Reserved +} CSTATE_ADDRESS_MSR; + + +/* + * Family 16h CPU Power Management PCI definitions + * + */ + +/* Extended Memory Controller Configuration Low Register F2x1B0 */ +#define EXT_MEMCTRL_CFG_LOW_REG 0x1B0 + +/// Extended Memory Controller Configuration Low PCI Register +typedef struct { + UINT32 AdapPrefMissRatio:2; ///< Adaptive prefetch miss ratio + UINT32 AdapPrefPositiveStep:2; ///< Adaptive prefetch positive step + UINT32 AdapPrefNegativeStep:2; ///< Adaptive prefetch negative step + UINT32 :2; ///< Reserved + UINT32 CohPrefPrbLmt:3; ///< Coherent prefetch probe limit + UINT32 DisIoCohPref:1; ///< Disable coherent prefetched for IO + UINT32 EnSplitDctLimits:1; ///< Split DCT write limits enable + UINT32 :7; ///< Reserved + UINT32 DblPrefEn:1; ///< Double prefetch enable + UINT32 :1; ///< Reserved + UINT32 PrefFourConf:3; ///< Prefetch four-ahead confidence + UINT32 PrefFiveConf:3; ///< Prefetch five-ahead confidence + UINT32 DcqBwThrotWm:4; ///< Dcq bandwidth throttle watermark +} EXT_MEMCTRL_CFG_LOW_REGISTER; + + +/* Hardware thermal control register F3x64 */ +#define HTC_REG 0x64 +#define HTC_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_3, HTC_REG)) + +/// Hardware Thermal Control PCI Register +typedef struct { + UINT32 HtcEn:1; ///< HTC Enable + UINT32 :3; ///< Reserved + UINT32 HtcAct:1; ///< HTC Active State + UINT32 HtcActSts:1; ///< HTC Active Status + UINT32 PslApicHiEn:1; ///< P-state limit higher APIC interrupt enable + UINT32 PslApicLoEn:1; ///< P-state limit lower APIC interrupt enable + UINT32 :8; ///< Reserved + UINT32 HtcTmpLmt:7; ///< HTC temperature limit + UINT32 HtcSlewSel:1; ///< HTC slew-controlled temp select + UINT32 HtcHystLmt:4; ///< HTC hysteresis + UINT32 HtcPstateLimit:3; ///< HTC P-state limit select + UINT32 :1; ///< Reserved +} HTC_REGISTER; + + +/* Software P-state limit register F3x68 */ +#define SW_PS_LIMIT_REG 0x68 + +/// Software P-state Limit PCI Register +typedef struct { + UINT32 :5; ///< Reserved + UINT32 SwPstateLimitEn:1; ///< Software P-state limit enable + UINT32 :22; ///< Reserved + UINT32 SwPstateLimit:3; ///< HTC P-state limit select + UINT32 :1; ///< Reserved +} SW_PS_LIMIT_REGISTER; + +/* ACPI Power State Control Registers F3x84:80 */ + +/// System Management Action Field (SMAF) Register +typedef struct { + UINT8 CpuPrbEn:1; ///< CPU direct probe enable + UINT8 NbLowPwrEn:1; ///< Northbridge low-power enable + UINT8 NbGateEn:1; ///< Northbridge gate enable + UINT8 Reserved:2; ///< Reserved + UINT8 ClkDivisor:3; ///< Clock divisor +} SMAF_REGISTER; + +/// union type for ACPI State SMAF setting +typedef union { + UINT8 SMAFValue; ///< SMAF raw value + SMAF_REGISTER SMAF; ///< SMAF structure +} ACPI_STATE_SMAF; + +/// ACPI Power State Control Register F3x80 +typedef struct { + ACPI_STATE_SMAF C2; ///< [7:0] SMAF Code 000b - C2 + ACPI_STATE_SMAF C1eLinkInit; ///< [15:8] SMAF Code 001b - C1e or Link init + ACPI_STATE_SMAF SmafAct2; ///< [23:16] SMAF Code 010b + ACPI_STATE_SMAF S1; ///< [31:24] SMAF Code 011b - S1 +} ACPI_PSC_0_REGISTER; + +/// ACPI Power State Control Register F3x84 +typedef struct { + ACPI_STATE_SMAF S3; ///< [7:0] SMAF Code 100b - S3 + ACPI_STATE_SMAF Throttling; ///< [15:8] SMAF Code 101b - Throttling + ACPI_STATE_SMAF S4S5; ///< [23:16] SMAF Code 110b - S4/S5 + ACPI_STATE_SMAF C1; ///< [31:24] SMAF Code 111b - C1 +} ACPI_PSC_4_REGISTER; + + +/* Popup P-state Register F3xA8 */ +#define POPUP_PSTATE_REG 0xA8 +#define POPUP_PSTATE_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_3, POPUP_PSTATE_REG)) + +/// Popup P-state Register +typedef struct { + UINT32 :29; ///< Reserved + UINT32 PopDownPstate:3; ///< PopDownPstate +} POPUP_PSTATE_REGISTER; + + +/* Clock Power/Timing Control 2 Register F3xDC */ +#define CPTC2_REG 0xDC +#define CPTC2_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_3, CPTC2_REG)) + +/// Clock Power Timing Control 2 PCI Register +typedef struct { + UINT32 :8; ///< Reserved + UINT32 HwPstateMaxVal:3; ///< P-state maximum value + UINT32 :1; ///< Reserved + UINT32 NbsynPtrAdj:3; ///< NB/Core sync FIFO ptr adjust + UINT32 NbSynPtrAdjPstate_0:1; ///< NB/Core synchronization FIFO pointer adjust P-state[0] + UINT32 CacheFlushOnHaltCtl:3; ///< Cache flush on halt control + UINT32 CacheFlushOnHaltTmr:7; ///< Cache flush on halt timer + UINT32 IgnCpuPrbEn:1; ///< ignore CPU probe enable + UINT32 NbSynPtrAdjLo:3; ///< NB/core synchronization FIFO pointer adjust low + UINT32 NbsynPtrAdjPstate2_1:2; ///< NB/core synchronization FIFO pointer adjust P-state[2:1] +} CLK_PWR_TIMING_CTRL2_REGISTER; + + +/* Core Performance Boost Control Register D18F4x15C */ +#define CPB_CTRL_REG 0x15C +#define CPB_CTRL_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_4, CPB_CTRL_REG)) + +/// Core Performance Boost Control Register of Family 16h common aceess +typedef struct { + UINT32 BoostSrc:2; ///< Boost source + UINT32 NumBoostStates:3; ///< Number of boosted states + UINT32 :2; ///< Reserved + UINT32 ApmMasterEn:1; ///< APM master enable + UINT32 CstatePowerEn:1; ///< C-state power enable + UINT32 :22; ///< Reserved + UINT32 BoostLock:1; ///< Boost source +} F16_CPB_CTRL_REGISTER; + + +#define NM_NB_PS_REG 4 /* Number of NB P-state registers */ + +/* Northbridge P-state */ +#define NB_PSTATE_0 0x160 +#define NB_PSTATE_0_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, NB_PSTATE_0)) + +#define NB_PSTATE_1 0x164 +#define NB_PSTATE_1_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, NB_PSTATE_1)) + +#define NB_PSTATE_2 0x168 +#define NB_PSTATE_2_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, NB_PSTATE_2)) + +#define NB_PSTATE_3 0x16C +#define NB_PSTATE_3_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, NB_PSTATE_3)) + + +/* Northbridge P-state Status */ +#define F16_NB_PSTATE_CTRL 0x170 +#define F16_NB_PSTATE_CTRL_PCI_ADDR (MAKE_SBDFO (0, 0, 0x18, FUNC_5, F16_NB_PSTATE_CTRL)) + +/// Northbridge P-state Control Register +typedef struct { + UINT32 NbPstateMaxVal:2; ///< NB P-state maximum value + UINT32 :1; ///< Reserved + UINT32 NbPstateLo:2; ///< NB P-state low + UINT32 :1; ///< Reserved + UINT32 NbPstateHi:2; ///< NB P-state high + UINT32 :1; ///< Reserved + UINT32 NbPstateThreshold:3; ///< NB P-state threshold + UINT32 :1; ///< Reserved + UINT32 NbPstateDisOnP0:1; ///< NB P-state disable on P0 + UINT32 SwNbPstateLoDis:1; ///< Software NB P-state low disable + UINT32 :17; ///< Reserved +} F16_NB_PSTATE_CTRL_REGISTER; + + +#endif /* _CPUF16POWERMGMT_H */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.c new file mode 100644 index 0000000000..87748240c7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.c @@ -0,0 +1,417 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 specific utility functions. + * + * Provides numerous utility functions specific to family 16h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuPstateTables.h" +#include "cpuF16PowerMgmt.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuF16Utilities.h" +#include "cpuEarlyInit.h" +#include "cpuPostInit.h" +#include "cpuFeatures.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16UTILITIES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Disables the desired P-state. + * + * @CpuServiceMethod{::F_CPU_DISABLE_PSTATE}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StateNumber The P-State to disable. + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F16DisablePstate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 LocalMsrRegister; + + ASSERT (StateNumber < NM_PS_REG); + LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader); + ((F16_PSTATE_MSR *) &LocalMsrRegister)->PsEnable = 0; + LibAmdMsrWrite (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader); + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Transitions the executing core to the desired P-state. + * + * @CpuServiceMethod{::F_CPU_TRANSITION_PSTATE}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StateNumber The new P-State to make effective. + * @param[in] WaitForTransition True if the caller wants the transition completed upon return. + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS Always Succeeds + */ +AGESA_STATUS +F16TransitionPstate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN BOOLEAN WaitForTransition, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 LocalMsrRegister; + + LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &LocalMsrRegister, StdHeader); + ASSERT (((PSTATE_CURLIM_MSR *) &LocalMsrRegister)->PstateMaxVal >= StateNumber); + LibAmdMsrRead (MSR_PSTATE_CTL, &LocalMsrRegister, StdHeader); + ((PSTATE_CTRL_MSR *) &LocalMsrRegister)->PstateCmd = (UINT64) StateNumber; + LibAmdMsrWrite (MSR_PSTATE_CTL, &LocalMsrRegister, StdHeader); + if (WaitForTransition) { + do { + LibAmdMsrRead (MSR_PSTATE_STS, &LocalMsrRegister, StdHeader); + } while (((PSTATE_STS_MSR *) &LocalMsrRegister)->CurPstate != (UINT64) StateNumber); + } + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the rate at which the executing core's time stamp counter is + * incrementing. + * + * @CpuServiceMethod{::F_CPU_GET_TSC_RATE}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] FrequencyInMHz TSC actual frequency. + * @param[in] StdHeader Header for library and services. + * + * @return The most severe status of all called services + */ +AGESA_STATUS +F16GetTscRate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NumBoostStates; + UINT32 LocalPciRegister; + UINT64 LocalMsrRegister; + PCI_ADDR PciAddress; + PSTATE_CPU_FAMILY_SERVICES *FamilyServices; + + LibAmdMsrRead (0xC0010015, &LocalMsrRegister, StdHeader); + if ((LocalMsrRegister & 0x01000000) != 0) { + FamilyServices = NULL; + GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, FUNC_4, CPB_CTRL_REG); + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + NumBoostStates = (UINT8) ((F16_CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates; + return (FamilyServices->GetPstateFrequency (FamilyServices, NumBoostStates, FrequencyInMHz, StdHeader)); + } else { + return (FamilySpecificServices->GetCurrentNbFrequency (FamilySpecificServices, FrequencyInMHz, StdHeader)); + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Initially launches the desired core to run from the reset vector. + * + * @CpuServiceMethod{::F_CPU_AP_INITIAL_LAUNCH}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] SocketNum The Processor on which the core is to be launched + * @param[in] ModuleNum The Module in that processor containing that core + * @param[in] CoreNum The Core to launch + * @param[in] PrimaryCoreNum The id of the module's primary core. + * @param[in] StdHeader Header for library and services + * + * @retval TRUE The core was launched + * @retval FALSE The core was previously launched + */ +BOOLEAN +F16LaunchApCore ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 SocketNum, + IN UINT32 ModuleNum, + IN UINT32 CoreNum, + IN UINT32 PrimaryCoreNum, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 NodeRelativeCoreNum; + UINT32 LocalPciRegister; + UINT32 LowCore; + UINT32 HighCore; + PCI_ADDR PciAddress; + BOOLEAN LaunchFlag; + + NodeRelativeCoreNum = CoreNum - PrimaryCoreNum; + PciAddress.Address.Bus = 0; + PciAddress.Address.Device = 0x18; + PciAddress.Address.Function = FUNC_0; + PciAddress.Address.Register = CORE_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + + GetGivenModuleCoreRange (0, 0, &LowCore, &HighCore, StdHeader); + ASSERT ((NodeRelativeCoreNum != 0) || (NodeRelativeCoreNum <= HighCore)) + + if ((LocalPciRegister & (1 << NodeRelativeCoreNum)) == 0) { + LocalPciRegister |= (1 << NodeRelativeCoreNum); + LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + LaunchFlag = TRUE; + } else { + LaunchFlag = FALSE; + } + + return (LaunchFlag); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns whether or not BIOS is responsible for configuring the NB COFVID. + * + * @CpuServiceMethod{::F_CPU_IS_NBCOF_INIT_NEEDED}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PciAddress The northbridge to query by pci base address. + * @param[out] NbVidUpdateAll Do all NbVids need to be updated + * @param[in] StdHeader Header for library and services + * + * @retval TRUE Perform northbridge frequency and voltage config. + * @retval FALSE Do not configure them. + */ +BOOLEAN +F16GetNbCofVidUpdate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT BOOLEAN *NbVidUpdateAll, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NbVidUpdateAll = FALSE; + return FALSE; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Is the Northbridge PState feature enabled? + * + * @CpuServiceMethod{::F_IS_NB_PSTATE_ENABLED}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE The NB PState feature is enabled. + * @retval FALSE The NB PState feature is not enabled. + */ +BOOLEAN +F16IsNbPstateEnabled ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 LocalPciRegister; + PCI_ADDR PciAddress; + BOOLEAN PowerMode; + BOOLEAN SkipHwCfg; + + SkipHwCfg = FALSE; + + IDS_OPTION_HOOK (IDS_NBPSDIS_OVERRIDE, &SkipHwCfg, StdHeader); + + // Defaults to Power Optimized Mode + PowerMode = TRUE; + + // If system is optimized for performance, disable NB P-States + if (PlatformConfig->PlatformProfile.PlatformPowerPolicy == Performance) { + PowerMode = FALSE; + } + + PciAddress.AddressValue = F16_NB_PSTATE_CTRL_PCI_ADDR; + LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); + if ((((((F16_NB_PSTATE_CTRL_REGISTER *) &LocalPciRegister)->NbPstateMaxVal != 0) && + (!IsNonCoherentHt1 (StdHeader))) || SkipHwCfg) && (PowerMode)) { + return TRUE; + } + return FALSE; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Set warm reset status and count + * + * @CpuServiceMethod{::F_CPU_SET_WARM_RESET_FLAG}. + * + * This function will use bit9, and bit 10 of register F0x6C as a warm reset status and count. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * @param[in] Request Indicate warm reset status + * + */ +VOID +F16SetAgesaWarmResetFlag ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader, + IN WARM_RESET_REQUEST *Request + ) +{ + PCI_ADDR PciAddress; + UINT32 PciData; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_0, HT_INIT_CTRL); + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + + // bit[5] - indicate a warm reset is or is not required + PciData &= ~(HT_INIT_BIOS_RST_DET_0); + PciData = PciData | (Request->RequestBit << 5); + + // bit[10,9] - indicate warm reset status and count + PciData &= ~(HT_INIT_BIOS_RST_DET_1 | HT_INIT_BIOS_RST_DET_2); + PciData |= Request->StateBits << 9; + + LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get warm reset status and count + * + * @CpuServiceMethod{::F_CPU_GET_WARM_RESET_FLAG}. + * + * This function will bit9, and bit 10 of register F0x6C as a warm reset status and count. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Config handle for library and services + * @param[out] Request Indicate warm reset status + * + */ +VOID +F16GetAgesaWarmResetFlag ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader, + OUT WARM_RESET_REQUEST *Request + ) +{ + PCI_ADDR PciAddress; + UINT32 PciData; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_0, HT_INIT_CTRL); + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + + // bit[5] - indicate a warm reset is or is not required + Request->RequestBit = (UINT8) ((PciData & HT_INIT_BIOS_RST_DET_0) >> 5); + // bit[10,9] - indicate warm reset status and count + Request->StateBits = (UINT8) ((PciData & (HT_INIT_BIOS_RST_DET_1 | HT_INIT_BIOS_RST_DET_2)) >> 9); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Return a number zero or one, based on the Core ID position in the initial APIC Id. + * + * @CpuServiceMethod{::F_CORE_ID_POSITION_IN_INITIAL_APIC_ID}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval CoreIdPositionZero Core Id is not low + * @retval CoreIdPositionOne Core Id is low + */ +CORE_ID_POSITION +F16CpuAmdCoreIdPositionInInitialApicId ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 InitApicIdCpuIdLo; + + // Check bit_54 [InitApicIdCpuIdLo] to find core id position. + LibAmdMsrRead (MSR_NB_CFG, &InitApicIdCpuIdLo, StdHeader); + InitApicIdCpuIdLo = ((InitApicIdCpuIdLo & BIT54) >> 54); + return ((InitApicIdCpuIdLo == 0) ? CoreIdPositionZero : CoreIdPositionOne); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.h new file mode 100644 index 0000000000..e635fb0938 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16Utilities.h @@ -0,0 +1,144 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 specific utility functions. + * + * Provides numerous utility functions specific to family 16h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_F16_UTILITES_H_ +#define _CPU_F16_UTILITES_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +/// The structure for Software Initiated NB Voltage Transitions +typedef struct { + UINT32 VidCode; ///< VID code to transition to + BOOLEAN SlamMode; ///< Whether voltage is to be slammed, or stepped +} SW_VOLT_TRANS_NB; + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +F16DisablePstate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F16TransitionPstate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN BOOLEAN WaitForTransition, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F16GetTscRate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16LaunchApCore ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 SocketNum, + IN UINT32 ModuleNum, + IN UINT32 CoreNum, + IN UINT32 PrimaryCoreNum, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16GetNbCofVidUpdate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT BOOLEAN *NbVidUpdateAll, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F16IsNbPstateEnabled ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +CORE_ID_POSITION +F16CpuAmdCoreIdPositionInInitialApicId ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F16SetAgesaWarmResetFlag ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader, + IN WARM_RESET_REQUEST *Request + ); + +VOID +F16GetAgesaWarmResetFlag ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader, + OUT WARM_RESET_REQUEST *Request + ); + +#endif // _CPU_F16_UTILITES_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16WheaInitDataTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16WheaInitDataTables.c new file mode 100644 index 0000000000..ab06fe196f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16WheaInitDataTables.c @@ -0,0 +1,127 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Family_16 WHEA initial Data + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x16 + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuLateInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FAMILY_0X16_CPUF16WHEAINITDATATABLES_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GetF16WheaInitData ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **F16WheaInitDataPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AMD_HEST_BANK_INIT_DATA F16HestBankInitData[] = { + {0xFFFFFFFF,0xFFFFFFFF,0x400,0x401,0x402,0x403}, + {0xFFFFFFFF,0xFFFFFFFF,0x404,0x405,0x406,0x407}, + {0xFFFFFFFF,0xFFFFFFFF,0x408,0x409,0x40A,0x40B}, + {0xFFFFFFFF,0xFFFFFFFF,0x410,0x411,0x412,0x413}, + {0xFFFFFFFF,0xFFFFFFFF,0x414,0x415,0x416,0x417}, + {0xFFFFFFFF,0xFFFFFFFF,0x418,0x419,0x41A,0x41B}, +}; + +AMD_WHEA_INIT_DATA F16WheaInitData = { + 0x000000000, // AmdGlobCapInitDataLsd + 0x000000000, // AmdGlobCapInitDataMsd + 0x000000077, // AmdGlobCtrlInitDataLsd + 0x000000000, // AmdGlobCtrlInitDataMsd + 0x00, // AmdMcbClrStatusOnInit + 0x02, // AmdMcbStatusDataFormat + 0x00, // AmdMcbConfWriteEn + (sizeof (F16HestBankInitData) / sizeof (F16HestBankInitData[0])), // HestBankNum + &F16HestBankInitData[0] // Pointer to Initial data of HEST Bank +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the family specific WHEA table properties. + * + * @CpuServiceMethod{::F_CPU_GET_FAMILY_SPECIFIC_ARRAY}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] F16WheaInitDataPtr Points to the family 16h WHEA properties. + * @param[out] NumberOfElements Will be one to indicate one structure. + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetF16WheaInitData ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **F16WheaInitDataPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = 1; + *F16WheaInitDataPtr = &F16WheaInitData; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/cpuFamRegisters.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/cpuFamRegisters.h new file mode 100644 index 0000000000..cfd0dae86a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/cpuFamRegisters.h @@ -0,0 +1,125 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Register Table Related Functions + * + * Contains the definition of the CPU CPUID MSRs and PCI registers with BKDG recommended values + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_FAM_REGISTERS_H_ +#define _CPU_FAM_REGISTERS_H_ + +/* + *-------------------------------------------------------------- + * + * M O D U L E S U S E D + * + *--------------------------------------------------------------- + */ + +/* + *-------------------------------------------------------------- + * + * D E F I N I T I O N S / M A C R O S + * + *--------------------------------------------------------------- + */ + +// This define should be equal to the total number of families +// in the cpuFamily enum. +#define MAX_CPU_FAMILIES 64 +#define MAX_CPU_REVISIONS 63 // Max Cpu Revisions Per Family + +// CPU_LOGICAL_ID.Family equates +// Family 15h equates +#define AMD_FAMILY_15_TN 0x0000000000000200ull +#define AMD_FAMILY_TN (AMD_FAMILY_15_TN) +#define AMD_FAMILY_15 (AMD_FAMILY_15_TN) + +// Family 16h equates +#define AMD_FAMILY_16_KB 0x0000000000010000ull +#define AMD_FAMILY_KB AMD_FAMILY_16_KB +#define AMD_FAMILY_16 (AMD_FAMILY_KB) + +// Family Unknown +#define AMD_FAMILY_UNKNOWN 0x8000000000000000ull + + +// Family 15h CPU_LOGICAL_ID.Revision equates +// ------------------------------------- + + // Family 15h TN steppings +#define AMD_F15_TN_A0 0x0000000000000100ull +#define AMD_F15_TN_A1 0x0000000000000200ull + // Family 15h Unknown stepping + // * This equate is used to ensure that unknown CPU revisions are * + // * identified as the last known revision of the silicon family: * + // * - Update AMD_F15_UNKNOWN whenever newer F15h steppings are added * +#define AMD_F15_UNKNOWN (AMD_FAMILY_UNKNOWN | AMD_F15_TN_A1) + + +#define AMD_F15_TN_Ax (AMD_F15_TN_A0 | AMD_F15_TN_A1) +#define AMD_F15_TN_GT_A0 (AMD_F15_TN_ALL & ~AMD_F15_TN_A0) +#define AMD_F15_TN_ONLY (AMD_F15_TN_Ax) +#define AMD_F15_TN_ALL (AMD_F15_TN_Ax | AMD_F15_RL_ALL) + + +#define AMD_F15_ALL (AMD_F15_TN_ALL) + +// Family 16h CPU_LOGICAL_ID.Revision equates +// ------------------------------------- + + // Family 16h KB steppings +#define AMD_F16_KB_A0 0x0000000000000001ull +#define AMD_F16_KB_A1 0x0000000000000002ull + // Family 16h ML steppings + // Family 16h Unknown stepping + // * This equate is used to ensure that unknown CPU revisions are * + // * identified as the last known revision of the silicon family: * + // * - Update AMD_F16_UNKNOWN whenever newer F16h steppings are added * +#define AMD_F16_UNKNOWN (AMD_FAMILY_UNKNOWN | AMD_F16_KB_A1) + +#define AMD_F16_KB_Ax (AMD_F16_KB_A0 | AMD_F16_KB_A1) +#define AMD_F16_KB_ALL (AMD_F16_KB_Ax) + + +#define AMD_F16_ALL (AMD_F16_KB_ALL) + +#endif // _CPU_FAM_REGISTERS_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/PreserveMailbox.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/PreserveMailbox.h new file mode 100644 index 0000000000..9417814ed1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/PreserveMailbox.h @@ -0,0 +1,97 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Preserve Registers used for AP Mailbox. + * + * Save and Restore the normal feature content of the registers being used for + * the AP Mailbox. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _PRESERVE_MAILBOX_H_ +#define _PRESERVE_MAILBOX_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +#define MAX_PRESERVE_REGISTER_ENTRIES 2 ///< There is room on the heap for up to this per node. + +/// Reference to a save buffer. +typedef UINT32 (*MAILBOX_REGISTER_SAVE_ENTRY) [MAX_PRESERVE_REGISTER_ENTRIES]; + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/** + * Family specific mailbox register descriptor. + * + * Describes a register and bits within the register used as the mailbox. + */ +typedef struct { + PCI_ADDR Register; ///< The PCI address of a mailbox register. + UINT32 Mask; ///< The mask of bits used in Register as the mailbox. +} PRESERVE_MAILBOX_FAMILY_REGISTER; + +/** + * Descriptor for family specific save-restore. + * + * Provide a list of the register offsets to save-restore on each node. Optionally, zero the + * register instead of restoring it. + */ +typedef struct { + UINT16 Revision; ///< Interface version + // Public Data. + BOOLEAN IsZeroOnCold; ///< On a cold boot, zero the register instead of restore. + PRESERVE_MAILBOX_FAMILY_REGISTER *RegisterList; ///< The list of registers, terminated by ILLEGAL_SBDFO. +} PRESERVE_MAILBOX_FAMILY_SERVICES; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _PRESERVE_MAILBOX_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.c new file mode 100644 index 0000000000..d5b3bd77ce --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.c @@ -0,0 +1,194 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Application Power Management (APM) feature support code. + * + * Contains code that declares the AGESA CPU APM related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 85057 $ @e \$Date: 2012-12-27 01:35:49 -0600 (Thu, 27 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuApicUtilities.h" +#include "cpuFeatures.h" +#include "cpuApm.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUAPM_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +EnableApmOnSocket ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE ApmFamilyServiceTable; + +/*---------------------------------------------------------------------------------------*/ +/** + * Should Application Power Management (APM) be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE APM is supported. + * @retval FALSE APM cannot be enabled. + * + */ +STATIC BOOLEAN +IsApmFeatureEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + BOOLEAN IsEnabled; + APM_FAMILY_SERVICES *FamilyServices; + + IsEnabled = FALSE; + + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&ApmFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); + if (FamilyServices != NULL) { + if (FamilyServices->IsApmSupported (FamilyServices, PlatformConfig, Socket, StdHeader)) { + IsEnabled = TRUE; + break; + } + } + } + } + return IsEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable Application Power Management (APM) + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +STATIC AGESA_STATUS +InitializeApmFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 BscSocket; + UINT32 Ignored; + UINT32 Socket; + UINT32 NumberOfSockets; + AP_TASK TaskPtr; + AGESA_STATUS IgnoredSts; + + IDS_HDT_CONSOLE (CPU_TRACE, " APM mode is enabled\n"); + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &Ignored, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + TaskPtr.FuncAddress.PfApTask = EnableApmOnSocket; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + if (Socket != BscSocket) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, 0, &TaskPtr, StdHeader); + } + } + } + + EnableApmOnSocket (StdHeader); + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * AP task to enable APM + * + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +EnableApmOnSocket ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + APM_FAMILY_SERVICES *FamilyServices; + + GetFeatureServicesOfCurrentCore (&ApmFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + FamilyServices->EnableApmOnSocket (FamilyServices, + StdHeader); +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureApm = +{ + CpuApm, + (CPU_FEAT_BEFORE_RELINQUISH_AP | CPU_FEAT_AFTER_RESUME_MTRR_SYNC), + IsApmFeatureEnabled, + InitializeApmFeature +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.h new file mode 100644 index 0000000000..ce418ec6a8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuApm.h @@ -0,0 +1,127 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Application Power Management (APM) Functions declarations. + * + * Contains code that declares the AGESA CPU APM related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_APM_H_ +#define _CPU_APM_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (APM_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if Application Power Management (APM) is supported. + * + * @param[in] ApmServices APM services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] Socket Zero-based socket number. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE APM is supported. + * @retval FALSE APM is not supported. + * + */ +typedef BOOLEAN F_APM_IS_SUPPORTED ( + IN APM_FAMILY_SERVICES *CpbServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_APM_IS_SUPPORTED *PF_APM_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable APM. + * + * @param[in] ApmServices APM services. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_APM_INIT ( + IN APM_FAMILY_SERVICES *ApmServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_APM_INIT *PF_APM_INIT; + +/** + * Provide the interface to the APM Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _APM_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_APM_IS_SUPPORTED IsApmSupported; ///< Method: Family specific call to check if APM is supported. + PF_APM_INIT EnableApmOnSocket; ///< Method: Family specific call to enable APM. +}; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_APM_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.c new file mode 100644 index 0000000000..9a1d937097 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.c @@ -0,0 +1,260 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU C6 feature support code. + * + * Contains code that declares the AGESA CPU C6 related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "OptionMultiSocket.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "cpuFeatures.h" +#include "cpuC6State.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUC6STATE_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +EnableC6OnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE C6FamilyServiceTable; +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------------------*/ +/** + * Should C6 be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE C6 is supported. + * @retval FALSE C6 cannot be enabled. + * + */ +BOOLEAN +STATIC +IsC6FeatureEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + BOOLEAN IsEnabled; + C6_FAMILY_SERVICES *FamilyServices; + + IsEnabled = FALSE; + if (PlatformConfig->CStateMode == CStateModeC6) { + IsEnabled = TRUE; + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&C6FamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); + if ((FamilyServices == NULL) || !FamilyServices->IsC6Supported (FamilyServices, Socket, PlatformConfig, StdHeader)) { + IsEnabled = FALSE; + break; + } + } + } + } + return IsEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable the C6 C-state + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +InitializeC6Feature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 BscSocket; + UINT32 Ignored; + UINT32 BscCoreNum; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + AP_TASK TaskPtr; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + C6_FAMILY_SERVICES *C6FamilyServices; + AGESA_STATUS IgnoredSts; + + CpuEarlyParams.PlatformConfig = *PlatformConfig; + + TaskPtr.FuncAddress.PfApTaskIC = EnableC6OnSocket; + TaskPtr.DataTransfer.DataSizeInDwords = 2; + TaskPtr.DataTransfer.DataPtr = &EntryPoint; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS; + OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, &CpuEarlyParams); + + if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { + // Load any required microcode patches on both normal boot and resume from S3. + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); + GetFeatureServicesOfSocket (&C6FamilyServiceTable, BscSocket, (CONST VOID **)&C6FamilyServices, StdHeader); + if (C6FamilyServices != NULL) { + C6FamilyServices->ReloadMicrocodePatchAfterMemInit (StdHeader); + } + + // run code on all APs + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = 0; + + NumberOfSockets = GetPlatformNumberOfSockets (); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&C6FamilyServiceTable, Socket, (CONST VOID **)&C6FamilyServices, StdHeader); + if (C6FamilyServices != NULL) { + // run code on all APs + TaskPtr.FuncAddress.PfApTask = C6FamilyServices->ReloadMicrocodePatchAfterMemInit; + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCoreNum)) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); + } + } + } + } + } + } + } + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 'Local' core 0 task to enable C6 on it's socket. + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] StdHeader Config Handle for library, services. + * @param[in] CpuEarlyParams Service parameters. + * + */ +VOID +STATIC +EnableC6OnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ) +{ + + C6_FAMILY_SERVICES *FamilyServices; + + IDS_HDT_CONSOLE (CPU_TRACE, " C6 is enabled\n"); + + GetFeatureServicesOfCurrentCore (&C6FamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + FamilyServices->InitializeC6 (FamilyServices, + *((UINT64 *) EntryPoint), + &CpuEarlyParams->PlatformConfig, + StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Reload microcode patch after memory is initialized. + * + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +ReloadMicrocodePatchAfterMemInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LoadMicrocodePatch (StdHeader); +} + + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureC6State = +{ + C6Cstate, + (CPU_FEAT_AFTER_PM_INIT | CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC | CPU_FEAT_BEFORE_RELINQUISH_AP), + IsC6FeatureEnabled, + InitializeC6Feature +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.h new file mode 100644 index 0000000000..1f77ca46a3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuC6State.h @@ -0,0 +1,156 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU C6 Functions declarations. + * + * Contains code that declares the AGESA CPU C6 related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_C6_STATE_H_ +#define _CPU_C6_STATE_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (C6_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if C6 is supported. + * + * @param[in] C6Services C6 C-state services. + * @param[in] Socket Zero-based socket number. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE C6 is supported. + * @retval FALSE C6 is not supported. + * + */ +typedef BOOLEAN F_C6_IS_SUPPORTED ( + IN C6_FAMILY_SERVICES *C6Services, + IN UINT32 Socket, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_C6_IS_SUPPORTED *PF_C6_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable C6. + * + * @param[in] C6Services C6 services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_C6_INIT ( + IN C6_FAMILY_SERVICES *C6Services, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_C6_INIT *PF_C6_INIT; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to reload microcode patch after memory is initialized. + * + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_C6_RELOAD_MICROCODE_PATCH_AFTER_MEM_INIT ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_C6_RELOAD_MICROCODE_PATCH_AFTER_MEM_INIT *PF_C6_RELOAD_MICROCODE_PATCH_AFTER_MEM_INIT; + +/** + * Provide the interface to the C6 Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _C6_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_C6_IS_SUPPORTED IsC6Supported; ///< Method: Family specific call to check if C6 is supported. + PF_C6_INIT InitializeC6; ///< Method: Family specific call to enable C6. + PF_C6_RELOAD_MICROCODE_PATCH_AFTER_MEM_INIT ReloadMicrocodePatchAfterMemInit; ///< Method: Family specific call to reload microcode patch after memory is initialized. +}; + +/*---------------------------------------------------------------------------------------*/ +/** + * Reload microcode patch after memory is initialized. + * + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +ReloadMicrocodePatchAfterMemInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_C6_STATE_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheFlushOnHalt.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheFlushOnHalt.c new file mode 100644 index 0000000000..cf7d157a7e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheFlushOnHalt.c @@ -0,0 +1,199 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Cache Flush On Halt Function. + * + * Contains code to initialize Cache Flush On Halt feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "cpuApicUtilities.h" +#include "OptionMultiSocket.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) +#define FILECODE PROC_CPU_FEATURE_CPUCACHEFLUSHONHALT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE CacheFlushOnHaltFamilyServiceTable; +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +VOID +STATIC +EnableCacheFlushOnHaltOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ); + +AGESA_STATUS +InitializeCacheFlushOnHaltFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * P U B L I C F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Should cache flush on halt be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE core leveling is supported. + * @retval FALSE core leveling cannot be enabled. + * + */ +BOOLEAN +STATIC +IsCFOHEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return (TRUE); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * InitializeCacheFlushOnHaltFeature + * + * CPU feature leveling. Enable Cpu Cache Flush On Halt Function + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in,out] StdHeader Pointer to AMD_CONFIG_PARAMS struct. + * + * @return The most severe status of any family specific service. + */ +AGESA_STATUS +InitializeCacheFlushOnHaltFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + + AP_TASK TaskPtr; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + + CpuEarlyParams.PlatformConfig = *PlatformConfig; + + IDS_HDT_CONSOLE (CPU_TRACE, " Cache flush on hlt feature is enabled\n"); + TaskPtr.FuncAddress.PfApTaskIC = EnableCacheFlushOnHaltOnSocket; + TaskPtr.DataTransfer.DataSizeInDwords = 2; + TaskPtr.DataTransfer.DataPtr = &EntryPoint; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS; + OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, &CpuEarlyParams); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 'Local' core 0 task to enable Cache Flush On Halt on it's socket. + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] StdHeader Config Handle for library, services. + * @param[in] CpuEarlyParams Service parameters. + * + */ +VOID +STATIC +EnableCacheFlushOnHaltOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ) +{ + CPU_CFOH_FAMILY_SERVICES *FamilyServices; + + GetFeatureServicesOfCurrentCore (&CacheFlushOnHaltFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + if (FamilyServices != NULL) { + FamilyServices->SetCacheFlushOnHaltRegister (FamilyServices, *((UINT64 *) EntryPoint), &CpuEarlyParams->PlatformConfig, StdHeader); + } +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureCacheFlushOnHalt = +{ + CacheFlushOnHalt, + (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC), + IsCFOHEnabled, + InitializeCacheFlushOnHaltFeature +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.c new file mode 100644 index 0000000000..b5a38b8021 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.c @@ -0,0 +1,751 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Execution Cache Allocation functions. + * + * Contains code for doing Execution Cache Allocation for ROM space + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "Topology.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuCacheInit.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUCACHEINIT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +// 4G - 1, ~max ROM space +#define SIZE_INFINITE_EXE_CACHE 0xFFFFFFFFul + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * L2 cache Association to Way translation table + *---------------------------------------------------------------------------- + */ +CONST UINT8 ROMDATA L2AssocToL2WayTranslationTable[] = +{ + 0, + 1, + 2, + 0xFF, + 4, + 0xFF, + 8, + 0xFF, + 16, + 0xFF, + 32, + 48, + 64, + 96, + 128, + 0xFF, +}; + + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +UINT8 +STATIC +Ceiling ( + IN UINT32 Divisor, + IN UINT32 Dividend + ); + +UINT32 +STATIC +CalculateOccupiedExeCache ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +CompareRegions ( + IN EXECUTION_CACHE_REGION ARegion, + IN EXECUTION_CACHE_REGION BRegion, + IN OUT MERGED_CACHE_REGION *CRegion, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +STATIC +IsPowerOfTwo ( + IN UINT32 TestNumber + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will setup ROM execution cache. + * + * The execution cache regions are passed in, the max number of execution cache regions + * is three. Several rules are checked for compliance. If a rule test fails then one of + * these error suffixes will be added to the general CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR + * in the SubReason field + * -1 available cache size is less than requested, the ROM execution cache + * region has been reduced or eliminated. + * -2 at least one execution cache region crosses the 1MB line, the ROM execution + * cache size has been reduced. + * -3 at least one execution cache region crosses the 4GB line, the ROM execution + * cache size has been reduced. + * -4 the start address of a region is not at the boundary of cache size, + * the starting address has been adjusted downward + * -5 execution cache start address less than D0000, request is ignored + * -6 more than 2 execution cache regions are above 1MB, request is ignored + * If the start address of all three regions are zero, then no execution cache is allocated. + * + * @param[in] StdHeader Handle to config for library and services + * @param[in] AmdExeAddrMapPtr Pointer to the start of EXECUTION_CACHE_REGION array + * + * @retval AGESA_SUCCESS No error + * @retval AGESA_WARNING AGESA_CACHE_SIZE_REDUCED; AGESA_CACHE_REGIONS_ACROSS_1MB; + * AGESA_CACHE_REGIONS_ACROSS_4GB; + * @retval AGESA_ERROR AGESA_REGION_NOT_ALIGNED_ON_BOUNDARY; + * AGESA_CACHE_START_ADDRESS_LESS_D0000; + * AGESA_THREE_CACHE_REGIONS_ABOVE_1MB; + * + */ +AGESA_STATUS +AllocateExecutionCache ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN EXECUTION_CACHE_REGION *AmdExeAddrMapPtr + ) +{ + AGESA_STATUS AgesaStatus; + AMD_GET_EXE_SIZE_PARAMS AmdGetExeSize; + UINT32 CurrentAllocatedExeCacheSize; + UINT32 RemainingExecutionCacheSize; + UINT64 MsrData; + UINT64 SecondMsrData; + UINT32 RequestStartAddr; + UINT32 RequestSize; + UINT32 StartFixMtrr; + UINT32 CurrentMtrr; + UINT32 EndFixMtrr; + UINT8 i; + UINT8 Ignored; + CACHE_INFO *CacheInfoPtr; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + EXECUTION_CACHE_REGION MtrrV6; + EXECUTION_CACHE_REGION MtrrV7; + MERGED_CACHE_REGION Result; + + // + // If start addresses of all three regions are zero, then return early + // + if (AmdExeAddrMapPtr[0].ExeCacheStartAddr == 0) { + if (AmdExeAddrMapPtr[1].ExeCacheStartAddr == 0) { + if (AmdExeAddrMapPtr[2].ExeCacheStartAddr == 0) { + // No regions defined by the caller + return AGESA_SUCCESS; + } + } + } + + // Get available cache size for ROM execution + AmdGetExeSize.StdHeader = *StdHeader; + AgesaStatus = AmdGetAvailableExeCacheSize (&AmdGetExeSize); + CurrentAllocatedExeCacheSize = CalculateOccupiedExeCache (StdHeader); + ASSERT (CurrentAllocatedExeCacheSize <= AmdGetExeSize.AvailableExeCacheSize); + IDS_HDT_CONSOLE (CPU_TRACE, " Cache size available for execution cache: 0x%x\n", AmdGetExeSize.AvailableExeCacheSize); + RemainingExecutionCacheSize = AmdGetExeSize.AvailableExeCacheSize - CurrentAllocatedExeCacheSize; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **) &CacheInfoPtr, &Ignored, StdHeader); + + // Process each request entry 0 to 2 + for (i = 0; i < 3; i++) { + // Exit if no more cache available + if (RemainingExecutionCacheSize == 0) { + break; + } + + // Skip the region if ExeCacheSize = 0 + if (AmdExeAddrMapPtr[i].ExeCacheSize == 0) { + continue; + } + + // Align starting addresses on 32K boundary + AmdExeAddrMapPtr[i].ExeCacheStartAddr = + AmdExeAddrMapPtr[i].ExeCacheStartAddr & 0xFFFF8000; + + // Adjust size to multiple of 32K (rounding up) + if ((AmdExeAddrMapPtr[i].ExeCacheSize % 0x8000) != 0) { + AmdExeAddrMapPtr[i].ExeCacheSize = ((AmdExeAddrMapPtr[i].ExeCacheSize + 0x8000) & 0xFFFF8000); + } + + // Boundary alignment check and confirm size is an even power of two + if ( !IsPowerOfTwo (AmdExeAddrMapPtr[i].ExeCacheSize) || + ((AmdExeAddrMapPtr[i].ExeCacheStartAddr % AmdExeAddrMapPtr[i].ExeCacheSize) != 0) ) { + AgesaStatus = AGESA_ERROR; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR + AGESA_REGION_NOT_ALIGNED_ON_BOUNDARY), + i, AmdExeAddrMapPtr[i].ExeCacheStartAddr, AmdExeAddrMapPtr[i].ExeCacheSize, 0, StdHeader); + break; + } + + // Check start address boundary + if (AmdExeAddrMapPtr[i].ExeCacheStartAddr < 0xD0000) { + AgesaStatus = AGESA_ERROR; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR + AGESA_CACHE_START_ADDRESS_LESS_D0000), + i, AmdExeAddrMapPtr[i].ExeCacheStartAddr, AmdExeAddrMapPtr[i].ExeCacheSize, 0, StdHeader); + break; + } + + if (CacheInfoPtr->CarExeType == LimitedByL2Size) { + // Verify available execution cache size for region 0 to 2 request + if (RemainingExecutionCacheSize < AmdExeAddrMapPtr[i].ExeCacheSize) { + // Request is larger than available, reduce the allocation & report the change + AmdExeAddrMapPtr[i].ExeCacheSize = RemainingExecutionCacheSize; + RemainingExecutionCacheSize = 0; + AgesaStatus = AGESA_WARNING; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR + AGESA_CACHE_SIZE_REDUCED), + i, AmdExeAddrMapPtr[i].ExeCacheStartAddr, AmdExeAddrMapPtr[i].ExeCacheSize, 0, StdHeader); + } else { + RemainingExecutionCacheSize = RemainingExecutionCacheSize - AmdExeAddrMapPtr[i].ExeCacheSize; + } + } + IDS_HDT_CONSOLE (CPU_TRACE, " Exe cache allocated: Base 0x%x, Size 0x%x\n", AmdExeAddrMapPtr[i].ExeCacheStartAddr, AmdExeAddrMapPtr[i].ExeCacheSize); + + RequestStartAddr = AmdExeAddrMapPtr[i].ExeCacheStartAddr; + RequestSize = AmdExeAddrMapPtr[i].ExeCacheSize; + + if (RequestStartAddr < 0x100000) { + // Region starts below 1MB - Fixed MTTR region, + // turn on modification bit: MtrrFixDramModEn + LibAmdMsrRead (MSR_SYS_CFG, &MsrData, StdHeader); + MsrData |= 0x80000; + LibAmdMsrWrite (MSR_SYS_CFG, &MsrData, StdHeader); + + + // Check for 1M boundary crossing + if ((RequestStartAddr + RequestSize) > 0x100000) { + // Request spans the 1M boundary, reduce the size & report the change + RequestSize = 0x100000 - RequestStartAddr; + AmdExeAddrMapPtr[i].ExeCacheSize = RequestSize; + AgesaStatus = AGESA_WARNING; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR + AGESA_CACHE_REGIONS_ACROSS_1MB), + i, RequestStartAddr, RequestSize, 0, StdHeader); + } + + // Find start MTTR and end MTTR for the requested region + StartFixMtrr = AMD_MTRR_FIX4K_BASE + ((RequestStartAddr >> 15) & 0x7); + EndFixMtrr = AMD_MTRR_FIX4K_BASE + ((((RequestStartAddr + RequestSize) - 1) >> 15) & 0x7); + + // + //Check Mtrr before we use it, + // if Mtrr has been used, we need to recover the previously allocated size. + // (only work in blocks of 32K size - no splitting of ways) + for (CurrentMtrr = StartFixMtrr; CurrentMtrr <= EndFixMtrr; CurrentMtrr++) { + LibAmdMsrRead (CurrentMtrr, &MsrData, StdHeader); + if ((CacheInfoPtr->CarExeType == LimitedByL2Size) && (MsrData != 0)) { + // MTRR previously allocated, recover size + RemainingExecutionCacheSize = RemainingExecutionCacheSize + 0x8000; + } else { + // Allocate this MTRR + MsrData = WP_IO; + LibAmdMsrWrite (CurrentMtrr, &MsrData, StdHeader); + } + } + // Turn off modification bit: MtrrFixDramModEn + LibAmdMsrRead (MSR_SYS_CFG, &MsrData, StdHeader); + MsrData &= 0xFFFFFFFFFFF7FFFFULL; + LibAmdMsrWrite (MSR_SYS_CFG, &MsrData, StdHeader); + + + } else { + // Region above 1MB - Variable MTTR region + // Need to check both VarMTRRs for each requested region for match or overlap + // + + // Check for 4G boundary crossing (using size-1 to keep in 32bit math range) + if ((0xFFFFFFFFUL - RequestStartAddr) < (RequestSize - 1)) { + RequestSize = (0xFFFFFFFFUL - RequestStartAddr) + 1; + AgesaStatus = AGESA_WARNING; + AmdExeAddrMapPtr[i].ExeCacheSize = RequestSize; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR + AGESA_CACHE_REGIONS_ACROSS_4GB), + i, RequestStartAddr, RequestSize, 0, StdHeader); + } + LibAmdMsrRead (AMD_MTRR_VARIABLE_BASE6, &MsrData, StdHeader); + MtrrV6.ExeCacheStartAddr = ((UINT32) MsrData) & 0xFFFFF000UL; + LibAmdMsrRead (AMD_MTRR_VARIABLE_BASE6 + 1, &MsrData, StdHeader); + MtrrV6.ExeCacheSize = (0xFFFFFFFFUL - (((UINT32) MsrData) & 0xFFFFF000UL)) + 1; + + LibAmdMsrRead (AMD_MTRR_VARIABLE_BASE7, &MsrData, StdHeader); + MtrrV7.ExeCacheStartAddr = ((UINT32) MsrData) & 0xFFFFF000UL; + LibAmdMsrRead (AMD_MTRR_VARIABLE_BASE7 + 1, &MsrData, StdHeader); + MtrrV7.ExeCacheSize = (0xFFFFFFFFUL - (((UINT32) MsrData) & 0xFFFFF000UL)) + 1; + + CompareRegions (AmdExeAddrMapPtr[i], MtrrV6, &Result, StdHeader); + if (Result.OverlapType == EmptySet) { + // MTRR6 is empty. Allocate request into MTRR6. + // Note: since all merges are moved down to MTRR6, if MTRR6 is empty so should MTRR7 also be empty + MtrrV6.ExeCacheStartAddr = AmdExeAddrMapPtr[i].ExeCacheStartAddr; + MtrrV6.ExeCacheSize = AmdExeAddrMapPtr[i].ExeCacheSize; + } else if ((Result.OverlapType == Disjoint) || + (Result.OverlapType == NotCombinable)) { + // MTRR6 is in use, and request does not overlap with MTRR6, check MTRR7 + CompareRegions (AmdExeAddrMapPtr[i], MtrrV7, &Result, StdHeader); + if (Result.OverlapType == EmptySet) { + // MTRR7 is empty. Allocate request into MTRR7. + MtrrV7.ExeCacheStartAddr = AmdExeAddrMapPtr[i].ExeCacheStartAddr; + MtrrV7.ExeCacheSize = AmdExeAddrMapPtr[i].ExeCacheSize; + } else if ((Result.OverlapType == Disjoint) || + (Result.OverlapType == NotCombinable)) { + // MTRR7 is also in use and request does not overlap - error: 3rd region above 1M + AgesaStatus = AGESA_ERROR; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR + AGESA_THREE_CACHE_REGIONS_ABOVE_1MB), + i, AmdExeAddrMapPtr[i].ExeCacheStartAddr, AmdExeAddrMapPtr[i].ExeCacheSize, 0, StdHeader); + break; + } else { + // Merge request with MTRR7 + MtrrV7.ExeCacheStartAddr = Result.MergedStartAddr; + MtrrV7.ExeCacheSize = Result.MergedSize; + if (CacheInfoPtr->CarExeType == LimitedByL2Size) { + RemainingExecutionCacheSize += Result.OverlapAmount; + } + } + } else { + // Request overlaps with MTRR6, Merge request with MTRR6 + MtrrV6.ExeCacheStartAddr = Result.MergedStartAddr; + MtrrV6.ExeCacheSize = Result.MergedSize; + if (CacheInfoPtr->CarExeType == LimitedByL2Size) { + RemainingExecutionCacheSize += Result.OverlapAmount; + } + CompareRegions (MtrrV6, MtrrV7, &Result, StdHeader); + if ((Result.OverlapType != Disjoint) && + (Result.OverlapType != EmptySet) && + (Result.OverlapType != NotCombinable)) { + // MTRR6 and MTRR7 now overlap, merge them into MTRR6 + MtrrV6.ExeCacheStartAddr = Result.MergedStartAddr; + MtrrV6.ExeCacheSize = Result.MergedSize; + MtrrV7.ExeCacheStartAddr = 0; + MtrrV7.ExeCacheSize = 0; + if (CacheInfoPtr->CarExeType == LimitedByL2Size) { + RemainingExecutionCacheSize += Result.OverlapAmount; + } + } + } + + // Set the VarMTRRs. Base first, then size/mask; this allows for expanding the region safely. + if (MtrrV6.ExeCacheSize != 0) { + MsrData = (UINT64) ( 0xFFFFFFFF00000000ULL | ((0xFFFFFFFFUL - (MtrrV6.ExeCacheSize - 1)) | 0x0800UL)); + MsrData &= CacheInfoPtr->VariableMtrrMask; + SecondMsrData = (UINT64) ( MtrrV6.ExeCacheStartAddr | (WP_IO & 0xFULL)); + } else { + MsrData = 0; + SecondMsrData = 0; + } + LibAmdMsrWrite (AMD_MTRR_VARIABLE_BASE6, &SecondMsrData, StdHeader); + LibAmdMsrWrite ((AMD_MTRR_VARIABLE_BASE6 + 1), &MsrData, StdHeader); + + if (MtrrV7.ExeCacheSize != 0) { + MsrData = (UINT64) ( 0xFFFFFFFF00000000ULL | ((0xFFFFFFFFUL - (MtrrV7.ExeCacheSize - 1)) | 0x0800UL)); + MsrData &= CacheInfoPtr->VariableMtrrMask; + SecondMsrData = (UINT64) ( MtrrV7.ExeCacheStartAddr | (WP_IO & 0xFULL)); + } else { + MsrData = 0; + SecondMsrData = 0; + } + LibAmdMsrWrite (AMD_MTRR_VARIABLE_BASE7, &SecondMsrData, StdHeader); + LibAmdMsrWrite ((AMD_MTRR_VARIABLE_BASE7 + 1), &MsrData, StdHeader); + } // endif of MTRR region check + } // end of requests For loop + + return AgesaStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function calculates available L2 cache space for ROM execution. + * + * @param[in] AmdGetExeSizeParams Pointer to the start of AmdGetExeSizeParamsPtr structure + * + * @retval AGESA_SUCCESS No error + * @retval AGESA_ALERT No cache available for execution cache. + * + */ +AGESA_STATUS +AmdGetAvailableExeCacheSize ( + IN OUT AMD_GET_EXE_SIZE_PARAMS *AmdGetExeSizeParams + ) +{ + UINT8 WayUsedForCar; + UINT8 L2Assoc; + UINT32 L2Size; + UINT32 L2WaySize; + UINT32 CurrentCoreNum; + UINT8 L2Ways; + UINT8 Ignored; + UINT32 DieNumber; + UINT32 TotalCores; + CPUID_DATA CpuIdDataStruct; + CACHE_INFO *CacheInfoPtr; + AP_MAIL_INFO ApMailboxInfo; + AGESA_STATUS IgnoredStatus; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &AmdGetExeSizeParams->StdHeader); + FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **) &CacheInfoPtr, &Ignored, &AmdGetExeSizeParams->StdHeader); + // CAR_EXE mode is either "Limited by L2 size" or "Infinite Execution space" + ASSERT (CacheInfoPtr->CarExeType < MaxCarExeMode); + if (CacheInfoPtr->CarExeType == InfiniteExe) { + AmdGetExeSizeParams->AvailableExeCacheSize = SIZE_INFINITE_EXE_CACHE; + return AGESA_SUCCESS; + } + + // EXE cache size is limited by size of the L2, minus previous allocations for stack, heap, etc. + // Check for L2 cache size and way size + LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuIdDataStruct, &AmdGetExeSizeParams->StdHeader); + L2Assoc = (UINT8) ((CpuIdDataStruct.ECX_Reg >> 12) & 0x0F); + + // get L2Ways from L2 Association to Way translation table + L2Ways = L2AssocToL2WayTranslationTable[L2Assoc]; + ASSERT (L2Ways != 0xFF); + + // get L2Size + L2Size = 1024 * ((CpuIdDataStruct.ECX_Reg >> 16) & 0xFFFF); + + // get each L2WaySize + L2WaySize = L2Size / L2Ways; + + // Determine the size for execution cache + if (IsBsp (&AmdGetExeSizeParams->StdHeader, &IgnoredStatus)) { + // BSC (Boot Strap Core) + WayUsedForCar = Ceiling (CacheInfoPtr->BspStackSize, L2WaySize) + + Ceiling (CacheInfoPtr->MemTrainingBufferSize, L2WaySize) + + Ceiling (AMD_HEAP_SIZE_PER_CORE , L2WaySize) + + Ceiling (CacheInfoPtr->SharedMemSize, L2WaySize); + } else { + // AP (Application Processor) + GetCurrentCore (&CurrentCoreNum, &AmdGetExeSizeParams->StdHeader); + + GetApMailbox (&ApMailboxInfo.Info, &AmdGetExeSizeParams->StdHeader); + DieNumber = (1 << ApMailboxInfo.Fields.ModuleType); + GetActiveCoresInCurrentSocket (&TotalCores, &AmdGetExeSizeParams->StdHeader); + ASSERT ((TotalCores % DieNumber) == 0); + if ((CurrentCoreNum % (TotalCores / DieNumber)) == 0) { + WayUsedForCar = Ceiling (CacheInfoPtr->Core0StackSize , L2WaySize) + + Ceiling (CacheInfoPtr->MemTrainingBufferSize, L2WaySize) + + Ceiling (AMD_HEAP_SIZE_PER_CORE , L2WaySize) + + Ceiling (CacheInfoPtr->SharedMemSize, L2WaySize); + } else { + WayUsedForCar = Ceiling (CacheInfoPtr->Core1StackSize , L2WaySize) + + Ceiling (AMD_HEAP_SIZE_PER_CORE , L2WaySize) + + Ceiling (CacheInfoPtr->SharedMemSize, L2WaySize); + } + } + + ASSERT (WayUsedForCar < L2Ways); + + if (WayUsedForCar < L2Ways) { + AmdGetExeSizeParams->AvailableExeCacheSize = L2WaySize * (L2Ways - WayUsedForCar); + return AGESA_SUCCESS; + } else { + AmdGetExeSizeParams->AvailableExeCacheSize = 0; + return AGESA_ALERT; + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * This function rounds a quotient up if the remainder is not zero. + * + * @param[in] Divisor The divisor + * @param[in] Dividend The dividend + * + * @retval Value Rounded quotient + * + */ +UINT8 +STATIC +Ceiling ( + IN UINT32 Divisor, + IN UINT32 Dividend + ) +{ + if ((Divisor % Dividend) == 0) { + return (UINT8) (Divisor / Dividend); + } else { + return (UINT8) ((Divisor / Dividend) + 1); + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * This function calculates the amount of cache that has already been allocated on the + * executing core. + * + * @param[in] StdHeader Handle to config for library and services + * + * @returns Allocated size in bytes + * + */ +UINT32 +STATIC +CalculateOccupiedExeCache ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 OccupExeCacheSize; + UINT64 MsrData; + UINT8 i; + + MsrData = 0; + OccupExeCacheSize = 0; + + // + //Calculate Variable MTRR base 6~7 + // + for (i = 0; i < 2; i++) { + LibAmdMsrRead ((AMD_MTRR_VARIABLE_BASE6 + (2*i)), &MsrData, StdHeader); + if (MsrData != 0) { + LibAmdMsrRead ((AMD_MTRR_VARIABLE_BASE6 + (2*i + 1)), &MsrData, StdHeader); + OccupExeCacheSize = OccupExeCacheSize + ((~((MsrData & (0xFFFF8000)) - 1))&0xFFFF8000); + } + } + + // + //Calculate Fixed MTRR base D0000~F8000 + // + for (i = 0; i < 6; i++) { + LibAmdMsrRead ((AMD_MTRR_FIX4K_BASE + 2 + i), &MsrData, StdHeader); + if (MsrData!= 0) { + OccupExeCacheSize = OccupExeCacheSize + 0x8000; + } + } + + return (UINT32)OccupExeCacheSize; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * This function compares two memory regions for overlap and returns the combined + * Base,Size to describe the new combined region. + * + * There are 13 cases for how two regions may overlap: key: [] region A, ** region B + * 1- [ ] *** 9- *** [ ] disjoint regions + * 2- [ ]*** 10- ***[ ] adjacent regions + * 3- [ ***] 11- **[**] common ending + * 4- [ *]** 12- *[** ] extending + * 5- [ ** ] 13- *[*]* contained + * 6- [*** ] common start, contained + * 7- [***] identity + * 8- [**]** common start, extending + * 0- one of the regions is empty (has base=0) + * + * @param[in] ARegion pointer to the base,size pair that describes region A + * @param[in] BRegion pointer to the base,size pair that describes region B + * @param[in,out] CRegion pointer to the base,size pair that describes region C This struct also has the + * overlap type and the amount of overlap between the regions. + * @param[in] StdHeader Handle to config for library and services + * + * @returns void, nothing + */ + +VOID +STATIC +CompareRegions ( + IN EXECUTION_CACHE_REGION ARegion, + IN EXECUTION_CACHE_REGION BRegion, + IN OUT MERGED_CACHE_REGION *CRegion, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // Use Int64 to handle regions ending at or above the 4G boundary. + UINT64 EndOfA; + UINT64 EndOfB; + + + if ((BRegion.ExeCacheStartAddr == 0) || + (ARegion.ExeCacheStartAddr == 0)) { + CRegion->MergedStartAddr = + CRegion->MergedSize = + CRegion->OverlapAmount = 0; + CRegion->OverlapType = EmptySet; + return; + } + if (BRegion.ExeCacheStartAddr < ARegion.ExeCacheStartAddr) { + //swap regions A & B. this collapses types 9-13 onto 1-5 and reduces the number of tests + CRegion->MergedStartAddr = ARegion.ExeCacheStartAddr; + CRegion->MergedSize = ARegion.ExeCacheSize; + ARegion = BRegion; + BRegion.ExeCacheStartAddr = CRegion->MergedStartAddr; + BRegion.ExeCacheSize = CRegion->MergedSize; + } + CRegion->MergedStartAddr = + CRegion->MergedSize = + CRegion->OverlapType = + CRegion->OverlapAmount = 0; + + if (ARegion.ExeCacheStartAddr == BRegion.ExeCacheStartAddr) { + // Common start, cases 6,7, or 8 + if (ARegion.ExeCacheSize == BRegion.ExeCacheSize) { + // case 7, identity. Need to recover the overlap size + CRegion->MergedStartAddr = ARegion.ExeCacheStartAddr; + CRegion->MergedSize = ARegion.ExeCacheSize; + CRegion->OverlapAmount = ARegion.ExeCacheSize; + CRegion->OverlapType = Identity; + } else if (ARegion.ExeCacheSize < BRegion.ExeCacheSize) { + // case 8, common start extending + CRegion->MergedStartAddr = ARegion.ExeCacheStartAddr; + CRegion->MergedSize = BRegion.ExeCacheSize; + CRegion->OverlapType = CommonStartExtending; + CRegion->OverlapAmount = ARegion.ExeCacheSize; + } else { + // case 6, common start contained + CRegion->MergedStartAddr = ARegion.ExeCacheStartAddr; + CRegion->MergedSize = ARegion.ExeCacheSize; + CRegion->OverlapType = CommonStartContained; + CRegion->OverlapAmount = BRegion.ExeCacheSize; + } + } else { + // A_Base is less than B_Base. check for cases 1-5 + EndOfA = ((UINT64) ARegion.ExeCacheStartAddr) + ((UINT64) ARegion.ExeCacheSize); + + if (EndOfA < ((UINT64) BRegion.ExeCacheStartAddr)) { + // case 1, disjoint + CRegion->MergedStartAddr = + CRegion->MergedSize = + CRegion->OverlapAmount = 0; + CRegion->OverlapType = Disjoint; + + } else if (EndOfA == ((UINT64) BRegion.ExeCacheStartAddr)) { + // case 2, adjacent + CRegion->OverlapType = Adjacent; + CRegion->MergedStartAddr = ARegion.ExeCacheStartAddr; + CRegion->MergedSize = ARegion.ExeCacheSize + BRegion.ExeCacheSize; + CRegion->OverlapAmount = 0; + } else { + // EndOfA is > B_Base. check for cases 3,4,5 + EndOfB = ((UINT64) BRegion.ExeCacheStartAddr) + ((UINT64) BRegion.ExeCacheSize); + + if ( EndOfA < EndOfB) { + // case 4, extending + CRegion->OverlapType = Extending; + CRegion->MergedStartAddr = ARegion.ExeCacheStartAddr; + CRegion->MergedSize = (UINT32) (EndOfB - ((UINT64) ARegion.ExeCacheStartAddr)); + CRegion->OverlapAmount = (UINT32) (EndOfA - ((UINT64) BRegion.ExeCacheStartAddr)); + } else { + // case 3, same end; or case 5, contained + CRegion->OverlapType = Contained; + CRegion->MergedStartAddr = ARegion.ExeCacheStartAddr; + CRegion->MergedSize = ARegion.ExeCacheSize; + CRegion->OverlapAmount = BRegion.ExeCacheSize; + } + } + } // endif + // Once we have combined the regions, they must still obey the MTRR size and boundary rules + if ( CRegion->OverlapType != Disjoint ) { + if ((!(IsPowerOfTwo (CRegion->MergedSize))) || + ((CRegion->MergedStartAddr % CRegion->MergedSize) != 0) ) { + CRegion->OverlapType = NotCombinable; + } + } + +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * This local function tests the parameter for being an even power of two + * + * @param[in] TestNumber Number to check + * + * @retval TRUE - TestNumber is a power of two, + * @retval FALSE - TestNumber is not a power of two + * + */ +BOOLEAN +STATIC +IsPowerOfTwo ( + IN UINT32 TestNumber + ) +{ + UINT32 PowerTwo; + + ASSERT (TestNumber >= 0x8000UL); + PowerTwo = 0x8000UL; // Start at 32K + while ( TestNumber > PowerTwo ) { + PowerTwo = PowerTwo * 2; + } + return (((TestNumber % PowerTwo) == 0) ? TRUE: FALSE); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.h new file mode 100644 index 0000000000..24cc757ea7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCacheInit.h @@ -0,0 +1,138 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Execution Cache Allocation functions. + * + * Contains code for doing Execution Cache Allocation for ROM space + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_CACHE_INIT_H_ +#define _CPU_CACHE_INIT_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define BSP_STACK_SIZE_64K 65536 +#define BSP_STACK_SIZE_32K 32768 + +#define CORE0_STACK_SIZE 16384 +#define CORE1_STACK_SIZE 4096 + +#define AMD_MTRR_FIX4K_BASE 0x268 +#define AMD_MTRR_VARIABLE_BASE6 0x20C +#define AMD_MTRR_VARIABLE_BASE7 0x20E + +#define WP_IO 0x0505050505050505ull + +#define AGESA_CACHE_SIZE_REDUCED 1 +#define AGESA_CACHE_REGIONS_ACROSS_1MB 2 +#define AGESA_CACHE_REGIONS_ACROSS_4GB 3 +#define AGESA_REGION_NOT_ALIGNED_ON_BOUNDARY 4 +#define AGESA_CACHE_START_ADDRESS_LESS_D0000 5 +#define AGESA_THREE_CACHE_REGIONS_ABOVE_1MB 6 +#define AGESA_DEALLOCATE_CACHE_REGIONS 7 + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ +/// Cache-As-Ram Executable region allocation modes +typedef enum { + LimitedByL2Size, ///< Execution space must be allocated from L2 + InfiniteExe, ///< Family can support unlimited Execution space + MaxCarExeMode ///< Used as limit or bounds check +} CAR_EXE_MODE; + +/// Cache Information +typedef struct { + IN UINT32 BspStackSize; ///< Stack size of BSP + IN UINT32 Core0StackSize; ///< Stack size of primary cores + IN UINT32 Core1StackSize; ///< Stack size of all non primary cores + IN UINT32 MemTrainingBufferSize; ///< Memory training buffer size + IN UINT32 SharedMemSize; ///< Shared memory size + IN UINT64 VariableMtrrMask; ///< Mask to apply before variable MTRR writes + IN UINT64 VariableMtrrHeapMask; ///< Mask to apply before variable MTRR writes for use in heap init. + IN UINT64 HeapBaseMask; ///< Mask used for the heap MTRR settings + IN CAR_EXE_MODE CarExeType; ///< Indicates which algorithm to use when allocating EXE space +} CACHE_INFO; + +/// Merged memory region overlap type +typedef enum { + EmptySet, ///< One of the regions is zero length + Disjoint, ///< The two regions do not touch + Adjacent, ///< one region is next to the other, no gap + CommonEnd, ///< regions overlap with a common end point + Extending, ///< the 2nd region is extending the size of the 1st + Contained, ///< the 2nd region is wholely contained inside the 1st + CommonStartContained, ///< the 2nd region is contained in the 1st with a common start + Identity, ///< the two regions are the same + CommonStartExtending, ///< the 2nd region has same start as 1st, but is larger size + NotCombinable ///< the combined regions do not follow the cache block rules +} OVERLAP_TYPE; + +/// Result of merging two memory regions for cache coverage +typedef struct { + IN OUT UINT32 MergedStartAddr; ///< Start address of the merged regions + IN OUT UINT32 MergedSize; ///< Size of the merged regions + OUT UINT32 OverlapAmount; ///< the size of the overlapping section + OUT OVERLAP_TYPE OverlapType; ///< indicates how the two regions overlap +} MERGED_CACHE_REGION; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +AllocateExecutionCache ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN EXECUTION_CACHE_REGION *AmdExeAddrMapPtr + ); + +#endif // _CPU_CACHE_INIT_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCdit.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCdit.c new file mode 100644 index 0000000000..e02e8706c2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCdit.c @@ -0,0 +1,347 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CDIT, ACPI table related API functions. + * + * Contains code that generates the CDIT table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------- + * This file provides functions, that will generate SLIT tables + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionCdit.h" +#include "heapManager.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "Ids.h" +#include "cpuFeatures.h" +#include "cpuFamilyTranslation.h" +#include "cpuL3Features.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FEATURE_CPUCDIT_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern OPTION_CDIT_CONFIGURATION OptionCditConfiguration; // global user config record + +STATIC ACPI_TABLE_HEADER ROMDATA CpuCditHdrStruct = +{ + {'C','D','I','T'}, + 0, + 1, + 0, + {0}, + {0}, + 1, + {'A','M','D',' '}, + 1 +}; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +AcpiCditHBufferFind ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN UINT8 **SocketTopologyPtr + ); + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GetAcpiCditStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT VOID **CditPtr + ); + +AGESA_STATUS +GetAcpiCditMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT VOID **CditPtr + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +extern CPU_FAMILY_SUPPORT_TABLE L3FeatureFamilyServiceTable; + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function generates a complete CDIT table into a memory buffer. + * After completion, this table must be set by the system BIOS into its + * internal ACPI namespace, and linked into the RSDT/XSDT + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in] PlatformConfig Config handle for platform specific information + * @param[out] CditPtr Point to Cdit Struct including buffer address and length + * + * @retval UINT32 AGESA_STATUS + */ +AGESA_STATUS +CreateAcpiCdit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT VOID **CditPtr + ) +{ + AGESA_TESTPOINT (TpProcCpuEntryCdit, StdHeader); + return ((*(OptionCditConfiguration.CditFeature)) (StdHeader, PlatformConfig, CditPtr)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This is the default routine for use when the CDIT option is NOT requested. + * + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in] PlatformConfig Config handle for platform specific information + * @param[out] CditPtr Point to Cdit Struct including buffer address and length + * + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GetAcpiCditStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT VOID **CditPtr + ) +{ + return AGESA_UNSUPPORTED; +} +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function generates a complete CDIT table into a memory buffer. + * After completion, this table must be set by the system BIOS into its + * internal ACPI namespace, and linked into the RSDT/XSDT + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in] PlatformConfig Config handle for platform specific information + * @param[out] CditPtr Point to Cdit Struct including buffer address and length + * + * @retval UINT32 AGESA_STATUS + */ +AGESA_STATUS +GetAcpiCditMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT VOID **CditPtr + ) +{ + UINT8 MaxHops; + UINT8 DomainNum; + UINT8 i; + UINT8 j; + UINT8 *BufferPtr; + UINT8 *SocketTopologyDataPtr; + UINT8 *SocketTopologyPtr; + UINT32 Socket; + BOOLEAN IsProbeFilterEnabled; + ACPI_TABLE_HEADER *CpuCditHeaderStructPtr; + AGESA_STATUS Flag; + ALLOCATE_HEAP_PARAMS AllocStruct; + L3_FEATURE_FAMILY_SERVICES *FamilyServices; + + MaxHops = 0; + SocketTopologyPtr = NULL; + Flag = AGESA_ERROR; + IsProbeFilterEnabled = FALSE; + + // find out the pointer to the BufferHandle which contains + // Node Topology information + AcpiCditHBufferFind (StdHeader, &SocketTopologyPtr); + if (SocketTopologyPtr == NULL) { + return (Flag); + } + + DomainNum = *SocketTopologyPtr; + + IDS_HDT_CONSOLE (CPU_TRACE, " CDIT is created\n"); + + // create a buffer by calling IBV callout routine + AllocStruct.RequestedBufferSize = (DomainNum * DomainNum) + AMD_ACPI_CDIT_NUM_DOMAINS_LENGTH + sizeof (ACPI_TABLE_HEADER); + AllocStruct.BufferHandle = AMD_ACPI_CDIT_BUFFER_HANDLE; + AllocStruct.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocStruct, StdHeader) != AGESA_SUCCESS) { + return (Flag); + } + *CditPtr = AllocStruct.BufferPtr; + + //CDIT header + LibAmdMemCopy (*CditPtr, (VOID *) &CpuCditHdrStruct, (UINTN) (sizeof (ACPI_TABLE_HEADER)), StdHeader); + CpuCditHeaderStructPtr = (ACPI_TABLE_HEADER *) *CditPtr; + CpuCditHeaderStructPtr->TableLength = (UINT32) AllocStruct.RequestedBufferSize; + // Update table OEM fields. + LibAmdMemCopy ((VOID *) &CpuCditHeaderStructPtr->OemId, (VOID *) &OptionCditConfiguration.OemIdString, + sizeof (OptionCditConfiguration.OemIdString), StdHeader); + LibAmdMemCopy ((VOID *) &CpuCditHeaderStructPtr->OemTableId, (VOID *) &OptionCditConfiguration.OemTableIdString, + sizeof (OptionCditConfiguration.OemTableIdString), StdHeader); + BufferPtr = *CditPtr; + + Flag = AGESA_SUCCESS; + // CDIT body + // Check if Probe Filter is enabled + if (IsFeatureEnabled (L3Features, PlatformConfig, StdHeader)) { + IsProbeFilterEnabled = TRUE; + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&L3FeatureFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); + if ((FamilyServices == NULL) || (!FamilyServices->IsHtAssistSupported (FamilyServices, PlatformConfig, StdHeader))) { + IsProbeFilterEnabled = FALSE; + break; + } + } + } + } + + + if (!IsProbeFilterEnabled) { + // probe filter is disabled + // get MaxHops + SocketTopologyDataPtr = SocketTopologyPtr + sizeof (DomainNum); + for (i = 0; i < DomainNum; i++) { + for (j = 0; j < DomainNum; j++) { + if (*SocketTopologyDataPtr > MaxHops) { + MaxHops = *SocketTopologyDataPtr; + } + SocketTopologyDataPtr++; + } + } + + // the Max hop entries have a value of 13 + // and all other entries have 10. + SocketTopologyDataPtr = SocketTopologyPtr + sizeof (DomainNum); + for (i = 0; i < DomainNum; i++) { + for (j = 0; j < DomainNum; j++) { + if (*SocketTopologyDataPtr++ == MaxHops) { + *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + + AMD_ACPI_CDIT_NUM_DOMAINS_LENGTH + (i * DomainNum) + j) = 13; + } else { + *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + + AMD_ACPI_CDIT_NUM_DOMAINS_LENGTH + (i * DomainNum) + j) = 10; + } + } + } + } else { + // probe filter is enabled + // formula : num_hops * 6 + 10 + SocketTopologyDataPtr = SocketTopologyPtr + sizeof (DomainNum); + for (i = 0; i < DomainNum; i++) { + for (j = 0; j < DomainNum; j++) { + *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + + AMD_ACPI_CDIT_NUM_DOMAINS_LENGTH + (i * DomainNum) + j) = + ((*SocketTopologyDataPtr++) * 6) + 10; + } + } + } + + BufferPtr += sizeof (ACPI_TABLE_HEADER); + *((UINT32 *) BufferPtr) = (UINT32) DomainNum; + + //Update CDIT header Checksum + ChecksumAcpiTable ((ACPI_TABLE_HEADER *) *CditPtr, StdHeader); + + return (Flag); +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Find out the pointer to the BufferHandle which contains + * Node Topology information + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in] SocketTopologyPtr Point to the address of Socket Topology + * + */ +VOID +STATIC +AcpiCditHBufferFind ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN UINT8 **SocketTopologyPtr + ) +{ + LOCATE_HEAP_PTR LocateBuffer; + + LocateBuffer.BufferHandle = HOP_COUNT_TABLE_HANDLE; + if (HeapLocateBuffer (&LocateBuffer, StdHeader) == AGESA_SUCCESS) { + *SocketTopologyPtr = (UINT8 *) LocateBuffer.BufferPtr; + } + + return; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCoreLeveling.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCoreLeveling.c new file mode 100644 index 0000000000..b00e97953d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCoreLeveling.c @@ -0,0 +1,374 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Core Leveling Function. + * + * Contains code to Level the number of core in a multi-socket system + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "AMD.h" +#include "Topology.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "cpuEarlyInit.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) +#define FILECODE PROC_CPU_FEATURE_CPUCORELEVELING_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE CoreLevelingFamilyServiceTable; + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +CoreLevelingAtEarly ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * P U B L I C F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Should core leveling be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE core leveling is supported. + * @retval FALSE core leveling cannot be enabled. + * + */ +BOOLEAN +STATIC +IsCoreLevelingEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CORE_LEVELING_TYPE CoreLevelMode; + + CoreLevelMode = (CORE_LEVELING_TYPE) PlatformConfig->CoreLevelingMode; + if (CoreLevelMode != CORE_LEVEL_NONE) { + return (TRUE); + } else { + return (FALSE); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Performs core leveling for the system. + * + * This function implements the AMD_CPU_EARLY_PARAMS.CoreLevelingMode parameter. + * The possible modes are: + * -0 CORE_LEVEL_LOWEST Level to lowest common denominator + * -1 CORE_LEVEL_TWO Level to 2 cores + * -2 CORE_LEVEL_POWER_OF_TWO Level to 1,2,4 or 8 + * -3 CORE_LEVEL_NONE Do no leveling + * -4 CORE_LEVEL_COMPUTE_UNIT Level cores to one core per compute unit + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the leveling mode parameter + * @param[in] StdHeader Config handle for library and services + * + * @return The most severe status of any family specific service. + * + */ +AGESA_STATUS +CoreLevelingAtEarly ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CoreNumPerComputeUnit; + UINT32 MinNumOfComputeUnit; + UINT32 EnabledComputeUnit; + UINT32 Socket; + UINT32 Module; + UINT32 NumberOfSockets; + UINT32 NumberOfModules; + UINT32 MinCoreCountOnNode; + UINT32 MaxCoreCountOnNode; + UINT32 LowCore; + UINT32 HighCore; + UINT32 LeveledCores; + UINT32 RequestedCores; + UINT32 TotalEnabledCoresOnNode; + BOOLEAN RegUpdated; + AP_MAIL_INFO ApMailboxInfo; + CORE_LEVELING_TYPE CoreLevelMode; + CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices; + WARM_RESET_REQUEST Request; + + IDS_HDT_CONSOLE (CPU_TRACE, "CoreLevelingAtEarly\n CoreLevelMode: %d\n", PlatformConfig->CoreLevelingMode); + + MaxCoreCountOnNode = 0; + MinCoreCountOnNode = 0xFFFFFFFF; + LeveledCores = 0; + CoreNumPerComputeUnit = 1; + MinNumOfComputeUnit = 0xFF; + + ASSERT (PlatformConfig->CoreLevelingMode < CoreLevelModeMax); + + // Get OEM IO core level mode + CoreLevelMode = (CORE_LEVELING_TYPE) PlatformConfig->CoreLevelingMode; + + // Get socket count + NumberOfSockets = GetPlatformNumberOfSockets (); + GetApMailbox (&ApMailboxInfo.Info, StdHeader); + NumberOfModules = ApMailboxInfo.Fields.ModuleType + 1; + + // Collect cpu core info + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + for (Module = 0; Module < NumberOfModules; Module++) { + if (GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader)) { + // Get the highest and lowest core count in all nodes + TotalEnabledCoresOnNode = HighCore - LowCore + 1; + if (TotalEnabledCoresOnNode < MinCoreCountOnNode) { + MinCoreCountOnNode = TotalEnabledCoresOnNode; + } + if (TotalEnabledCoresOnNode > MaxCoreCountOnNode) { + MaxCoreCountOnNode = TotalEnabledCoresOnNode; + } + EnabledComputeUnit = TotalEnabledCoresOnNode; + switch (GetComputeUnitMapping (StdHeader)) { + case AllCoresMapping: + // All cores are in their own compute unit. + break; + case EvenCoresMapping: + // Cores are paired in compute units. + CoreNumPerComputeUnit = 2; + EnabledComputeUnit = (TotalEnabledCoresOnNode / 2); + break; + case TripleCoresMapping: + // Three cores are grouped in compute units. + CoreNumPerComputeUnit = 3; + EnabledComputeUnit = (TotalEnabledCoresOnNode / 3); + break; + case QuadCoresMapping: + // Four cores are grouped in compute units. + CoreNumPerComputeUnit = 4; + EnabledComputeUnit = (TotalEnabledCoresOnNode / 4); + break; + default: + ASSERT (FALSE); + } + // Get minimum of compute unit. This will either be the minimum number of cores (AllCoresMapping), + // or less (EvenCoresMapping). + if (EnabledComputeUnit < MinNumOfComputeUnit) { + MinNumOfComputeUnit = EnabledComputeUnit; + } + IDS_HDT_CONSOLE (CPU_TRACE, " Socket %d Module %d MaxCoreCountOnNode %d MinCoreCountOnNode %d TotalEnabledCoresOnNode %d EnabledComputeUnit %d MinNumOfComputeUnit %d\n", \ + Socket, Module, MaxCoreCountOnNode, MinCoreCountOnNode, TotalEnabledCoresOnNode, EnabledComputeUnit, MinNumOfComputeUnit); + } + } + } + } + + // Get LeveledCores + switch (CoreLevelMode) { + case CORE_LEVEL_LOWEST: + if (MinCoreCountOnNode == MaxCoreCountOnNode) { + return (AGESA_SUCCESS); + } + LeveledCores = (MinCoreCountOnNode / CoreNumPerComputeUnit) * CoreNumPerComputeUnit; + break; + case CORE_LEVEL_TWO: + LeveledCores = 2 / NumberOfModules; + if (LeveledCores != 0) { + LeveledCores = (LeveledCores <= MinCoreCountOnNode) ? LeveledCores : MinCoreCountOnNode; + } else { + return (AGESA_WARNING); + } + if ((LeveledCores * NumberOfModules) != 2) { + PutEventLog ( + AGESA_WARNING, + CPU_WARNING_ADJUSTED_LEVELING_MODE, + 2, (LeveledCores * NumberOfModules), 0, 0, StdHeader + ); + } + break; + case CORE_LEVEL_POWER_OF_TWO: + // Level to power of 2 (1, 2, 4, 8...) + LeveledCores = 1; + while (MinCoreCountOnNode >= (LeveledCores * 2)) { + LeveledCores = LeveledCores * 2; + } + break; + case CORE_LEVEL_COMPUTE_UNIT: + case CORE_LEVEL_COMPUTE_UNIT_TWO: + case CORE_LEVEL_COMPUTE_UNIT_THREE: + // Level cores to 1~3 core(s) per compute unit, with additional reduction to level + // all processors to match the processor with the minimum number of cores. + if (CoreNumPerComputeUnit == 1) { + // If there is one core per compute unit, this is the same as CORE_LEVEL_LOWEST. + if (MinCoreCountOnNode == MaxCoreCountOnNode) { + return (AGESA_SUCCESS); + } + LeveledCores = MinCoreCountOnNode; + } else { + // If there are more than one core per compute unit, level to the number of compute units * cores per compute unit. + LeveledCores = MinNumOfComputeUnit * (CoreLevelMode - CORE_LEVEL_COMPUTE_UNIT + 1); + } + break; + case CORE_LEVEL_ONE: + LeveledCores = 1; + if (NumberOfModules > 1) { + PutEventLog ( + AGESA_WARNING, + CPU_WARNING_ADJUSTED_LEVELING_MODE, + 1, NumberOfModules, 0, 0, StdHeader + ); + } + break; + case CORE_LEVEL_THREE: + case CORE_LEVEL_FOUR: + case CORE_LEVEL_FIVE: + case CORE_LEVEL_SIX: + case CORE_LEVEL_SEVEN: + case CORE_LEVEL_EIGHT: + case CORE_LEVEL_NINE: + case CORE_LEVEL_TEN: + case CORE_LEVEL_ELEVEN: + case CORE_LEVEL_TWELVE: + case CORE_LEVEL_THIRTEEN: + case CORE_LEVEL_FOURTEEN: + case CORE_LEVEL_FIFTEEN: + // MCM processors can not have an odd number of cores. For an odd CORE_LEVEL_N, MCM processors will be + // leveled as though CORE_LEVEL_N+1 was chosen. + // Processors with compute units disable all cores in an entire compute unit at a time, or on an MCM processor, + // two compute units at a time. For example, on an SCM processor with two cores per compute unit, the effective + // explicit levels are CORE_LEVEL_ONE, CORE_LEVEL_TWO, CORE_LEVEL_FOUR, CORE_LEVEL_SIX, and + // CORE_LEVEL_EIGHT. The same example for an MCM processor with two cores per compute unit has effective + // explicit levels of CORE_LEVEL_TWO, CORE_LEVEL_FOUR, CORE_LEVEL_EIGHT, and CORE_LEVEL_TWELVE. + RequestedCores = CoreLevelMode - CORE_LEVEL_THREE + 3; + LeveledCores = (RequestedCores + NumberOfModules - 1) / NumberOfModules; + LeveledCores = (LeveledCores / CoreNumPerComputeUnit) * CoreNumPerComputeUnit; + LeveledCores = (LeveledCores <= MinCoreCountOnNode) ? LeveledCores : MinCoreCountOnNode; + if (LeveledCores != 1) { + LeveledCores = (LeveledCores / CoreNumPerComputeUnit) * CoreNumPerComputeUnit; + } + if ((LeveledCores * NumberOfModules * CoreNumPerComputeUnit) != RequestedCores) { + PutEventLog ( + AGESA_WARNING, + CPU_WARNING_ADJUSTED_LEVELING_MODE, + RequestedCores, (LeveledCores * NumberOfModules * CoreNumPerComputeUnit), 0, 0, StdHeader + ); + } + break; + default: + ASSERT (FALSE); + } + + // Set down core register + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&CoreLevelingFamilyServiceTable, Socket, (CONST VOID **)&FamilySpecificServices, StdHeader); + if (FamilySpecificServices != NULL) { + for (Module = 0; Module < NumberOfModules; Module++) { + IDS_HDT_CONSOLE (CPU_TRACE, " SetDownCoreRegister: Socket %d Module %d LeveledCores %d CoreLevelMode %d\n", Socket, Module, LeveledCores, CoreLevelMode); + RegUpdated = FamilySpecificServices->SetDownCoreRegister (FamilySpecificServices, &Socket, &Module, &LeveledCores, CoreLevelMode, StdHeader); + // If the down core register is updated, trigger a warm reset. + if (RegUpdated) { + GetWarmResetFlag (StdHeader, &Request); + Request.RequestBit = TRUE; + Request.StateBits = Request.PostStage - 1; + IDS_HDT_CONSOLE (CPU_TRACE, " Request a warm reset.\n"); + SetWarmResetFlag (StdHeader, &Request); + } + } + } + } + } + + return (AGESA_SUCCESS); +} + + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureCoreLeveling = +{ + CoreLeveling, + (CPU_FEAT_AFTER_PM_INIT), + IsCoreLevelingEnabled, + CoreLevelingAtEarly +}; + +/*---------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.c new file mode 100644 index 0000000000..0745452755 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.c @@ -0,0 +1,175 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Core performance boost feature support code. + * + * Contains code that declares the AGESA CPU CPB related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "cpuCpb.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUCPB_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE CpbFamilyServiceTable; + +/*---------------------------------------------------------------------------------------*/ +/** + * Should CPB be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE CPB is supported. + * @retval FALSE CPB cannot be enabled. + * + */ +BOOLEAN +STATIC +IsCpbFeatureEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + BOOLEAN IsEnabled; + CPB_FAMILY_SERVICES *FamilyServices; + + IsEnabled = FALSE; + + ASSERT (PlatformConfig->CpbMode < MaxCpbMode); + + if (PlatformConfig->CpbMode == CpbModeAuto) { + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&CpbFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); + if (FamilyServices != NULL) { + if (FamilyServices->IsCpbSupported (FamilyServices, PlatformConfig, Socket, StdHeader)) { + IsEnabled = TRUE; + break; + } + } + } + } + } + return IsEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable core performance boost + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +InitializeCpbFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + AGESA_STATUS AgesaStatus; + AGESA_STATUS CalledStatus; + CPB_FAMILY_SERVICES *FamilyServices; + + AgesaStatus = AGESA_SUCCESS; + CalledStatus = AGESA_SUCCESS; + + IDS_HDT_CONSOLE (CPU_TRACE, " Boost is enabled\n"); + + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&CpbFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); + if (FamilyServices != NULL) { + if (FamilyServices->IsCpbSupported (FamilyServices, PlatformConfig, Socket, StdHeader)) { + CalledStatus = FamilyServices->EnableCpbOnSocket (FamilyServices, PlatformConfig, EntryPoint, Socket, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + } + } + } + } + + return AgesaStatus; +} + + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureCpb = +{ + CoreBoost, + (CPU_FEAT_AFTER_PM_INIT | CPU_FEAT_INIT_LATE_END | CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_S3_LATE_RESTORE_END | CPU_FEAT_AFTER_RESUME_MTRR_SYNC), + IsCpbFeatureEnabled, + InitializeCpbFeature +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.h new file mode 100644 index 0000000000..dd3e359fe6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCpb.h @@ -0,0 +1,133 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Core Performance Boost Functions declarations. + * + * Contains code that declares the AGESA CPU CPB related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_CPB_H_ +#define _CPU_CPB_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (CPB_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if CPB is supported. + * + * @param[in] CpbServices Core Performance Boost services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] Socket Zero-based socket number. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE CPB is supported. + * @retval FALSE CPB is not supported. + * + */ +typedef BOOLEAN F_CPB_IS_SUPPORTED ( + IN CPB_FAMILY_SERVICES *CpbServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPB_IS_SUPPORTED *PF_CPB_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable CPB. + * + * @param[in] CpbServices Core Performance Boost services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] EntryPoint Timepoint designator. + * @param[in] Socket Zero-based socket number. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_CPB_INIT ( + IN CPB_FAMILY_SERVICES *CpbServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT64 EntryPoint, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPB_INIT *PF_CPB_INIT; + +/** + * Provide the interface to the CPB Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _CPB_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_CPB_IS_SUPPORTED IsCpbSupported; ///< Method: Family specific call to check if CPB is supported. + PF_CPB_INIT EnableCpbOnSocket; ///< Method: Family specific call to enable CPB. +}; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_CPB_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.c new file mode 100644 index 0000000000..552713d2cd --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.c @@ -0,0 +1,513 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CRAT, ACPI table related API functions. + * + * Contains code that Create the APCI CRAT Table after early reset. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FEATURE + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************/ + + +/*---------------------------------------------------------------------------- + * This file provides functions, that will generate CRAT tables + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuServices.h" +#include "OptionCrat.h" +#include "cpuCrat.h" +#include "mfCrat.h" +#include "heapManager.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuLateInit.h" +#include "Ids.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FEATURE_CPUCRAT_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_CRAT_CONFIGURATION OptionCratConfiguration; // global user config record +extern CPU_FAMILY_SUPPORT_TABLE CratFamilyServiceTable; +extern S_MAKE_CRAT_ENTRY MakeCratEntryTable[]; + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GetAcpiCratStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **CratPtr + ); + +AGESA_STATUS +GetAcpiCratMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **CratPtr + ); + +/*---------------------------------------------------------------------------- + * All of the DATA should be defined in _CODE segment. + * Use ROMDATA to specify that it belongs to _CODE. + *---------------------------------------------------------------------------- + */ +CONST UINT8 ROMDATA L2L3Associativity[] = +{ + 0, + 1, + 2, + 0, + 4, + 0, + 8, + 0, + 16, + 0, + 32, + 48, + 64, + 96, + 128, + 0xFF +}; + +STATIC CRAT_HEADER ROMDATA CratHeaderStruct = +{ + {'C','R','A','T'}, + 0, + 1, + 0, + {0}, + {0}, + 1, + {'A','M','D',' '}, + 1, + 0, + 0, + {0, 0, 0, 0, 0, 0} +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function will generate a complete Component Resource Affinity Table + * i.e. CRAT into a memory buffer. After completion, this table must be set + * by the system BIOS into its internal ACPI name space. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[out] CratPtr Point to Crat Struct including buffer address and length + * + * @retval AGESA_STATUS + */ + +AGESA_STATUS +CreateAcpiCrat ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **CratPtr + ) +{ + AGESA_TESTPOINT (TpProcCpuEntryCrat, StdHeader); + return ((*(OptionCratConfiguration.CratFeature)) (StdHeader, CratPtr)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This is the default routine for use when the CRAT option is NOT requested. + * + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[out] CratPtr Point to Crat Struct including buffer address and length + * + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GetAcpiCratStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **CratPtr + ) +{ + return AGESA_UNSUPPORTED; +} +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function will generate a complete Component Resource Affinity Table + * i.e. CRAT into a memory buffer. After completion, this table must be set + * by the system BIOS into its internal ACPI name space. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[out] CratPtr Point to Crat Struct including buffer address and length + * + * @retval AGESA_STATUS + */ +AGESA_STATUS +GetAcpiCratMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **CratPtr + ) +{ + UINT8 i; + UINT8 *TableEnd; + CRAT_HEADER *CratHeaderStructPtr; + ALLOCATE_HEAP_PARAMS AllocParams; + + // Allocate a buffer + AllocParams.RequestedBufferSize = CRAT_MAX_LENGTH; + AllocParams.BufferHandle = AMD_CRAT_INFO_BUFFER_HANDLE; + AllocParams.Persist = HEAP_SYSTEM_MEM; + + if (HeapAllocateBuffer (&AllocParams, StdHeader) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + *CratPtr = AllocParams.BufferPtr; + + + CratHeaderStructPtr = (CRAT_HEADER *) *CratPtr; + TableEnd = (UINT8 *) *CratPtr; + + // Copy CratHeaderStruct -> data buffer + LibAmdMemCopy ((VOID *) CratHeaderStructPtr, (VOID *) &CratHeaderStruct, (UINTN) (sizeof (CRAT_HEADER)), StdHeader); + // Update table OEM fields. + LibAmdMemCopy ((VOID *) &CratHeaderStructPtr->OemId, (VOID *) &OptionCratConfiguration.OemIdString, + sizeof (OptionCratConfiguration.OemIdString), StdHeader); + LibAmdMemCopy ((VOID *) &CratHeaderStructPtr->OemTableId, (VOID *) &OptionCratConfiguration.OemTableIdString, + sizeof (OptionCratConfiguration.OemTableIdString), StdHeader); + + TableEnd += sizeof (CRAT_HEADER); + + // Make all CRAT entries. + for (i = 0; MakeCratEntryTable[i].MakeCratEntry != NULL; i++) { + MakeCratEntryTable[i].MakeCratEntry (CratHeaderStructPtr, &TableEnd, StdHeader); + + } + + // Store size in table (current buffer offset - buffer start offset) + CratHeaderStructPtr->Length = (UINT32) (TableEnd - (UINT8 *) CratHeaderStructPtr); + + //Update SSDT header Checksum + ChecksumAcpiTable ((ACPI_TABLE_HEADER *) CratHeaderStructPtr, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " CRAT is created\n"); + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will add HSA Processing Unit entry. + * + * @param[in] CratHeaderStructPtr CRAT header pointer + * @param[in, out] TableEnd The end of CRAT + * @param[in, out] StdHeader Standard Head Pointer + * + */ +VOID +MakeHSAProcUnitEntry ( + IN CRAT_HEADER *CratHeaderStructPtr, + IN OUT UINT8 **TableEnd, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NodeNum; + UINT8 NodeCount; + UINT32 Socket; + UINT32 Module; + UINT32 LowCore; + UINT32 HighCore; + UINT32 RegVal; + CRAT_HSA_PROCESSING_UNIT *EntryPtr; + AMD_APIC_PARAMS ApicParams; + PCI_ADDR PciAddress; + + // Get Node count + PciAddress.AddressValue = MAKE_SBDFO (0, 0, LOW_NODE_DEVICEID, FUNC_0, 0x60); + LibAmdPciRead (AccessWidth32 , PciAddress, &RegVal, StdHeader); + NodeCount = (UINT8) (((RegVal >> 4) & 0x7) + 1); + + NodeNum = 0; + ApicParams.StdHeader = *StdHeader; + while (NodeNum < NodeCount) { + GetSocketModuleOfNode ((UINT32) NodeNum, &Socket, &Module, StdHeader); + GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader); + ApicParams.Socket = (UINT8) Socket; + ApicParams.Core = 0; + AmdGetApicId (&ApicParams); + if (ApicParams.IsPresent) { + // Adding one CRAT entry for every node + EntryPtr = (CRAT_HSA_PROCESSING_UNIT *) AddOneCratEntry (CRAT_TYPE_HSA_PROC_UNIT, CratHeaderStructPtr, TableEnd, StdHeader); + + EntryPtr->ProximityDomain = NodeNum; + EntryPtr->ProcessorIdLow = ApicParams.ApicAddress; + EntryPtr->NumCPUCores = (UINT16) (HighCore - LowCore + 1); + EntryPtr->Flags.Enabled = 1; + EntryPtr->Flags.CpuPresent = 1; + } + /// @todo SimdCount SimdWidth IoCount + CratHeaderStructPtr->NumDomains++; + NodeNum++; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will add memory entry. + * + * @param[in] CratHeaderStructPtr CRAT header pointer + * @param[in, out] TableEnd The end of CRAT + * @param[in, out] StdHeader Standard Head Pointer + * + */ +VOID +MakeMemoryEntry ( + IN CRAT_HEADER *CratHeaderStructPtr, + IN OUT UINT8 **TableEnd, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 EntryNum; + UINT8 NumOfMemAffinityInfoEntries; + UINT32 Width; + AGESA_STATUS AgesaStatus; + CRAT_MEMORY *EntryPtr; + LOCATE_HEAP_PTR LocateHeapParams; + CRAT_MEMORY_AFFINITY_INFO_HEADER *MemAffinityInfoHeaderPtr; + CRAT_MEMORY_AFFINITY_INFO_ENTRY *MemAffinityInfoEntryPtr; + + EntryNum = 0; + + // Get the CRAT memory affinity info from heap + LocateHeapParams.BufferHandle = AMD_MEM_CRAT_INFO_BUFFER_HANDLE; + AgesaStatus = HeapLocateBuffer (&LocateHeapParams, StdHeader); + if (AgesaStatus != AGESA_SUCCESS) { + ASSERT (FALSE); + } else { + MemAffinityInfoHeaderPtr = (CRAT_MEMORY_AFFINITY_INFO_HEADER *) (LocateHeapParams.BufferPtr); + MemAffinityInfoHeaderPtr ++; + MemAffinityInfoEntryPtr = (CRAT_MEMORY_AFFINITY_INFO_ENTRY *) MemAffinityInfoHeaderPtr; + MemAffinityInfoHeaderPtr --; + + // Get the number of CRAT memory affinity entries + NumOfMemAffinityInfoEntries = MemAffinityInfoHeaderPtr->NumOfMemAffinityInfoEntries; + Width = MemAffinityInfoHeaderPtr->MemoryWidth; + + // Create CRAT memory affinity entries + IDS_HDT_CONSOLE (MAIN_FLOW, " CRAT memory affinity entries\n"); + while (EntryNum < NumOfMemAffinityInfoEntries) { + // Add one CRAT memory entry + EntryPtr = (CRAT_MEMORY *) AddOneCratEntry (CRAT_TYPE_MEMORY, CratHeaderStructPtr, TableEnd, StdHeader); + EntryPtr->Flags.Enabled = 1; + EntryPtr->ProximityDomain = MemAffinityInfoEntryPtr->Domain; + EntryPtr->BaseAddressLow = MemAffinityInfoEntryPtr->BaseAddressLow; + EntryPtr->BaseAddressHigh = MemAffinityInfoEntryPtr->BaseAddressHigh; + EntryPtr->LengthLow = MemAffinityInfoEntryPtr->LengthLow; + EntryPtr->LengthHigh = MemAffinityInfoEntryPtr->LengthHigh; + EntryPtr->Width = Width; + IDS_HDT_CONSOLE (MAIN_FLOW, " Entry #%d\n", EntryNum); + IDS_HDT_CONSOLE (MAIN_FLOW, " Type: 0x%08x\n", EntryPtr->Type); + IDS_HDT_CONSOLE (MAIN_FLOW, " Length: 0x%08x\n", EntryPtr->Length); + IDS_HDT_CONSOLE (MAIN_FLOW, " Flags: %s %s %s\n", (EntryPtr->Flags.Enabled == 1) ? "Enabled" : "", + (EntryPtr->Flags.HotPluggable == 1) ? "EnHotPluggableabled" : "", + (EntryPtr->Flags.NonVolatile == 1) ? "NonVolatile" : "" + ); + IDS_HDT_CONSOLE (MAIN_FLOW, " Proximity Domain: 0x%08x\n", EntryPtr->ProximityDomain); + IDS_HDT_CONSOLE (MAIN_FLOW, " Base Address Low: 0x%08x\n", EntryPtr->BaseAddressLow); + IDS_HDT_CONSOLE (MAIN_FLOW, " Base Address High: 0x%08x\n", EntryPtr->BaseAddressHigh); + IDS_HDT_CONSOLE (MAIN_FLOW, " Length Low: 0x%08x\n", EntryPtr->LengthLow); + IDS_HDT_CONSOLE (MAIN_FLOW, " Length High: 0x%08x\n", EntryPtr->LengthHigh); + IDS_HDT_CONSOLE (MAIN_FLOW, " Width: 0x%08x\n", EntryPtr->Width); + MemAffinityInfoEntryPtr ++; + EntryNum ++; + } + HeapDeallocateBuffer ((UINT32) AMD_MEM_CRAT_INFO_BUFFER_HANDLE, StdHeader); + } + + return; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will add cache entry. + * + * @param[in] CratHeaderStructPtr CRAT header pointer + * @param[in, out] TableEnd The end of CRAT + * @param[in, out] StdHeader Standard Head Pointer + * + */ +VOID +MakeCacheEntry ( + IN CRAT_HEADER *CratHeaderStructPtr, + IN OUT UINT8 **TableEnd, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CRAT_FAMILY_SERVICES *CratFamilyServices; + + GetFeatureServicesOfSocket (&CratFamilyServiceTable, 0, (CONST VOID **)&CratFamilyServices, StdHeader); + CratFamilyServices->generateCratCacheEntry (CratHeaderStructPtr, TableEnd, StdHeader); + return; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will add TLB entry. + * + * @param[in] CratHeaderStructPtr CRAT header pointer + * @param[in, out] TableEnd The end of CRAT + * @param[in, out] StdHeader Standard Head Pointer + * + */ +VOID +MakeTLBEntry ( + IN CRAT_HEADER *CratHeaderStructPtr, + IN OUT UINT8 **TableEnd, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CRAT_FAMILY_SERVICES *CratFamilyServices; + + GetFeatureServicesOfSocket (&CratFamilyServiceTable, 0, (CONST VOID **)&CratFamilyServices, StdHeader); + CratFamilyServices->generateCratTLBEntry (CratHeaderStructPtr, TableEnd, StdHeader); + return; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will add CRAT entry. + * + * @param[in] CratEntryType CRAT entry type + * @param[in] CratHeaderStructPtr CRAT header pointer + * @param[in, out] TableEnd The end of CRAT + * @param[in, out] StdHeader Standard Head Pointer + * + */ +UINT8 * +AddOneCratEntry ( + IN CRAT_ENTRY_TYPE CratEntryType, + IN CRAT_HEADER *CratHeaderStructPtr, + IN OUT UINT8 **TableEnd, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *CurrentEntry; + + CurrentEntry = *TableEnd; + CratHeaderStructPtr->TotalEntries++; + switch (CratEntryType) { + case CRAT_TYPE_HSA_PROC_UNIT: + *TableEnd += sizeof (CRAT_HSA_PROCESSING_UNIT); + ASSERT ((*TableEnd - (UINT8 *) CratHeaderStructPtr) <= CRAT_MAX_LENGTH); + CratHeaderStructPtr->Length += sizeof (CRAT_HSA_PROCESSING_UNIT); + ((CRAT_HSA_PROCESSING_UNIT *) CurrentEntry)->Type = (UINT8) CratEntryType; + ((CRAT_HSA_PROCESSING_UNIT *) CurrentEntry)->Length = sizeof (CRAT_HSA_PROCESSING_UNIT); + break; + case CRAT_TYPE_MEMORY: + *TableEnd += sizeof (CRAT_MEMORY); + ASSERT ((*TableEnd - (UINT8 *) CratHeaderStructPtr) <= CRAT_MAX_LENGTH); + CratHeaderStructPtr->Length += sizeof (CRAT_MEMORY); + ((CRAT_MEMORY *) CurrentEntry)->Type = (UINT8) CratEntryType; + ((CRAT_MEMORY *) CurrentEntry)->Length = sizeof (CRAT_MEMORY); + break; + case CRAT_TYPE_CACHE: + *TableEnd += sizeof (CRAT_CACHE); + ASSERT ((*TableEnd - (UINT8 *) CratHeaderStructPtr) <= CRAT_MAX_LENGTH); + CratHeaderStructPtr->Length += sizeof (CRAT_CACHE); + ((CRAT_CACHE *) CurrentEntry)->Type = (UINT8) CratEntryType; + ((CRAT_CACHE *) CurrentEntry)->Length = sizeof (CRAT_CACHE); + break; + case CRAT_TYPE_TLB: + *TableEnd += sizeof (CRAT_TLB); + ASSERT ((*TableEnd - (UINT8 *) CratHeaderStructPtr) <= CRAT_MAX_LENGTH); + CratHeaderStructPtr->Length += sizeof (CRAT_TLB); + ((CRAT_TLB *) CurrentEntry)->Type = (UINT8) CratEntryType; + ((CRAT_TLB *) CurrentEntry)->Length = sizeof (CRAT_TLB); + break; + case CRAT_TYPE_FPU: + *TableEnd += sizeof (CRAT_FPU); + ASSERT ((*TableEnd - (UINT8 *) CratHeaderStructPtr) <= CRAT_MAX_LENGTH); + CratHeaderStructPtr->Length += sizeof (CRAT_FPU); + ((CRAT_FPU *) CurrentEntry)->Type = (UINT8) CratEntryType; + ((CRAT_FPU *) CurrentEntry)->Length = sizeof (CRAT_FPU); + break; + case CRAT_TYPE_IO: + *TableEnd += sizeof (CRAT_IO); + ASSERT ((*TableEnd - (UINT8 *) CratHeaderStructPtr) <= CRAT_MAX_LENGTH); + CratHeaderStructPtr->Length += sizeof (CRAT_IO); + ((CRAT_IO *) CurrentEntry)->Type = (UINT8) CratEntryType; + ((CRAT_IO *) CurrentEntry)->Length = sizeof (CRAT_IO); + break; + default: + ASSERT (FALSE); + break; + } + return CurrentEntry; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.h new file mode 100644 index 0000000000..6b2b9d611a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuCrat.h @@ -0,0 +1,85 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU CRAT + * + * Contains code that declares the AGESA CRAT related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_CRAT_H_ +#define _CPU_CRAT_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/** + * Make CRAT entry + * + * @param[in] CratHeaderStructPtr CRAT header pointer + * @param[in, out] TableEnd The end of CRAT + * @param[in, out] StdHeader Standard Head Pointer + * + */ +typedef VOID F_MAKE_CRAT_ENTRY ( + IN CRAT_HEADER *CratHeaderStructPtr, + IN OUT UINT8 **TableEnd, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a Method. +typedef F_MAKE_CRAT_ENTRY *PF_MAKE_CRAT_ENTRY; + +/** + * A struct that contains function pointe + */ +typedef struct _S_MAKE_CRAT_ENTRY { + PF_MAKE_CRAT_ENTRY MakeCratEntry; ///< Function Pointer, which points to the function which makes CRAT entry. +} S_MAKE_CRAT_ENTRY; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_CRAT_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuDmi.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuDmi.c new file mode 100644 index 0000000000..6ff30d2faf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuDmi.c @@ -0,0 +1,872 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD DMI Record Creation API, and related functions. + * + * Contains code that produce the DMI related information. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "OptionDmi.h" +#include "cpuLateInit.h" +#include "cpuServices.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "heapManager.h" +#include "Ids.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FEATURE_CPUDMI_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_DMI_CONFIGURATION OptionDmiConfiguration; // global user config record + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +CHAR8 ROMDATA str_ProcManufacturer[] = "Advanced Micro Devices, Inc."; +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +UINT16 +STATIC +AdjustGranularity ( + IN UINT32 *CacheSizePtr + ); + +VOID +STATIC +IntToString ( + IN OUT CHAR8 *String, + IN UINT8 *Integer, + IN UINT8 SizeInByte +); + +AGESA_STATUS +GetDmiInfoStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ); + +AGESA_STATUS +GetDmiInfoMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ); + +AGESA_STATUS +ReleaseDmiBufferStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +ReleaseDmiBuffer ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * CreateDmiRecords + * + * Description: + * This function creates DMI/SMBios records pertinent to the processor + * SMBIOS type 4, type 7, and type 40. + * + * Parameters: + * @param[in, out] *StdHeader + * @param[in, out] **DmiTable + * + * @retval AGESA_STATUS + * + */ + +AGESA_STATUS +CreateDmiRecords ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ) +{ + AGESA_TESTPOINT (TpProcCpuEntryDmi, StdHeader); + return ((*(OptionDmiConfiguration.DmiFeature)) (StdHeader, DmiTable)); +} + +/* -----------------------------------------------------------------------------*/ +/** + * GetDmiInfoStub + * + * Description: + * This is the default routine for use when the DMI option is NOT requested. + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * Parameters: + * @param[in, out] *StdHeader + * @param[in, out] **DmiTable + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +GetDmiInfoStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ) +{ + return AGESA_UNSUPPORTED; +} + +/* -----------------------------------------------------------------------------*/ +/** + * GetDmiInfoMain + * + * Description: + * This is the common routine for getting Dmi type4 and type7 CPU related information. + * + * Parameters: + * @param[in, out] *StdHeader + * @param[in, out] **DmiTable + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +GetDmiInfoMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ) +{ + UINT8 Socket; + UINT8 Channel; + UINT8 Dimm; + UINT16 Index; + UINT16 DimmIndex; + UINT8 MaxPhysicalDimms; + UINT8 MaxLogicalDimms; + UINT32 MaxCapacity; + UINT64 MsrData; + UINT64 Value64; + UINT8 TypeDetail; + UINT32 *TotalMemSizePtr; + BOOLEAN FamilyNotFound; + AGESA_STATUS Flag; + AGESA_STATUS CalledStatus; + AP_EXE_PARAMS ApParams; + UINT8 *MemInfo; + DMI_T17_MEMORY_TYPE *DmiType17MemTypePtr; + DMI_T17_MEMORY_TYPE MemType; + MEM_DMI_PHYSICAL_DIMM_INFO *DmiPhysicalDimmInfoTable; + MEM_DMI_LOGICAL_DIMM_INFO *DmiLogicalDimmInfoTable; + DMI_INFO *DmiBufferPtr; + ALLOCATE_HEAP_PARAMS AllocateHeapParams; + LOCATE_HEAP_PTR LocateHeapParams; + CPU_LOGICAL_ID LogicalId; + PROC_FAMILY_TABLE *ProcData; + CPU_GET_MEM_INFO CpuGetMemInfo; + + MsrData = 0; + Flag = TRUE; + ProcData = NULL; + MemInfo = NULL; + DmiBufferPtr = *DmiTable; + FamilyNotFound = TRUE; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + for (Index = 0; Index < OptionDmiConfiguration.NumEntries; Index++) { + ProcData = (PROC_FAMILY_TABLE *) ((*OptionDmiConfiguration.FamilyList)[Index]); + if ((ProcData->ProcessorFamily & LogicalId.Family) != 0) { + FamilyNotFound = FALSE; + break; + } + } + + if (FamilyNotFound) { + return AGESA_ERROR; + } + + if (DmiBufferPtr == NULL) { + // + // Allocate a buffer by heap function + // + AllocateHeapParams.BufferHandle = AMD_DMI_INFO_BUFFER_HANDLE; + AllocateHeapParams.RequestedBufferSize = sizeof (DMI_INFO); + AllocateHeapParams.Persist = HEAP_SYSTEM_MEM; + + if (HeapAllocateBuffer (&AllocateHeapParams, StdHeader) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + + DmiBufferPtr = (DMI_INFO *) AllocateHeapParams.BufferPtr; + *DmiTable = DmiBufferPtr; + } + + IDS_HDT_CONSOLE (CPU_TRACE, " DMI is enabled\n"); + + // Fill with 0x00 + LibAmdMemFill (DmiBufferPtr, 0x00, sizeof (DMI_INFO), StdHeader); + + // + // Get CPU information + // + + // Run GetType4Type7Info on all core0s. + ApParams.StdHeader = *StdHeader; + ApParams.FunctionNumber = AP_LATE_TASK_GET_TYPE4_TYPE7; + ApParams.RelatedDataBlock = (VOID *) DmiBufferPtr; + ApParams.RelatedBlockLength = sizeof (DMI_INFO); + CalledStatus = RunLateApTaskOnAllCore0s (&ApParams, StdHeader); + if (CalledStatus > Flag) { + Flag = CalledStatus; + } + CalledStatus = GetType4Type7Info (&ApParams); + if (CalledStatus > Flag) { + Flag = CalledStatus; + } + + //------------------------------ + // T Y P E 16 17 19 20 + //------------------------------ + + LocateHeapParams.BufferHandle = AMD_DMI_MEM_DEV_INFO_HANDLE; + if (HeapLocateBuffer (&LocateHeapParams, StdHeader) != AGESA_SUCCESS) { + if (Flag < AGESA_ERROR) { + Flag = AGESA_ERROR; + } + } else { + MemInfo = (UINT8 *) (LocateHeapParams.BufferPtr); + // Max number of physical DIMMs + MaxPhysicalDimms = *MemInfo; + MemInfo ++; + // Type Detail; + TypeDetail = *MemInfo; + MemInfo ++; + // Pointer to total memory size + TotalMemSizePtr = (UINT32 *) MemInfo; + MemInfo += sizeof (UINT32); + // Memory Type + DmiType17MemTypePtr = (DMI_T17_MEMORY_TYPE *) MemInfo; + MemType = *DmiType17MemTypePtr; + DmiType17MemTypePtr ++; + MemInfo = (UINT8 *) DmiType17MemTypePtr; + // Pointer to DMI info of Physical DIMMs + DmiPhysicalDimmInfoTable = (MEM_DMI_PHYSICAL_DIMM_INFO *) MemInfo; + // TYPE 16 + DmiBufferPtr->T16.Location = 0x03; + DmiBufferPtr->T16.Use = 0x03; + + // Gather memory information + ProcData->DmiGetMemInfo (&CpuGetMemInfo, StdHeader); + + if (CpuGetMemInfo.EccCapable) { + DmiBufferPtr->T16.MemoryErrorCorrection = Dmi16MultiBitEcc; + } else { + DmiBufferPtr->T16.MemoryErrorCorrection = Dmi16NoneErrCorrection; + } + + MaxCapacity = *TotalMemSizePtr; + // For the total size >= 2TB case, we need leave MaximumCapacity (offset 07h) to 80000000h + // and fill the size in bytes into ExtMaxCapacity (offset 0Fh). + if (MaxCapacity < 0x200000) { + DmiBufferPtr->T16.MaximumCapacity = MaxCapacity << 10; + DmiBufferPtr->T16.ExtMaxCapacity = 0; + } else { + DmiBufferPtr->T16.MaximumCapacity = 0x80000000; + DmiBufferPtr->T16.ExtMaxCapacity = (UINT64) MaxCapacity << 20; + } + + DmiBufferPtr->T16.NumberOfMemoryDevices = (UINT16) MaxPhysicalDimms; + + // TYPE 17 entries are organized by physical DIMMs + for (DimmIndex = 0; DimmIndex < MaxPhysicalDimms; DimmIndex ++, DmiPhysicalDimmInfoTable ++) { + Socket = DmiPhysicalDimmInfoTable->Socket; + Channel = DmiPhysicalDimmInfoTable->Channel; + Dimm = DmiPhysicalDimmInfoTable->Dimm; + + DmiBufferPtr->T17[Socket][Channel][Dimm].Handle = DmiPhysicalDimmInfoTable->Handle; + DmiBufferPtr->T17[Socket][Channel][Dimm].TotalWidth = DmiPhysicalDimmInfoTable->TotalWidth; + DmiBufferPtr->T17[Socket][Channel][Dimm].DataWidth = DmiPhysicalDimmInfoTable->DataWidth; + DmiBufferPtr->T17[Socket][Channel][Dimm].MemorySize = DmiPhysicalDimmInfoTable->MemorySize; + DmiBufferPtr->T17[Socket][Channel][Dimm].FormFactor = DmiPhysicalDimmInfoTable->FormFactor; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceSet = 0; + + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[0] = 'D'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[1] = 'I'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[2] = 'M'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[3] = 'M'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[4] = ' '; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[5] = Dimm + 0x30; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[6] = '\0'; + DmiBufferPtr->T17[Socket][Channel][Dimm].DeviceLocator[7] = '\0'; + + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[0] = 'C'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[1] = 'H'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[2] = 'A'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[3] = 'N'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[4] = 'N'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[5] = 'E'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[6] = 'L'; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[7] = ' '; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[8] = Channel + 0x41; + DmiBufferPtr->T17[Socket][Channel][Dimm].BankLocator[9] = '\0'; + + DmiBufferPtr->T17[Socket][Channel][Dimm].MemoryType = MemType; + if (DmiPhysicalDimmInfoTable->MemorySize != 0) { + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Synchronous = 1; + if (TypeDetail == 1) { + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Registered = 1; + } else if (TypeDetail == 2) { + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Unbuffered = 1; + } else { + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Unknown = 1; + } + } + DmiBufferPtr->T17[Socket][Channel][Dimm].Speed = DmiPhysicalDimmInfoTable->Speed; + + DmiBufferPtr->T17[Socket][Channel][Dimm].ManufacturerIdCode = DmiPhysicalDimmInfoTable->ManufacturerIdCode; + + IntToString (DmiBufferPtr->T17[Socket][Channel][Dimm].SerialNumber, DmiPhysicalDimmInfoTable->SerialNumber, (sizeof DmiBufferPtr->T17[Socket][Channel][Dimm].SerialNumber - 1) / 2); + + LibAmdMemCopy (&DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber, &DmiPhysicalDimmInfoTable->PartNumber, sizeof (DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber), StdHeader); + DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber[18] = 0; + + DmiBufferPtr->T17[Socket][Channel][Dimm].Attributes = DmiPhysicalDimmInfoTable->Attributes; + DmiBufferPtr->T17[Socket][Channel][Dimm].ExtSize = DmiPhysicalDimmInfoTable->ExtSize; + DmiBufferPtr->T17[Socket][Channel][Dimm].ConfigSpeed = DmiPhysicalDimmInfoTable->ConfigSpeed; + } + + // Max number of logical DIMMs + MemInfo = (UINT8 *) DmiPhysicalDimmInfoTable; + MaxLogicalDimms = *MemInfo; + MemInfo ++; + + // Pointer to DMI info of Logical DIMMs + DmiLogicalDimmInfoTable = (MEM_DMI_LOGICAL_DIMM_INFO *) MemInfo; + + // TYPE 20 entries are organized by logical DIMMs + for (DimmIndex = 0; DimmIndex < MaxLogicalDimms; DimmIndex ++, DmiLogicalDimmInfoTable ++) { + Socket = DmiLogicalDimmInfoTable->Socket; + Channel = DmiLogicalDimmInfoTable->Channel; + Dimm = DmiLogicalDimmInfoTable->Dimm; + DmiBufferPtr->T20[Socket][Channel][Dimm].PartitionRowPosition = 0xFF; + DmiBufferPtr->T20[Socket][Channel][Dimm].InterleavePosition = 0xFF; + DmiBufferPtr->T20[Socket][Channel][Dimm].InterleavedDataDepth = 0xFF; + + if (DmiLogicalDimmInfoTable->DimmPresent) { + DmiBufferPtr->T20[Socket][Channel][Dimm].MemoryDeviceHandle = DmiLogicalDimmInfoTable->MemoryDeviceHandle; + DmiBufferPtr->T20[Socket][Channel][Dimm].StartingAddr = DmiLogicalDimmInfoTable->StartingAddr; + DmiBufferPtr->T20[Socket][Channel][Dimm].EndingAddr = DmiLogicalDimmInfoTable->EndingAddr; + DmiBufferPtr->T20[Socket][Channel][Dimm].ExtStartingAddr = DmiLogicalDimmInfoTable->ExtStartingAddr; + DmiBufferPtr->T20[Socket][Channel][Dimm].ExtEndingAddr = DmiLogicalDimmInfoTable->ExtEndingAddr; + } + } + + // TYPE 19 + DmiBufferPtr->T19.StartingAddr = 0; + DmiBufferPtr->T19.ExtStartingAddr = 0; + DmiBufferPtr->T19.ExtEndingAddr = 0; + + // If Ending Address >= 0xFFFFFFFF, update Starting Address (offset 04h) & Ending Address (offset 08h) to 0xFFFFFFFF, + // and use the Extended Starting Address (offset 0Fh) & Extended Ending Address (offset 17h) instead. + Value64 = (UINT64) ((MaxCapacity << 10) - 1); + // Value64 = EndingAddr = MaxCapacity in KByte - 1 + if (Value64 >= ((UINT64) 0xFFFFFFFF)) { + DmiBufferPtr->T19.StartingAddr = 0xFFFFFFFFUL; + DmiBufferPtr->T19.EndingAddr = 0xFFFFFFFFUL; + // In Byte + DmiBufferPtr->T19.ExtEndingAddr = Value64 << 10; + } else { + // In KByte + DmiBufferPtr->T19.EndingAddr = (UINT32) Value64; + } + + DmiBufferPtr->T19.PartitionWidth = 0xFF; + } + return (Flag); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * GetType4Type7Info + * + * Description: + * This routine should be run on core 0 of every socket. It creates DMI type 4 and type 7 tables. + * + * Parameters: + * @param[in] ApExeParams Handle to config for library and services. + * + * @retval AGESA_STATUS + * + * Processing: + * + */ +AGESA_STATUS +GetType4Type7Info ( + IN AP_EXE_PARAMS *ApExeParams + ) +{ + UINT8 ByteIndexInUint64; + UINT16 Index; + UINT32 SocketNum; + UINT32 IgnoredModule; + UINT32 IgnoredCore; + UINT64 MsrData; + DMI_INFO *DmiBufferPtr; + AGESA_STATUS IgnoredSts; + AGESA_STATUS Flag; + BOOLEAN FamilyNotFound; + CPUID_DATA CpuId; + CPU_TYPE_INFO CpuInfo; + PROC_FAMILY_TABLE *ProcData; + CPU_LOGICAL_ID LogicalID; + + Flag = TRUE; + DmiBufferPtr = (DMI_INFO *) ApExeParams->RelatedDataBlock; + GetLogicalIdOfCurrentCore (&LogicalID, &ApExeParams->StdHeader); + + ProcData = NULL; + FamilyNotFound = TRUE; + for (Index = 0; Index < OptionDmiConfiguration.NumEntries; Index++) { + ProcData = (PROC_FAMILY_TABLE *) ((*OptionDmiConfiguration.FamilyList)[Index]); + if ((ProcData->ProcessorFamily & LogicalID.Family) != 0) { + FamilyNotFound = FALSE; + break; + } + } + + if (FamilyNotFound) { + return AGESA_ERROR; + } + + ProcData->DmiGetCpuInfo (&CpuInfo, &ApExeParams->StdHeader); + + // ------------------------------ + // T Y P E 4 + // ------------------------------ + + IdentifyCore (&ApExeParams->StdHeader, &SocketNum, &IgnoredModule, &IgnoredCore, &IgnoredSts); + + // Type 4 Offset 0x05, Processor Type + DmiBufferPtr->T4[SocketNum].T4ProcType = CENTRAL_PROCESSOR; + + // Type 4 Offset 0x06, Processor Family + ProcData->DmiGetT4ProcFamily (&DmiBufferPtr->T4[SocketNum].T4ProcFamily, ProcData, &CpuInfo, &ApExeParams->StdHeader); + + if (DmiBufferPtr->T4[SocketNum].T4ProcFamily == P_UPGRADE_UNKNOWN) { + Flag = AGESA_ERROR; + } + + // Type4 Offset 0x08, Processor ID + LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuId, &ApExeParams->StdHeader); + DmiBufferPtr->T4[SocketNum].T4ProcId.ProcIdLsd = CpuId.EAX_Reg; + DmiBufferPtr->T4[SocketNum].T4ProcId.ProcIdMsd = CpuId.EDX_Reg; + + // Type4 Offset 0x11, Voltage + DmiBufferPtr->T4[SocketNum].T4Voltage = ProcData->DmiGetVoltage (&ApExeParams->StdHeader); + + // Type4 Offset 0x12, External Clock + DmiBufferPtr->T4[SocketNum].T4ExternalClock = ProcData->DmiGetExtClock (&ApExeParams->StdHeader); + + // Type4 Offset 0x14, Max Speed + DmiBufferPtr->T4[SocketNum].T4MaxSpeed = ProcData->DmiGetMaxSpeed (&ApExeParams->StdHeader); + + // Type4 Offset 0x16, Current Speed + DmiBufferPtr->T4[SocketNum].T4CurrentSpeed = DmiBufferPtr->T4[SocketNum].T4MaxSpeed; + + // Type4 Offset 0x18, Status + DmiBufferPtr->T4[SocketNum].T4Status = SOCKET_POPULATED | CPU_STATUS_ENABLED; + + // Type4 Offset 0x19, Processor Upgrade + DmiBufferPtr->T4[SocketNum].T4ProcUpgrade = CpuInfo.ProcUpgrade; + + // Type4 Offset 0x23, 0x24 and 0x25, Core Count, Core Enabled and Thread Count + DmiBufferPtr->T4[SocketNum].T4CoreCount = CpuInfo.TotalCoreNumber + 1; + DmiBufferPtr->T4[SocketNum].T4CoreEnabled = CpuInfo.EnabledCoreNumber + 1; + DmiBufferPtr->T4[SocketNum].T4ThreadCount = CpuInfo.EnabledCoreNumber + 1; + + // Type4 Offset 0x26, Processor Characteristics + DmiBufferPtr->T4[SocketNum].T4ProcCharacteristics = P_CHARACTERISTICS; + + // Type4 Offset 0x28, Processor Family 2 + DmiBufferPtr->T4[SocketNum].T4ProcFamily2 = DmiBufferPtr->T4[SocketNum].T4ProcFamily; + + // Type4 ProcVersion + for (Index = 0; Index <= 5; Index++) { + LibAmdMsrRead ((MSR_CPUID_NAME_STRING0 + Index), &MsrData, &ApExeParams->StdHeader); + for (ByteIndexInUint64 = 0; ByteIndexInUint64 <= 7; ByteIndexInUint64++) { + DmiBufferPtr->T4[SocketNum].T4ProcVersion[Index * 8 + ByteIndexInUint64] = (UINT8) (MsrData >> (8 * ByteIndexInUint64)); + } + } + + // Type4 Manufacturer + ASSERT (PROC_MANU_LENGTH >= sizeof (str_ProcManufacturer)); + LibAmdMemCopy (DmiBufferPtr->T4[SocketNum].T4ProcManufacturer, str_ProcManufacturer, sizeof (str_ProcManufacturer), &ApExeParams->StdHeader); + + //------------------------------ + // T Y P E 7 + //------------------------------ + + // Type7 Offset 0x05, Cache Configuration + DmiBufferPtr->T7L1[SocketNum].T7CacheCfg = CACHE_CFG_L1; + DmiBufferPtr->T7L2[SocketNum].T7CacheCfg = CACHE_CFG_L2; + DmiBufferPtr->T7L3[SocketNum].T7CacheCfg = CACHE_CFG_L3; + + // Type7 Offset 0x07 and 09, Maximum Cache Size and Installed Size + + // Maximum L1 cache size + DmiBufferPtr->T7L1[SocketNum].T7MaxCacheSize = AdjustGranularity (&CpuInfo.CacheInfo.L1CacheSize); + + // Installed L1 cache size + DmiBufferPtr->T7L1[SocketNum].T7InstallSize = DmiBufferPtr->T7L1[SocketNum].T7MaxCacheSize; + + // Maximum L2 cache size + DmiBufferPtr->T7L2[SocketNum].T7MaxCacheSize = AdjustGranularity (&CpuInfo.CacheInfo.L2CacheSize); + + // Installed L2 cache size + DmiBufferPtr->T7L2[SocketNum].T7InstallSize = DmiBufferPtr->T7L2[SocketNum].T7MaxCacheSize; + + // Maximum L3 cache size + DmiBufferPtr->T7L3[SocketNum].T7MaxCacheSize = AdjustGranularity (&CpuInfo.CacheInfo.L3CacheSize); + + // Installed L3 cache size + DmiBufferPtr->T7L3[SocketNum].T7InstallSize = DmiBufferPtr->T7L3[SocketNum].T7MaxCacheSize; + + // Type7 Offset 0x0B and 0D, Supported SRAM Type and Current SRAM Type + DmiBufferPtr->T7L1[SocketNum].T7SupportedSramType = SRAM_TYPE; + DmiBufferPtr->T7L1[SocketNum].T7CurrentSramType = SRAM_TYPE; + DmiBufferPtr->T7L2[SocketNum].T7SupportedSramType = SRAM_TYPE; + DmiBufferPtr->T7L2[SocketNum].T7CurrentSramType = SRAM_TYPE; + DmiBufferPtr->T7L3[SocketNum].T7SupportedSramType = SRAM_TYPE; + DmiBufferPtr->T7L3[SocketNum].T7CurrentSramType = SRAM_TYPE; + + // Type7 Offset 0x0F, Cache Speed + DmiBufferPtr->T7L1[SocketNum].T7CacheSpeed = 1; + DmiBufferPtr->T7L2[SocketNum].T7CacheSpeed = 1; + DmiBufferPtr->T7L3[SocketNum].T7CacheSpeed = 1; + + // Type7 Offset 0x10, Error Correction Type + DmiBufferPtr->T7L1[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE; + DmiBufferPtr->T7L2[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE; + DmiBufferPtr->T7L3[SocketNum].T7ErrorCorrectionType = ERR_CORRECT_TYPE; + + // Type7 Offset 0x11, System Cache Type + DmiBufferPtr->T7L1[SocketNum].T7SystemCacheType = CACHE_TYPE; + DmiBufferPtr->T7L2[SocketNum].T7SystemCacheType = CACHE_TYPE; + DmiBufferPtr->T7L3[SocketNum].T7SystemCacheType = CACHE_TYPE; + + // Type7 Offset 0x12, Associativity + DmiBufferPtr->T7L1[SocketNum].T7Associativity = CpuInfo.CacheInfo.L1CacheAssoc; + DmiBufferPtr->T7L2[SocketNum].T7Associativity = CpuInfo.CacheInfo.L2CacheAssoc; + DmiBufferPtr->T7L3[SocketNum].T7Associativity = CpuInfo.CacheInfo.L3CacheAssoc; + + return (Flag); +} + +/* -----------------------------------------------------------------------------*/ +/** + * DmiGetT4ProcFamilyFromBrandId + * + * Description: + * This is the common routine for getting Type 4 processor family information from brand ID + * + * Parameters: + * @param[in, out] *T4ProcFamily Pointer to type 4 processor family information + * @param[in] *CpuDmiProcFamilyTable Pointer to DMI family special service + * @param[in] *CpuInfo Pointer to CPU_TYPE_INFO struct + * @param[in, out] *StdHeader Standard Head Pointer + * + * @retval AGESA_STATUS + * + */ +VOID +DmiGetT4ProcFamilyFromBrandId ( + IN OUT UINT8 *T4ProcFamily, + IN PROC_FAMILY_TABLE *CpuDmiProcFamilyTable, + IN CPU_TYPE_INFO *CpuInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 Index; + *T4ProcFamily = P_UPGRADE_UNKNOWN; + if (CpuInfo->BrandId.Model != P_ENGINEERING_SAMPLE) { + for (Index = 0; Index < CpuDmiProcFamilyTable->LenBrandList; Index++) { + if ((CpuDmiProcFamilyTable->DmiBrandList[Index].PackageType == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].PackageType == CpuInfo->PackageType) && + (CpuDmiProcFamilyTable->DmiBrandList[Index].PgOfBrandId == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].PgOfBrandId == CpuInfo->BrandId.Pg) && + (CpuDmiProcFamilyTable->DmiBrandList[Index].NumberOfCores == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].NumberOfCores == CpuInfo->TotalCoreNumber) && + (CpuDmiProcFamilyTable->DmiBrandList[Index].String1ofBrandId == 'x' || CpuDmiProcFamilyTable->DmiBrandList[Index].String1ofBrandId == CpuInfo->BrandId.String1)) { + *T4ProcFamily = CpuDmiProcFamilyTable->DmiBrandList[Index].ValueSetToDmiTable; + break; + } + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * GetNameString + * + * Description: + * Get name string from MSR_C001_00[35:30] + * + * Parameters: + * @param[in, out] *String Pointer to name string + * @param[in, out] *StdHeader + * + */ +VOID +GetNameString ( + IN OUT CHAR8 *String, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 StringIndex; + UINT8 MsrIndex; + UINT64 MsrData; + + StringIndex = 0; + for (MsrIndex = 0; MsrIndex <= 5; MsrIndex++) { + LibAmdMsrRead ((MSR_CPUID_NAME_STRING0 + MsrIndex), &MsrData, StdHeader); + for (i = 0; i < 8; i++) { + String[StringIndex] = (CHAR8) (MsrData >> (8 * i)); + StringIndex++; + } + } + String[StringIndex] = '\0'; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * IsSourceStrContainTargetStr + * + * Description: + * check if source string contains target string. + * + * Parameters: + * @param[in, out] *SourceStr Pointer to source CHAR array + * @param[in, out] *TargetStr Pointer to target CHAR array + * @param[in, out] *StdHeader + * + * @retval TRUE Target string is contained in the source string + * @retval FALSE Target string is not contained in the source string + */ +BOOLEAN +IsSourceStrContainTargetStr ( + IN OUT CHAR8 *SourceStr, + IN OUT CONST CHAR8 *TargetStr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN IsContained; + UINT32 SourceStrIndex; + UINT32 TargetStrIndex; + CHAR8 TargetChar; + + IsContained = FALSE; + if ((TargetStr != NULL) && (SourceStr != NULL)) { + for (SourceStrIndex = 0; SourceStr[SourceStrIndex] != '\0'; SourceStrIndex++) { + // Compare TrgString with SrcString from frist charactor to the '\0' + for (TargetStrIndex = 0; TargetStr[TargetStrIndex] != '\0'; TargetStrIndex++) { + if (TargetStr[TargetStrIndex] != SourceStr[SourceStrIndex + TargetStrIndex]) { + // if it's not match, try to check the upcase/lowcase + TargetChar = 0; + if (TargetStr[TargetStrIndex] >= 'a' && TargetStr[TargetStrIndex] <= 'z') { + TargetChar = TargetStr[TargetStrIndex] - ('a' - 'A'); + } else if (TargetStr[TargetStrIndex] >= 'A' && TargetStr[TargetStrIndex] <= 'Z') { + TargetChar = TargetStr[TargetStrIndex] + ('a' - 'A'); + } + // compare again + if (TargetChar != SourceStr[SourceStrIndex + TargetStrIndex]) { + break; + } + } + } + + if ((TargetStr[TargetStrIndex] == '\0') && (TargetStrIndex != 0)) { + IsContained = TRUE; + break; + } + } + } + return IsContained; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * AdjustGranularity + * + * Description: + * If cache size is greater than or equal to 32M, then set granularity + * to 64K. otherwise, set granularity to 1K + * + * Parameters: + * @param[in] *CacheSizePtr + * + * @retval CacheSize + * + * Processing: + * + */ +UINT16 +STATIC +AdjustGranularity ( + IN UINT32 *CacheSizePtr + ) +{ + UINT16 CacheSize; + + if (*CacheSizePtr >= 0x8000) { + CacheSize = (UINT16) (*CacheSizePtr / 64); + CacheSize |= 0x8000; + } else { + CacheSize = (UINT16) *CacheSizePtr; + } + + return (CacheSize); +} + +/* -----------------------------------------------------------------------------*/ +/** + * ReleaseDmiBufferStub + * + * Description: + * This is the default routine for use when the DMI option is NOT requested. + * + * Parameters: + * @param[in, out] *StdHeader + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +ReleaseDmiBufferStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + return AGESA_UNSUPPORTED; +} + +/* -----------------------------------------------------------------------------*/ +/** + * ReleaseDmiBuffer + * + * Description: + * Deallocate DMI buffer + * + * Parameters: + * @param[in, out] *StdHeader + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +ReleaseDmiBuffer ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + HeapDeallocateBuffer ((UINT32) AMD_DMI_MEM_DEV_INFO_HANDLE, StdHeader); + + return AGESA_SUCCESS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * IntToString + * + * Description: + * Translate UINT array to CHAR array. + * + * Parameters: + * @param[in, out] *String Pointer to CHAR array + * @param[in] *Integer Pointer to UINT array + * @param[in] SizeInByte The size of UINT array + * + * Processing: + * + */ +VOID +STATIC +IntToString ( + IN OUT CHAR8 *String, + IN UINT8 *Integer, + IN UINT8 SizeInByte + ) +{ + UINT8 Index; + + for (Index = 0; Index < SizeInByte; Index++) { + *(String + Index * 2) = (*(Integer + Index) >> 4) & 0x0F; + *(String + Index * 2 + 1) = *(Integer + Index) & 0x0F; + } + for (Index = 0; Index < (SizeInByte * 2); Index++) { + if (*(String + Index) >= 0x0A) { + *(String + Index) += 0x37; + } else { + *(String + Index) += 0x30; + } + } + *(String + SizeInByte * 2) = 0x0; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatureLeveling.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatureLeveling.c new file mode 100644 index 0000000000..6494c69407 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatureLeveling.c @@ -0,0 +1,265 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Feature Leveling Function. + * + * Contains code to Level the Feature in a multi-socket system + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuPostInit.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUFEATURELEVELING_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +VOID +STATIC +SaveFeatures ( + IN OUT VOID *cpuFeatureListPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +WriteFeatures ( + IN OUT VOID *cpuFeatureListPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +GetGlobalCpuFeatureListAddress ( + OUT UINT64 **Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * P U B L I C F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * FeatureLeveling + * + * CPU feature leveling. Set least common features set of all CPUs + * + * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + */ +VOID +FeatureLeveling ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 BscSocket; + UINT32 Ignored; + UINT32 BscCoreNum; + UINT32 Socket; + UINT32 Core; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + BOOLEAN *FirstTime; + BOOLEAN *NeedLeveling; + AGESA_STATUS IgnoredSts; + CPU_FEATURES_LIST *globalCpuFeatureList; + AP_TASK TaskPtr; + + ASSERT (IsBsp (StdHeader, &IgnoredSts)); + + GetGlobalCpuFeatureListAddress ((UINT64 **) &globalCpuFeatureList, StdHeader); + FirstTime = (BOOLEAN *) ((UINT8 *) globalCpuFeatureList + sizeof (CPU_FEATURES_LIST)); + NeedLeveling = (BOOLEAN *) ((UINT8 *) globalCpuFeatureList + sizeof (CPU_FEATURES_LIST) + sizeof (BOOLEAN)); + + *FirstTime = TRUE; + *NeedLeveling = FALSE; + + LibAmdMemFill (globalCpuFeatureList, 0xFF, sizeof (CPU_FEATURES_LIST), StdHeader); + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + TaskPtr.FuncAddress.PfApTaskI = SaveFeatures; + TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (CPU_FEATURES_LIST); + TaskPtr.ExeFlags = WAIT_FOR_CORE; + TaskPtr.DataTransfer.DataPtr = globalCpuFeatureList; + TaskPtr.DataTransfer.DataTransferFlags = DATA_IN_MEMORY; + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + if (Socket != BscSocket) { + ApUtilRunCodeOnSocketCore ((UINT8)Socket, 0, &TaskPtr, StdHeader); + } + } + } + ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, NULL); + + if (*NeedLeveling) { + TaskPtr.FuncAddress.PfApTaskI = WriteFeatures; + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCoreNum)) { + ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8)Core, &TaskPtr, StdHeader); + } + } + } + } + ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, NULL); + } +} + +/*---------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * SaveFeatures + * + * save least common features set of all CPUs + * + * @param[in,out] cpuFeatureListPtr - Pointer to CPU Feature List. + * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + */ +VOID +STATIC +SaveFeatures ( + IN OUT VOID *cpuFeatureListPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + FamilySpecificServices = NULL; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->SaveFeatures (FamilySpecificServices, cpuFeatureListPtr, StdHeader); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * WriteFeatures + * + * Write out least common features set of all CPUs + * + * @param[in,out] cpuFeatureListPtr - Pointer to CPU Feature List. + * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + */ +VOID +STATIC +WriteFeatures ( + IN OUT VOID *cpuFeatureListPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + FamilySpecificServices = NULL; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->WriteFeatures (FamilySpecificServices, cpuFeatureListPtr, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * GetGlobalCpuFeatureListAddress + * + * Determines the address in system DRAM that should be used for CPU feature leveling. + * + * @param[out] Address Address to utilize + * @param[in] StdHeader Config handle for library and services + * + * + */ +VOID +STATIC +GetGlobalCpuFeatureListAddress ( + OUT UINT64 **Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 AddressValue; + + AddressValue = GLOBAL_CPU_FEATURE_LIST_TEMP_ADDR; + + *Address = (UINT64 *)(UINT32)(AddressValue); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.c new file mode 100644 index 0000000000..d3753cb16a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.c @@ -0,0 +1,283 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Implement general feature dispatcher. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "GeneralServices.h" +#include "cpuFeatures.h" +#include "cpuFamilyTranslation.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) +#define FILECODE PROC_CPU_FEATURE_CPUFEATURES_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S - External General Services API + *---------------------------------------------------------------------------------------- + */ +extern CONST CPU_FEATURE_DESCRIPTOR* ROMDATA SupportedCpuFeatureList[]; + +/** + * Update the status of a specific feature + * + * Update the status (is enabled or not) in heap + * + * @param[in] Feature Indicates the desired feature. + * @param[in] IsEnabled Indicates the desired feature + * @param[in] StdHeader Standard AMD configuration parameters. + * + */ +VOID +UpdateFeatureStatusInHeap ( + IN DISPATCHABLE_CPU_FEATURES Feature, + IN BOOLEAN IsEnabled, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *CpuFeatureIsEnabledHeap; + LOCATE_HEAP_PTR LocateHeap; + + ASSERT (Feature < MaxCpuFeature); + + CpuFeatureIsEnabledHeap = NULL; + LocateHeap.BufferHandle = AMD_IS_FEATURE_ENABLED; + if (HeapLocateBuffer (&LocateHeap, StdHeader) == AGESA_SUCCESS) { + CpuFeatureIsEnabledHeap = LocateHeap.BufferPtr; + } + if (CpuFeatureIsEnabledHeap != NULL) { + CpuFeatureIsEnabledHeap[Feature] = (UINT8) IsEnabled; + } +} + +/** + * Determines if a specific feature is or will be enabled. + * + * This code traverses the feature list until a match is + * found, then invokes the 'IsEnabled' function of the + * feature. + * + * @param[in] Feature Indicates the desired feature. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Standard AMD configuration parameters. + * + * @retval TRUE Feature is or will be enabled + * @retval FALSE Feature is not enabled + */ +BOOLEAN +IsFeatureEnabled ( + IN DISPATCHABLE_CPU_FEATURES Feature, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *CpuFeatureIsEnabledHeap; + UINTN i; + LOCATE_HEAP_PTR LocateHeap; + + ASSERT (Feature < MaxCpuFeature); + + CpuFeatureIsEnabledHeap = NULL; + LocateHeap.BufferHandle = AMD_IS_FEATURE_ENABLED; + if (HeapLocateBuffer (&LocateHeap, StdHeader) == AGESA_SUCCESS) { + CpuFeatureIsEnabledHeap = LocateHeap.BufferPtr; + } + if (CpuFeatureIsEnabledHeap != NULL) { + if (CpuFeatureIsEnabledHeap[Feature] != CPU_FEATURE_UNDECIDED) { + return ((BOOLEAN) CpuFeatureIsEnabledHeap[Feature]); + } + } + + for (i = 0; SupportedCpuFeatureList[i] != NULL; i++) { + if (SupportedCpuFeatureList[i]->Feature == Feature) { + return (SupportedCpuFeatureList[i]->IsEnabled (PlatformConfig, StdHeader)); + } + } + return FALSE; +} + +/** + * Dispatches all features needing to perform some initialization at + * this time point. + * + * This routine searches the feature table for features needing to + * run at this time point, and invokes them. + * + * @param[in] EntryPoint Timepoint designator + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Standard AMD configuration parameters. + * + * @return The most severe status of any called service. + */ +AGESA_STATUS +DispatchCpuFeatures ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *CpuFeatureIsEnabledHeap; + UINTN i; + BOOLEAN FeatureIsEnabled; + BOOLEAN ResultDecided; + AGESA_STATUS AgesaStatus; + AGESA_STATUS CalledStatus; + AGESA_STATUS IgnoredStatus; + LOCATE_HEAP_PTR LocateHeap; + ALLOCATE_HEAP_PARAMS AllocateHeap; + + + AgesaStatus = AGESA_SUCCESS; + + CpuFeatureIsEnabledHeap = NULL; + LocateHeap.BufferHandle = AMD_IS_FEATURE_ENABLED; + if (HeapLocateBuffer (&LocateHeap, StdHeader) == AGESA_SUCCESS) { + CpuFeatureIsEnabledHeap = LocateHeap.BufferPtr; + } else { + AllocateHeap.BufferHandle = AMD_IS_FEATURE_ENABLED; + AllocateHeap.RequestedBufferSize = MaxCpuFeature; + AllocateHeap.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocateHeap, StdHeader) == AGESA_SUCCESS) { + CpuFeatureIsEnabledHeap = AllocateHeap.BufferPtr; + // Initialize all feature as NOT_KNOW_YET + LibAmdMemFill ((VOID *) CpuFeatureIsEnabledHeap, CPU_FEATURE_UNDECIDED, MaxCpuFeature, StdHeader); + } + } + + if (IsBsp (StdHeader, &IgnoredStatus)) { + for (i = 0; SupportedCpuFeatureList[i] != NULL; i++) { + if ((SupportedCpuFeatureList[i]->EntryPoint & EntryPoint) != 0) { + ResultDecided = FALSE; + FeatureIsEnabled = FALSE; + /// @todo IDS need updated + IDS_SKIP_HOOK (IDS_CPU_FEAT, (CPU_FEATURE_DESCRIPTOR *) SupportedCpuFeatureList[i], StdHeader) { + if (CpuFeatureIsEnabledHeap != NULL) { + // Try to get isFeatureEnabled from heap + if (CpuFeatureIsEnabledHeap[SupportedCpuFeatureList[i]->Feature] != CPU_FEATURE_UNDECIDED) { + FeatureIsEnabled = (BOOLEAN) (CpuFeatureIsEnabledHeap[SupportedCpuFeatureList[i]->Feature]); + ResultDecided = TRUE; + } + } + if (!ResultDecided) { + // Get isFeatureEnabled by running IsEnabled + FeatureIsEnabled = SupportedCpuFeatureList[i]->IsEnabled (PlatformConfig, StdHeader); + if (CpuFeatureIsEnabledHeap != NULL) { + CpuFeatureIsEnabledHeap[SupportedCpuFeatureList[i]->Feature] = (UINT8) FeatureIsEnabled; + } + } + if (FeatureIsEnabled) { + CalledStatus = SupportedCpuFeatureList[i]->InitializeFeature (EntryPoint, PlatformConfig, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + } + } + } + } + } + return AgesaStatus; +} + +/** + * This routine checks whether any non-coherent links in the system + * runs in HT1 mode; used to determine whether certain features + * should be disabled when this routine returns TRUE. + * + * @param[in] StdHeader Standard AMD configuration parameters. + * + * @retval TRUE One of the non-coherent links in the + * system runs in HT1 mode + * @retval FALSE None of the non-coherent links in the + * system is running in HT1 mode + */ +BOOLEAN +IsNonCoherentHt1 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN Link; + UINT32 Socket; + UINT32 Module; + PCI_ADDR PciAddress; + AGESA_STATUS AgesaStatus; + HT_HOST_FEATS HtHostFeats; + CPU_SPECIFIC_SERVICES *CpuServices; + + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetCpuServicesOfSocket (Socket, (CONST CPU_SPECIFIC_SERVICES **)&CpuServices, StdHeader); + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) { + HtHostFeats.HtHostValue = 0; + Link = 0; + while (CpuServices->GetNextHtLinkFeatures (CpuServices, &Link, &PciAddress, &HtHostFeats, StdHeader)) { + // Return TRUE and exit routine once we find a non-coherent link in HT1 + if ((HtHostFeats.HtHostFeatures.NonCoherent == 1) && (HtHostFeats.HtHostFeatures.Ht1 == 1)) { + return TRUE; + } + } + } + } + } + } + + return FALSE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.h new file mode 100644 index 0000000000..47444ef1ba --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuFeatures.h @@ -0,0 +1,281 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Generic CPU feature dispatcher and related services. + * + * Provides a feature processing engine to handle feature in a + * more generic way. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Common + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_FEATURES_H_ +#define _CPU_FEATURES_H_ + +/** + * @page cpufeatimpl CPU Generic Feature Implementation Guide + * + * The CPU generic feature dispatcher provides services which can be used to implement a + * wide range of features in a manner that isolates calling code from knowledge about which + * families or features are supported in the current build. + * + * @par Determine if a New Feature is a Suitable Candidate + * + * A feature must meet the following requirements: + *
    + *
  • Any core in the system must be able to determine if the feature should be enabled or not. + * + *
      + *
    • MSRs cannot be read in multisocket systems in the 'IsEnabled' function. + * + *
    • Cores cannot be launched in the 'IsEnabled' function. + *
    + *
+ * + * @par Determine the Time Point at which the Feature Should be Enabled + * + * Factors to consider in making this determination: + * + *
    + *
  • Determine if there are any dependencies on other settings that require strict ordering. + * + *
  • Consider the state of the APs that you will need. + * + *
  • Remember that features enabled during AmdInitEarly will automatically be restored on S3 resume. + *
+ * + * @par Implementing a new feature + * + * Perform the following steps to implement a new feature: + * + *
    + *
  • Create a unique equate for your time point, @b if you cannot use an existing time point. + * + *
  • Create a new value in the DISPATCHABLE_CPU_FEATURES enum for your feature. + * + *
  • Add a new 'C' file to the Features folder for your feature. + * + *
      + *
    • The 'C' file must implement 2 functions -- 'IsEnabled' and 'Initialize' + * + *
    • The 'C' file must instantiate a CPU_FEATURE_DESCRIPTOR structure. + *
    + * + *
  • Add a new 'H' file to the Features folder for your feature. + * + *
      + *
    • The 'H' file declares whatever family specific functions required by the feature. + * + *
    • The 'H' file declares a structure containing all family specific functions. For a reference + * example, your feature API should have a set of conventions similar to cpu specific services, + * @ref cpuimplfss. + *
    + * + *
  • Create 'C' files in all applicable family folders. + * + *
      + *
    • Implement the required family specific functions. + * + *
    • Instantiate a family specific services structure. + *
    + * + *
  • Create \Install.h in the include folder. + * + *
      + *
    • Add logic to determine when your feature should be included in the build. + * + *
    • If the feature should be included, define OPTION_\ to the address of your + * CPU_FEATURE_DESCRIPTOR instantiation. If not, define OPTION_\ to be blank. + * + *
    • Create a family translation table pointing to all applicable instantiations of + * family specific function structures. + *
    + * + *
  • Modify OptionCpuFeaturesInstall.h in the include folder. + * + *
      + *
    • Include \Install.h. + * + *
    • Add OPTION_\ to the SupportedCpuFeatureList array. + *
    + * + *
  • If a new time point was created, add a call to DispatchCpuFeatures at the desired location, + * passing your new time point equate. + *
+ * + */ + + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *---------------------------------------------------------------------------------------- + */ +#define CPU_FEAT_BEFORE_PM_INIT (0x0000000000000001ull) +#define CPU_FEAT_AFTER_PM_INIT (0x0000000000000002ull) +#define CPU_FEAT_AFTER_POST_MTRR_SYNC (0x0000000000000004ull) +#define CPU_FEAT_INIT_MID_END (0x0000000000000008ull) +#define CPU_FEAT_INIT_LATE_END (0x0000000000000010ull) +#define CPU_FEAT_S3_LATE_RESTORE_END (0x0000000000000020ull) +#define CPU_FEAT_AFTER_RESUME_MTRR_SYNC (0x0000000000000040ull) +#define CPU_FEAT_AFTER_COHERENT_DISCOVERY (0x0000000000000080ull) +#define CPU_FEAT_BEFORE_RELINQUISH_AP (0x0000000000000100ull) + +#define CPU_FEATURE_UNDECIDED 0xFFul +#define CPU_FEATURE_DISABLED ((UINT8) FALSE) +#define CPU_FEATURE_ENABLED ((UINT8) TRUE) + +/** + * Enumerated list of supported features. + */ +typedef enum { + L3Features, ///< L3 dependent features + MsgBasedC1e, ///< Message-based C1e + CoreLeveling, ///< Core Leveling + C6Cstate, ///< C6 C-state + IoCstate, ///< IO C-state + CacheFlushOnHalt, ///< Cache Flush On Halt + PreserveAroundMailbox, ///< Save-Restore the registers used for AP mailbox, to preserve their normal function. + CpuApm, ///< Application Power Management + CoreBoost, ///< Core Performance Boost (CPB) + LowPwrPstate, ///< 500 MHz Low Power P-state + PstateHpcMode, ///< High performance computing mode + CpuPsi, ///< Power Status Indicator + CpuHtc, ///< Hardware Thermal Control + CpuTdpLimiting, ///< TDP limiting + PrefetchMode, ///< CPU Prefetch Mode + MaxCpuFeature ///< Not a valid value, used for verifying input +} DISPATCHABLE_CPU_FEATURES; + +/*---------------------------------------------------------------------------------------*/ +/** + * Feature specific call to check if it is supported by the system. + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE Feature is supported. + * @retval FALSE Feature is not supported. + * + */ +typedef BOOLEAN F_CPU_FEATURE_IS_ENABLED ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_FEATURE_IS_ENABLED *PF_CPU_FEATURE_IS_ENABLED; + +/*---------------------------------------------------------------------------------------*/ +/** + * The feature's main entry point for enablement. + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_CPU_FEATURE_INITIALIZE ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_FEATURE_INITIALIZE *PF_CPU_FEATURE_INITIALIZE; + + +/** + * Generic feature descriptor + */ +typedef struct { + DISPATCHABLE_CPU_FEATURES Feature; ///< Enumerated feature ID + UINT64 EntryPoint; ///< Timepoint designator + PF_CPU_FEATURE_IS_ENABLED IsEnabled; ///< Pointer to the function that checks if the feature is supported + PF_CPU_FEATURE_INITIALIZE InitializeFeature; ///< Pointer to the function that enables the feature +} CPU_FEATURE_DESCRIPTOR; + +/** + * Table descriptor for the installed features. + */ +typedef struct { + UINT8 NumberOfFeats; ///< Number of valid entries in the table. + CPU_FEATURE_DESCRIPTOR *FeatureList; ///< Pointer to the first element in the array. +} CPU_FEATURE_TABLE; + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ +VOID +UpdateFeatureStatusInHeap ( + IN DISPATCHABLE_CPU_FEATURES Feature, + IN BOOLEAN IsEnabled, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +IsFeatureEnabled ( + IN DISPATCHABLE_CPU_FEATURES Feature, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +DispatchCpuFeatures ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +IsNonCoherentHt1 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_FEATURES_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.c new file mode 100644 index 0000000000..9807102fe3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.c @@ -0,0 +1,201 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Hardware Thermal Control (HTC) feature support code. + * + * Contains code that declares the AGESA CPU HTC related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuApicUtilities.h" +#include "cpuFeatures.h" +#include "cpuHtc.h" +#include "OptionMultiSocket.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUHTC_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +UINT32 +STATIC +EnableHtcOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE HtcFamilyServiceTable; +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------------------*/ +/** + * Should Hardware Thermal Control (HTC) be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HTC is supported. + * @retval FALSE HTC cannot be enabled. + * + */ +BOOLEAN +STATIC +IsHtcFeatureEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + BOOLEAN IsEnabled; + HTC_FAMILY_SERVICES *HtcFamilyServices; + + IsEnabled = TRUE; + + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&HtcFamilyServiceTable, Socket, (CONST VOID **)&HtcFamilyServices, StdHeader); + if ((HtcFamilyServices == NULL) || (!HtcFamilyServices->IsHtcSupported (HtcFamilyServices, Socket, PlatformConfig, StdHeader))) { + IsEnabled = FALSE; + break; + } + } + } + return IsEnabled; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable Hardware Thermal Control (HTC) + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +InitializeHtcFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + AGESA_STATUS AgesaStatus; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + + IDS_HDT_CONSOLE (CPU_TRACE, " HTC is being initialized\n"); + + CpuEarlyParams.PlatformConfig = *PlatformConfig; + + TaskPtr.FuncAddress.PfApTaskIOC = EnableHtcOnSocket; + TaskPtr.DataTransfer.DataSizeInDwords = 2; + TaskPtr.DataTransfer.DataPtr = &EntryPoint; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS | TASK_HAS_OUTPUT; + AgesaStatus = OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, &CpuEarlyParams); + + IDS_HDT_CONSOLE (CPU_TRACE, " HTC is enabled\n"); + + return AgesaStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * AP task to enable HTC + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] StdHeader Config Handle for library, services. + * @param[in] CpuEarlyParams Service parameters. + * + */ +UINT32 +STATIC +EnableHtcOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ) +{ + AGESA_STATUS CalledStatus; + HTC_FAMILY_SERVICES *HtcFamilyServices; + + CalledStatus = AGESA_UNSUPPORTED; + GetFeatureServicesOfCurrentCore (&HtcFamilyServiceTable, (CONST VOID **)&HtcFamilyServices, StdHeader); + if (HtcFamilyServices != NULL) { + CalledStatus = HtcFamilyServices->EnableHtcOnSocket (HtcFamilyServices, *((UINT64 *) EntryPoint), &CpuEarlyParams->PlatformConfig, StdHeader); + } + return (UINT32) CalledStatus; +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureHtc = +{ + CpuHtc, + (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC), + IsHtcFeatureEnabled, + InitializeHtcFeature +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.h new file mode 100644 index 0000000000..913802f8e9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuHtc.h @@ -0,0 +1,130 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Hardware Thermal Control (HTC) Functions declarations. + * + * Contains code that declares the AGESA CPU HTC related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_HTC_H_ +#define _CPU_HTC_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (HTC_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if Hardware Thermal Control (HTC) is supported. + * + * @param[in] HtcServices HTC services. + * @param[in] Socket Zero-based socket number. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HTC is supported. + * @retval FALSE HTC is not supported. + * + */ +typedef BOOLEAN F_HTC_IS_SUPPORTED ( + IN HTC_FAMILY_SERVICES *HtcServices, + IN UINT32 Socket, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HTC_IS_SUPPORTED *PF_HTC_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable HTC. + * + * @param[in] HtcServices HTC services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_HTC_INIT ( + IN HTC_FAMILY_SERVICES *HtcServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HTC_INIT *PF_HTC_INIT; + +/** + * Provide the interface to the HTC Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +typedef struct _HTC_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_HTC_IS_SUPPORTED IsHtcSupported; ///< Method: Family specific call to check if HTC is supported. + PF_HTC_INIT EnableHtcOnSocket; ///< Method: Family specific call to enable HTC. +} HTC_FAMILY_SERVICES; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_HTC_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.c new file mode 100644 index 0000000000..a98f1823b1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.c @@ -0,0 +1,207 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU IO Cstate function declarations. + * + * Contains code that declares the AGESA CPU IO Cstate related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "cpuFeatures.h" +#include "cpuIoCstate.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuApicUtilities.h" +#include "OptionMultiSocket.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUIOCSTATE_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +STATIC +EnableIoCstateOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE IoCstateFamilyServiceTable; +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------------------*/ +/** + * Should IO Cstate be enabled + * If all processors support IO Cstate, return TRUE. Otherwise, return FALSE + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE IO Cstate is supported. + * @retval FALSE IO Cstate cannot be enabled. + * + */ +BOOLEAN +STATIC +IsIoCstateFeatureSupported ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + BOOLEAN IsSupported; + IO_CSTATE_FAMILY_SERVICES *IoCstateServices; + + IsSupported = FALSE; + if ((PlatformConfig->CStateIoBaseAddress != 0) && (PlatformConfig->CStateIoBaseAddress <= 0xFFF8)) { + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&IoCstateFamilyServiceTable, Socket, (CONST VOID **)&IoCstateServices, StdHeader); + if (IoCstateServices != NULL) { + if (IoCstateServices->IsIoCstateSupported (IoCstateServices, Socket, StdHeader)) { + IsSupported = TRUE; + } else { + // Stop checking remaining socket(s) once we find one that does not support IO Cstates + IsSupported = FALSE; + break; + } + } else { + // Exit the for loop if we found a socket that does not have the IO Cstates feature installed + IsSupported = FALSE; + break; + } + } + } + } + return IsSupported; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable IO Cstate feature + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +InitializeIoCstateFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + + IDS_HDT_CONSOLE (CPU_TRACE, " IO C-state is enabled\n"); + + CpuEarlyParams.PlatformConfig = *PlatformConfig; + + TaskPtr.FuncAddress.PfApTaskIC = EnableIoCstateOnSocket; + TaskPtr.DataTransfer.DataSizeInDwords = 2; + TaskPtr.DataTransfer.DataPtr = &EntryPoint; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS; + OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, &CpuEarlyParams); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 'Local' core 0 task to enable IO Cstate on it's socket. + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] StdHeader Config Handle for library, services. + * @param[in] CpuEarlyParams Service parameters. + * + */ +VOID +STATIC +EnableIoCstateOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ) +{ + IO_CSTATE_FAMILY_SERVICES *FamilyServices; + + GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + FamilyServices->InitializeIoCstate (FamilyServices, + *((UINT64 *) EntryPoint), + &CpuEarlyParams->PlatformConfig, + StdHeader); +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureIoCstate = +{ + IoCstate, + (CPU_FEAT_AFTER_PM_INIT), + IsIoCstateFeatureSupported, + InitializeIoCstateFeature +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.h new file mode 100644 index 0000000000..5cd9c823b4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuIoCstate.h @@ -0,0 +1,283 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU IO Cstate feature support code. + * + * Contains code that declares the AGESA CPU IO Cstate related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_IO_CSTATE_H_ +#define _CPU_IO_CSTATE_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (IO_CSTATE_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +// Defines for ACPI C-State Objects +#define CST_NAME__ '_' +#define CST_NAME_C 'C' +#define CST_NAME_S 'S' +#define CST_NAME_T 'T' +#define CST_LENGTH (CST_BODY_SIZE - 1) +#define CST_NUM_OF_ELEMENTS 0x02 +#define CST_COUNT 0x01 +#define CST_PKG_LENGTH (CST_BODY_SIZE - 6) // CST_BODY_SIZE - PkgHeader - Count Buffer +#define CST_PKG_ELEMENTS 0x04 +#define CST_SUBPKG_LENGTH 0x14 +#define CST_SUBPKG_ELEMENTS 0x0A +#define CST_GDR_LENGTH 0x000C +#define CST_C1_TYPE 0x01 +#define CST_C2_TYPE 0x02 + +#define CSD_NAME_D 'D' +#define CSD_COORD_TYPE_HW_ALL 0xFE + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +/* AML code definition */ + +/// CST Header +typedef struct _CST_HEADER_STRUCT { + UINT8 NameOpcode; ///< Name Opcode + UINT8 CstName_a__; ///< String "_" + UINT8 CstName_a_C; ///< String "C" + UINT8 CstName_a_S; ///< String "S" + UINT8 CstName_a_T; ///< String "T" +} CST_HEADER_STRUCT; +#define CST_HEADER_SIZE 5 + +/// CST Body +typedef struct _CST_BODY_STRUCT { + UINT8 PkgOpcode; ///< Package Opcode + UINT8 PkgLength; ///< Package Length + UINT8 PkgElements; ///< Number of Elements + UINT8 BytePrefix; ///< Byte Prefix Opcode + UINT8 Count; ///< Number of Cstate info packages + UINT8 PkgOpcode2; ///< Package Opcode + UINT8 PkgLength2; ///< Package Length + UINT8 PkgElements2; ///< Number of Elements + UINT8 BufferOpcode; ///< Buffer Opcode + UINT8 BufferLength; ///< Buffer Length + UINT8 BufferElements; ///< Number of Elements + UINT8 BufferOpcode2; ///< Buffer Opcode + UINT8 GdrOpcode; ///< Generic Register Descriptor Opcode + UINT16 GdrLength; ///< Descriptor Length + UINT8 AddrSpaceId; ///< Address Space ID + UINT8 RegBitWidth; ///< Register Bit Width + UINT8 RegBitOffset; ///< Register Bit Offset + UINT8 AddressSize; ///< Address Size + UINT64 RegisterAddr; ///< Register Address + UINT16 EndTag; ///< End Tag Descriptor + UINT8 BytePrefix2; ///< Byte Prefix Opcode + UINT8 Type; ///< Type + UINT8 WordPrefix; ///< Word Prefix Opcode + UINT16 Latency; ///< Latency + UINT8 DWordPrefix; ///< Dword Prefix Opcode + UINT32 Power; ///< Power +} CST_BODY_STRUCT; +#define CST_BODY_SIZE 39 + +/// CSD Header +typedef struct _CSD_HEADER_STRUCT { + UINT8 NameOpcode; ///< Name Opcode + UINT8 CsdName_a__; ///< String "_" + UINT8 CsdName_a_C; ///< String "C" + UINT8 CsdName_a_S; ///< String "S" + UINT8 CsdName_a_D; ///< String "D" +} CSD_HEADER_STRUCT; +#define CSD_HEADER_SIZE 5 + +/// CSD Body +typedef struct _CSD_BODY_STRUCT { + UINT8 PkgOpcode; ///< Package Opcode + UINT8 PkgLength; ///< Package Length + UINT8 PkgElements; ///< Number of Elements + UINT8 PkgOpcode2; ///< Package Opcode + UINT8 PkgLength2; ///< Package Length + UINT8 PkgElements2; ///< Number of Elements + UINT8 BytePrefix; ///< Byte Prefix Opcode + UINT8 NumEntries; ///< Number of Entries + UINT8 BytePrefix2; ///< Byte Prefix Opcode + UINT8 Revision; ///< Revision + UINT8 DWordPrefix; ///< DWord Prefix Opcode + UINT32 Domain; ///< Dependency Domain Number + UINT8 DWordPrefix2; ///< DWord Prefix Opcode + UINT32 CoordType; ///< Coordination Type + UINT8 DWordPrefix3; ///< Dword Prefix Opcode + UINT32 NumProcessors; ///< Number of Processors in the Domain + UINT8 DWordPrefix4; ///< Dword Prefix Opcode + UINT32 Index; ///< Index of C-State entry for which dependency applies +} CSD_BODY_STRUCT; +#define CSD_BODY_SIZE 30 + +/// input for create _CST +typedef struct _ACPI_CST_CREATE_INPUT { + IO_CSTATE_FAMILY_SERVICES *IoCstateServices; ///< Family service of IoCstate + UINT8 LocalApicId; ///< Local Apic for create _CST + VOID **PstateAcpiBufferPtr; ///< buffer for fill _CST +} ACPI_CST_CREATE_INPUT ; + +/// input for get _CST +typedef struct _ACPI_CST_GET_INPUT { + IO_CSTATE_FAMILY_SERVICES *IoCstateServices; ///< Family service of IoCstate + PLATFORM_CONFIGURATION *PlatformConfig; ///< platform config + UINT32 *CStateAcpiObjSizePtr; ///< Point to size of _CST +} ACPI_CST_GET_INPUT ; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if IO Cstate is supported. + * + * @param[in] IoCstateServices IO Cstate services. + * @param[in] Socket Zero-based socket number. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE IO Cstate is supported. + * @retval FALSE IO Cstate is not supported. + * + */ +typedef BOOLEAN F_IO_CSTATE_IS_SUPPORTED ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable IO Cstate. + * + * @param[in] IoCstateServices IO Cstate services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_IO_CSTATE_INIT ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to return the size of ACPI C-State Objects + * + * @param[in] IoCstateServices IO Cstate services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data + * @param[in] StdHeader Config Handle for library, services. + * + * @retval Size of ACPI C-State Objects + * + */ +typedef UINT32 F_IO_CSTATE_GET_CST_SIZE ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to create ACPI C-State Objects + * + * @param[in] IoCstateServices IO Cstate services. + * @param[in] LocalApicId Local Apic Id + * @param[in, out] PstateAcpiBufferPtr Pointer to Pstate data buffer + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_IO_CSTATE_CREATE_CST ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN UINT8 LocalApicId, + IN OUT VOID **PstateAcpiBufferPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check whether CSD object should be created. + * + * @param[in] IoCstateServices IO Cstate services. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE CSD Object should be created. + * @retval FALSE CSD Object should not be created. + * + */ +typedef BOOLEAN F_IO_CSTATE_IS_CSD_GENERATED ( + IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method +typedef F_IO_CSTATE_IS_SUPPORTED *PF_IO_CSTATE_IS_SUPPORTED; +typedef F_IO_CSTATE_INIT *PF_IO_CSTATE_INIT; +typedef F_IO_CSTATE_GET_CST_SIZE *PF_IO_CSTATE_GET_CST_SIZE; +typedef F_IO_CSTATE_CREATE_CST *PF_IO_CSTATE_CREATE_CST; +typedef F_IO_CSTATE_IS_CSD_GENERATED *PF_IO_CSTATE_IS_CSD_GENERATED; + +/** + * Provide the interface to the IO Cstate Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _IO_CSTATE_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_IO_CSTATE_IS_SUPPORTED IsIoCstateSupported; ///< Method: Family specific call to check if IO Cstate is supported. + PF_IO_CSTATE_INIT InitializeIoCstate; ///< Method: Family specific call to enable IO Cstate + PF_IO_CSTATE_GET_CST_SIZE GetAcpiCstObj; ///< Method: Family specific call to return the size of ACPI CST objects. + PF_IO_CSTATE_CREATE_CST CreateAcpiCstObj; ///< Method: Family specific call to create ACPI CST object + PF_IO_CSTATE_IS_CSD_GENERATED IsCsdObjGenerated; ///< Method: Family specific call to check whether CSD Object should be created. +}; + +#endif // _CPU_IO_CSTATE_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuL3Features.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuL3Features.h new file mode 100644 index 0000000000..d2c1424f12 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuL3Features.h @@ -0,0 +1,399 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU L3 Features Initialization functions. + * + * Contains code that declares the AGESA CPU L3 dependent feature related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_L3_FEATURES_H_ +#define _CPU_L3_FEATIRES_H_ + +#include "Filecode.h" +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (L3_FEATURE_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +#define AP_LATE_TASK_DISABLE_CACHE (0x00000000ul | PROC_CPU_FEATURE_CPUL3FEATURES_FILECODE) +#define AP_LATE_TASK_ENABLE_CACHE (0x00010000ul | PROC_CPU_FEATURE_CPUL3FEATURES_FILECODE) + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +#define L3_SCRUBBER_CONTEXT_ARRAY_SIZE 4 + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if L3 Features are supported. + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE L3 dependent features are supported + * @retval FALSE L3 dependent features are not supported + * + */ +typedef BOOLEAN F_L3_FEATURE_IS_SUPPORTED ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_L3_FEATURE_IS_SUPPORTED *PF_L3_FEATURE_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific hook before L3 features are initialized. + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_L3_FEATURE_BEFORE_INIT ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_L3_FEATURE_BEFORE_INIT *PF_L3_FEATURE_BEFORE_INIT; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to disable cache. + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] HtAssistEnabled Indicates whether Ht Assist is enabled. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_L3_FEATURE_DISABLE_CACHE ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN BOOLEAN HtAssistEnabled, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_L3_FEATURE_DISABLE_CACHE *PF_L3_FEATURE_DISABLE_CACHE; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to disable cache. + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef VOID F_L3_FEATURE_ENABLE_CACHE ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_L3_FEATURE_ENABLE_CACHE *PF_L3_FEATURE_ENABLE_CACHE; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to Initialize L3 Features + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] Socket Processor socket to enable. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_L3_FEATURE_INIT ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_L3_FEATURE_INIT *PF_L3_FEATURE_INIT; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific hook after L3 Features are initialized. + * + * @param[in] L3FeatureServices L3 Features family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_L3_FEATURE_AFTER_INIT ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_L3_FEATURE_AFTER_INIT *PF_L3_FEATURE_AFTER_INIT; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to save the L3 scrubber. + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] Socket Processor socket to check. + * @param[in] ScrubSettings Location to store current L3 scrubber settings. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_L3_FEATURE_GET_L3_SCRUB_CTRL ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE], + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_L3_FEATURE_GET_L3_SCRUB_CTRL *PF_L3_FEATURE_GET_L3_SCRUB_CTRL; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to restore the L3 scrubber. + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] Socket Processor socket to check. + * @param[in] ScrubSettings Contains L3 scrubber settings to restore. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_L3_FEATURE_SET_L3_SCRUB_CTRL ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE], + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_L3_FEATURE_SET_L3_SCRUB_CTRL *PF_L3_FEATURE_SET_L3_SCRUB_CTRL; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if HT Assist is supported. + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HT Assist is supported. + * @retval FALSE HT Assist is not supported. + * + */ +typedef BOOLEAN F_HT_ASSIST_IS_SUPPORTED ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_IS_SUPPORTED *PF_HT_ASSIST_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to Initialize HT Assist + * + * @param[in] L3FeatureServices L3 Features family services. + * @param[in] Socket Processor socket to enable. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_HT_ASSIST_INIT ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_INIT *PF_HT_ASSIST_INIT; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to provide non_optimal HT Assist support + * + * @param[in] L3FeatureServices L3 Feature family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + * @return TRUE The system may be running with non-optimal settings. + * @return FALSE The system may is running optimally. + * + */ +typedef BOOLEAN F_HT_ASSIST_IS_NONOPTIMAL ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_IS_NONOPTIMAL *PF_HT_ASSIST_IS_NONOPTIMAL; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if ATM Mode is supported. + * + * @param[in] L3FeatureServices L3 Features family services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE ATM Mode is supported. + * @retval FALSE ATM Mode is not supported. + * + */ +typedef BOOLEAN F_ATM_MODE_IS_SUPPORTED ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_ATM_MODE_IS_SUPPORTED *PF_ATM_MODE_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to Initialize ATM mode + * + * @param[in] L3FeatureServices L3 Features family services. + * @param[in] Socket Processor socket to enable. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_ATM_MODE_INIT ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_ATM_MODE_INIT *PF_ATM_MODE_INIT; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if Neighbor Cache Mode is supported. + * + * @param[in] L3FeatureServices L3 Features family services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE Neighbor Cache is supported. + * @retval FALSE Neighbor Cache is not supported. + * + */ +typedef BOOLEAN F_NBR_CACHE_IS_SUPPORTED ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_NBR_CACHE_IS_SUPPORTED *PF_NBR_CACHE_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to Initialize Neighbor Cache + * + * @param[in] L3FeatureServices L3 Features family services. + * @param[in] Socket Processor socket to enable. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_NBR_CACHE_INIT ( + IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_NBR_CACHE_INIT *PF_NBR_CACHE_INIT; + +/** + * Provide the interface to the L3 dependent features Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _L3_FEATURE_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_L3_FEATURE_IS_SUPPORTED IsL3FeatureSupported; ///< Method: Check if L3 dependent features are supported. + PF_L3_FEATURE_GET_L3_SCRUB_CTRL GetL3ScrubCtrl; ///< Method: Save/disable the L3 scrubber. + PF_L3_FEATURE_SET_L3_SCRUB_CTRL SetL3ScrubCtrl; ///< Method: Restore the L3 scrubber. + PF_L3_FEATURE_BEFORE_INIT HookBeforeInit; ///< Method: Hook before enabling L3 dependent features. + PF_L3_FEATURE_AFTER_INIT HookAfterInit; ///< Method: Hook after enabling L3 dependent features. + PF_L3_FEATURE_DISABLE_CACHE HookDisableCache; ///< Method: Core hook just before disabling cache. + PF_L3_FEATURE_ENABLE_CACHE HookEnableCache; ///< Method: Core hook just after enabling cache. + PF_HT_ASSIST_IS_SUPPORTED IsHtAssistSupported; ///< Method: Check if HT Assist is supported. + PF_HT_ASSIST_INIT HtAssistInit; ///< Method: Enable HT Assist. + PF_HT_ASSIST_IS_NONOPTIMAL IsNonOptimalConfig; ///< Method: Check if HT Assist is running optimally. + PF_ATM_MODE_IS_SUPPORTED IsAtmModeSupported; ///< Method: Check if ATM Mode is supported. + PF_ATM_MODE_INIT AtmModeInit; ///< Method: Enable ATM Mode. + PF_NBR_CACHE_IS_SUPPORTED IsNbrCacheSupported; ///< Method: Check if Neighbor Cache is supported. + PF_NBR_CACHE_INIT NbrCacheInit; ///< Method: Enable Neighbor Cache. +}; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +DisableAllCaches ( + IN AP_EXE_PARAMS *ApExeParams + ); + +AGESA_STATUS +EnableAllCaches ( + IN AP_EXE_PARAMS *ApExeParams + ); + +#endif // _CPU_L3_FEATURES_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuMsgBasedC1e.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuMsgBasedC1e.h new file mode 100644 index 0000000000..0fc252f109 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuMsgBasedC1e.h @@ -0,0 +1,127 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Message-based C1e Functions declarations. + * + * Contains code that declares the AGESA CPU C1e related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_MSG_BASED_C1E_H_ +#define _CPU_MSG_BASED_C1E_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (MSG_BASED_C1E_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if message-based C1e is supported. + * + * @param[in] MsgBasedC1eServices Contains the runtime modifiable feature input data. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE Message-based C1e is supported. + * @retval FALSE Message-based C1e is not supported. + * + */ +typedef BOOLEAN F_MSG_BASED_C1E_IS_SUPPORTED ( + IN MSG_BASED_C1E_FAMILY_SERVICES *MsgBasedC1eServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_MSG_BASED_C1E_IS_SUPPORTED *PF_MSG_BASED_C1E_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable hardware C1e. + * + * @param[in] MsgBasedC1eServices Hardware C1e services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_MSG_BASED_C1E_INIT ( + IN MSG_BASED_C1E_FAMILY_SERVICES *MsgBasedC1eServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_MSG_BASED_C1E_INIT *PF_MSG_BASED_C1E_INIT; + +/** + * Provide the interface to the hardware C1e Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _MSG_BASED_C1E_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_MSG_BASED_C1E_IS_SUPPORTED IsMsgBasedC1eSupported; ///< Method: Family specific call to check if hardware C1e is supported. + PF_MSG_BASED_C1E_INIT InitializeMsgBasedC1e; ///< Method: Family specific call to enable hardware C1e. +}; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_MSG_BASED_C1E_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPrefetchMode.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPrefetchMode.h new file mode 100644 index 0000000000..1d837f5c24 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPrefetchMode.h @@ -0,0 +1,110 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Prefetch Mode Functions declarations. + * + * Contains code that declares the AGESA CPU prefetch mode related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_PREFETCH_MODE_H_ +#define _CPU_PREFETCH_MODE_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (PREFETCH_MODE_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +#define AP_LATE_TASK_CPU_PREFETCH_MODE (PROC_CPU_FEATURE_CPUPREFETCHMODE_FILECODE) + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable prefetch mode. + * + * @param[in] PrefetchModeServices Prefetch mode services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_PREFETCH_MODE_INIT ( + IN PREFETCH_MODE_FAMILY_SERVICES *PrefetchModeServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_PREFETCH_MODE_INIT *PF_PREFETCH_MODE_INIT; + +/** + * Provide the interface to the prefetch mode Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _PREFETCH_MODE_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_PREFETCH_MODE_INIT PrefetchModeControlOnCore; ///< Method: Family specific call to control prefetch mode. +}; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +CpuPrefetchModeApTask ( + IN AP_EXE_PARAMS *ApExeParams + ); + +#endif // _CPU_PREFETCH_MODE_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.c new file mode 100644 index 0000000000..897723624c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.c @@ -0,0 +1,213 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Power Status Indicator (PSI) feature support code. + * + * Contains code that declares the AGESA CPU PSI related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuApicUtilities.h" +#include "cpuFeatures.h" +#include "cpuPsi.h" +#include "OptionMultiSocket.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUPSI_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +UINT32 +STATIC +EnablePsiOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE PsiFamilyServiceTable; +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------------------*/ +/** + * Should Power Status Indicator (PSI) be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE PSI is supported. + * @retval FALSE PSI cannot be enabled. + * + */ +BOOLEAN +STATIC +IsPsiFeatureEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + BOOLEAN IsEnabled; + PSI_FAMILY_SERVICES *PsiFamilyServices; + UINT32 VrmType; + + IsEnabled = FALSE; + + for (VrmType = 0; VrmType < MaxVrmType; VrmType++) { + if (PlatformConfig->VrmProperties[VrmType].LowPowerThreshold != 0) { + IsEnabled = TRUE; + break; + } + } + + if (!IsEnabled) { + return FALSE; + } + + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&PsiFamilyServiceTable, Socket, (CONST VOID **)&PsiFamilyServices, StdHeader); + if ((PsiFamilyServices == NULL) || (!PsiFamilyServices->IsPsiSupported (PsiFamilyServices, Socket, PlatformConfig, StdHeader))) { + IsEnabled = FALSE; + break; + } + } + } + return IsEnabled; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable Power Status Indicator (PSI) + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +STATIC +InitializePsiFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + AGESA_STATUS AgesaStatus; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + + IDS_HDT_CONSOLE (CPU_TRACE, " PSI mode is being initialized\n"); + + CpuEarlyParams.PlatformConfig = *PlatformConfig; + + TaskPtr.FuncAddress.PfApTaskIOC = EnablePsiOnSocket; + TaskPtr.DataTransfer.DataSizeInDwords = 2; + TaskPtr.DataTransfer.DataPtr = &EntryPoint; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS | TASK_HAS_OUTPUT; + AgesaStatus = OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, &CpuEarlyParams); + + IDS_HDT_CONSOLE (CPU_TRACE, " PSI mode is enabled\n"); + + return AgesaStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * AP task to enable PSI + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] StdHeader Config Handle for library, services. + * @param[in] CpuEarlyParams Service parameters. + * + */ +UINT32 +STATIC +EnablePsiOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ) +{ + AGESA_STATUS CalledStatus; + PSI_FAMILY_SERVICES *PsiFamilyServices; + + CalledStatus = AGESA_UNSUPPORTED; + GetFeatureServicesOfCurrentCore (&PsiFamilyServiceTable, (CONST VOID **)&PsiFamilyServices, StdHeader); + if (PsiFamilyServices != NULL) { + CalledStatus = PsiFamilyServices->EnablePsiOnSocket (PsiFamilyServices, *((UINT64 *) EntryPoint), &CpuEarlyParams->PlatformConfig, StdHeader); + } + return (UINT32) CalledStatus; +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeaturePsi = +{ + CpuPsi, + (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC), + IsPsiFeatureEnabled, + InitializePsiFeature +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.h new file mode 100644 index 0000000000..ad2a5e545c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPsi.h @@ -0,0 +1,130 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Power Status Indicator (PSI) Functions declarations. + * + * Contains code that declares the AGESA CPU PSI related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_PSI_H_ +#define _CPU_PSI_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (PSI_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if Power Status Indicator (PSI) is supported. + * + * @param[in] PsiServices PSI services. + * @param[in] Socket Zero-based socket number. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE PSI is supported. + * @retval FALSE PSI is not supported. + * + */ +typedef BOOLEAN F_PSI_IS_SUPPORTED ( + IN PSI_FAMILY_SERVICES *PsiServices, + IN UINT32 Socket, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_PSI_IS_SUPPORTED *PF_PSI_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable PSI. + * + * @param[in] PsiServices PSI services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_PSI_INIT ( + IN PSI_FAMILY_SERVICES *PsiServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_PSI_INIT *PF_PSI_INIT; + +/** + * Provide the interface to the PSI Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +typedef struct _PSI_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_PSI_IS_SUPPORTED IsPsiSupported; ///< Method: Family specific call to check if PSI is supported. + PF_PSI_INIT EnablePsiOnSocket; ///< Method: Family specific call to enable PSI. +} PSI_FAMILY_SERVICES; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_PSI_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateGather.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateGather.c new file mode 100644 index 0000000000..796b455e25 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateGather.c @@ -0,0 +1,410 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Pstate Data Gather Function. + * + * Contains code to collect all the Pstate related information from MSRs, and PCI registers. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "OptionPstate.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuPostInit.h" +#include "Ids.h" +#include "cpuFamilyTranslation.h" +#include "cpuPstateTables.h" +#include "cpuApicUtilities.h" +#include "cpuFeatures.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUPSTATEGATHER_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +extern OPTION_PSTATE_POST_CONFIGURATION OptionPstatePostConfiguration; // global user config record +extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable; + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +PStateGatherStub ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr + ); + +AGESA_STATUS +PStateGatherMain ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr + ); + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +VOID +PStateGather ( + IN OUT VOID *PStateBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + *--------------------------------------------------------------------------------------- + * + * PStateGatherData + * + * Description: + * This function will gather PState information from the MSRs and fill up the + * pStateBuf. This buffer will be used by the PState Leveling, and PState Table + * generation code later. + * + * Parameters: + * @param[in] *PlatformConfig + * @param[in, out] *PStateStrucPtr + * @param[in] *StdHeader + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +PStateGatherData ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + + AGESA_STATUS AgesaStatus; + + AGESA_TESTPOINT (TpProcCpuEntryPstateGather, StdHeader); + AgesaStatus = AGESA_SUCCESS; + + // Gather data for ACPI Tables if ACPI P-States/C-States object generation is enabled. + if ((PlatformConfig->UserOptionPState) || (IsFeatureEnabled (IoCstate, PlatformConfig, StdHeader))) { + AgesaStatus = (*(OptionPstatePostConfiguration.PstateGather)) (StdHeader, PStateStrucPtr); + // Note: Split config struct into PEI/DXE halves. This one is PEI. + } + + return AgesaStatus; +} + +/**-------------------------------------------------------------------------------------- + * + * PStateGatherStub + * + * Description: + * This is the default routine for use when the PState option is NOT requested. + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * Parameters: + * @param[in] *StdHeader + * @param[in, out] *PStateStrucPtr + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +PStateGatherStub ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr + ) +{ + return AGESA_UNSUPPORTED; +} + +/**-------------------------------------------------------------------------------------- + * + * PStateGatherMain + * + * Description: + * This is the common routine for BSP gathering the Pstate data. + * + * Parameters: + * @param[in] *StdHeader + * @param[in, out] *PStateStrucPtr + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +PStateGatherMain ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr + ) +{ + AP_TASK TaskPtr; + UINT32 BscSocket; + UINT32 Ignored; + UINT32 PopulatedSockets; + UINT32 NumberOfSockets; + UINT32 Socket; + AGESA_STATUS IgnoredSts; + PSTATE_LEVELING *PStateBufferPtr; + PSTATE_CPU_FAMILY_SERVICES *FamilyServices; + UINT32 MaxState; + UINT8 IgnoredByte; + + ASSERT (IsBsp (StdHeader, &IgnoredSts)); + + FamilyServices = NULL; + GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + PopulatedSockets = 1; + PStateBufferPtr = PStateStrucPtr->PStateLevelingStruc; + + NumberOfSockets = GetPlatformNumberOfSockets (); + IdentifyCore (StdHeader, &BscSocket, &Ignored, &Ignored, &IgnoredSts); + + PStateStrucPtr->SizeOfBytes = sizeof (S_CPU_AMD_PSTATE); + + MaxState = 0; + FamilyServices->GetPstateMaxState (FamilyServices, &MaxState, &IgnoredByte, StdHeader); + + TaskPtr.FuncAddress.PfApTaskI = PStateGather; + // + // Calculate max buffer size in dwords that need to pass to ap task. + // + TaskPtr.DataTransfer.DataSizeInDwords = (UINT16) ((MaxState + 1) * (SIZE_IN_DWORDS (S_PSTATE_VALUES))); + TaskPtr.ExeFlags = WAIT_FOR_CORE; + TaskPtr.DataTransfer.DataPtr = PStateBufferPtr; + TaskPtr.DataTransfer.DataTransferFlags = DATA_IN_MEMORY; + + // + //Get P-States and fill the PStateBufferPtr for BSP + // + ApUtilTaskOnExecutingCore (&TaskPtr, StdHeader, NULL); + + // + //Calculate next node buffer address + // + PStateBufferPtr->SocketNumber = (UINT8) BscSocket; + PStateBufferPtr->PStateLevelingSizeOfBytes = (UINT16) (sizeof (PSTATE_LEVELING) + (UINT32) (PStateBufferPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES))); + PStateStrucPtr->SizeOfBytes += (UINT32) (PStateBufferPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES)); + PStateBufferPtr = (PSTATE_LEVELING *) ((UINT8 *) PStateBufferPtr + (UINTN) sizeof (PSTATE_LEVELING) + (UINTN) (PStateBufferPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES))); + CpuGetPStateLevelStructure (&PStateBufferPtr, PStateStrucPtr, 1, StdHeader); + // + //Get CPU P-States and fill the PStateBufferPtr for each node(BSC) + // + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (Socket != BscSocket) { + if (IsProcessorPresent (Socket, StdHeader)) { + PopulatedSockets++; + LibAmdMemFill (PStateBufferPtr, 0, sizeof (PSTATE_LEVELING), StdHeader); + TaskPtr.DataTransfer.DataPtr = PStateBufferPtr; + ApUtilRunCodeOnSocketCore ((UINT8)Socket, 0, &TaskPtr, StdHeader); + PStateBufferPtr->SocketNumber = (UINT8) Socket; + // + //Calculate next node buffer address + // + PStateBufferPtr->PStateLevelingSizeOfBytes = (UINT16) (sizeof (PSTATE_LEVELING) + (UINT32) (PStateBufferPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES))); + PStateStrucPtr->SizeOfBytes += PStateBufferPtr->PStateLevelingSizeOfBytes; + PStateBufferPtr = (PSTATE_LEVELING *) ((UINT8 *) PStateBufferPtr + (UINTN) sizeof (PSTATE_LEVELING) + (UINTN) (PStateBufferPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES))); + } + } + } + PStateStrucPtr->TotalSocketInSystem = PopulatedSockets; + + return AGESA_SUCCESS; +} +/**-------------------------------------------------------------------------------------- + * + * PStateGather + * + * Description: + * This is the common routine run on each BSC for gathering Pstate data. + * + * Parameters: + * @param[in,out] *PStateBuffer + * @param[in] *StdHeader + * + * @retval VOID + * + *--------------------------------------------------------------------------------------- + **/ +VOID +PStateGather ( + IN OUT VOID *PStateBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 k; + UINT32 IddVal; + UINT32 IddDiv; + UINT32 NodeNum; + UINT32 CoreNum; + UINT32 TempVar_c; + UINT32 TotalEnabledPStates; + UINT32 SwPstate; + UINT8 BoostStates; + PCI_ADDR PciAddress; + PSTATE_LEVELING *PStateBufferPtr; + BOOLEAN PStateEnabled; + PSTATE_CPU_FAMILY_SERVICES *FamilyServices; + UINT32 Socket; + AGESA_STATUS IgnoredSts; + CPUID_DATA CpuId; + + PStateBufferPtr = (PSTATE_LEVELING *) PStateBuffer; + TotalEnabledPStates = 0; + FamilyServices = NULL; + PStateEnabled = FALSE; + + GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + // + /// Sockets number: code looking at PStateBufferPtr->TotalCoresInNode + /// needs to know it is Processor (or socket) core count and NOT a Node Core count. + GetActiveCoresInCurrentSocket (&CoreNum, StdHeader); + PStateBufferPtr->TotalCoresInNode = (UINT8) CoreNum; + + // + // Assume current CoreNum always zero.(BSC) + // + GetCurrentNodeAndCore (&NodeNum, &CoreNum, StdHeader); + + PStateBufferPtr->CreateAcpiTables = 1; + + // + // We need to know the max pstate state in this socket. + // + FamilyServices->GetPstateMaxState (FamilyServices, &TempVar_c, &BoostStates, StdHeader); + PStateBufferPtr->PStateCoreStruct[0].PStateMaxValue = (UINT8) TempVar_c; + PStateBufferPtr->PStateCoreStruct[0].NumberOfBoostedStates = BoostStates; + + for (k = 0; k <= TempVar_c; k++) { + // Check if PState is enabled + FamilyServices->GetPstateRegisterInfo ( FamilyServices, + k, + &PStateEnabled, + &IddVal, + &IddDiv, + &SwPstate, + StdHeader); + + LibAmdMemFill (&(PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k]), 0, sizeof (S_PSTATE_VALUES), StdHeader); + + if (PStateEnabled) { + FamilyServices->GetPstateFrequency ( + FamilyServices, + (UINT8) k, + &(PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq), + StdHeader); + + FamilyServices->GetPstatePower ( + FamilyServices, + (UINT8) k, + &(PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k].Power), + StdHeader); + + PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k].IddValue = IddVal; + PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k].IddDiv = IddDiv; + PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k].SwPstateNumber = SwPstate; + + PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 1; + TotalEnabledPStates++; + } + } // for (k = 0; k < MPPSTATE_MAXIMUM_STATES; k++) + + // Don't create ACPI Tables if there is one or less than one PState is enabled + if (TotalEnabledPStates <= 1) { + PStateBufferPtr[0].CreateAcpiTables = 0; + } + + //--------------------Check Again-------------------------------- + + IdentifyCore (StdHeader, &Socket, &NodeNum, &CoreNum, &IgnoredSts); + // Get the PCI address of internal die 0 as it is the only die programmed. + GetPciAddress (StdHeader, Socket, 0, &PciAddress, &IgnoredSts); + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NORTH_BRIDGE_CAPABILITIES_REG; + TempVar_c = 0; + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_c, StdHeader); + PStateBufferPtr->PStateCoreStruct[0].HtcCapable = + (UINT8) ((TempVar_c & 0x00000400) >> 10); // Bit 10 + + TempVar_c = 0; + PciAddress.Address.Register = HARDWARE_THERMAL_CTRL_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_c, StdHeader); + PStateBufferPtr->PStateCoreStruct[0].HtcPstateLimit = + (UINT8) ((TempVar_c & 0x70000000) >> 28); // Bits 30:28 + + // Get LocalApicId from CPUID Fn0000_0001_EBX + LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuId, StdHeader); + PStateBufferPtr->PStateCoreStruct[0].LocalApicId = (UINT8) ((CpuId.EBX_Reg & 0xFF000000) >> 24); +} + + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateHpcMode.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateHpcMode.h new file mode 100644 index 0000000000..f8f41bfeb6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateHpcMode.h @@ -0,0 +1,98 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Pstate HPC mode Functions declarations. + * + * Contains code that declares the AGESA CPU Pstate HPC mode related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_PSTATE_HPC_MODE_H_ +#define _CPU_PSTATE_HPC_MODE_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +AGESA_FORWARD_DECLARATION (PSTATE_HPC_MODE_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable P-state HPC mode + * + * @param[in] PstateHpcModeService P-state HPC mode services. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_PSTATE_HPC_MODE_INIT ( + IN PSTATE_HPC_MODE_FAMILY_SERVICES *PstateHpcModeService, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_PSTATE_HPC_MODE_INIT *PF_PSTATE_HPC_MODE_INIT; + +/** + * Provide the interface to the P-state HPC mode Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _PSTATE_HPC_MODE_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_PSTATE_HPC_MODE_INIT EnablePstateHpcMode; ///< Method: Family specific call to enable P-state HPC mode. +}; +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_PSTATE_HPC_MODE_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateLeveling.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateLeveling.c new file mode 100644 index 0000000000..ab135b9ec6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateLeveling.c @@ -0,0 +1,1100 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Pstate Leveling Function. + * + * Contains code to level the Pstates in a multi-socket system + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "OptionPstate.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "cpuPostInit.h" +#include "Ids.h" +#include "cpuFamilyTranslation.h" +#include "cpuPstateTables.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_FEATURE_CPUPSTATELEVELING_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +extern OPTION_PSTATE_POST_CONFIGURATION OptionPstatePostConfiguration; // global user config record +extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable; + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +PutAllCoreInPState0 ( + IN OUT PSTATE_LEVELING *PStateBufferPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +StartPstateMsrModify ( + IN S_CPU_AMD_PSTATE *CpuAmdPState, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +PutCoreInPState0 ( + IN VOID *PStateBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PStateLevelingStub ( + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PStateLevelingMain ( + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +CorePstateRegModify ( + IN VOID *CpuAmdPState, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + *--------------------------------------------------------------------------------------- + * + * PStateLeveling + * + * Description: + * This function will populate the PStateBuffer, after doing the PState Leveling + * Note: This function should be called for every core in the system. + * + * Parameters: + * @param[in,out] *PStateStrucPtr + * @param[in] *StdHeader + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +PStateLeveling ( + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_TESTPOINT (TpProcCpuEntryPstateLeveling, StdHeader); + return ((*(OptionPstatePostConfiguration.PstateLeveling)) (PStateStrucPtr, StdHeader)); + // Note: Split config struct into PEI/DXE halves. This one is PEI. +} + +/**-------------------------------------------------------------------------------------- + * + * PStateLevelingStub + * + * Description: + * This is the default routine for use when the PState option is NOT requested. + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * Parameters: + * @param[in,out] *PStateStrucPtr + * @param[in] *StdHeader + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +PStateLevelingStub ( + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return AGESA_UNSUPPORTED; +} + +/**-------------------------------------------------------------------------------------- + * + * PStateLevelingMain + * + * Description: + * This is the common routine for creating the ACPI information tables. + * + * Parameters: + * @param[in,out] *PStateStrucPtr + * @param[in] *StdHeader + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +PStateLevelingMain ( + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 i; + UINT32 k; + UINT32 m; + UINT32 TotalIterations; + UINT32 LogicalSocketCount; + UINT32 TempVar_a; + UINT32 TempVar_b; + UINT32 TempVar_c; + UINT32 TempVar_d; + UINT32 TempVar_e; + UINT32 TempVar_f; + PCI_ADDR PciAddress; + + UINT32 TempFreqArray[20]; + UINT32 TempPowerArray[20]; + UINT32 TempIddValueArray[20]; + UINT32 TempIddDivArray[20]; + UINT32 TempSocketPiArray[20]; + UINT32 TempSwP0Array[MAX_SOCKETS_SUPPORTED]; + + BOOLEAN TempFlag1; + BOOLEAN TempFlag2; + BOOLEAN TempFlag3; + BOOLEAN TempFlag4; + BOOLEAN AllCoresHaveHtcCapEquToZeroFlag; + BOOLEAN AllCoreHaveMaxOnePStateFlag; + BOOLEAN PstateMaxValEquToPstateHtcLimitFlag; + BOOLEAN AtLeastOneCoreHasPstateHtcLimitEquToOneFlag; + BOOLEAN PstateMaxValMinusHtcPstateLimitLessThan2Flag; + PSTATE_LEVELING *PStateBufferPtr; + PSTATE_LEVELING *PStateBufferPtrTmp; + UINT32 MaxPstateInNode; + AGESA_STATUS Status; + + TempFlag1 = FALSE; + TempFlag2 = FALSE; + TempFlag3 = FALSE; + TempFlag4 = FALSE; + AllCoresHaveHtcCapEquToZeroFlag = FALSE; + AllCoreHaveMaxOnePStateFlag = FALSE; + PstateMaxValEquToPstateHtcLimitFlag = FALSE; + AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = FALSE; + PstateMaxValMinusHtcPstateLimitLessThan2Flag = FALSE; + PStateBufferPtr = PStateStrucPtr->PStateLevelingStruc; + Status = AGESA_SUCCESS; + + if (PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_1) { + PStateBufferPtr[0].AllCpusHaveIdenticalPStates = TRUE; + PStateBufferPtr[0].InitStruct = 1; + return AGESA_UNSUPPORTED; + } + + LogicalSocketCount = PStateStrucPtr->TotalSocketInSystem; + ASSERT (LogicalSocketCount <= MAX_SOCKETS_SUPPORTED); + + // This section of code will execute only for "core 0" i.e. BSP + // Read P-States of all the cores. + if (PStateBufferPtr[0].InitStruct == 0) { + // Determine 'software' P0 indices for each socket + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + TempSwP0Array[i] = (UINT32) (PStateBufferPtrTmp->PStateCoreStruct[0].NumberOfBoostedStates); + } + + // Check if core frequency and power are same across all sockets. + TempFlag1 = FALSE; + m = TempSwP0Array[0]; + for (i = 1; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue != PStateBufferPtr[0].PStateCoreStruct[0].PStateMaxValue)) { + TempFlag1 = TRUE; + break; + } + MaxPstateInNode = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; + for (k = TempSwP0Array[i]; k <= MaxPstateInNode; k++, m++) { + if ((PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[m].CoreFreq != + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].CoreFreq) || + (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[m].Power != + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].Power)) { + TempFlag1 = TRUE; + break; // Come out of the inner FOR loop + } + } + if (TempFlag1) { + break; // Come out of the outer FOR loop + } + } + + if (!TempFlag1) { + // No need to do pStateLeveling, or writing to pState MSR registers + // if all CPUs have Identical PStates + PStateBufferPtr[0].AllCpusHaveIdenticalPStates = TRUE; + PStateBufferPtr[0].InitStruct = 1; + PutAllCoreInPState0 (PStateBufferPtr, StdHeader); + return AGESA_UNSUPPORTED; + } else { + PStateBufferPtr[0].AllCpusHaveIdenticalPStates = FALSE; + } + + // 1_b) & 1_c) + TempFlag1 = FALSE; + TempFlag2 = FALSE; + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue == TempSwP0Array[i]) { + TempFlag1 = TRUE; + } else { + TempFlag2 = TRUE; + } + if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcCapable == 0) { + TempFlag3 = TRUE; + } else { + TempFlag4 = TRUE; + } + + if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - + PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) < 2) { + PstateMaxValMinusHtcPstateLimitLessThan2Flag = TRUE; + } + + if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue == + PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) { + PstateMaxValEquToPstateHtcLimitFlag = TRUE; + } + + if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 1) { + AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = TRUE; + } + } + + // Do general setup of flags, that we may use later + // Implementation of (1_b) + if (TempFlag1 && TempFlag2) { + // + //Processors with only one enabled P-state (F3xDC[PstateMaxVal]=000b) cannot be mixed in a system with + //processors with more than one enabled P-state (F3xDC[PstateMaxVal]!=000b). + // + PStateBufferPtr[0].InitStruct = 1; + PStateBufferPtr[0].CreateAcpiTables = 0; + PutAllCoreInPState0 (PStateBufferPtr, StdHeader); + return AGESA_UNSUPPORTED; + } else if (TempFlag1 && !TempFlag2) { + // + //all processors have only 1 enabled P-state + // + AllCoreHaveMaxOnePStateFlag = TRUE; + PStateBufferPtr[0].OnlyOneEnabledPState = TRUE; + } + + // Processors with F3xE8[HTC_CAPABLE] = 1 can not be + // mixed in system with processors with F3xE8[HTC_CAPABLE] = 0. + if (TempFlag3 && TempFlag4) { + PStateBufferPtr[0].InitStruct = 1; + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + PStateBufferPtrTmp[0].CreateAcpiTables = 0; + } + PutAllCoreInPState0 (PStateBufferPtr, StdHeader); + return AGESA_UNSUPPORTED; + } + + if (TempFlag3) { + // + //If code run to here means that all processors do not have HTC_CAPABLE. + // + AllCoresHaveHtcCapEquToZeroFlag = TRUE; + } + + //-------------------------------------------------------------------------------- + // S T E P - 2 + //-------------------------------------------------------------------------------- + // Now run the PState Leveling Algorithm which will create mixed CPU P-State + // Tables. + // Follow the algorithm in the latest BKDG + // ------------------------------------------------------------------------------- + // Match P0 CPU COF for all CPU cores to the lowest P0 CPU COF value in the + // coherent fabric, and match P0 power for all CPU cores to the highest P0 power + // value in the coherent fabric. + // 2_a) If all processors have only 1 enabled P-State BIOS must write the + // appropriate CpuFid value resulting from the matched CPU COF to all + // copies of MSRC001_0070[CpuFid], and exit the sequence (No further + // steps are executed) + //-------------------------------------------------------------------------------- + // Identify the lowest P0 Frequency and maximum P0 Power + TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].CoreFreq; + TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].Power; + TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].IddValue; + TempVar_b = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].IddDiv; + + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if (TempVar_d > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq) { + TempVar_d = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq; + } + + if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power) { + TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power; + TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddValue; + TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddDiv; + } + } + + // Set P0 Frequency and Power for all CPUs + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq = TempVar_d; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power = TempVar_e; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddValue = TempVar_a; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddDiv = TempVar_b; + } + + // 2_a) + if (!AllCoreHaveMaxOnePStateFlag) { + //-------------------------------------------------------------------------- + // STEP - 3 + //-------------------------------------------------------------------------- + // Match the CPU COF and power for P-states used by HTC. Skip to step 4 + // is any processor reports F3xE8[HTC_Capable] = 0; + // 3_a) Set F3x64[HtcPstateLimit] = 001b and F3x68[StcPstateLimit] = 001b for + // processors with F3x64[HtcPstateLimit] = 000b. + // 3_b) Identify the lowest CPU COF for all processors in the P-state + // pointed to by [The Hardware Thermal Control (HTC) Register] + // F3x64[HtcPstateLimit] + // 3_c) Modify the CPU COF pointed to by [The Hardware Thermal Control + // (HTC) Register] F3x64[HtcPstateLimit] for all processors to the + // previously identified lowest CPU COF value. + // 3_d) Identify the highest power for all processors in the P-state + // pointed to by [The Hardware Thermal Control (HTC) Register] + // F3x64[HtcPstateLimit]. + // 3_e) Modify the power pointed to by [The Hardware Thermal Control (HTC) + // Register] F3x64[HtcPstateLimit] to the previously identified + // highest power value. + if (!AllCoresHaveHtcCapEquToZeroFlag) { + // 3_a) + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 0) { + // To Be Done (Set Htc and Stc PstateLimit values) + // for this CPU (using PCI address space) + for (k = 0; k < (UINT8)GetPlatformNumberOfModules (); k++) { + if (GetPciAddress (StdHeader, PStateBufferPtrTmp->SocketNumber, k, &PciAddress, &Status)) { + // Set F3x64[HtcPstateLimit] = 001b + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = HARDWARE_THERMAL_CTRL_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader); + // Bits 30:28 + TempVar_d = (TempVar_d & 0x8FFFFFFF) | 0x10000000; + LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader); + + // Set F3x68[StcPstateLimit] = 001b + PciAddress.Address.Register = SOFTWARE_THERMAL_CTRL_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader); + // Bits 28:30 + TempVar_d = (TempVar_d & 0x8FFFFFFF) | 0x10000000; + LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader); + } + } + // Set LocalBuffer + PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit = 1; + if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1) < 2) { + PstateMaxValMinusHtcPstateLimitLessThan2Flag = TRUE; + } + + if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue == 1) { + PstateMaxValEquToPstateHtcLimitFlag = TRUE; + } + } + + if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 1) { + AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = TRUE; + } + } + + // 3_b) and 3_d) + TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit; + TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq; + TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].Power; + TempVar_f = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue; + TempVar_c = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv; + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + for (k = 0; k < 1; k++) { + TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit; + if (TempVar_d > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq) { + TempVar_d = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq; + } + + if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power) { + TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power; + TempVar_f = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddValue; + TempVar_c = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddDiv; + } + } + } + + // 3_c) and 3_e) + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq = TempVar_d; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].Power = TempVar_e; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue = TempVar_f; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv = TempVar_c; + } + } // if(AllCoresHaveHtcCapEquToZeroFlag) + + + //-------------------------------------------------------------------------- + // STEP - 4 + //-------------------------------------------------------------------------- + // Match the CPU COF and power for the lowest performance P-state: + // 4_a) If F3xDC[PstateMaxVal] = F3x64[HtcPstateLimit] for any processor, + // set PstateEn = 0 for all the P-states greater than + // F3x64[HtcPstateLimit] for all processors. + // 4_b) Identify the lowest CPU COF for all processors in the P-state + // pointed to by F3xDC[PstateMaxVal]. + // 4_c) Modify the CPU COF for all processors in the P-state pointed to by + // F3xDC[PstateMaxVal] to the previously identified lowest CPU COF + // value. + // 4_d) Identify the highest power for all processors in the P-state + // pointed to by F3xDC[PstateMaxVal]. + // 4_e) Modify the power for all processors in the P-state pointed to by + // F3xDC[PstateMaxVal] to the previously identified highest power + // value. + + // 4_a) + if (PstateMaxValEquToPstateHtcLimitFlag) { + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit + 1; + for (k = TempVar_b; k <= PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; k++) { + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0; + } + //-------------------------------------------------------------------------- + // STEP - 5 + //-------------------------------------------------------------------------- + // 5_a) Modify F3xDC[PstateMaxVal] to indicate the lowest performance + // P-state with PstateEn set for each processor (Step 4 can disable + // P-states pointed to by F3xDC[PstateMaxVal]) + + // Use this value of HtcPstateLimit to program the + // F3xDC[pStateMaxValue] + TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit; + TempVar_e <<= 8; + // Bits 10:8 + + for (m = 0; m < (UINT8)GetPlatformNumberOfModules (); m++) { + if (GetPciAddress (StdHeader, PStateBufferPtrTmp->SocketNumber, m, &PciAddress, &Status)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader); + TempVar_d = (TempVar_d & 0xFFFFF8FF) | TempVar_e; + LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader); + } + }//End of step 5 + } + }// End of 4_a) + + // 4_b) and 4_d) + TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].PStateMaxValue; + TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq; + TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].Power; + TempVar_f = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue; + TempVar_c = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv; + + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; + if (TempVar_d > + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq) { + TempVar_d = + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq; + } + + if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power) { + TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power; + TempVar_f = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddValue; + TempVar_c = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddDiv; + } + } + + // 4_c) and 4_e) + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq = TempVar_d; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].Power = TempVar_e; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue = TempVar_f; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv = TempVar_c; + } + + + //-------------------------------------------------------------------------- + // STEP - 6 + //-------------------------------------------------------------------------- + // Match the CPU COF and power for upper intermediate performance + // P-state(s): + // Upper intermediate PStates = PStates between (Not including) P0 and + // F3x64[HtcPstateLimit] + // 6_a) If F3x64[HtcPstateLimit] = 001b for any processor, set PstateEn = 0 + // for enabled upper intermediate P-states for all processors with + // F3x64[HtcPstateLimit] > 001b and skip the remaining actions for + // this numbered step. + // 6_b) Define each of the available upper intermediate P-states; for each + // processor concurrently evaluate the following loop; when any + // processor falls out of the loop (runs out of available upper + // intermediate Pstates) all other processors have their remaining + // upper intermediate P-states invalidated (PstateEn = 0); + // for (i = F3x64[HtcPstateLimit] - 1; i > 0; i--) + // - Identify the lowest CPU COF for P(i). + // - Identify the highest power for P(i). + // - Modify P(i) CPU COF for all processors to the previously + // identified lowest CPU COF value. + // - Modify P(i) power for all processors to the previously + // identified highest power value. + + // 6_a) + if (AtLeastOneCoreHasPstateHtcLimitEquToOneFlag) { + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + for (k = TempSwP0Array[i] + 1; k < (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit); k++) { + if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit > 1) { + // Make a function call to clear the + // structure values + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0; + } + } + } + } + // 6_b) + else { + // Identify Lowest Frequency and Highest Power + TotalIterations = 0; + TempFlag1 = TRUE; + + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + TempSocketPiArray[i] = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit - 1; + } + + do { + //For first socket, try to find a candidate + if (TempSocketPiArray[0] != TempSwP0Array[0]) { + while (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].PStateEnable == 0) { + TempSocketPiArray[0] = TempSocketPiArray[0] - 1; + if (TempSocketPiArray[0] == TempSwP0Array[0]) { + TempFlag1 = FALSE; + break; + } + } + } else { + TempFlag1 = FALSE; + } + if (TempFlag1) { + TempFreqArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].CoreFreq; + TempPowerArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].Power; + TempIddValueArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddValue; + TempIddDivArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddDiv; + + //Try to find next candidate + for (i = 1; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if (TempSocketPiArray[i] != TempSwP0Array[i]) { + while (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].PStateEnable == 0) { + TempSocketPiArray[i]--; + if (TempSocketPiArray[i] == TempSwP0Array[i]) { + TempFlag1 = FALSE; + break; + } + }//end while + } else { + TempFlag1 = FALSE; + } + + } //end for LogicalSocketCount + } + + if (TempFlag1) { + for (i = 0; i < LogicalSocketCount; i++) { + // + //Compare + // + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if (TempFreqArray[TotalIterations] > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq) { + TempFreqArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq; + } + + if (TempPowerArray[TotalIterations] < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power) { + TempPowerArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power; + TempIddValueArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue; + TempIddDivArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv; + } + } + // Modify (Pi) CPU COF and Power for all the CPUs + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq = TempFreqArray[TotalIterations]; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power = TempPowerArray[TotalIterations]; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue = TempIddValueArray[TotalIterations]; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv = TempIddDivArray[TotalIterations]; + TempSocketPiArray[i] = TempSocketPiArray[i] - 1; + } + } else { + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + for (m = TempSocketPiArray[i]; m > TempSwP0Array[i]; m--) { + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[m].PStateEnable = 0; + } + } + } + + TotalIterations++; + } while (TempFlag1); + + } // else + + //-------------------------------------------------------------------------- + // STEP - 7 + //-------------------------------------------------------------------------- + // Match the CPU COF and power for lower intermediate performance P - state(s) + // Lower Intermediate Pstates = Pstates between (not including) + // F3x64[HtcPstateLimit] and F3xDC[PstateMaxVal] + // 7_a) If F3xDC[PstateMaxVal] - F3x64[HtcPstateLimit] < 2 for any + // processor, set PstateEn = 0 for enabled lower intermediate P - states + // for all processors with (F3xDC[PstateMaxVal] - + // F3x64[HtcPstateLimit] > 1) and skip the remaining actions for this + // numbered step. + // 7_b) Define each of the available lower intermediate P-states; for each + // processor concurrently evaluate the following loop; when any + // processor falls out of the loop (runs out of available lower + // intermediate Pstates) all other processors have their remaining + // lower intermediate P-states invalidated (PstateEn = 0); + // for (i = F3xDC[PstateMaxVal]-1; i > F3x64[HtcPstateLimit]; i--) + // - Identify the lowest CPU COF for P-states between + // (not including) F3x64[HtcPstateLimit] and P(i). + // - Identify the highest power for P-states between + // (not including) F3x64[HtcPstateLimit] and P(i). + // - Modify P(i) CPU COF for all processors to the previously + // identified lowest CPU COF value. + // - Modify P(i) power for all processors to the previously + // identified highest power value. + + + // 7_a) + if (PstateMaxValMinusHtcPstateLimitLessThan2Flag) { + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + + for (k = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1; + k > PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit; + k--) { + if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - + PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) > 1) { + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0; + } + } + } + } + + // 7_b) + else { + // Identify Lowest Frequency and Highest Power + + TotalIterations = 0; + TempFlag1 = TRUE; + + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + TempSocketPiArray[i] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1; + } + + do { + //For first socket, try to find a candidate + if (TempSocketPiArray[0] != PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit) { + while (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].PStateEnable == 0) { + TempSocketPiArray[0] = TempSocketPiArray[0] - 1; + if (TempSocketPiArray[0] == PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit) { + TempFlag1 = FALSE; + break; + } + } + } else { + TempFlag1 = FALSE; + } + if (TempFlag1) { + TempFreqArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].CoreFreq; + TempPowerArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].Power; + TempIddValueArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddValue; + TempIddDivArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddDiv; + + //Try to find next candidate + for (i = 1; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if (TempSocketPiArray[i] != PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) { + while (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].PStateEnable == 0) { + TempSocketPiArray[i]--; + if (TempSocketPiArray[i] == PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) { + TempFlag1 = FALSE; + break; + } + }//end while + } else { + TempFlag1 = FALSE; + } + } //end for LogicalSocketCount + } + + if (TempFlag1) { + for (i = 0; i < LogicalSocketCount; i++) { + // + //Compare + // + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if (TempFreqArray[TotalIterations] > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq) { + TempFreqArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq; + } + if (TempPowerArray[TotalIterations] < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power) { + TempPowerArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power; + TempIddValueArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue; + TempIddDivArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv; + } + } + // Modify (Pi) CPU COF and Power for all the CPUs + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq = TempFreqArray[TotalIterations]; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power = TempPowerArray[TotalIterations]; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue = TempIddValueArray[TotalIterations]; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv = TempIddDivArray[TotalIterations]; + TempSocketPiArray[i] = TempSocketPiArray[i] - 1; + } + } else { + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + for (m = TempSocketPiArray[i]; m > PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit; m--) { + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[m].PStateEnable = 0; + } + } + } + TotalIterations++; + } while (TempFlag1); + } // else + } // if(!AllCoreHaveMaxOnePStateFlag) + + PStateBufferPtr[0].InitStruct = 1; + } // CurrentCore + + + // Update the pState MSRs + // This can be done only by individual core + StartPstateMsrModify (PStateStrucPtr, StdHeader); + + //---------------------------------------------------------------------------------- + // STEP - 8 + //---------------------------------------------------------------------------------- + // Place all cores into a valid COF and VID configuration corresponding to an + // enabled P-state: + // 8_a) Select an enabled P-state != to the P-state pointed to by + // MSRC001_0063[CurPstate] for each core. + // 8_b) Transition all cores to the selected P-states by writing the Control value + // from the_PSS object corresponding to the selected P-state to + // MSRC001_0062[PstateCmd]. + // 8_c) Wait for all cores to report the Status value from the _PSS object + // corresponding to the selected P-state in MSRC001_0063[CurPstate]. + // + PutAllCoreInPState0 (PStateBufferPtr, StdHeader); + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/** + *--------------------------------------------------------------------------------------- + * + * PutAllCoreInPState0 + * + * Description: + * This function will put core pstate to p0. + * + * Parameters: + * @param[in,out] *PStateBufferPtr + * @param[in] *StdHeader + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +PutAllCoreInPState0 ( + IN OUT PSTATE_LEVELING *PStateBufferPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + UINT32 BscSocket; + UINT32 Ignored; + UINT32 BscCoreNum; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + AGESA_STATUS IgnoredSts; + + TaskPtr.FuncAddress.PfApTaskI = PutCoreInPState0; + TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (PSTATE_LEVELING); + TaskPtr.ExeFlags = WAIT_FOR_CORE; + TaskPtr.DataTransfer.DataPtr = PStateBufferPtr; + TaskPtr.DataTransfer.DataTransferFlags = DATA_IN_MEMORY; + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + PutCoreInPState0 (PStateBufferPtr, StdHeader); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != (UINT32) BscSocket) || (Core != (UINT32) BscCoreNum)) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); + } + } + } + } + + return AGESA_SUCCESS; +} + +/** + *--------------------------------------------------------------------------------------- + * + * CorePstateRegModify + * + * Description: + * This function will setting the Pstate MSR to each APs base on Pstate Buffer. + * Note: This function should be called for every core in the system. + * + * Parameters: + * @param[in,out] *CpuAmdPState + * @param[in] *StdHeader + * + * @retval VOID + * + *--------------------------------------------------------------------------------------- + **/ +VOID +CorePstateRegModify ( + IN VOID *CpuAmdPState, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PSTATE_CPU_FAMILY_SERVICES *FamilySpecificServices; + FamilySpecificServices = NULL; + + GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilySpecificServices, StdHeader); + ASSERT (FamilySpecificServices != NULL) + FamilySpecificServices->SetPStateLevelReg (FamilySpecificServices, (S_CPU_AMD_PSTATE *) CpuAmdPState, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will set msr on all cores of all nodes. + * + * @param[in] CpuAmdPState Pointer to S_CPU_AMD_PSTATE. + * @param[in] StdHeader Header for library and services. + * + * @retval AGESA_SUCCESS Always succeeds + * + */ +AGESA_STATUS +StartPstateMsrModify ( + IN S_CPU_AMD_PSTATE *CpuAmdPState, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + UINT32 BscSocket; + UINT32 Ignored; + UINT32 BscCoreNum; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + AGESA_STATUS IgnoredSts; + + TaskPtr.FuncAddress.PfApTaskI = CorePstateRegModify; + TaskPtr.DataTransfer.DataSizeInDwords = (UINT16) (CpuAmdPState->SizeOfBytes / 4 + 1); + TaskPtr.ExeFlags = WAIT_FOR_CORE; + TaskPtr.DataTransfer.DataPtr = CpuAmdPState; + TaskPtr.DataTransfer.DataTransferFlags = DATA_IN_MEMORY; + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + CorePstateRegModify (CpuAmdPState, StdHeader); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != (UINT32) BscSocket) || (Core != (UINT32) BscCoreNum)) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); + } + } + } + } + + return AGESA_SUCCESS; +} + + +/** + *--------------------------------------------------------------------------------------- + * + * CpuGetPStateLevelStructure + * + * Description: + * Based on the LogicalSocketNumber, this function will return a pointer + * point to the accurate offset of the PSTATE_LEVELING structure. + * + * Parameters: + * @param[in,out] *PStateBufferPtr + * @param[in] *CpuAmdPState + * @param[in] LogicalSocketNumber + * @param[in] *StdHeader + * + * @retval VOID + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +CpuGetPStateLevelStructure ( + OUT PSTATE_LEVELING **PStateBufferPtr, + IN S_CPU_AMD_PSTATE *CpuAmdPState, + IN UINT32 LogicalSocketNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PSTATE_LEVELING *PStateBufferPtrTmp; + UINT32 i; + + if (LogicalSocketNumber > CpuAmdPState->TotalSocketInSystem) { + return AGESA_UNSUPPORTED; + } + + PStateBufferPtrTmp = CpuAmdPState->PStateLevelingStruc; + + for (i = 1; i <= LogicalSocketNumber; i++) { + PStateBufferPtrTmp = (PSTATE_LEVELING *) ((UINT8 *) PStateBufferPtrTmp + ((UINTN) PStateBufferPtrTmp->PStateLevelingSizeOfBytes)); + } + + *PStateBufferPtr = PStateBufferPtrTmp; + + return AGESA_SUCCESS; +} + + +/** + *--------------------------------------------------------------------------------------- + * + * PutCoreInPState0 + * + * Description: + * This function will take the CPU core into P0 + * + * Parameters: + * @param[in] *PStateBuffer + * @param[in] *StdHeader + * + * @retval VOID + * + *--------------------------------------------------------------------------------------- + **/ +VOID +STATIC +PutCoreInPState0 ( + IN VOID *PStateBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + PSTATE_LEVELING *PStateBufferPtr; + + PStateBufferPtr = (PSTATE_LEVELING *) PStateBuffer; + + if ((PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_1 ) || + (PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_2)) { + return; + } + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) FALSE, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.c new file mode 100644 index 0000000000..3be6fea352 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.c @@ -0,0 +1,940 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD PSTATE, ACPI table related API functions. + * + * Contains code that generates the _PSS, _PCT, and other ACPI tables. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "OptionPstate.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "heapManager.h" +#include "Ids.h" +#include "Filecode.h" +#include "GeneralServices.h" +#include "cpuPstateTables.h" +#include "cpuFeatures.h" +#include "cpuIoCstate.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FEATURE_CPUPSTATETABLES_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +extern OPTION_PSTATE_LATE_CONFIGURATION OptionPstateLateConfiguration; // global user config record +extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable; +extern CPU_FAMILY_SUPPORT_TABLE IoCstateFamilyServiceTable; + +STATIC ACPI_TABLE_HEADER ROMDATA CpuSsdtHdrStruct = +{ + {'S','S','D','T'}, + 0, + 1, + 0, + {0}, + {0}, + 1, + {'A','M','D',' '}, + 1 +}; + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +UINT32 +STATIC +CalAcpiTablesSize ( + IN S_CPU_AMD_PSTATE *AmdPstatePtr, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GenerateSsdtStub ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SsdtPtr + ); + +UINT32 +CreateAcpiTablesStub ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PSTATE_LEVELING *PStateLevelingBuffer, + IN OUT VOID **SsdtPtr, + IN UINT8 LocalApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +CreatePStateAcpiTables ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PSTATE_LEVELING *PStateLevelingBuffer, + IN OUT VOID **SsdtPtr, + IN UINT8 LocalApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +CreateCStateAcpiTables ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PSTATE_LEVELING *PStateLevelingBuffer, + IN OUT VOID **SsdtPtr, + IN UINT8 LocalApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GenerateSsdt ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SsdtPtr + ); + +/** + *--------------------------------------------------------------------------------------- + * + * CalAcpiTablesSize + * + * Description: + * This function will calculate the size of ACPI PState tables + * + * Parameters: + * @param[in] *AmdPstatePtr + * @param[in] *PlatformConfig + * @param[in] *StdHeader + * + * @retval UINT32 + * + *--------------------------------------------------------------------------------------- + */ +UINT32 +STATIC +CalAcpiTablesSize ( + IN S_CPU_AMD_PSTATE *AmdPstatePtr, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ScopeSize; + UINT32 CoreCount; + UINT32 SocketCount; + UINT32 MaxCoreNumberInCurrentSocket; + UINT32 MaxSocketNumberInSystem; + UINT32 MaxPstateNumberInCurrentCore; + UINT32 CstateAcpiObjSize; + PSTATE_LEVELING *PStateLevelingBufferStructPtr; + IO_CSTATE_FAMILY_SERVICES *IoCstateFamilyServices; + + ScopeSize = sizeof (ACPI_TABLE_HEADER); + CstateAcpiObjSize = 0; + IoCstateFamilyServices = NULL; + + PStateLevelingBufferStructPtr = AmdPstatePtr->PStateLevelingStruc; + MaxSocketNumberInSystem = AmdPstatePtr->TotalSocketInSystem; + + if (IsFeatureEnabled (IoCstate, PlatformConfig, StdHeader)) { + GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&IoCstateFamilyServices, StdHeader); + if (IoCstateFamilyServices != NULL) { + CstateAcpiObjSize = IoCstateFamilyServices->GetAcpiCstObj (IoCstateFamilyServices, PlatformConfig, StdHeader); + } + } + + for (SocketCount = 0; SocketCount < MaxSocketNumberInSystem; SocketCount++) { + MaxCoreNumberInCurrentSocket = PStateLevelingBufferStructPtr->TotalCoresInNode; + for (CoreCount = 0; CoreCount < MaxCoreNumberInCurrentSocket; CoreCount++) { + MaxPstateNumberInCurrentCore = PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue + 1; + + ScopeSize += (SCOPE_STRUCT_SIZE - 1); // Scope size per core + ScopeSize += CstateAcpiObjSize; // C-State ACPI objects size per core + + // Add P-State ACPI Objects size per core + if ((PStateLevelingBufferStructPtr[0].CreateAcpiTables != 0) && (PlatformConfig->UserOptionPState)) { + ScopeSize += (PCT_STRUCT_SIZE + + PSS_HEADER_STRUCT_SIZE + + (MaxPstateNumberInCurrentCore * PSS_BODY_STRUCT_SIZE) + + XPSS_HEADER_STRUCT_SIZE + + (MaxPstateNumberInCurrentCore * XPSS_BODY_STRUCT_SIZE) + + PSD_HEADER_STRUCT_SIZE + + PSD_BODY_STRUCT_SIZE + + PPC_HEADER_BODY_STRUCT_SIZE); + } + } + ScopeSize += MaxCoreNumberInCurrentSocket; + PStateLevelingBufferStructPtr = (PSTATE_LEVELING *) ((UINT8 *) PStateLevelingBufferStructPtr + (UINTN) sizeof (PSTATE_LEVELING) + (UINTN) (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES))); + } + AmdPstatePtr->SizeOfBytes = ScopeSize; + + return ScopeSize; +} + +/**-------------------------------------------------------------------------------------- + * + * GenerateSsdtStub + * + * Description: + * This is the default routine for use when both PState and CState option is NOT + * requested. The option install process will create and fill the transfer vector + * with the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * Parameters: + * @param[in] StdHeader Handle to config for library and services + * @param[in] PlatformConfig Contains the power cap parameter + * @param[in,out] SsdtPtr ACPI SSDT table pointer + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +GenerateSsdtStub ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SsdtPtr + ) +{ + return AGESA_UNSUPPORTED; +} + +/** + *--------------------------------------------------------------------------------------- + * + * GenerateSsdt + * + * Description: + * This function will populate the SSDT with ACPI P-States and C-States Objects, whenever + * necessary + * This function should be called only from BSP + * + * Parameters: + * @param[in] StdHeader Handle to config for library and services + * @param[in] PlatformConfig Contains the power cap parameter + * @param[in,out] SsdtPtr ACPI SSDT pointer + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GenerateSsdt ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SsdtPtr + ) +{ + UINT32 i; + UINT32 j; + UINT32 TempVar8_a; + UINT32 CurrSize; + UINT32 TempVar_a; + UINT32 TempVar_b; + UINT32 ScopeSize; + UINT32 CoreCount; + UINT32 SocketCount; + UINT32 MaxCorePerNode; + UINT8 LocalApicId; + UINT8 *IntermediatePtr; + AGESA_STATUS AgesaStatus; + LOCATE_HEAP_PTR LocateHeapParams; + ALLOCATE_HEAP_PARAMS AllocateHeapParams; + S_CPU_AMD_PSTATE *AmdPstatePtr; + PSTATE_LEVELING *PStateLevelingBufferStructPtr; + SCOPE *ScopeAcpiTablesStructPtr; + SCOPE *ScopeAcpiTablesStructPtrTemp; + + AGESA_TESTPOINT (TpProcCpuEntryPstate, StdHeader); + + ASSERT (IsBsp (StdHeader, &AgesaStatus)); + + // If P-State and C-State ACPI tables do not need to be generated, exit this routine + if ((!PlatformConfig->UserOptionPState) && (!IsFeatureEnabled (IoCstate, PlatformConfig, StdHeader))) { + AgesaStatus = AGESA_UNSUPPORTED; + return AgesaStatus; + } + + // Initialize data variables + ScopeSize = 0; + CoreCount = 0; + LocalApicId = 0; + CurrSize = 0; + + // Locate P-State data buffer + LocateHeapParams.BufferHandle = AMD_PSTATE_DATA_BUFFER_HANDLE; + AGESA_TESTPOINT (TpProcCpuBeforeLocateSsdtBuffer, StdHeader); + if (HeapLocateBuffer (&LocateHeapParams, StdHeader) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpProcCpuAfterLocateSsdtBuffer, StdHeader); + + AmdPstatePtr = (S_CPU_AMD_PSTATE *) LocateHeapParams.BufferPtr; + PStateLevelingBufferStructPtr = AmdPstatePtr->PStateLevelingStruc; + + // Allocate rough buffer for AcpiTable, if SsdtPtr is NULL + if (*SsdtPtr == NULL) { + //Do not know the actual size.. pre-calculate it. + AllocateHeapParams.RequestedBufferSize = CalAcpiTablesSize (AmdPstatePtr, PlatformConfig, StdHeader); + AllocateHeapParams.BufferHandle = AMD_PSTATE_ACPI_BUFFER_HANDLE; + AllocateHeapParams.Persist = HEAP_SYSTEM_MEM; + + AGESA_TESTPOINT (TpProcCpuBeforeAllocateSsdtBuffer, StdHeader); + if (HeapAllocateBuffer (&AllocateHeapParams, StdHeader) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpProcCpuAfterAllocateSsdtBuffer, StdHeader); + *SsdtPtr = AllocateHeapParams.BufferPtr; + } + + IDS_HDT_CONSOLE (CPU_TRACE, " SSDT is created\n"); + + // Copy SSDT header into allocated buffer + LibAmdMemCopy (*SsdtPtr, (VOID *) &CpuSsdtHdrStruct, (UINTN) (sizeof (ACPI_TABLE_HEADER)), StdHeader); + // Update table OEM fields. + LibAmdMemCopy ((VOID *) ((ACPI_TABLE_HEADER *) *SsdtPtr)->OemId, (VOID *) &OptionPstateLateConfiguration.OemIdString, + sizeof (OptionPstateLateConfiguration.OemIdString), StdHeader); + LibAmdMemCopy ((VOID *) ((ACPI_TABLE_HEADER *) *SsdtPtr)->OemTableId, (VOID *) &OptionPstateLateConfiguration.OemTableIdString, + sizeof (OptionPstateLateConfiguration.OemTableIdString), StdHeader); + IntermediatePtr = (UINT8 *) *SsdtPtr; + ScopeAcpiTablesStructPtr = (SCOPE *) &IntermediatePtr[sizeof (ACPI_TABLE_HEADER)]; + + SocketCount = AmdPstatePtr->TotalSocketInSystem; + + // Generate name scope and ACPI objects for every core in the system + for (i = 0; i < SocketCount; i++) { + MaxCorePerNode = PStateLevelingBufferStructPtr->TotalCoresInNode; + for (j = 0; j < MaxCorePerNode; j++) { + CoreCount++; + // Set Name Scope for CPU0, 1, 2, ..... n + // CPU0 to CPUn will name as C000 to Cnnn + // ----------------------------------------- + ScopeAcpiTablesStructPtr->ScopeOpcode = SCOPE_OPCODE; + // This value will be filled at the end of this function + // Since at this time, we don't know how many Pstates we + // would have + ScopeAcpiTablesStructPtr->ScopeLength = 0; + ScopeAcpiTablesStructPtr->ScopeValue1 = SCOPE_VALUE1; + ScopeAcpiTablesStructPtr->ScopeValue2 = SCOPE_VALUE2; + ScopeAcpiTablesStructPtr->ScopeNamePt1a__ = SCOPE_NAME__; + if (PlatformConfig->ProcessorScopeInSb) { + ScopeAcpiTablesStructPtr->ScopeNamePt1a_P = SCOPE_NAME_S; + ScopeAcpiTablesStructPtr->ScopeNamePt1a_R = SCOPE_NAME_B; + } else { + ScopeAcpiTablesStructPtr->ScopeNamePt1a_P = SCOPE_NAME_P; + ScopeAcpiTablesStructPtr->ScopeNamePt1a_R = SCOPE_NAME_R; + } + ScopeAcpiTablesStructPtr->ScopeNamePt1b__ = SCOPE_NAME__; + ASSERT ((PlatformConfig->ProcessorScopeName0 >= 'A') && (PlatformConfig->ProcessorScopeName0 <= 'Z')); + ASSERT (((PlatformConfig->ProcessorScopeName1 >= 'A') && (PlatformConfig->ProcessorScopeName1 <= 'Z')) || \ + ((PlatformConfig->ProcessorScopeName1 >= '0') && (PlatformConfig->ProcessorScopeName1 <= '9')) || \ + (PlatformConfig->ProcessorScopeName1 == '_')); + + ScopeAcpiTablesStructPtr->ScopeNamePt2a_C = PlatformConfig->ProcessorScopeName0; + ScopeAcpiTablesStructPtr->ScopeNamePt2a_P = PlatformConfig->ProcessorScopeName1; + + TempVar8_a = ((CoreCount - 1) >> 4) & 0x0F; + ScopeAcpiTablesStructPtr->ScopeNamePt2a_U = (UINT8) (SCOPE_NAME_0 + TempVar8_a); + + TempVar8_a = (CoreCount - 1) & 0x0F; + if (TempVar8_a < 0xA) { + ScopeAcpiTablesStructPtr->ScopeNamePt2a_0 = (UINT8) (SCOPE_NAME_0 + TempVar8_a); + } else { + ScopeAcpiTablesStructPtr->ScopeNamePt2a_0 = (UINT8) (SCOPE_NAME_A + TempVar8_a - 0xA); + } + // Increment and typecast the pointer + ScopeAcpiTablesStructPtrTemp = ScopeAcpiTablesStructPtr; + ScopeAcpiTablesStructPtrTemp++; + + // Get the Local Apic Id for each core + LocalApicId = PStateLevelingBufferStructPtr->PStateCoreStruct[0].LocalApicId + (UINT8) j; + + // Create P-State ACPI Objects + CurrSize += ((*(OptionPstateLateConfiguration.PstateFeature)) (PlatformConfig, PStateLevelingBufferStructPtr, (VOID *) &ScopeAcpiTablesStructPtrTemp, LocalApicId, StdHeader)); + + // Create C-State ACPI Objects + CurrSize += ((*(OptionPstateLateConfiguration.CstateFeature)) (PlatformConfig, PStateLevelingBufferStructPtr, (VOID *) &ScopeAcpiTablesStructPtrTemp, LocalApicId, StdHeader)); + + // Now update the SCOPE Length field + { + CurrSize += (SCOPE_STRUCT_SIZE - 1); + ScopeSize += CurrSize; + + TempVar_b = ((CurrSize << 4) & 0x0000FF00); + TempVar_b |= ((CurrSize & 0x0000000F) | 0x00000040); + TempVar_a = TempVar_b; + ScopeAcpiTablesStructPtr->ScopeLength = (UINT16) TempVar_a; + CurrSize = 0; + } + + ScopeAcpiTablesStructPtr = ScopeAcpiTablesStructPtrTemp; + } + //Calculate next node buffer address + PStateLevelingBufferStructPtr = (PSTATE_LEVELING *) ((UINT8 *) PStateLevelingBufferStructPtr + (UINTN) sizeof (PSTATE_LEVELING) + (UINTN) (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES))); + } + //Update SSDT header Checksum + ((ACPI_TABLE_HEADER *) *SsdtPtr)->TableLength = (ScopeSize + CoreCount + sizeof (ACPI_TABLE_HEADER)); + ChecksumAcpiTable ((ACPI_TABLE_HEADER *) *SsdtPtr, StdHeader); + + return AGESA_SUCCESS; +} + +/**-------------------------------------------------------------------------------------- + * + * CreateAcpiTablesStub + * + * Description: + * This is the default routine for use when the P-State or C-State option is NOT + * requested. The option install process will create and fill the transfer vector + * with the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * Parameters: + * @param[in] PlatformConfig Platform operational characteristics; power cap + * @param[in] PStateLevelingBuffer Buffer that contains P-State Leveling information + * @param[in,out] SsdtPtr ACPI SSDT table pointer + * @param[in] LocalApicId Local Apic Id + * @param[in] StdHeader Handle to config for library and services + * + * @retval Size of generated ACPI objects + * + *--------------------------------------------------------------------------------------- + **/ +UINT32 +CreateAcpiTablesStub ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PSTATE_LEVELING *PStateLevelingBuffer, + IN OUT VOID **SsdtPtr, + IN UINT8 LocalApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return 0; +} + + +/**-------------------------------------------------------------------------------------- + * + * CreatePStateAcpiTables + * + * Description: + * This is the common routine for creating ACPI P-State objects + * + * Parameters: + * @param[in] PlatformConfig Platform operational characteristics; power cap + * @param[in] PStateLevelingBuffer Buffer that contains P-State Leveling information + * @param[in,out] SsdtPtr ACPI SSDT table pointer + * @param[in] LocalApicId Local Apic Id + * @param[in] StdHeader Handle to config for library and services + * + * @retval Size of generated ACPI P-States objects + * + *--------------------------------------------------------------------------------------- + **/ +UINT32 +CreatePStateAcpiTables ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PSTATE_LEVELING *PStateLevelingBuffer, + IN OUT VOID **SsdtPtr, + IN UINT8 LocalApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PstateCapLevelSupport; + UINT8 PStateMaxValueOnCurrentCore; + BOOLEAN PstateCapEnable; + BOOLEAN PstateCapLevelSupportDetermined; + BOOLEAN IsPsdDependent; + UINT32 k; + UINT32 TempVar_a; + UINT32 TempVar_b; + UINT32 TempVar_c; + UINT32 PstateCapInputMilliWatts; + UINT32 CurrSize; + UINT32 PstateCount; + UINT32 CoreCount1; + UINT32 TransAndBusMastLatency; + UINT32 EffectivePstatesPsdPolicy; + AGESA_STATUS IgnoredStatus; + PCI_ADDR PciAddress; + PCT_HEADER_BODY *pPctAcpiTables; + PSS_HEADER *pPssHeaderAcpiTables; + PSS_BODY *pPssBodyAcpiTables; + XPSS_HEADER *pXpssHeaderAcpiTables; + XPSS_BODY *pXpssBodyAcpiTables; + PSD_HEADER *pPsdHeaderAcpiTables; + PSD_BODY *pPsdBodyAcpiTables; + PPC_HEADER_BODY *pPpcAcpiTables; + PSTATE_CPU_FAMILY_SERVICES *FamilyServices; + + CurrSize = 0; + PstateCount = 0; + PstateCapEnable = FALSE; + PstateCapLevelSupport = DEFAULT_PERF_PRESENT_CAP; + PstateCapLevelSupportDetermined = TRUE; + PstateCapInputMilliWatts = PlatformConfig->PowerCeiling; + ASSERT (PlatformConfig->PstatesPsdPolicy < PsdPolicyMax); + + EffectivePstatesPsdPolicy = PlatformConfig->PstatesPsdPolicy; + // Runtime P-state dependence settings conflict check and consolidation + if (PlatformConfig->ForcePstateIndependent) { + switch (EffectivePstatesPsdPolicy) { + case PsdPolicyProcessorDefault: + // Consolidate P-state dependence setings + EffectivePstatesPsdPolicy = PsdPolicyIndependent; + break; + case PsdPolicyDependent: + // Ensure P-state dependence settings do not conflict + IDS_HDT_CONSOLE (CPU_TRACE, " P-state PSD dependence settings conflict between ForcePstateIndependent and PstatesPsdPolicy. PstatesPsdPolicy will take precedence.\n"); + ASSERT (FALSE); + break; + case PsdPolicyIndependent: + // Do nothing. Two interfaces have the same setting. + break; + default: + // Invalid setting, overrides to processor default. + IDS_HDT_CONSOLE (CPU_TRACE, " P-state PSD dependence settings invalid! Override PstatesPsdPolicy to PsdPolicyProcessorDefault.\n"); + EffectivePstatesPsdPolicy = PsdPolicyProcessorDefault; + break; + } + } + + TransAndBusMastLatency = 0; + + if ((PStateLevelingBuffer[0].CreateAcpiTables != 0) && (PlatformConfig->UserOptionPState)) { + pPctAcpiTables = (PCT_HEADER_BODY *) *SsdtPtr; + + //Check Pstate Capability + if (PstateCapInputMilliWatts != 0) { + PstateCapEnable = TRUE; + PstateCapLevelSupportDetermined = FALSE; + } + + PStateMaxValueOnCurrentCore = PStateLevelingBuffer->PStateCoreStruct[0].PStateMaxValue; + if (OptionPstateLateConfiguration.CfgPstatePct) { + // Set _PCT Table + // -------------- + pPctAcpiTables->NameOpcode = NAME_OPCODE; + pPctAcpiTables->PctName_a__ = PCT_NAME__; + pPctAcpiTables->PctName_a_P = PCT_NAME_P; + pPctAcpiTables->PctName_a_C = PCT_NAME_C; + pPctAcpiTables->PctName_a_T = PCT_NAME_T; + pPctAcpiTables->Value1 = PCT_VALUE1; + pPctAcpiTables->Value2 = PCT_VALUE2; + pPctAcpiTables->Value3 = PCT_VALUE3; + pPctAcpiTables->GenericRegDescription1 = GENERIC_REG_DESCRIPTION; + pPctAcpiTables->Length1 = PCT_LENGTH; + pPctAcpiTables->AddressSpaceId1 = PCT_ADDRESS_SPACE_ID; + pPctAcpiTables->RegisterBitWidth1 = PCT_REGISTER_BIT_WIDTH; + pPctAcpiTables->RegisterBitOffset1 = PCT_REGISTER_BIT_OFFSET; + pPctAcpiTables->Reserved1 = PCT_RESERVED; + pPctAcpiTables->ControlRegAddressLo = PCT_CONTROL_REG_LO; + pPctAcpiTables->ControlRegAddressHi = PCT_CONTROL_REG_HI; + pPctAcpiTables->Value4 = PCT_VALUE4; + pPctAcpiTables->Value5 = PCT_VALUE5; + pPctAcpiTables->GenericRegDescription2 = GENERIC_REG_DESCRIPTION; + pPctAcpiTables->Length2 = PCT_LENGTH; + pPctAcpiTables->AddressSpaceId2 = PCT_ADDRESS_SPACE_ID; + pPctAcpiTables->RegisterBitWidth2 = PCT_REGISTER_BIT_WIDTH; + pPctAcpiTables->RegisterBitOffset2 = PCT_REGISTER_BIT_OFFSET; + pPctAcpiTables->Reserved2 = PCT_RESERVED; + pPctAcpiTables->StatusRegAddressLo = PCT_STATUS_REG_LO; + pPctAcpiTables->StatusRegAddressHi = PCT_STATUS_REG_HI; + pPctAcpiTables->Value6 = PCT_VALUE6; + + // Increment and then typecast the pointer + pPctAcpiTables++; + CurrSize += PCT_STRUCT_SIZE; + + *SsdtPtr = pPctAcpiTables; + } // end of OptionPstateLateConfiguration.CfgPstatePct + + pPssHeaderAcpiTables = (PSS_HEADER *) pPctAcpiTables; + pPssBodyAcpiTables = (PSS_BODY *) pPctAcpiTables; + if (OptionPstateLateConfiguration.CfgPstatePss) { + // Set _PSS Header + // Note: Set pssLength and numOfItemsInPss later + //--------------------------------------------------- + pPssHeaderAcpiTables->NameOpcode = NAME_OPCODE; + pPssHeaderAcpiTables->PssName_a__ = PSS_NAME__; + pPssHeaderAcpiTables->PssName_a_P = PSS_NAME_P; + pPssHeaderAcpiTables->PssName_a_S = PSS_NAME_S; + pPssHeaderAcpiTables->PssName_b_S = PSS_NAME_S; + pPssHeaderAcpiTables->PkgOpcode = PACKAGE_OPCODE; + + pPssHeaderAcpiTables++; + pPssBodyAcpiTables = (PSS_BODY *) pPssHeaderAcpiTables; + // Restore the pPssHeaderAcpiTables + pPssHeaderAcpiTables--; + + // Set _PSS Body + //--------------- + PstateCount = 0; + + // Calculate PCI address for socket only + GetPciAddress (StdHeader, (UINT32) PStateLevelingBuffer->SocketNumber, 0, &PciAddress, &IgnoredStatus); + TransAndBusMastLatency = 0; + GetFeatureServicesOfSocket (&PstateFamilyServiceTable, (UINT32) PStateLevelingBuffer->SocketNumber, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + FamilyServices->GetPstateLatency ( FamilyServices, + PStateLevelingBuffer, + &PciAddress, + &TransAndBusMastLatency, + StdHeader); + + for (k = 0; k <= PStateMaxValueOnCurrentCore; k++) { + if (PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].PStateEnable != 0) { + pPssBodyAcpiTables->PkgOpcode = PACKAGE_OPCODE; + pPssBodyAcpiTables->PkgLength = PSS_PKG_LENGTH; + pPssBodyAcpiTables->NumOfElements = PSS_NUM_OF_ELEMENTS; + pPssBodyAcpiTables->DwordPrefixOpcode1 = DWORD_PREFIX_OPCODE; + pPssBodyAcpiTables->Frequency = + PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].CoreFreq; + pPssBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE; + pPssBodyAcpiTables->Power = + PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].Power; + + if (PstateCapEnable && (!PstateCapLevelSupportDetermined) && (PstateCapInputMilliWatts >= pPssBodyAcpiTables->Power)) { + PstateCapLevelSupport = (UINT8) PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].SwPstateNumber; + PstateCapLevelSupportDetermined = TRUE; + } + + pPssBodyAcpiTables->DwordPrefixOpcode3 = DWORD_PREFIX_OPCODE; + pPssBodyAcpiTables->TransitionLatency = TransAndBusMastLatency; + pPssBodyAcpiTables->DwordPrefixOpcode4 = DWORD_PREFIX_OPCODE; + pPssBodyAcpiTables->BusMasterLatency = TransAndBusMastLatency; + pPssBodyAcpiTables->DwordPrefixOpcode5 = DWORD_PREFIX_OPCODE; + pPssBodyAcpiTables->Control = + PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].SwPstateNumber; + pPssBodyAcpiTables->DwordPrefixOpcode6 = DWORD_PREFIX_OPCODE; + pPssBodyAcpiTables->Status = + PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].SwPstateNumber; + + pPssBodyAcpiTables++; + PstateCount++; + } + } // for (k = 0; k < MPPSTATE_MAXIMUM_STATES; k++) + + if (PstateCapEnable && (!PstateCapLevelSupportDetermined)) { + PstateCapLevelSupport = PStateMaxValueOnCurrentCore; + } + + // Set _PSS Header again + // Now Set pssLength and numOfItemsInPss + //--------------------------------------- + TempVar_a = (PstateCount * PSS_BODY_STRUCT_SIZE) + 3; + TempVar_b = TempVar_a; + TempVar_c = ((TempVar_b << 4) & 0x0000FF00); + TempVar_c = TempVar_c | ((TempVar_b & 0x0000000F) | 0x00000040); + TempVar_a = (UINT16) TempVar_c; + + pPssHeaderAcpiTables->PssLength = (UINT16) TempVar_a; + pPssHeaderAcpiTables->NumOfItemsInPss = (UINT8) PstateCount; + CurrSize += (PSS_HEADER_STRUCT_SIZE + (PstateCount * PSS_BODY_STRUCT_SIZE)); + + *SsdtPtr = pPssBodyAcpiTables; + } // end of PSS Body if OptionPstateLateConfiguration.CfgPstatePss + + // Set XPSS Table + //--------------- + // Typecast the pointer + pXpssHeaderAcpiTables = (XPSS_HEADER *) pPssBodyAcpiTables; + pXpssBodyAcpiTables = (XPSS_BODY *) pPssBodyAcpiTables; + if (OptionPstateLateConfiguration.CfgPstateXpss) { + // Set XPSS Header + // Note: Set the pssLength and numOfItemsInPss later + //--------------------------------------------------- + pXpssHeaderAcpiTables->NameOpcode = NAME_OPCODE; + pXpssHeaderAcpiTables->XpssName_a_X = PSS_NAME_X; + pXpssHeaderAcpiTables->XpssName_a_P = PSS_NAME_P; + pXpssHeaderAcpiTables->XpssName_a_S = PSS_NAME_S; + pXpssHeaderAcpiTables->XpssName_b_S = PSS_NAME_S; + pXpssHeaderAcpiTables->PkgOpcode = PACKAGE_OPCODE; + + // Increment and then typecast the pointer + pXpssHeaderAcpiTables++; + pXpssBodyAcpiTables = (XPSS_BODY *) pXpssHeaderAcpiTables; + // Restore the pXpssHeaderAcpiTables + pXpssHeaderAcpiTables--; + + // Set XPSS Body + //--------------- + for (k = 0; k <= PStateMaxValueOnCurrentCore; k++) { + if (PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].PStateEnable != 0) { + pXpssBodyAcpiTables->PkgOpcode = PACKAGE_OPCODE; + pXpssBodyAcpiTables->PkgLength = XPSS_PKG_LENGTH; + pXpssBodyAcpiTables->NumOfElements = XPSS_NUM_OF_ELEMENTS; + pXpssBodyAcpiTables->XpssValueTbd = 04; + pXpssBodyAcpiTables->DwordPrefixOpcode1 = DWORD_PREFIX_OPCODE; + pXpssBodyAcpiTables->Frequency = + PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].CoreFreq; + pXpssBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE; + pXpssBodyAcpiTables->Power = + PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].Power; + pXpssBodyAcpiTables->DwordPrefixOpcode3 = DWORD_PREFIX_OPCODE; + pXpssBodyAcpiTables->TransitionLatency = TransAndBusMastLatency; + pXpssBodyAcpiTables->DwordPrefixOpcode4 = DWORD_PREFIX_OPCODE; + pXpssBodyAcpiTables->BusMasterLatency = TransAndBusMastLatency; + pXpssBodyAcpiTables->ControlBuffer = XPSS_ACPI_BUFFER; + pXpssBodyAcpiTables->ControlLo = + PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].SwPstateNumber; + pXpssBodyAcpiTables->ControlHi = 0; + pXpssBodyAcpiTables->StatusBuffer = XPSS_ACPI_BUFFER; + pXpssBodyAcpiTables->StatusLo = + PStateLevelingBuffer->PStateCoreStruct[0].PStateStruct[k].SwPstateNumber; + pXpssBodyAcpiTables->StatusHi = 0; + pXpssBodyAcpiTables->ControlMaskBuffer = XPSS_ACPI_BUFFER; + pXpssBodyAcpiTables->ControlMaskLo = 0; + pXpssBodyAcpiTables->ControlMaskHi = 0; + pXpssBodyAcpiTables->StatusMaskBuffer = XPSS_ACPI_BUFFER; + pXpssBodyAcpiTables->StatusMaskLo = 0; + pXpssBodyAcpiTables->StatusMaskHi = 0; + + pXpssBodyAcpiTables++; + } + } // for (k = 0; k < MPPSTATE_MAXIMUM_STATES; k++) + + // Set XPSS Header again + // Now set pssLength and numOfItemsInPss + //--------------------------------------- + TempVar_a = (PstateCount * XPSS_BODY_STRUCT_SIZE) + 3; + TempVar_b = TempVar_a; + TempVar_c = ((TempVar_b << 4) & 0x0000FF00); + TempVar_c = TempVar_c | ((TempVar_b & 0x0000000F) | 0x00000040); + TempVar_a = (UINT16) TempVar_c; + + pXpssHeaderAcpiTables->XpssLength = (UINT16) TempVar_a; + pXpssHeaderAcpiTables->NumOfItemsInXpss = (UINT8) PstateCount; + CurrSize += (XPSS_HEADER_STRUCT_SIZE + (PstateCount * XPSS_BODY_STRUCT_SIZE)); + + *SsdtPtr = pXpssBodyAcpiTables; + } //end of XPSS Body OptionPstateLateConfiguration.CfgPstateXpss + + // Set _PSD Table + //--------------- + // Typecast the pointer + pPsdHeaderAcpiTables = (PSD_HEADER *) pXpssBodyAcpiTables; + pPsdBodyAcpiTables = (PSD_BODY *) pXpssBodyAcpiTables; + // Get Total Cores Per Node + if (GetActiveCoresInGivenSocket ((UINT32) PStateLevelingBuffer->SocketNumber, &CoreCount1, StdHeader)) { + GetFeatureServicesOfSocket (&PstateFamilyServiceTable, (UINT32) PStateLevelingBuffer->SocketNumber, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + if ((CoreCount1 != 1) && (OptionPstateLateConfiguration.CfgPstatePsd) && + FamilyServices->IsPstatePsdNeeded (FamilyServices, PlatformConfig, StdHeader)) { + // Set _PSD Header + //---------------- + pPsdHeaderAcpiTables->NameOpcode = NAME_OPCODE; + pPsdHeaderAcpiTables->PkgOpcode = PACKAGE_OPCODE; + pPsdHeaderAcpiTables->PsdLength = PSD_HEADER_LENGTH; + pPsdHeaderAcpiTables->Value1 = PSD_VALUE1; + pPsdHeaderAcpiTables->PsdName_a__ = PSD_NAME__; + pPsdHeaderAcpiTables->PsdName_a_P = PSD_NAME_P; + pPsdHeaderAcpiTables->PsdName_a_S = PSD_NAME_S; + pPsdHeaderAcpiTables->PsdName_a_D = PSD_NAME_D; + + // Typecast the pointer + pPsdHeaderAcpiTables++; + CurrSize += PSD_HEADER_STRUCT_SIZE; + pPsdBodyAcpiTables = (PSD_BODY *) pPsdHeaderAcpiTables; + + pPsdHeaderAcpiTables--; + // Set _PSD Body + //-------------- + pPsdBodyAcpiTables->PkgOpcode = PACKAGE_OPCODE; + pPsdBodyAcpiTables->PkgLength = PSD_PKG_LENGTH; + pPsdBodyAcpiTables->NumOfEntries = NUM_OF_ENTRIES; + pPsdBodyAcpiTables->BytePrefixOpcode1 = BYTE_PREFIX_OPCODE; + pPsdBodyAcpiTables->PsdNumOfEntries = PSD_NUM_OF_ENTRIES; + pPsdBodyAcpiTables->BytePrefixOpcode2 = BYTE_PREFIX_OPCODE; + pPsdBodyAcpiTables->PsdRevision = PSD_REVISION; + pPsdBodyAcpiTables->DwordPrefixOpcode1 = DWORD_PREFIX_OPCODE; + + if (EffectivePstatesPsdPolicy == PsdPolicyProcessorDefault) { + IsPsdDependent = FamilyServices->IsPstatePsdDependent (FamilyServices, PlatformConfig, StdHeader); + } else { + if (EffectivePstatesPsdPolicy == PsdPolicyDependent) { + IsPsdDependent = TRUE; + } else { + IsPsdDependent = FALSE; + } + IDS_HDT_CONSOLE (CPU_TRACE, " P-state PSD is forced by interface choice as dependent: %d\n", IsPsdDependent); + } + + if (IsPsdDependent) { + pPsdBodyAcpiTables->DependencyDomain = PSD_DEPENDENCY_DOMAIN; + pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_SW_ALL; + pPsdBodyAcpiTables->NumOfProcessors = CoreCount1; + } else { + switch (GetComputeUnitMapping (StdHeader)) { + case AllCoresMapping: + // All cores are in their own compute unit. + pPsdBodyAcpiTables->DependencyDomain = LocalApicId; + pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_SW_ANY; + pPsdBodyAcpiTables->NumOfProcessors = PSD_NUM_OF_PROCESSORS; + break; + case EvenCoresMapping: + // Two cores per compute unit. + pPsdBodyAcpiTables->DependencyDomain = LocalApicId >> 1; + pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_HW_ALL; + pPsdBodyAcpiTables->NumOfProcessors = PSD_TWO_CORES_PER_COMPUTE_UNIT; + break; + case TripleCoresMapping: + // Three cores per compute unit. + pPsdBodyAcpiTables->DependencyDomain = LocalApicId / 3; + pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_HW_ALL; + pPsdBodyAcpiTables->NumOfProcessors = PSD_THREE_CORES_PER_COMPUTE_UNIT; + break; + case QuadCoresMapping: + // Four cores per compute unit. + pPsdBodyAcpiTables->DependencyDomain = LocalApicId >> 2; + pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_HW_ALL; + pPsdBodyAcpiTables->NumOfProcessors = PSD_FOUR_CORES_PER_COMPUTE_UNIT; + break; + default: + ASSERT (FALSE); + } + } + pPsdBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE; + pPsdBodyAcpiTables->DwordPrefixOpcode3 = DWORD_PREFIX_OPCODE; + + pPsdBodyAcpiTables++; + *SsdtPtr = pPsdBodyAcpiTables; + CurrSize += PSD_BODY_STRUCT_SIZE; + } + }// end of PSD Body if (CoreCount1 != 1) || (OptionPstateLateConfiguration.CfgPstatePsd) + // Typecast the pointer + + pPpcAcpiTables = (PPC_HEADER_BODY *) pPsdBodyAcpiTables; + + // Set _PPC Table + //--------------- + if (OptionPstateLateConfiguration.CfgPstatePpc) { + // Name (PPCV, value) + pPpcAcpiTables->NameOpcode = NAME_OPCODE; + pPpcAcpiTables->PpcName_a_P = PPC_NAME_P; + pPpcAcpiTables->PpcName_b_P = PPC_NAME_P; + pPpcAcpiTables->PpcName_a_C = PPC_NAME_C; + pPpcAcpiTables->PpcName_a_V = PPC_NAME_V; + pPpcAcpiTables->Value1 = PPC_VALUE1; + pPpcAcpiTables->DefaultPerfPresentCap = PstateCapLevelSupport; + // Method (_PPC) { return (PPCV) } + pPpcAcpiTables->MethodOpcode = METHOD_OPCODE; + pPpcAcpiTables->PpcLength = PPC_METHOD_LENGTH; + pPpcAcpiTables->PpcName_a__ = PPC_NAME__; + pPpcAcpiTables->PpcName_c_P = PPC_NAME_P; + pPpcAcpiTables->PpcName_d_P = PPC_NAME_P; + pPpcAcpiTables->PpcName_b_C = PPC_NAME_C; + pPpcAcpiTables->MethodFlags = PPC_METHOD_FLAGS; + pPpcAcpiTables->ReturnOpcode = RETURN_OPCODE; + pPpcAcpiTables->PpcName_e_P = PPC_NAME_P; + pPpcAcpiTables->PpcName_f_P = PPC_NAME_P; + pPpcAcpiTables->PpcName_c_C = PPC_NAME_C; + pPpcAcpiTables->PpcName_b_V = PPC_NAME_V; + + CurrSize += PPC_HEADER_BODY_STRUCT_SIZE; + // Increment and typecast the pointer + pPpcAcpiTables++; + *SsdtPtr = pPpcAcpiTables; + }// end of OptionPstateLateConfiguration.CfgPstatePpc + } + return CurrSize; +} + +/**-------------------------------------------------------------------------------------- + * + * CreateCStateAcpiTables + * + * Description: + * This is the common routine for creating ACPI C-State objects + * + * Parameters: + * @param[in] PlatformConfig Platform operational characteristics; power cap + * @param[in] PStateLevelingBuffer Buffer that contains P-State Leveling information + * @param[in,out] SsdtPtr ACPI SSDT table pointer + * @param[in] LocalApicId Local Apic Id + * @param[in] StdHeader Handle to config for library and services + * + * @retval Size of ACPI C-States objects generated + * + *--------------------------------------------------------------------------------------- + **/ +UINT32 +CreateCStateAcpiTables ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PSTATE_LEVELING *PStateLevelingBuffer, + IN OUT VOID **SsdtPtr, + IN UINT8 LocalApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ObjSize; + IO_CSTATE_FAMILY_SERVICES *IoCstateFamilyServices; + + ObjSize = 0; + + if (IsFeatureEnabled (IoCstate, PlatformConfig, StdHeader)) { + GetFeatureServicesOfCurrentCore (&IoCstateFamilyServiceTable, (CONST VOID **)&IoCstateFamilyServices, StdHeader); + if (IoCstateFamilyServices != NULL) { + IoCstateFamilyServices->CreateAcpiCstObj (IoCstateFamilyServices, LocalApicId, SsdtPtr, StdHeader); + ObjSize = IoCstateFamilyServices->GetAcpiCstObj (IoCstateFamilyServices, PlatformConfig, StdHeader); + } + } + return ObjSize; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.h new file mode 100644 index 0000000000..9ccacb4491 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuPstateTables.h @@ -0,0 +1,314 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU Pstate Table Functions declarations. + * + * Contains code that declares the AGESA CPU _PSS related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_PSTATE_TABLES_H_ +#define _CPU_PSTATE_TABLES_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (PSTATE_CPU_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +/// P-state structure for each state +typedef struct { + IN OUT UINT32 PStateEnable; ///< Pstate enable + IN OUT UINT32 CoreFreq; ///< MHz + IN OUT UINT32 Power; ///< milliWatts + IN OUT UINT32 IddValue; ///< Current value field + IN OUT UINT32 IddDiv; ///< Current divisor field + IN OUT UINT32 SwPstateNumber; ///< Software P-state number +} S_PSTATE_VALUES; + +/// P-state structure for each core +typedef struct { + IN OUT UINT8 PStateMaxValue; ///< Max p-state number in this core + IN OUT UINT8 HtcPstateLimit; ///< Htc limit + IN OUT UINT8 HtcCapable; ///< Htc capable + IN OUT UINT8 LocalApicId; ///< Local Apic Id + IN OUT UINT8 NumberOfBoostedStates; ///< Number of boost P-states + IN OUT S_PSTATE_VALUES PStateStruct[1]; ///< P state struc +} S_PSTATE; + +/// P-state structure for each node +typedef struct { + IN UINT8 SetPState0; ///< If value = 0x55 (Don't set PState0) + IN UINT8 TotalCoresInNode; ///< core number per node + IN UINT16 PStateLevelingSizeOfBytes; ///< Size + IN BOOLEAN OnlyOneEnabledPState; ///< Only P0 + IN UINT8 InitStruct; ///< Init struc + IN BOOLEAN AllCpusHaveIdenticalPStates; ///< Have Identical p state + IN UINT8 CreateAcpiTables; ///< Create table flag + IN UINT8 SocketNumber; ///< Physical socket number of this socket + IN UINT8 Reserved[2]; ///< Reserved. + IN OUT S_PSTATE PStateCoreStruct[1]; ///< P state core struc +} PSTATE_LEVELING; + +/// P-state structure for whole system +typedef struct { + IN OUT UINT32 TotalSocketInSystem; ///< Total node number in system + IN OUT UINT32 SizeOfBytes; ///< Structure size + IN OUT PSTATE_LEVELING PStateLevelingStruc[1]; ///< P state level structure +} S_CPU_AMD_PSTATE; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if PSD need to be generated. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[in,out] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE PSD need to be generated + * @retval FALSE PSD does NOT need to be generated + * + */ +typedef BOOLEAN F_PSTATE_PSD_IS_NEEDED ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_PSTATE_PSD_IS_NEEDED *PF_PSTATE_PSD_IS_NEEDED; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if Pstate PSD is dependent. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[in,out] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE PSD is dependent. + * @retval FALSE PSD is independent. + * + */ +typedef BOOLEAN F_PSTATE_PSD_IS_DEPENDENT ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_PSTATE_PSD_IS_DEPENDENT *PF_PSTATE_PSD_IS_DEPENDENT; + +/** + * Family specific call to get CPU pstate transition latency for current socket. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[in] PStateLevelingBufferStructPtr Pstate row data buffer pointer. + * @param[in] PciAddress Pci address struct. + * @param[out] TransitionLatency Pstate Transition latency result. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_PSTATE_TRANSITION_LATENCY ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN PSTATE_LEVELING *PStateLevelingBufferStructPtr, + IN PCI_ADDR *PciAddress, + OUT UINT32 *TransitionLatency, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_PSTATE_TRANSITION_LATENCY *PF_CPU_PSTATE_TRANSITION_LATENCY; + +/** + * Family specific call to get the desired P-state's frequency in megahertz. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[in] StateNumber P-state number. + * @param[out] PowerInMw P-state frequency in megahertz. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_PSTATE_FREQ ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT8 StateNumber, + OUT UINT32 *FreqInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_PSTATE_FREQ *PF_CPU_GET_PSTATE_FREQ; + +/** + * Family specific call to set the system wide P-state settings on the current core. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[in] CpuAmdPState The current core's P-state data. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_SET_PSTATE_LEVELING_REG ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN S_CPU_AMD_PSTATE *CpuAmdPState, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_SET_PSTATE_LEVELING_REG *PF_CPU_SET_PSTATE_LEVELING_REG; + +/** + * Family specific call to get the desired P-state's rated power in milliwatts. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[in] StateNumber P-state number. + * @param[out] PowerInMw P-state power in milliwatts. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_PSTATE_POWER ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT8 StateNumber, + OUT UINT32 *PowerInMw, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_PSTATE_POWER *PF_CPU_GET_PSTATE_POWER; + +/** + * Family specific call to get CPU Pstate Max State. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[out] MaxPStateNumber The max hw pstate value on the current socket. + * @param[out] NumberOfBoostStates The number of boosted P-states on the current socket. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_PSTATE_MAX_STATE ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + OUT UINT32 *MaxPStateNumber, + OUT UINT8 *NumberOfBoostStates, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_PSTATE_MAX_STATE *PF_CPU_GET_PSTATE_MAX_STATE; + +/** + * Family specific call to get CPU pstate register information. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[in] PState Input hardware Pstate number for query. + * @param[out] PStateEnabled Boolean flag return pstate enable. + * @param[in,out] IddVal Pstate current value. + * @param[in,out] IddDiv Pstate current divisor. + * @param[out] SwPstateNumber Software P-state number. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_PSTATE_REGISTER_INFO ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN UINT32 PState, + OUT BOOLEAN *PStateEnabled, + IN OUT UINT32 *IddVal, + IN OUT UINT32 *IddDiv, + OUT UINT32 *SwPstateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_PSTATE_REGISTER_INFO *PF_CPU_GET_PSTATE_REGISTER_INFO; + +/** + * Provide the interface to the Pstate dependent Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _PSTATE_CPU_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_PSTATE_PSD_IS_NEEDED IsPstatePsdNeeded; ///< Method: Family specific call to check if PSD need to be generated. + PF_PSTATE_PSD_IS_DEPENDENT IsPstatePsdDependent; ///< Method: Family specific call to check if PSD is dependent. + PF_CPU_PSTATE_TRANSITION_LATENCY GetPstateLatency; ///< Method: Family specific call to get pstate transition latency. + PF_CPU_GET_PSTATE_FREQ GetPstateFrequency; ///< Method: Family specific call to get the desired P-state's frequency in megahertz. + PF_CPU_SET_PSTATE_LEVELING_REG SetPStateLevelReg; ///< Method: Family specific call to set the system wide P-state settings on the current core. + PF_CPU_GET_PSTATE_POWER GetPstatePower; ///< Method: Family specific call to get the desired P-state's rated power in milliwatts. + PF_CPU_GET_PSTATE_MAX_STATE GetPstateMaxState; ///< Method: Family specific call to get pstate max state number. + PF_CPU_GET_PSTATE_REGISTER_INFO GetPstateRegisterInfo; ///< Method: Family specific call to get pstate register information. +}; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PStateGatherData ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PStateLeveling ( + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +CpuGetPStateLevelStructure ( + OUT PSTATE_LEVELING **PStateBufferPtr, + IN S_CPU_AMD_PSTATE *CpuAmdPState, + IN UINT32 LogicalSocketNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_PSTATE_TABLES_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuSlit.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuSlit.c new file mode 100644 index 0000000000..cbabf67287 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuSlit.c @@ -0,0 +1,398 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD SLIT, ACPI table related API functions. + * + * Contains code that generates the SLIT table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------- + * This file provides functions, that will generate SLIT tables + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionSlit.h" +#include "heapManager.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "Ids.h" +#include "cpuFeatures.h" +#include "cpuFamilyTranslation.h" +#include "cpuL3Features.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FEATURE_CPUSLIT_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern OPTION_SLIT_CONFIGURATION OptionSlitConfiguration; // global user config record + +STATIC ACPI_TABLE_HEADER ROMDATA CpuSlitHdrStruct = +{ + {'S','L','I','T'}, + 0, + 1, + 0, + {0}, + {0}, + 1, + {'A','M','D',' '}, + 1 +}; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +AcpiSlitHBufferFind ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN UINT8 **SocketTopologyPtr + ); + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GetAcpiSlitStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SlitPtr + ); + +AGESA_STATUS +GetAcpiSlitMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SlitPtr + ); + +AGESA_STATUS +ReleaseSlitBufferStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +ReleaseSlitBuffer ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +extern CPU_FAMILY_SUPPORT_TABLE L3FeatureFamilyServiceTable; + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function generates a complete SLIT table into a memory buffer. + * After completion, this table must be set by the system BIOS into its + * internal ACPI namespace, and linked into the RSDT/XSDT + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in, out] SlitPtr Point to Slit Struct including buffer address and length + * + * @retval UINT32 AGESA_STATUS + */ +AGESA_STATUS +CreateAcpiSlit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SlitPtr + ) +{ + AGESA_TESTPOINT (TpProcCpuEntrySlit, StdHeader); + return ((*(OptionSlitConfiguration.SlitFeature)) (StdHeader, PlatformConfig, SlitPtr)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This is the default routine for use when the SLIT option is NOT requested. + * + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in, out] SlitPtr Point to Slit Struct including buffer address and length + * + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GetAcpiSlitStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SlitPtr + ) +{ + return AGESA_UNSUPPORTED; +} +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function generates a complete SLIT table into a memory buffer. + * After completion, this table must be set by the system BIOS into its + * internal ACPI namespace, and linked into the RSDT/XSDT + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in, out] SlitPtr Point to Slit Struct including buffer address and length + * + * @retval UINT32 AGESA_STATUS + */ +AGESA_STATUS +GetAcpiSlitMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SlitPtr + ) +{ + UINT8 MaxHops; + UINT8 SocketNum; + UINT8 i; + UINT8 j; + UINT8 *BufferPtr; + UINT8 *SocketTopologyDataPtr; + UINT8 *SocketTopologyPtr; + UINT32 Socket; + BOOLEAN var8; + ACPI_TABLE_HEADER *CpuSlitHeaderStructPtr; + AGESA_STATUS Flag; + ALLOCATE_HEAP_PARAMS AllocStruct; + L3_FEATURE_FAMILY_SERVICES *FamilyServices; + + MaxHops = 0; + SocketTopologyPtr = NULL; + Flag = AGESA_ERROR; + var8 = FALSE; + + // find out the pointer to the BufferHandle which contains + // Node Topology information + AcpiSlitHBufferFind (StdHeader, &SocketTopologyPtr); + if (SocketTopologyPtr == NULL) { + return (Flag); + } + + SocketNum = *SocketTopologyPtr; + + IDS_HDT_CONSOLE (CPU_TRACE, " SLIT is created\n"); + + // create a buffer by calling IBV callout routine + AllocStruct.RequestedBufferSize = (SocketNum * SocketNum) + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + sizeof (ACPI_TABLE_HEADER); + AllocStruct.BufferHandle = AMD_ACPI_SLIT_BUFFER_HANDLE; + AllocStruct.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocStruct, StdHeader) != AGESA_SUCCESS) { + return (Flag); + } + *SlitPtr = AllocStruct.BufferPtr; + + //SLIT header + LibAmdMemCopy (*SlitPtr, (VOID *) &CpuSlitHdrStruct, (UINTN) (sizeof (ACPI_TABLE_HEADER)), StdHeader); + CpuSlitHeaderStructPtr = (ACPI_TABLE_HEADER *) *SlitPtr; + CpuSlitHeaderStructPtr->TableLength = (UINT32) AllocStruct.RequestedBufferSize; + // Update table OEM fields. + LibAmdMemCopy ((VOID *) &CpuSlitHeaderStructPtr->OemId, (VOID *) &OptionSlitConfiguration.OemIdString, + sizeof (OptionSlitConfiguration.OemIdString), StdHeader); + LibAmdMemCopy ((VOID *) &CpuSlitHeaderStructPtr->OemTableId, (VOID *) &OptionSlitConfiguration.OemTableIdString, + sizeof (OptionSlitConfiguration.OemTableIdString), StdHeader); + BufferPtr = *SlitPtr; + + Flag = AGESA_SUCCESS; + // SLIT body + if (IsFeatureEnabled (L3Features, PlatformConfig, StdHeader)) { + var8 = TRUE; + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&L3FeatureFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); + if ((FamilyServices == NULL) || (!FamilyServices->IsHtAssistSupported (FamilyServices, PlatformConfig, StdHeader))) { + var8 = FALSE; + break; + } + } + } + } + + + if (!var8) { + // get MaxHops + SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum); + for (i = 0; i < SocketNum; i++) { + for (j = 0; j < SocketNum; j++) { + if (*SocketTopologyDataPtr > MaxHops) { + MaxHops = *SocketTopologyDataPtr; + } + SocketTopologyDataPtr++; + } + } + + // the Max hop entries have a value of 13 + // and all other entries have 10. + SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum); + for (i = 0; i < SocketNum; i++) { + for (j = 0; j < SocketNum; j++) { + if (*SocketTopologyDataPtr++ == MaxHops) { + *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) = 13; + } else { + *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) = 10; + } + } + } + } else { + // formula : num_hops * 6 + 10 + SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum); + for (i = 0; i < SocketNum; i++) { + for (j = 0; j < SocketNum; j++) { + *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) = + ((*SocketTopologyDataPtr++) * 6) + 10; + } + } + } + + BufferPtr += sizeof (ACPI_TABLE_HEADER); + *((UINT64 *) BufferPtr) = (UINT64) SocketNum; + + //Update SLIT header Checksum + ChecksumAcpiTable ((ACPI_TABLE_HEADER *) *SlitPtr, StdHeader); + + return (Flag); +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Find out the pointer to the BufferHandle which contains + * Node Topology information + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in] SocketTopologyPtr Point to the address of Socket Topology + * + */ +VOID +STATIC +AcpiSlitHBufferFind ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN UINT8 **SocketTopologyPtr + ) +{ + LOCATE_HEAP_PTR LocateBuffer; + + LocateBuffer.BufferHandle = HOP_COUNT_TABLE_HANDLE; + if (HeapLocateBuffer (&LocateBuffer, StdHeader) == AGESA_SUCCESS) { + *SocketTopologyPtr = (UINT8 *) LocateBuffer.BufferPtr; + } + + return; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * ReleaseSlitBufferStub + * + * Description: + * This is the default routine for use when the SLIT option is NOT requested. + * + * Parameters: + * @param[in, out] *StdHeader + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +ReleaseSlitBufferStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + return AGESA_UNSUPPORTED; +} + +/* -----------------------------------------------------------------------------*/ +/** + * ReleaseSlitBuffer + * + * Description: + * Deallocate SLIT buffer + * + * Parameters: + * @param[in, out] *StdHeader + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +ReleaseSlitBuffer ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + HeapDeallocateBuffer ((UINT32) HOP_COUNT_TABLE_HANDLE, StdHeader); + + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuSrat.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuSrat.c new file mode 100644 index 0000000000..9d6ca3d06b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuSrat.c @@ -0,0 +1,618 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD SRAT, ACPI table related API functions. + * + * Contains code that Create the APCI SRAT Table after early reset. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ***************************************************************************/ + + +/*---------------------------------------------------------------------------- + * This file provides functions, that will generate SRAT tables + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "cpuServices.h" +#include "OptionSrat.h" +#include "heapManager.h" +#include "cpuRegisters.h" +#include "cpuLateInit.h" +#include "Ids.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FEATURE_CPUSRAT_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_SRAT_CONFIGURATION OptionSratConfiguration; // global user config record + +#define NodeID 0x60 +#define FOURGB 0x010000ul + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GetAcpiSratStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **SratPtr + ); + +AGESA_STATUS +GetAcpiSratMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **SratPtr + ); + +/*---------------------------------------------------------------------------- + * All of the DATA should be defined in _CODE segment. + * Use ROMDATA to specify that it belongs to _CODE. + *---------------------------------------------------------------------------- + */ +STATIC CPU_SRAT_HEADER ROMDATA CpuSratHdrStruct = +{ + {'S','R','A','T'}, + 0, + 2, + 0, + {0}, + {0}, + 1, + {'A','M','D',' '}, + 1, + 1, + {0, 0, 0, 0, 0, 0, 0, 0} +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +UINT8 +STATIC +*MakeApicEntry ( + IN UINT8 ApicId, + IN UINT8 Domain, + IN UINT8 *BufferLocPtr + ); + +UINT8 +STATIC +*FillMemoryForCurrentNode ( + IN UINT8 *PDomain, + IN OUT UINT8 *PDomainForBase640K, + IN UINT8 Node, + IN OUT UINT8 *BufferLocPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +STATIC +*MakeMemEntry ( + IN UINT8 PDomain, + IN UINT8 Node, + IN UINT32 Base, + IN UINT32 Size, + IN UINT8 *BufferLocPtr + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function will generate a complete Static Resource Affinity Table + * i.e. SRAT into a memory buffer. After completion, this table must be set + * by the system BIOS into its internal ACPI name space. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in, out] SratPtr Point to Srat Struct including buffer address and length + * + * @retval AGESA_STATUS + */ + +AGESA_STATUS +CreateAcpiSrat ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **SratPtr + ) +{ + AGESA_TESTPOINT (TpProcCpuEntrySrat, StdHeader); + return ((*(OptionSratConfiguration.SratFeature)) (StdHeader, SratPtr)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This is the default routine for use when the SRAT option is NOT requested. + * + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in, out] SratPtr Point to Srat Struct including buffer address and length + * + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GetAcpiSratStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **SratPtr + ) +{ + return AGESA_UNSUPPORTED; +} +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function will generate a complete Static Resource Affinity Table + * i.e. SRAT into a memory buffer. After completion, this table must be set + * by the system BIOS into its internal ACPI name space. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in, out] SratPtr Point to Srat Struct including buffer address and length + * + * @retval AGESA_STATUS + */ +AGESA_STATUS +GetAcpiSratMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **SratPtr + ) +{ + UINT8 *BufferPtr; + UINT8 NodeNum; + UINT8 NodeCount; + UINT8 PDomain; + UINT8 PDomainForBase640K; + UINT32 Socket; + UINT32 Module; + UINT32 LowCore; + UINT32 HighCore; + UINT32 CoreNum; + UINT32 tempVar_32; + AMD_APIC_PARAMS ApicParams; + CPU_SRAT_HEADER *CpuSratHeaderStructPtr; + ALLOCATE_HEAP_PARAMS AllocParams; + + // Get Node count + NodeCount = 1; + NodeCount = 1; + + // The worst-case buffer size to request is for the SRAT table header, one + // entree for special region (base 640k block), two memory + // regions per node, and APIC entries for each core in the system. + tempVar_32 = (sizeof (CPU_SRAT_HEADER)) + (sizeof (CPU_SRAT_MEMORY_ENTRY)) + + ((UINT32) NodeCount * (2 * (sizeof (CPU_SRAT_MEMORY_ENTRY)) + + ((UINT32) GetActiveCoresInCurrentModule (StdHeader) * sizeof (CPU_SRAT_APIC_ENTRY)))); + + if (*SratPtr == NULL) { + // + // Allocate a buffer + // + AllocParams.RequestedBufferSize = tempVar_32; + AllocParams.BufferHandle = AMD_SRAT_INFO_BUFFER_HANDLE; + AllocParams.Persist = HEAP_SYSTEM_MEM; + + AGESA_TESTPOINT (TpProcCpuBeforeAllocateSratBuffer, StdHeader); + if (HeapAllocateBuffer (&AllocParams, StdHeader) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpProcCpuAfterAllocateSratBuffer, StdHeader); + + *SratPtr = AllocParams.BufferPtr; + } + + IDS_HDT_CONSOLE (CPU_TRACE, " SRAT is created\n"); + + CpuSratHeaderStructPtr = (CPU_SRAT_HEADER *) *SratPtr; + BufferPtr = (UINT8 *) *SratPtr; + + // Copy acpiSRATHeader -> data buffer + LibAmdMemCopy (*SratPtr, (VOID *) &CpuSratHdrStruct, (UINTN) (sizeof (CPU_SRAT_HEADER)), StdHeader); + // Update table OEM fields. + LibAmdMemCopy ((VOID *) &CpuSratHeaderStructPtr->OemId, (VOID *) &OptionSratConfiguration.OemIdString, + sizeof (OptionSratConfiguration.OemIdString), StdHeader); + LibAmdMemCopy ((VOID *) &CpuSratHeaderStructPtr->OemTableId, (VOID *) &OptionSratConfiguration.OemTableIdString, + sizeof (OptionSratConfiguration.OemTableIdString), StdHeader); + + BufferPtr += sizeof (CPU_SRAT_HEADER); + + // Place all memory and IO affinity entries + NodeNum = 0; + PDomain = 0; + PDomainForBase640K = 0xFF; + ApicParams.StdHeader = *StdHeader; + while (NodeNum < NodeCount) { + GetSocketModuleOfNode ((UINT32) NodeNum, &Socket, &Module, StdHeader); + GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader); + BufferPtr = FillMemoryForCurrentNode (&PDomain, &PDomainForBase640K, NodeNum, BufferPtr, StdHeader); + for (CoreNum = LowCore; CoreNum <= HighCore; CoreNum++) { + ApicParams.Socket = (UINT8) Socket; + ApicParams.Core = (UINT8) CoreNum; + AmdGetApicId (&ApicParams); + if (ApicParams.IsPresent) { + BufferPtr = MakeApicEntry (ApicParams.ApicAddress, PDomain, BufferPtr); + } + } + + NodeNum++; + PDomain = NodeNum; + } + + // Store size in table (current buffer offset - buffer start offset) + CpuSratHeaderStructPtr->TableLength = (UINT32) (BufferPtr - (UINT8 *) CpuSratHeaderStructPtr); + + //Update SSDT header Checksum + ChecksumAcpiTable ((ACPI_TABLE_HEADER *) CpuSratHeaderStructPtr, StdHeader); + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function will build Memory entry for current node. + * Note that we only create a memory affinity entry if we find one + * that matches the current node. This makes an easier to read table + * though it is not necessary. + * + * @param[in] PDomain Proximity Domain + * @param[in, out] PDomainForBase640K The PDomain for Base 640K + * @param[in] Node The number of Node + * @param[in, out] BufferLocPtr Point to the address of buffer + * @param[in, out] StdHeader Standard Head Pointer + * + * @retval UINT8 *(New buffer location ptr) + */ +UINT8 +STATIC +*FillMemoryForCurrentNode ( + IN UINT8 *PDomain, + IN OUT UINT8 *PDomainForBase640K, + IN UINT8 Node, + IN OUT UINT8 *BufferLocPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ValueLimit; + UINT32 ValueTOM; + BOOLEAN isModified; + UINT8 Domain; + UINT32 RegVal; + UINT32 DramLeng; + UINT32 DramBase; + UINT32 DramLimit; + UINT32 OffsetRegs; + PCI_ADDR PciAddress; + UINT64 MsrValue; + UINT32 TopOfMemoryAbove4Gb; + + Domain = *PDomain; + + PciAddress.Address.Segment = 0; + PciAddress.Address.Bus = 0; + PciAddress.Address.Device = LOW_NODE_DEVICEID; + PciAddress.Address.Function = FUNC_1; + + for (OffsetRegs = DRAMBase0; OffsetRegs < MMIOBase0; OffsetRegs += 8) { + isModified = FALSE; // FALSE means normal update procedure + // Get DRAM Base Address + PciAddress.Address.Register = OffsetRegs; + LibAmdPciRead (AccessWidth32, PciAddress, &DramBase, StdHeader); + if ((DramBase & 3) != 3) { + // 0:1 set if memory range enabled + // Not set, so we don't have an enabled range + continue; // Proceed to next Base register + } + + // Get DRAM Limit + PciAddress.Address.Register = OffsetRegs + 4; + LibAmdPciRead (AccessWidth32, PciAddress, &DramLimit, StdHeader); + if (DramLimit == 0xFFFFFFFF) { + // Node not installed(all FF's)? + continue; // Proceed to next Base register + } + + if ((DramLimit & 0xFF) != Node) { + // Check if Destination Node ID is current node + continue; // Proceed to next Base register + } + + // We only add an entry now if detected range belongs to current node/PDomain + PciAddress.Address.Register = OffsetRegs + 0x104; + LibAmdPciRead (AccessWidth32, PciAddress, &RegVal, StdHeader); + + DramLimit = (((RegVal & 0xFF) << 16) | (DramLimit >> 16)); // Get DRAM Limit addr [47:24] + DramLimit++; // Add 1 for potential length + DramLimit <<= 8; + + // Get DRAM Base Address + PciAddress.Address.Register = OffsetRegs + 0x100; + LibAmdPciRead (AccessWidth32, PciAddress, &RegVal, StdHeader); + DramBase = ((((RegVal & 0xFF) << 24) | (DramBase >> 8)) & 0xFFFFFF00); // Get DRAM Base Base value [47:24] + DramLeng = DramLimit - DramBase; // Subtract base from limit to get length + + // Leave hole for conventional memory (Less than 640K). It must be on CPU 0. + if (DramBase == 0) { + if (*PDomainForBase640K == 0xFF) { + // It is the first time that the range start at 0. + // If Yes, then Place 1MB memory gap and save Domain to PDomainForBase640K + BufferLocPtr = MakeMemEntry ( + Domain, + Node, + 0, // Base = 0 + 0xA0000 >> 16, // Put it into format used in DRAM regs.. + BufferLocPtr + ); + DramBase += 0x10; // Add 1MB, so range = 1MB to Top of Region + DramLeng -= 0x10; // Also subtract 1MB from the length + *PDomainForBase640K = Domain; // Save Domain number for memory Less than 640K + } else { + // If No, there are more than one memory range less than 640K, it should that + // node interleaving is enabled. All nodes have the same memory ranges + // and all cores in these nodes belong to the same domain. + *PDomain = *PDomainForBase640K; + return (BufferLocPtr); + } + } + LibAmdMsrRead (TOP_MEM, &MsrValue, StdHeader); + ValueTOM = (UINT32) MsrValue >> 16; // Save it in 39:24 format + ValueLimit = DramBase + DramLeng; // We need to know how large region is + + LibAmdMsrRead (SYS_CFG, &MsrValue, StdHeader); + if ((MsrValue & BIT21) != 0) { + LibAmdMsrRead (TOP_MEM2, &MsrValue, StdHeader); + TopOfMemoryAbove4Gb = (UINT32) (MsrValue >> 16); // Save it in 47:16 format + } else { + TopOfMemoryAbove4Gb = 0xFFFFFFFF; + } + + // SPECIAL CASES: + // + // Several conditions require that we process the values of the memory range differently. + // Here are descriptions of the corner cases. + // + // 1. TRUNCATE LOW - Memory range starts below TOM, ends in TOM (memory hole). For this case, + // the range must be truncated to end at TOM. + // ******************************* ******************************* + // * * * -> * * + // ******************************* ******************************* + // 2 TOM 4 2 TOM + // + // 2. TRUNCATE HIGH - Memory range starts below 4GB, ends above 4GB. This is handled by changing the + // start base to 4GB. + // **************** ********** + // * * * -> * * + // **************** ********** + // TOM 3.8 4 6 TOM 3.8 4 6 + // + // 3. Memory range starts below TOM, ends above 4GB. For this case, the range must be truncated + // to end at TOM. Note that this scenario creates two ranges, as the second comparison below + // will find that it ends above 4GB since base and limit have been restored after first truncation, + // and a second range will be written based at 4GB ending at original end address. + // ******************************* **************** ********** + // * * * * -> * * * * + // ******************************* **************** ********** + // 2 TOM 4 6 2 TOM 4 6 + // + // 4. Memory range starts above TOM, ends below or equal to 4GB. This invalid range should simply + // be ignored. + // ******* + // * * -> < NULL > + // ******* + // TOM 3.8 4 + // + // 5. Memory range starts below TOM2, and ends beyond TOM2. This range must be truncated to TOM2. + // ************************ ******************************* + // * * * -> * * + // ************************ ******************************* + // 768 TOM2 1024 768 TOM2 + // + // 6. Memory range starts above TOM2. This invalid range should simply be ignored. + // ******************** + // * * -> < NULL > + // ******************** + // TOM2 1024 1280 + + if (((DramBase < ValueTOM) && (ValueLimit <= FOURGB) && (ValueLimit > ValueTOM)) + || ((DramBase < ValueTOM) && (ValueLimit > FOURGB))) { + // TRUNCATE LOW!!! Shrink entry below TOM... + // Base = DramBase, Size = TOM - DramBase + BufferLocPtr = MakeMemEntry (Domain, Node, DramBase, (ValueTOM - DramBase), BufferLocPtr); + isModified = TRUE; + } + + if ((ValueLimit > FOURGB) && (DramBase < FOURGB)) { + // TRUNCATE HIGH!!! Shrink entry above 4GB... + // Size = Base + Size - 4GB, Base = 4GB + BufferLocPtr = MakeMemEntry (Domain, Node, FOURGB, (DramLeng + DramBase - FOURGB), BufferLocPtr); + isModified = TRUE; + } + + if ((DramBase >= ValueTOM) && (ValueLimit <= FOURGB)) { + // IGNORE!!! Entry located entirely within memory hole + isModified = TRUE; + } + + if ((DramBase < TopOfMemoryAbove4Gb) && (ValueLimit > TopOfMemoryAbove4Gb)) { + // Truncate to TOM2 + // Base = DramBase, Size = TOM2 - DramBase + BufferLocPtr = MakeMemEntry (Domain, Node, DramBase, (TopOfMemoryAbove4Gb - DramBase), BufferLocPtr); + isModified = TRUE; + } + + if (DramBase >= TopOfMemoryAbove4Gb) { + // IGNORE!!! Entry located entirely above TOM2 + isModified = TRUE; + } + + // If special range(isModified), we are done. + // If not, finally write the memory entry. + if (isModified == FALSE) { + // Finally write the memory entry. + BufferLocPtr = MakeMemEntry (Domain, Node, DramBase, DramLeng, BufferLocPtr); + } + + } // for ( OffsetRegs = DRAMBase0; ... ) + + return (BufferLocPtr); +} // FillMemoryForCurrentNode() + + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will add APIC entry. + * + * @param[in] ApicId APIC ID number + * @param[in] Domain Domain number + * @param[in] BufferLocPtr Point to the address of buffer + * + * @retval UINT8 *(New buffer location ptr) + */ +UINT8 +STATIC +*MakeApicEntry ( + IN UINT8 ApicId, + IN UINT8 Domain, + IN UINT8 *BufferLocPtr + ) +{ + CPU_SRAT_APIC_ENTRY *psSratApicEntry; + UINT8 ReservedBytes; + + psSratApicEntry = (CPU_SRAT_APIC_ENTRY *)BufferLocPtr; + + psSratApicEntry->Type = AE_APIC; + psSratApicEntry->Length = (UINT8)sizeof (CPU_SRAT_APIC_ENTRY); + psSratApicEntry->Domain = Domain; + psSratApicEntry->ApicId = ApicId; + psSratApicEntry->Flags = ENABLED; + psSratApicEntry->LSApicEid = 0; + for (ReservedBytes = 0; ReservedBytes < (UINT8)sizeof (psSratApicEntry->Reserved); ReservedBytes++) { + psSratApicEntry->Reserved[ReservedBytes] = 0; + } + return (BufferLocPtr + (UINT8)sizeof (CPU_SRAT_APIC_ENTRY)); +} // MakeApicEntry + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function will add Memory entry. + * + * Parameters: + * @param[in] PDomain Proximity Domain + * @param[in] Node The number of Node + * @param[in] Base Memory Base + * @param[in] Size Memory Size + * @param[in] BufferLocPtr Point to the address of buffer + * + * @retval UINT8 * (new buffer location ptr) + */ +UINT8 +STATIC +*MakeMemEntry ( + IN UINT8 PDomain, + IN UINT8 Node, + IN UINT32 Base, + IN UINT32 Size, + IN UINT8 *BufferLocPtr + ) +{ + CPU_SRAT_MEMORY_ENTRY *psSratMemEntry; + UINT8 ReservedBytes; + + psSratMemEntry = (CPU_SRAT_MEMORY_ENTRY *)BufferLocPtr; + + psSratMemEntry->Type = AE_MEMORY; // [0] = Memory Entry + psSratMemEntry->Length = (UINT8)sizeof (CPU_SRAT_MEMORY_ENTRY); // [1] = 40 + psSratMemEntry->Domain = PDomain; // [2] = Proximity Domain + + // [6-7] = Reserved + for (ReservedBytes = 0; ReservedBytes < (UINT8)sizeof (psSratMemEntry->Reserved1); ReservedBytes++) { + psSratMemEntry->Reserved1[ReservedBytes] = 0; + } + + // [8-11] = Keep 31:0 of address only -> Base Addr Low + psSratMemEntry->BaseAddrLow = Base << 16; + + // [12-15] = Keep 39:32 of address only -> Base Addr High + psSratMemEntry->BaseAddrHigh = Base >> 16; + + // [16-19] = Keep 31:0 of address only -> Length Low + psSratMemEntry->LengthAddrLow = Size << 16; + + // [20-23] = Keep 39:32 of address only -> Length High + psSratMemEntry->LengthAddrHigh = Size >> 16; + + // [24-27] = Reserved + for (ReservedBytes = 0; ReservedBytes < (UINT8)sizeof (psSratMemEntry->Reserved2); ReservedBytes++) { + psSratMemEntry->Reserved2[ReservedBytes] = 0; + } + + // [28-31] = Flags + psSratMemEntry->Flags = ENABLED; + + // [32-40] = Reserved + for (ReservedBytes = 0; ReservedBytes < (UINT8)sizeof (psSratMemEntry->Reserved3); ReservedBytes++) { + psSratMemEntry->Reserved3[ReservedBytes] = 0; + } + return (BufferLocPtr + (UINT8)sizeof (CPU_SRAT_MEMORY_ENTRY)); +} // MakeMemEntry() + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuTdpLimiting.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuTdpLimiting.h new file mode 100644 index 0000000000..91ccd33790 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuTdpLimiting.h @@ -0,0 +1,129 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA CPU TDP limiting Functions declarations. + * + * Contains code that declares the AGESA CPU TDP limiting related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_TDP_LIMITING_H_ +#define _CPU_TDP_LIMITING_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (TDP_LIMIT_FAMILY_SERVICES); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to check if TDP limiting is supported. + * + * @param[in] TdpLimitServices TDP limiting services. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] Socket Zero-based socket number. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE TDP limiting is supported. + * @retval FALSE TDP limiting is not supported. + * + */ +typedef BOOLEAN F_TDP_LIMIT_IS_SUPPORTED ( + IN TDP_LIMIT_FAMILY_SERVICES *TdpLimitServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_TDP_LIMIT_IS_SUPPORTED *PF_TDP_LIMIT_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable TDP limiting. + * + * @param[in] TdpLimitServices TDP limiting services. + * @param[in] PowerCeiling Specifies a maximum power usage limit for the platform. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_TDP_LIMIT_INIT ( + IN TDP_LIMIT_FAMILY_SERVICES *TdpLimitServices, + IN UINT32 *PowerCeiling, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_TDP_LIMIT_INIT *PF_TDP_LIMIT_INIT; + +/** + * Provide the interface to the TDP limiting Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _TDP_LIMIT_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_TDP_LIMIT_IS_SUPPORTED IsTdpLimitSupported; ///< Method: Family specific call to check if TDP limiting is supported. + PF_TDP_LIMIT_INIT EnableTdpLimitOnSocket; ///< Method: Family specific call to enable TDP limiting. +}; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_TDP_LIMITING_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuWhea.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuWhea.c new file mode 100644 index 0000000000..f41dca92aa --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Feature/cpuWhea.c @@ -0,0 +1,288 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD WHEA Table Creation API, and related functions. + * + * Contains code that produce the ACPI WHEA related information. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "OptionWhea.h" +#include "cpuLateInit.h" +#include "heapManager.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "Ids.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_FEATURE_CPUWHEA_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + +extern OPTION_WHEA_CONFIGURATION OptionWheaConfiguration; // global user config record + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +CreateHestBank ( + IN AMD_HEST_BANK *HestBankPtr, + IN UINT8 BankNum, + IN AMD_WHEA_INIT_DATA *WheaInitDataPtr + ); + +AGESA_STATUS +GetAcpiWheaStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **WheaMcePtr, + IN OUT VOID **WheaCmcPtr + ); + +AGESA_STATUS +GetAcpiWheaMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **WheaMcePtr, + IN OUT VOID **WheaCmcPtr + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * + * It will create the ACPI table of WHEA and return the pointer to the table. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in, out] WheaMcePtr Point to Whea Hest Mce table + * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table + * + * @retval AGESA_STATUS + */ +AGESA_STATUS +CreateAcpiWhea ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **WheaMcePtr, + IN OUT VOID **WheaCmcPtr + ) +{ + AGESA_TESTPOINT (TpProcCpuEntryWhea, StdHeader); + return ((*(OptionWheaConfiguration.WheaFeature)) (StdHeader, WheaMcePtr, WheaCmcPtr)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This is the default routine for use when the WHEA option is NOT requested. + * + * The option install process will create and fill the transfer vector with + * the address of the proper routine (Main or Stub). The link optimizer will + * strip out of the .DLL the routine that is not used. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in, out] WheaMcePtr Point to Whea Hest Mce table + * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table + * + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GetAcpiWheaStub ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **WheaMcePtr, + IN OUT VOID **WheaCmcPtr + ) +{ + return AGESA_UNSUPPORTED; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * It will create the ACPI tale of WHEA and return the pointer to the table. + * + * @param[in, out] StdHeader Standard Head Pointer + * @param[in, out] WheaMcePtr Point to Whea Hest Mce table + * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table + * + * @retval UINT32 AGESA_STATUS + */ +AGESA_STATUS +GetAcpiWheaMain ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **WheaMcePtr, + IN OUT VOID **WheaCmcPtr + ) +{ + UINT8 BankNum; + UINT8 Entries; + UINT16 HestMceTableSize; + UINT16 HestCmcTableSize; + UINT64 MsrData; + AMD_HEST_MCE_TABLE *HestMceTablePtr; + AMD_HEST_CMC_TABLE *HestCmcTablePtr; + AMD_HEST_BANK *HestBankPtr; + AMD_WHEA_INIT_DATA *WheaInitDataPtr; + ALLOCATE_HEAP_PARAMS AllocParams; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + FamilySpecificServices = NULL; + + IDS_HDT_CONSOLE (CPU_TRACE, " WHEA is created\n"); + + // step 1: calculate Hest table size + LibAmdMsrRead (MSR_MCG_CAP, &MsrData, StdHeader); + BankNum = (UINT8) (((MSR_MCG_CAP_STRUCT *) (&MsrData))->Count); + if (BankNum == 0) { + return AGESA_ERROR; + } + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetWheaInitData (FamilySpecificServices, (CONST VOID **) &WheaInitDataPtr, &Entries, StdHeader); + + ASSERT (WheaInitDataPtr != NULL); + if (WheaInitDataPtr == NULL) { + return AGESA_ERROR; + } + + ASSERT (WheaInitDataPtr->HestBankNum <= BankNum); + + HestMceTableSize = sizeof (AMD_HEST_MCE_TABLE) + WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK); + HestCmcTableSize = sizeof (AMD_HEST_CMC_TABLE) + WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK); + + HestMceTablePtr = (AMD_HEST_MCE_TABLE *) *WheaMcePtr; + HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) *WheaCmcPtr; + + // step 2: allocate a buffer by callback function + if ((HestMceTablePtr == NULL) || (HestCmcTablePtr == NULL)) { + AllocParams.RequestedBufferSize = (UINT32) (HestMceTableSize + HestCmcTableSize); + AllocParams.BufferHandle = AMD_WHEA_BUFFER_HANDLE; + AllocParams.Persist = HEAP_SYSTEM_MEM; + + AGESA_TESTPOINT (TpProcCpuBeforeAllocateWheaBuffer, StdHeader); + if (HeapAllocateBuffer (&AllocParams, StdHeader) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpProcCpuAfterAllocateWheaBuffer, StdHeader); + + HestMceTablePtr = (AMD_HEST_MCE_TABLE *) AllocParams.BufferPtr; + HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) ((UINT8 *) (HestMceTablePtr + 1) + (WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK))); + } + + // step 3: fill in Hest MCE table + HestMceTablePtr->TblLength = HestMceTableSize; + HestMceTablePtr->GlobCapInitDataLSD = WheaInitDataPtr->GlobCapInitDataLSD; + HestMceTablePtr->GlobCapInitDataMSD = WheaInitDataPtr->GlobCapInitDataMSD; + HestMceTablePtr->GlobCtrlInitDataLSD = WheaInitDataPtr->GlobCtrlInitDataLSD; + HestMceTablePtr->GlobCtrlInitDataMSD = WheaInitDataPtr->GlobCtrlInitDataMSD; + HestMceTablePtr->NumHWBanks = WheaInitDataPtr->HestBankNum; + + HestBankPtr = (AMD_HEST_BANK *) (HestMceTablePtr + 1); + CreateHestBank (HestBankPtr, WheaInitDataPtr->HestBankNum, WheaInitDataPtr); + + // step 4: fill in Hest CMC table + HestCmcTablePtr->NumHWBanks = WheaInitDataPtr->HestBankNum; + HestCmcTablePtr->TblLength = HestCmcTableSize; + + HestBankPtr = (AMD_HEST_BANK *) (HestCmcTablePtr + 1); + CreateHestBank (HestBankPtr, WheaInitDataPtr->HestBankNum, WheaInitDataPtr); + + // step 5: fill in the incoming structure + *WheaMcePtr = HestMceTablePtr; + *WheaCmcPtr = HestCmcTablePtr; + + return (AGESA_SUCCESS); +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * + * It will create Bank structure for Hest table + * + * @param[in] HestBankPtr Pointer to the Hest Back structure + * @param[in] BankNum The number of Bank + * @param[in] WheaInitDataPtr Pointer to the AMD_WHEA_INIT_DATA structure + * + */ +VOID +STATIC +CreateHestBank ( + IN AMD_HEST_BANK *HestBankPtr, + IN UINT8 BankNum, + IN AMD_WHEA_INIT_DATA *WheaInitDataPtr + ) +{ + UINT8 BankIndex; + for (BankIndex = 0; BankIndex < BankNum; BankIndex++) { + HestBankPtr->BankNum = BankIndex; + HestBankPtr->ClrStatusOnInit = WheaInitDataPtr->ClrStatusOnInit; + HestBankPtr->StatusDataFormat = WheaInitDataPtr->StatusDataFormat; + HestBankPtr->ConfWriteEn = WheaInitDataPtr->ConfWriteEn; + HestBankPtr->CtrlRegMSRAddr = WheaInitDataPtr->HestBankInitData[BankIndex].CtrlRegMSRAddr; + HestBankPtr->CtrlInitDataLSD = WheaInitDataPtr->HestBankInitData[BankIndex].CtrlInitDataLSD; + HestBankPtr->CtrlInitDataMSD = WheaInitDataPtr->HestBankInitData[BankIndex].CtrlInitDataMSD; + HestBankPtr->StatRegMSRAddr = WheaInitDataPtr->HestBankInitData[BankIndex].StatRegMSRAddr; + HestBankPtr->AddrRegMSRAddr = WheaInitDataPtr->HestBankInitData[BankIndex].AddrRegMSRAddr; + HestBankPtr->MiscRegMSRAddr = WheaInitDataPtr->HestBankInitData[BankIndex].MiscRegMSRAddr; + HestBankPtr++; + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.c new file mode 100644 index 0000000000..7feb3faee2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.c @@ -0,0 +1,1274 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * ACPI S3 Support routines + * + * Contains routines needed for supporting resume from the ACPI S3 sleep state. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "S3.h" +#include "mfs3.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_S3_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +SaveDeviceContext ( + IN DEVICE_BLOCK_HEADER *DeviceList, + IN CALL_POINTS CallPoint, + OUT UINT32 *ActualBufferSize, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SavePciDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PCI_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT VOID **OrMask + ); + +VOID +SaveConditionalPciDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT VOID **OrMask + ); + +VOID +SaveMsrDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN MSR_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT UINT64 **OrMask + ); + +VOID +SaveConditionalMsrDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT UINT64 **OrMask + ); + +VOID +RestorePciDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PCI_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT VOID **OrMask + ); + +VOID +RestoreConditionalPciDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT VOID **OrMask + ); + +VOID +RestoreMsrDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN MSR_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT UINT64 **OrMask + ); + +VOID +RestoreConditionalMsrDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT UINT64 **OrMask + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Saves all devices in the given device list. + * + * This traverses the entire device list twice. In the first pass, we save + * all devices identified as Pre ESR. In the second pass, we save devices + * marked as post ESR. + * + * @param[in] DeviceList Beginning of the device list to save. + * @param[in] Storage Beginning of the context buffer. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[out] ActualBufferSize Actual size used in saving the device list. + * @param[in] StdHeader AMD standard header config param. + * + */ +VOID +SaveDeviceListContext ( + IN DEVICE_BLOCK_HEADER *DeviceList, + IN VOID *Storage, + IN CALL_POINTS CallPoint, + OUT UINT32 *ActualBufferSize, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // Copy device list over + LibAmdMemCopy (Storage, + DeviceList, + (UINTN) DeviceList->RelativeOrMaskOffset, + StdHeader); + SaveDeviceContext (Storage, CallPoint, ActualBufferSize, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Saves all devices in the given device list. + * + * This traverses the entire device list twice. In the first pass, we save + * all devices identified as Pre ESR. In the second pass, we save devices + * marked as post ESR. + * + * @param[in,out] DeviceList Beginning of the device list to save. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[out] ActualBufferSize Actual size used in saving the device list. + * @param[in] StdHeader AMD standard header config param. + * + */ +VOID +SaveDeviceContext ( + IN DEVICE_BLOCK_HEADER *DeviceList, + IN CALL_POINTS CallPoint, + OUT UINT32 *ActualBufferSize, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + DEVICE_DESCRIPTORS Device; + UINT16 i; + UINT64 StartAddress; + UINT64 EndAddress; + VOID *OrMask; + + StartAddress = (UINT64)(UINT32) DeviceList; + Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1]; + OrMask = (UINT8 *) DeviceList + DeviceList->RelativeOrMaskOffset; + + // Process Pre ESR List + for (i = 0; i < DeviceList->NumDevices; i++) { + switch (Device.CommonDeviceHeader->Type) { + case DEV_TYPE_PCI_PRE_ESR: + SavePciDevice (StdHeader, Device.PciDevice, CallPoint, &OrMask); + // Fall through to advance the pointer after saving context + case DEV_TYPE_PCI: + Device.PciDevice++; + break; + case DEV_TYPE_CPCI_PRE_ESR: + SaveConditionalPciDevice (StdHeader, Device.CPciDevice, CallPoint, &OrMask); + // Fall through to advance the pointer after saving context + case DEV_TYPE_CPCI: + Device.CPciDevice++; + break; + case DEV_TYPE_MSR_PRE_ESR: + SaveMsrDevice (StdHeader, Device.MsrDevice, CallPoint, (UINT64 **) &OrMask); + // Fall through to advance the pointer after saving context + case DEV_TYPE_MSR: + Device.MsrDevice++; + break; + case DEV_TYPE_CMSR_PRE_ESR: + SaveConditionalMsrDevice (StdHeader, Device.CMsrDevice, CallPoint, (UINT64 **) &OrMask); + // Fall through to advance the pointer after saving context + case DEV_TYPE_CMSR: + Device.CMsrDevice++; + break; + } + } + + Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1]; + // Process Post ESR List + for (i = 0; i < DeviceList->NumDevices; i++) { + switch (Device.CommonDeviceHeader->Type) { + case DEV_TYPE_PCI: + SavePciDevice (StdHeader, Device.PciDevice, CallPoint, &OrMask); + // Fall through to advance the pointer after saving context + case DEV_TYPE_PCI_PRE_ESR: + Device.PciDevice++; + break; + case DEV_TYPE_CPCI: + SaveConditionalPciDevice (StdHeader, Device.CPciDevice, CallPoint, &OrMask); + // Fall through to advance the pointer after saving context + case DEV_TYPE_CPCI_PRE_ESR: + Device.CPciDevice++; + break; + case DEV_TYPE_MSR: + SaveMsrDevice (StdHeader, Device.MsrDevice, CallPoint, (UINT64 **) &OrMask); + // Fall through to advance the pointer after saving context + case DEV_TYPE_MSR_PRE_ESR: + Device.MsrDevice++; + break; + case DEV_TYPE_CMSR: + SaveConditionalMsrDevice (StdHeader, Device.CMsrDevice, CallPoint, (UINT64 **) &OrMask); + // Fall through to advance the pointer after saving context + case DEV_TYPE_CMSR_PRE_ESR: + Device.CMsrDevice++; + break; + } + } + EndAddress = (UINT64)(UINT32) OrMask; + *ActualBufferSize = (UINT32) (EndAddress - StartAddress); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Saves the context of a PCI device. + * + * This traverses the provided register list saving PCI registers. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in] Device PCI device to restore. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in,out] OrMask Current buffer pointer of raw register values. + * + */ +VOID +SavePciDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PCI_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT VOID **OrMask + ) +{ + UINT8 RegSizeInBytes; + UINT8 SpecialCaseIndex; + UINT8 *IntermediatePtr; + UINT16 i; + UINT32 Socket; + UINT32 Module; + UINT32 AndMask; + ACCESS_WIDTH AccessWidth; + AGESA_STATUS IgnoredSts; + PCI_ADDR PciAddress; + PCI_REGISTER_BLOCK_HEADER *RegisterHdr; + + GetSocketModuleOfNode ((UINT32) Device->Node, + &Socket, + &Module, + StdHeader); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + if (CallPoint == INIT_RESUME) { + MemFS3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } else { + S3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } + + for (i = 0; i < RegisterHdr->NumRegisters; i++) { + PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function; + PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset; + RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize; + switch (RegSizeInBytes) { + case 1: + AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask); + AccessWidth = AccessS3SaveWidth8; + break; + case 2: + AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask); + AccessWidth = AccessS3SaveWidth16; + break; + case 3: + // In this case, we don't need to save a register. We just need to call a special + // function to do certain things in the save and resume sequence. + // This should not be used in a non-special case. + AndMask = 0; + RegSizeInBytes = 0; + AccessWidth = 0; + break; + default: + AndMask = RegisterHdr->RegisterList[i].AndMask; + RegSizeInBytes = 4; + AccessWidth = AccessS3SaveWidth32; + break; + } + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0)); + LibAmdPciRead (AccessWidth, PciAddress, *OrMask, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, PciAddress, *OrMask, StdHeader); + } + if (AndMask != 0) { + // If AndMask is 0, then it is a not-care. Don't need to apply it to the OrMask + **((UINT32 **) OrMask) &= AndMask; + } + if ((RegSizeInBytes == 0) && (**((UINT32 **) OrMask) == RESTART_FROM_BEGINNING_LIST)) { + // Restart from the beginning of the register list + i = 0xFFFF; + } + IntermediatePtr = (UINT8 *) *OrMask; + *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Saves the context of a 'conditional' PCI device. + * + * This traverses the provided register list saving PCI registers when appropriate. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in] Device 'conditional' PCI device to restore. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in,out] OrMask Current buffer pointer of raw register values. + * + */ +VOID +SaveConditionalPciDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT VOID **OrMask + ) +{ + UINT8 RegSizeInBytes; + UINT8 SpecialCaseIndex; + UINT8 *IntermediatePtr; + UINT16 i; + UINT32 Socket; + UINT32 Module; + UINT32 AndMask; + ACCESS_WIDTH AccessWidth; + AGESA_STATUS IgnoredSts; + PCI_ADDR PciAddress; + CPCI_REGISTER_BLOCK_HEADER *RegisterHdr; + + GetSocketModuleOfNode ((UINT32) Device->Node, + &Socket, + &Module, + StdHeader); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + if (CallPoint == INIT_RESUME) { + MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } else { + S3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } + + for (i = 0; i < RegisterHdr->NumRegisters; i++) { + if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) && + ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) { + PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function; + PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset; + RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize; + switch (RegSizeInBytes) { + case 1: + AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask); + AccessWidth = AccessS3SaveWidth8; + break; + case 2: + AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask); + AccessWidth = AccessS3SaveWidth16; + break; + case 3: + // In this case, we don't need to save a register. We just need to call a special + // function to do certain things in the save and resume sequence. + // This should not be used in a non-special case. + AndMask = 0; + RegSizeInBytes = 0; + AccessWidth = 0; + break; + default: + AndMask = RegisterHdr->RegisterList[i].AndMask; + RegSizeInBytes = 4; + AccessWidth = AccessS3SaveWidth32; + break; + } + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0)); + LibAmdPciRead (AccessWidth, PciAddress, *OrMask, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, PciAddress, *OrMask, StdHeader); + } + if (AndMask != 0) { + // If AndMask is 0, then it is a not-care. Don't need to apply it to the OrMask + **((UINT32 **) OrMask) &= AndMask; + } + if ((RegSizeInBytes == 0) && (**((UINT32 **) OrMask) == RESTART_FROM_BEGINNING_LIST)) { + // Restart from the beginning of the register list + i = 0xFFFF; + } + IntermediatePtr = (UINT8 *) *OrMask; + *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Saves the context of an MSR device. + * + * This traverses the provided register list saving MSRs. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in] Device MSR device to restore. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in,out] OrMask Current buffer pointer of raw register values. + * + */ +VOID +SaveMsrDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN MSR_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT UINT64 **OrMask + ) +{ + UINT8 SpecialCaseIndex; + UINT16 i; + MSR_REGISTER_BLOCK_HEADER *RegisterHdr; + + if (CallPoint == INIT_RESUME) { + MemFS3GetMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } else { + S3GetMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } + + for (i = 0; i < RegisterHdr->NumRegisters; i++) { + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, *OrMask, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address, *OrMask, StdHeader); + } + **OrMask &= RegisterHdr->RegisterList[i].AndMask; + (*OrMask)++; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Saves the context of a 'conditional' MSR device. + * + * This traverses the provided register list saving MSRs when appropriate. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in] Device 'conditional' MSR device to restore. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in,out] OrMask Current buffer pointer of raw register values. + * + */ +VOID +SaveConditionalMsrDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT UINT64 **OrMask + ) +{ + UINT8 SpecialCaseIndex; + UINT16 i; + CMSR_REGISTER_BLOCK_HEADER *RegisterHdr; + + if (CallPoint == INIT_RESUME) { + MemFS3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } else { + S3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } + + for (i = 0; i < RegisterHdr->NumRegisters; i++) { + if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) && + ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) { + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, (UINT64 *) *OrMask, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address, (UINT64 *) *OrMask, StdHeader); + } + **OrMask &= RegisterHdr->RegisterList[i].AndMask; + (*OrMask)++; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the maximum amount of space required to store all raw register + * values for the given device list. + * + * This traverses the entire device list, and calculates the worst case size + * of each device in the device list. + * + * @param[in] DeviceList Beginning of the device list. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in] StdHeader AMD standard header config param. + * + * @retval Size in bytes required for storing all registers. + */ +UINT32 +GetWorstCaseContextSize ( + IN DEVICE_BLOCK_HEADER *DeviceList, + IN CALL_POINTS CallPoint, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 WorstCaseSize; + DEVICE_DESCRIPTORS Device; + UINT16 i; + REGISTER_BLOCK_HEADERS RegisterHdr; + + WorstCaseSize = DeviceList->RelativeOrMaskOffset; + Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1]; + + // Process Device List + for (i = 0; i < DeviceList->NumDevices; i++) { + switch (Device.CommonDeviceHeader->Type) { + case DEV_TYPE_PCI_PRE_ESR: + // PRE_ESR and post ESR take the same amount of space + case DEV_TYPE_PCI: + if (CallPoint == INIT_RESUME) { + MemFS3GetPciDeviceRegisterList (Device.PciDevice, &RegisterHdr.PciRegisters, StdHeader); + } else { + S3GetPciDeviceRegisterList (Device.PciDevice, &RegisterHdr.PciRegisters, StdHeader); + } + WorstCaseSize += (RegisterHdr.PciRegisters->NumRegisters * 4); + Device.PciDevice++; + break; + case DEV_TYPE_CPCI_PRE_ESR: + // PRE_ESR and post ESR take the same amount of space + case DEV_TYPE_CPCI: + if (CallPoint == INIT_RESUME) { + MemFS3GetCPciDeviceRegisterList (Device.CPciDevice, &RegisterHdr.CPciRegisters, StdHeader); + } else { + S3GetCPciDeviceRegisterList (Device.CPciDevice, &RegisterHdr.CPciRegisters, StdHeader); + } + WorstCaseSize += (RegisterHdr.CPciRegisters->NumRegisters * 4); + Device.CPciDevice++; + break; + case DEV_TYPE_MSR_PRE_ESR: + // PRE_ESR and post ESR take the same amount of space + case DEV_TYPE_MSR: + if (CallPoint == INIT_RESUME) { + MemFS3GetMsrDeviceRegisterList (Device.MsrDevice, &RegisterHdr.MsrRegisters, StdHeader); + } else { + S3GetMsrDeviceRegisterList (Device.MsrDevice, &RegisterHdr.MsrRegisters, StdHeader); + } + WorstCaseSize += (RegisterHdr.MsrRegisters->NumRegisters * 8); + Device.MsrDevice++; + break; + case DEV_TYPE_CMSR_PRE_ESR: + // PRE_ESR and post ESR take the same amount of space + case DEV_TYPE_CMSR: + if (CallPoint == INIT_RESUME) { + MemFS3GetCMsrDeviceRegisterList (Device.CMsrDevice, &RegisterHdr.CMsrRegisters, StdHeader); + } else { + S3GetCMsrDeviceRegisterList (Device.CMsrDevice, &RegisterHdr.CMsrRegisters, StdHeader); + } + WorstCaseSize += (RegisterHdr.CMsrRegisters->NumRegisters * 8); + Device.CMsrDevice++; + break; + default: + ASSERT (FALSE); + } + } + return (WorstCaseSize); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Restores all devices marked as 'before exiting self-refresh.' + * + * This traverses the entire device list, restoring all devices identified + * as Pre ESR. + * + * @param[in,out] OrMaskPtr Current buffer pointer of raw register values. + * @param[in] Storage Beginning of the device list. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in] StdHeader AMD standard header config param. + * + */ +VOID +RestorePreESRContext ( + OUT VOID **OrMaskPtr, + IN VOID *Storage, + IN CALL_POINTS CallPoint, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + DEVICE_DESCRIPTORS Device; + UINT16 i; + DEVICE_BLOCK_HEADER *DeviceList; + + DeviceList = (DEVICE_BLOCK_HEADER *) Storage; + Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1]; + *OrMaskPtr = (UINT8 *) DeviceList + DeviceList->RelativeOrMaskOffset; + + // Process Pre ESR List + for (i = 0; i < DeviceList->NumDevices; i++) { + switch (Device.CommonDeviceHeader->Type) { + case DEV_TYPE_PCI_PRE_ESR: + RestorePciDevice (StdHeader, Device.PciDevice, CallPoint, OrMaskPtr); + // Fall through to advance the pointer after restoring context + case DEV_TYPE_PCI: + Device.PciDevice++; + break; + case DEV_TYPE_CPCI_PRE_ESR: + RestoreConditionalPciDevice (StdHeader, Device.CPciDevice, CallPoint, OrMaskPtr); + // Fall through to advance the pointer after restoring context + case DEV_TYPE_CPCI: + Device.CPciDevice++; + break; + case DEV_TYPE_MSR_PRE_ESR: + RestoreMsrDevice (StdHeader, Device.MsrDevice, CallPoint, (UINT64 **) OrMaskPtr); + // Fall through to advance the pointer after restoring context + case DEV_TYPE_MSR: + Device.MsrDevice++; + break; + case DEV_TYPE_CMSR_PRE_ESR: + RestoreConditionalMsrDevice (StdHeader, Device.CMsrDevice, CallPoint, (UINT64 **) OrMaskPtr); + // Fall through to advance the pointer after restoring context + case DEV_TYPE_CMSR: + Device.CMsrDevice++; + break; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Restores all devices marked as 'after exiting self-refresh.' + * + * This traverses the entire device list, restoring all devices identified + * as Post ESR. + * + * @param[in] OrMaskPtr Current buffer pointer of raw register values. + * @param[in] Storage Beginning of the device list. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in] StdHeader AMD standard header config param. + * + */ +VOID +RestorePostESRContext ( + IN VOID *OrMaskPtr, + IN VOID *Storage, + IN CALL_POINTS CallPoint, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + DEVICE_DESCRIPTORS Device; + UINT16 i; + DEVICE_BLOCK_HEADER *DeviceList; + + DeviceList = (DEVICE_BLOCK_HEADER *) Storage; + Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1]; + + // Process Pre ESR List + for (i = 0; i < DeviceList->NumDevices; i++) { + switch (Device.CommonDeviceHeader->Type) { + case DEV_TYPE_PCI: + RestorePciDevice (StdHeader, Device.PciDevice, CallPoint, &OrMaskPtr); + // Fall through to advance the pointer after restoring context + case DEV_TYPE_PCI_PRE_ESR: + Device.PciDevice++; + break; + case DEV_TYPE_CPCI: + RestoreConditionalPciDevice (StdHeader, Device.CPciDevice, CallPoint, &OrMaskPtr); + // Fall through to advance the pointer after restoring context + case DEV_TYPE_CPCI_PRE_ESR: + Device.CPciDevice++; + break; + case DEV_TYPE_MSR: + RestoreMsrDevice (StdHeader, Device.MsrDevice, CallPoint, (UINT64 **) &OrMaskPtr); + // Fall through to advance the pointer after restoring context + case DEV_TYPE_MSR_PRE_ESR: + Device.MsrDevice++; + break; + case DEV_TYPE_CMSR: + RestoreConditionalMsrDevice (StdHeader, Device.CMsrDevice, CallPoint, (UINT64 **) &OrMaskPtr); + // Fall through to advance the pointer after restoring context + case DEV_TYPE_CMSR_PRE_ESR: + Device.CMsrDevice++; + break; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Restores the context of a PCI device. + * + * This traverses the provided register list restoring PCI registers. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in] Device 'conditional' PCI device to restore. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in,out] OrMask Current buffer pointer of raw register values. + * + */ +VOID +RestorePciDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PCI_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT VOID **OrMask + ) +{ + UINT8 RegSizeInBytes; + UINT8 SpecialCaseIndex; + UINT8 *IntermediatePtr; + UINT8 BootMode; + UINT16 i; + UINT32 Socket; + UINT32 Module; + UINT32 AndMask; + UINT32 RegValueRead; + UINT32 RegValueWrite; + ACCESS_WIDTH AccessWidth; + AGESA_STATUS IgnoredSts; + PCI_ADDR PciAddress; + PCI_REGISTER_BLOCK_HEADER *RegisterHdr; + + GetSocketModuleOfNode ((UINT32) Device->Node, + &Socket, + &Module, + StdHeader); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + if (CallPoint == INIT_RESUME) { + MemFS3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } else { + S3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } + + BootMode = S3_RESUME_MODE; + if (StdHeader->Func == AMD_INIT_POST) { + BootMode = RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE; + } + + for (i = 0; i < RegisterHdr->NumRegisters; i++) { + PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function; + PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset; + RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize; + switch (RegSizeInBytes) { + case 1: + AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask); + RegValueWrite = **(UINT8 **)OrMask; + AccessWidth = AccessS3SaveWidth8; + break; + case 2: + AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask); + RegValueWrite = **(UINT16 **)OrMask; + AccessWidth = AccessS3SaveWidth16; + break; + case 3: + // In this case, we don't need to restore a register. We just need to call a special + // function to do certain things in the save and resume sequence. + // This should not be used in a non-special case. + AndMask = 0; + RegValueWrite = 0; + RegSizeInBytes = 0; + AccessWidth = 0; + break; + default: + AndMask = RegisterHdr->RegisterList[i].AndMask; + RegSizeInBytes = 4; + RegValueWrite = **(UINT32 **)OrMask; + AccessWidth = AccessS3SaveWidth32; + break; + } + if ((RegisterHdr->RegisterList[i].BootMode == 0) || ((BootMode & RegisterHdr->RegisterList[i].BootMode) != 0)) { + // Do not restore the register if not in the right boot mode + // Pointer to the saved data buffer still needs to be adjusted as data will be saved regardless of boot mode + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0)); + LibAmdPciRead (AccessWidth, PciAddress, &RegValueRead, StdHeader); + RegValueWrite |= RegValueRead & (~AndMask); + LibAmdPciWrite (AccessWidth, PciAddress, &RegValueWrite, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + if (AndMask != 0) { + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, + PciAddress, + &RegValueRead, + StdHeader); + RegValueWrite |= RegValueRead & (~AndMask); + } + RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth, + PciAddress, + &RegValueWrite, + StdHeader); + } + IDS_OPTION_HOOK (IDS_AFTER_RESTORING_PCI_REG, RegisterHdr, StdHeader); + } + IntermediatePtr = (UINT8 *) *OrMask; + *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes; + if ((RegSizeInBytes == 0) && (RegValueWrite == RESTART_FROM_BEGINNING_LIST)) { + // Restart from the beginning of the register list + i = 0xFFFF; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Restores the context of a 'conditional' PCI device. + * + * This traverses the provided register list restoring PCI registers when appropriate. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in] Device 'conditional' PCI device to restore. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in,out] OrMask Current buffer pointer of raw register values. + * + */ +VOID +RestoreConditionalPciDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT VOID **OrMask + ) +{ + UINT8 RegSizeInBytes; + UINT8 SpecialCaseIndex; + UINT8 *IntermediatePtr; + UINT8 BootMode; + UINT16 i; + UINT32 Socket; + UINT32 Module; + UINT32 RegValueRead; + UINT32 RegValueWrite; + UINT32 AndMask; + ACCESS_WIDTH AccessWidth; + AGESA_STATUS IgnoredSts; + PCI_ADDR PciAddress; + CPCI_REGISTER_BLOCK_HEADER *RegisterHdr; + + GetSocketModuleOfNode ((UINT32) Device->Node, + &Socket, + &Module, + StdHeader); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + if (CallPoint == INIT_RESUME) { + MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } else { + S3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } + + BootMode = S3_RESUME_MODE; + if (StdHeader->Func == AMD_INIT_POST) { + BootMode = RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE; + } + + for (i = 0; i < RegisterHdr->NumRegisters; i++) { + if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) && + ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) { + PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function; + PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset; + RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize; + switch (RegSizeInBytes) { + case 1: + AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask); + RegValueWrite = **(UINT8 **)OrMask; + AccessWidth = AccessS3SaveWidth8; + break; + case 2: + AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask); + RegValueWrite = **(UINT16 **)OrMask; + AccessWidth = AccessS3SaveWidth16; + break; + case 3: + // In this case, we don't need to restore a register. We just need to call a special + // function to do certain things in the save and resume sequence. + // This should not be used in a non-special case. + AndMask = 0; + RegValueWrite = 0; + RegSizeInBytes = 0; + AccessWidth = 0; + break; + default: + AndMask = RegisterHdr->RegisterList[i].AndMask; + RegSizeInBytes = 4; + RegValueWrite = **(UINT32 **)OrMask; + AccessWidth = AccessS3SaveWidth32; + break; + } + if ((RegisterHdr->RegisterList[i].BootMode == 0) || ((BootMode & RegisterHdr->RegisterList[i].BootMode) != 0)) { + // Do not restore the register if not in the right boot mode + // Pointer to the saved data buffer still needs to be adjusted as data will be saved regardless of boot mode + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + LibAmdPciRead (AccessWidth, PciAddress, &RegValueRead, StdHeader); + RegValueWrite |= RegValueRead & (~AndMask); + LibAmdPciWrite (AccessWidth, PciAddress, &RegValueWrite, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + if (AndMask != 0) { + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, + PciAddress, + &RegValueRead, + StdHeader); + RegValueWrite |= RegValueRead & (~AndMask); + } + RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth, + PciAddress, + &RegValueWrite, + StdHeader); + } + IDS_OPTION_HOOK (IDS_AFTER_RESTORING_PCI_REG, RegisterHdr, StdHeader); + } + IntermediatePtr = (UINT8 *) *OrMask; + *OrMask = &IntermediatePtr[RegSizeInBytes]; + if ((RegSizeInBytes == 0) && (RegValueWrite == RESTART_FROM_BEGINNING_LIST)) { + // Restart from the beginning of the register list + i = 0xFFFF; + } + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Restores the context of an MSR device. + * + * This traverses the provided register list restoring MSRs. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in] Device MSR device to restore. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in,out] OrMask Current buffer pointer of raw register values. + * + */ +VOID +RestoreMsrDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN MSR_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT UINT64 **OrMask + ) +{ + UINT8 SpecialCaseIndex; + UINT8 BootMode; + UINT16 i; + UINT64 RegValueRead; + UINT64 RegValueWrite; + MSR_REGISTER_BLOCK_HEADER *RegisterHdr; + + if (CallPoint == INIT_RESUME) { + MemFS3GetMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } else { + S3GetMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } + + BootMode = S3_RESUME_MODE; + if (StdHeader->Func == AMD_INIT_POST) { + BootMode = RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE; + } + + for (i = 0; i < RegisterHdr->NumRegisters; i++) { + if ((RegisterHdr->RegisterList[i].BootMode == 0) || ((BootMode & RegisterHdr->RegisterList[i].BootMode) != 0)) { + // Do not restore the register if not in the right boot mode + // Pointer to the saved data buffer still needs to be adjusted as data will be saved regardless of boot mode + RegValueWrite = **OrMask; + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, &RegValueRead, StdHeader); + RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask); + LibAmdMsrWrite (RegisterHdr->RegisterList[i].Address, &RegValueWrite, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address, + &RegValueRead, + StdHeader); + RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask); + RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (RegisterHdr->RegisterList[i].Address, + &RegValueWrite, + StdHeader); + } + } + (*OrMask)++; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Restores the context of a 'conditional' MSR device. + * + * This traverses the provided register list restoring MSRs when appropriate. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in] Device 'conditional' MSR device to restore. + * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or + * AMD_S3LATE_RESTORE. + * @param[in,out] OrMask Current buffer pointer of raw register values. + * + */ +VOID +RestoreConditionalMsrDevice ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, + IN CALL_POINTS CallPoint, + IN OUT UINT64 **OrMask + ) +{ + UINT8 SpecialCaseIndex; + UINT8 BootMode; + UINT16 i; + UINT64 RegValueRead; + UINT64 RegValueWrite; + CMSR_REGISTER_BLOCK_HEADER *RegisterHdr; + + if (CallPoint == INIT_RESUME) { + MemFS3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } else { + S3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); + } + + BootMode = S3_RESUME_MODE; + if (StdHeader->Func == AMD_INIT_POST) { + BootMode = RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE; + } + + for (i = 0; i < RegisterHdr->NumRegisters; i++) { + if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) && + ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) { + if ((RegisterHdr->RegisterList[i].BootMode == 0) || ((BootMode & RegisterHdr->RegisterList[i].BootMode) != 0)) { + // Do not restore the register if not in the right boot mode + // Pointer to the saved data buffer still needs to be adjusted as data will be saved regardless of boot mode + RegValueWrite = **OrMask; + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, &RegValueRead, StdHeader); + RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask); + LibAmdMsrWrite (RegisterHdr->RegisterList[i].Address, &RegValueWrite, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address, + &RegValueRead, + StdHeader); + RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask); + RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (RegisterHdr->RegisterList[i].Address, + &RegValueWrite, + StdHeader); + } + } + (*OrMask)++; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Unique device ID to PCI register list translator. + * + * This translates the given device header in storage to the appropriate list + * of registers in the AGESA image. + * + * @param[out] NonMemoryRelatedDeviceList List of devices to save and restore + * during S3LateRestore. + * @param[in] StdHeader AMD standard header config param. + * + */ +VOID +GetNonMemoryRelatedDeviceList ( + OUT DEVICE_BLOCK_HEADER **NonMemoryRelatedDeviceList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NonMemoryRelatedDeviceList = NULL; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Unique device ID to PCI register list translator. + * + * This translates the given device header in storage to the appropriate list + * of registers in the AGESA image. + * + * @param[in] Device Device header containing the unique ID. + * @param[out] RegisterHdr Output PCI register list pointer. + * @param[in] StdHeader AMD standard header config param. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +S3GetPciDeviceRegisterList ( + IN PCI_DEVICE_DESCRIPTOR *Device, + OUT PCI_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *RegisterHdr = NULL; + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Unique device ID to 'conditional' PCI register list translator. + * + * This translates the given device header in storage to the appropriate list + * of registers in the AGESA image. + * + * @param[in] Device Device header containing the unique ID. + * @param[out] RegisterHdr Output 'conditional' PCI register list pointer. + * @param[in] StdHeader AMD standard header config param. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +S3GetCPciDeviceRegisterList ( + IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device, + OUT CPCI_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *RegisterHdr = NULL; + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Unique device ID to MSR register list translator. + * + * This translates the given device header in storage to the appropriate list + * of registers in the AGESA image. + * + * @param[in] Device Device header containing the unique ID. + * @param[out] RegisterHdr Output MSR register list pointer. + * @param[in] StdHeader AMD standard header config param. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +S3GetMsrDeviceRegisterList ( + IN MSR_DEVICE_DESCRIPTOR *Device, + OUT MSR_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *RegisterHdr = NULL; + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Unique device ID to 'conditional' MSR register list translator. + * + * This translates the given device header in storage to the appropriate list + * of registers in the AGESA image. + * + * @param[in] Device Device header containing the unique ID. + * @param[out] RegisterHdr Output 'conditional' MSR register list pointer. + * @param[in] StdHeader AMD standard header config param. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +S3GetCMsrDeviceRegisterList ( + IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, + OUT CMSR_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *RegisterHdr = NULL; + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Constructor for the AMD_S3_PARAMS structure. + * + * This routine initializes failsafe values for the AMD_S3_PARAMS structure + * to be used by the AMD_INIT_RESUME, AMD_S3_SAVE, and AMD_S3LATE_RESTORE + * entry points. + * + * @param[in,out] S3Params Required input parameter for the AMD_S3_SAVE, + * AMD_INIT_RESUME, and AMD_S3_SAVE entry points. + * + */ +VOID +AmdS3ParamsInitializer ( + OUT AMD_S3_PARAMS *S3Params + ) +{ + S3Params->Signature = 0x52545341; + S3Params->Version = 0x0000; + S3Params->VolatileStorage = NULL; + S3Params->VolatileStorageSize = 0x00000000; + S3Params->Flags = 0x00000000; + S3Params->NvStorage = NULL; + S3Params->NvStorageSize = 0x00000000; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.h new file mode 100644 index 0000000000..6f776d072c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/S3.h @@ -0,0 +1,399 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * ACPI S3 support definitions. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _S3_H_ +#define _S3_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ +#define RESTART_FROM_BEGINNING_LIST 0xFFFFFFFFul + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +/* Device related definitions */ + +/// Header at the beginning of a context save buffer. +typedef struct { + UINT16 Version; ///< Version of header + UINT16 NumDevices; ///< Number of devices in the list + UINT16 RelativeOrMaskOffset; ///< Size of device list + header + UINT32 NextBlockOffset; ///< Size of the whole device save context +} DEVICE_BLOCK_HEADER; + +/// S3 device types +typedef enum { + DEV_TYPE_PCI_PRE_ESR, ///< PCI device before exiting self-refresh + DEV_TYPE_PCI, ///< PCI device after exiting self-refresh + DEV_TYPE_CPCI_PRE_ESR, ///< 'conditional' PCI device before exiting self-refresh + DEV_TYPE_CPCI, ///< 'conditional' PCI device after exiting self-refresh + DEV_TYPE_MSR_PRE_ESR, ///< MSR device before exiting self-refresh + DEV_TYPE_MSR, ///< MSR device after exiting self-refresh + DEV_TYPE_CMSR_PRE_ESR, ///< 'conditional' MSR device before exiting self-refresh + DEV_TYPE_CMSR ///< 'conditional' MSR device after exiting self-refresh +} S3_DEVICE_TYPES; + +/// S3 restoration call points +typedef enum { + INIT_RESUME, ///< AMD_INIT_RESUME + S3_LATE_RESTORE ///< AMD_S3LATE_RESTORE +} CALL_POINTS; + +/// S3 device common header +typedef struct { + UINT32 RegisterListID; ///< Unique ID of this device + UINT8 Type; ///< Appropriate S3_DEVICE_TYPES type +} DEVICE_DESCRIPTOR; + +/// S3 PCI device header +typedef struct { + UINT32 RegisterListID; ///< Unique ID of this device + UINT8 Type; ///< DEV_TYPE_PCI / DEV_TYPE_PCI_PRE_ESR + UINT8 Node; ///< Zero-based node number +} PCI_DEVICE_DESCRIPTOR; + +/// S3 'conditional' PCI device header +typedef struct { + UINT32 RegisterListID; ///< Unique ID of this device + UINT8 Type; ///< DEV_TYPE_CPCI / DEV_TYPE_CPCI_PRE_ESR + UINT8 Node; ///< Zero-based node number + UINT8 Mask1; ///< Conditional mask 1 + UINT8 Mask2; ///< Conditional mask 2 +} CONDITIONAL_PCI_DEVICE_DESCRIPTOR; + +/// S3 MSR device header +typedef struct { + UINT32 RegisterListID; ///< Unique ID of this device + UINT8 Type; ///< DEV_TYPE_MSR / DEV_TYPE_MSR_PRE_ESR +} MSR_DEVICE_DESCRIPTOR; + +/// S3 'conditional' MSR device header +typedef struct { + UINT32 RegisterListID; ///< Unique ID of this device + UINT8 Type; ///< DEV_TYPE_CMSR / DEV_TYPE_CMSR_PRE_ESR + UINT8 Mask1; ///< Conditional mask 1 + UINT8 Mask2; ///< Conditional mask 2 +} CONDITIONAL_MSR_DEVICE_DESCRIPTOR; + +/* Special case related definitions */ + +/** + * PCI special case save handler + * + * @param[in] AccessWidth 8, 16, or 32 bit wide access + * @param[in] Address full PCI address of the register to save + * @param[out] Value Value read from the register + * @param[in] ConfigPtr AMD standard header config parameter + * + */ +typedef VOID (*PF_S3_SPECIAL_PCI_SAVE) ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + OUT VOID *Value, + IN VOID *ConfigPtr + ); + +/** + * PCI special case restore handler + * + * @param[in] AccessWidth 8, 16, or 32 bit wide access + * @param[in] Address full PCI address of the register to save + * @param[in] Value Value to write to the register + * @param[in] ConfigPtr AMD standard header config parameter + * + */ +typedef VOID (*PF_S3_SPECIAL_PCI_RESTORE) ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR PciAddress, + IN VOID *Value, + IN VOID *StdHeader + ); + +/** + * MSR special case save handler + * + * @param[in] MsrAddress Address of model specific register to save + * @param[out] Value Value read from the register + * @param[in] ConfigPtr AMD standard header config parameter + * + */ +typedef VOID (*PF_S3_SPECIAL_MSR_SAVE) ( + IN UINT32 MsrAddress, + OUT UINT64 *Value, + IN VOID *StdHeader + ); + +/** + * MSR special case restore handler + * + * @param[in] MsrAddress Address of model specific register to restore + * @param[in] Value Value to write to the register + * @param[in] ConfigPtr AMD standard header config parameter + * + */ +typedef VOID (*PF_S3_SPECIAL_MSR_RESTORE) ( + IN UINT32 MsrAddress, + IN UINT64 *Value, + IN VOID *StdHeader + ); + +/// PCI special case save/restore structure. +typedef struct { + PF_S3_SPECIAL_PCI_SAVE Save; ///< Save routine + PF_S3_SPECIAL_PCI_RESTORE Restore; ///< Restore routine +} PCI_SPECIAL_CASE; + +/// MSR special case save/restore structure. +typedef struct { + PF_S3_SPECIAL_MSR_SAVE Save; ///< Save routine + PF_S3_SPECIAL_MSR_RESTORE Restore; ///< Restore routine +} MSR_SPECIAL_CASE; + +/* Register related definitions */ +/// S3 register type bit fields +typedef struct { + UINT8 SpecialCaseIndex:4; ///< Special Case array index + UINT8 RegisterSize:3; ///< For PCI, 1 = byte, 2 = word, else = dword. + ///< For MSR, don't care + UINT8 SpecialCaseFlag:1; ///< Indicates special case +} S3_REGISTER_TYPE; + +/// S3 PCI register descriptor. +typedef struct { + S3_REGISTER_TYPE Type; ///< Type[7] = special case flag, + ///< Type[6:3] = register size in bytes, + ///< Type[2:0] = special case index + UINT8 Function; ///< PCI function of the register + UINT16 Offset; ///< PCI offset of the register + UINT32 AndMask; ///< AND mask to be applied to the value before saving + UINT8 BootMode; ///< Boot mode +} PCI_REG_DESCRIPTOR; + +/// S3 'conditional' PCI register descriptor. +typedef struct { + S3_REGISTER_TYPE Type; ///< Type[7] = special case flag, + ///< Type[6:3] = register size in bytes, + ///< Type[2:0] = special case index + UINT8 Function; ///< PCI function of the register + UINT16 Offset; ///< PCI offset of the register + UINT32 AndMask; ///< AND mask to be applied to the value before saving + UINT8 Mask1; ///< conditional mask 1 + UINT8 Mask2; ///< conditional mask 2 + UINT8 BootMode; ///< Boot mode +} CONDITIONAL_PCI_REG_DESCRIPTOR; + +/// S3 MSR register descriptor. +typedef struct { + S3_REGISTER_TYPE Type; ///< Type[7] = special case flag, + ///< Type[6:3] = reserved, + ///< Type[2:0] = special case index + UINT32 Address; ///< MSR address + UINT64 AndMask; ///< AND mask to be applied to the value before saving + UINT8 BootMode; ///< Boot mode +} MSR_REG_DESCRIPTOR; + +/// S3 'conditional' MSR register descriptor. +typedef struct { + S3_REGISTER_TYPE Type; ///< Type[7] = special case flag, + ///< Type[6:3] = reserved, + ///< Type[2:0] = special case index + UINT32 Address; ///< MSR address + UINT64 AndMask; ///< AND mask to be applied to the value before saving + UINT8 Mask1; ///< conditional mask 1 + UINT8 Mask2; ///< conditional mask 2 + UINT8 BootMode; ///< Boot mode +} CONDITIONAL_MSR_REG_DESCRIPTOR; + +/// Common header at the beginning of an S3 register list. +typedef struct { + UINT16 Version; ///< Version of header + UINT16 NumRegisters; ///< Number of registers in the list +} REGISTER_BLOCK_HEADER; + +/// S3 PCI register list header. +typedef struct { + UINT16 Version; ///< Version of header + UINT16 NumRegisters; ///< Number of registers in the list + PCI_REG_DESCRIPTOR *RegisterList; ///< Pointer to the first register descriptor + PCI_SPECIAL_CASE *SpecialCases; ///< Pointer to array of special case handlers +} PCI_REGISTER_BLOCK_HEADER; + +/// S3 'conditional' PCI register list header. +typedef struct { + UINT16 Version; ///< Version of header + UINT16 NumRegisters; ///< Number of registers in the list + CONDITIONAL_PCI_REG_DESCRIPTOR *RegisterList; ///< Pointer to the first register descriptor + PCI_SPECIAL_CASE *SpecialCases; ///< Pointer to array of special case handlers +} CPCI_REGISTER_BLOCK_HEADER; + +/// S3 MSR register list header. +typedef struct { + UINT16 Version; ///< Version of header + UINT16 NumRegisters; ///< Number of registers in the list + MSR_REG_DESCRIPTOR *RegisterList; ///< Pointer to the first register descriptor + MSR_SPECIAL_CASE *SpecialCases; ///< Pointer to array of special case handlers +} MSR_REGISTER_BLOCK_HEADER; + +/// S3 'conditional' MSR register list header. +typedef struct { + UINT16 Version; ///< Version of header + UINT16 NumRegisters; ///< Number of registers in the list + CONDITIONAL_MSR_REG_DESCRIPTOR *RegisterList; ///< Pointer to the first register descriptor + MSR_SPECIAL_CASE *SpecialCases; ///< Pointer to array of special case handlers +} CMSR_REGISTER_BLOCK_HEADER; + +/// S3 device descriptor pointers for ease of proper pointer advancement. +typedef union { + DEVICE_DESCRIPTOR *CommonDeviceHeader; ///< Common header + PCI_DEVICE_DESCRIPTOR *PciDevice; ///< PCI header + CONDITIONAL_PCI_DEVICE_DESCRIPTOR *CPciDevice; ///< 'conditional' PCI header + MSR_DEVICE_DESCRIPTOR *MsrDevice; ///< MSR header + CONDITIONAL_MSR_DEVICE_DESCRIPTOR *CMsrDevice; ///< 'conditional' MSR header +} DEVICE_DESCRIPTORS; + +/// S3 register list header pointers for ease of proper pointer advancement. +typedef union { + DEVICE_DESCRIPTOR *CommonDeviceHeader; ///< Common header + PCI_REGISTER_BLOCK_HEADER *PciRegisters; ///< PCI header + CPCI_REGISTER_BLOCK_HEADER *CPciRegisters; ///< 'conditional' PCI header + MSR_REGISTER_BLOCK_HEADER *MsrRegisters; ///< MSR header + CMSR_REGISTER_BLOCK_HEADER *CMsrRegisters; ///< 'conditional' MSR header +} REGISTER_BLOCK_HEADERS; + +/// S3 Volatile Storage Header +typedef struct { + UINT32 HeapOffset; ///< Offset to beginning of heap data + UINT32 HeapSize; ///< Size of the heap data + UINT32 RegisterDataOffset; ///< Offset to beginning of raw save data + UINT32 RegisterDataSize; ///< Size of raw save data +} S3_VOLATILE_STORAGE_HEADER; + + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +UINT32 +GetWorstCaseContextSize ( + IN DEVICE_BLOCK_HEADER *DeviceList, + IN CALL_POINTS CallPoint, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SaveDeviceListContext ( + IN DEVICE_BLOCK_HEADER *DeviceList, + IN VOID *Storage, + IN CALL_POINTS CallPoint, + OUT UINT32 *ActualBufferSize, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +RestorePreESRContext ( + OUT VOID **OrMaskPtr, + IN VOID *Storage, + IN CALL_POINTS CallPoint, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +RestorePostESRContext ( + IN VOID *OrMaskPtr, + IN VOID *Storage, + IN CALL_POINTS CallPoint, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +AmdS3ParamsInitializer ( + OUT AMD_S3_PARAMS *S3Params + ); + +VOID +GetNonMemoryRelatedDeviceList ( + OUT DEVICE_BLOCK_HEADER **NonMemoryRelatedDeviceList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +S3GetPciDeviceRegisterList ( + IN PCI_DEVICE_DESCRIPTOR *Device, + OUT PCI_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +S3GetCPciDeviceRegisterList ( + IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device, + OUT CPCI_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +S3GetMsrDeviceRegisterList ( + IN MSR_DEVICE_DESCRIPTOR *Device, + OUT MSR_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +S3GetCMsrDeviceRegisterList ( + IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, + OUT CMSR_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +#endif // _S3_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.c new file mode 100644 index 0000000000..a27140bacf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.c @@ -0,0 +1,927 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Register Table Related Functions + * + * Set registers according to a set of register tables + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Topology.h" +#include "OptionMultiSocket.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "Table.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuFeatures.h" +#include "CommonReturns.h" +#include "cpuL3Features.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_TABLE_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +SetRegistersFromTablesBeforeApLaunch ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SetRegistersFromTablesAfterApLaunch ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; +extern CPU_FAMILY_SUPPORT_TABLE L3FeatureFamilyServiceTable; + +/*---------------------------------------------------------------------------------------*/ +/** + * An iterator for all the Family and Model Register Tables. + * + * RegisterTableHandle should be set to NULL to begin iteration, the first time the method is + * invoked. Register tables can be processed, until this method returns NULL. RegisterTableHandle + * should simply be passed back to the method without modification or use by the caller. + * The table selector allows the relevant tables for different cores to be iterated, if the family separates + * tables. For example, MSRs can be in a table processed by all cores and PCI registers in a table processed by + * primary cores. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] Selector Select whether to iterate over tables for either all cores, primary cores, bsp, .... + * @param[in] TimePoint Time point designator + * @param[in,out] RegisterTableHandle IN: The handle of the current register table, or NULL if Begin. + * OUT: The handle of the next register table, if not End. + * @param[out] NumberOfEntries The number of entries in the table returned, if not End. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @return The pointer to the next Register Table, or NULL if End. + */ +TABLE_ENTRY_FIELDS +STATIC +*GetNextRegisterTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN TABLE_CORE_SELECTOR Selector, + IN UINT32 TimePoint, + IN OUT REGISTER_TABLE ***RegisterTableHandle, + OUT UINTN *NumberOfEntries, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + REGISTER_TABLE **NextTable; + TABLE_ENTRY_FIELDS *Entries; + + ASSERT ((FamilySpecificServices != NULL) && (StdHeader != NULL)); + ASSERT (Selector < TableCoreSelectorMax); + + NextTable = *RegisterTableHandle; + if (NextTable == NULL) { + // Begin + NextTable = FamilySpecificServices->RegisterTableList; + IDS_OPTION_HOOK (IDS_TRAP_TABLE, &NextTable, StdHeader); + } else { + NextTable++; + } + // skip if not selected + while ((*NextTable != NULL) && (((*NextTable)->Selector != Selector) || (((*NextTable)->TimePoint & TimePoint) == 0))) { + NextTable++; + } + if (*NextTable == NULL) { + // End + *RegisterTableHandle = NULL; + Entries = NULL; + } else { + // Iterate next table + *RegisterTableHandle = NextTable; + *NumberOfEntries = (*NextTable)->NumberOfEntries; + Entries = (TABLE_ENTRY_FIELDS *) (*NextTable)->Table; + } + return Entries; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Compare counts to a pair of ranges. + * + * @param[in] FirstCount The actual count to be compared to the first range. + * @param[in] SecondCount The actual count to be compared to the second range. + * @param[in] Ranges The ranges which the counts are compared to. + * + * @retval TRUE Either one, or both, of the counts is in the range given. + * @retval FALSE Neither count is in the range given. + */ +BOOLEAN +IsEitherCountInRange ( + IN UINTN FirstCount, + IN UINTN SecondCount, + IN COUNT_RANGE_FEATURE Ranges + ) +{ + // Errors: Entire Range value is zero, Min and Max reversed or not <=, ranges overlap (OK if first range is all), + // the real counts are too big. + ASSERT ((Ranges.Range0Min <= Ranges.Range0Max) && + (Ranges.Range1Min <= Ranges.Range1Max) && + (Ranges.Range0Max != 0) && + (Ranges.Range1Max != 0) && + ((Ranges.Range0Max == COUNT_RANGE_HIGH) || (Ranges.Range0Max < Ranges.Range1Min)) && + ((FirstCount < COUNT_RANGE_HIGH) && (SecondCount < COUNT_RANGE_HIGH))); + + return (BOOLEAN) (((FirstCount <= Ranges.Range0Max) && (FirstCount >= Ranges.Range0Min)) || + ((SecondCount <= Ranges.Range1Max) && (SecondCount >= Ranges.Range1Min))); +} + +/*-------------------------------------------------------------------------------------*/ +/** + * Returns the performance profile features list of the currently running processor core. + * + * @param[out] Features The performance profile features supported by this platform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Header for library and services + * + */ +VOID +GetPerformanceFeatures ( + OUT PERFORMANCE_PROFILE_FEATS *Features, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPUID_DATA CpuidDataStruct; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + L3_FEATURE_FAMILY_SERVICES *FeatureFamilyServices; + + Features->PerformanceProfileValue = 0; + // Reflect Probe Filter Configuration. + Features->PerformanceProfileFeatures.ProbeFilter = 0; + if (IsFeatureEnabled (L3Features, PlatformConfig, StdHeader)) { + GetFeatureServicesOfCurrentCore (&L3FeatureFamilyServiceTable, (CONST VOID **)&FeatureFamilyServices, StdHeader); + if ((FeatureFamilyServices != NULL) && + (FeatureFamilyServices->IsHtAssistSupported (FeatureFamilyServices, PlatformConfig, StdHeader))) { + Features->PerformanceProfileFeatures.ProbeFilter = 1; + } + } + + // Reflect Display Refresh Requests use 32 bytes Configuration. + Features->PerformanceProfileFeatures.RefreshRequest32Byte = 0; + if (PlatformConfig->PlatformProfile.Use32ByteRefresh) { + Features->PerformanceProfileFeatures.RefreshRequest32Byte = 1; + } + // Reflect Mct Isoc Read Priority set to variable Configuration. + Features->PerformanceProfileFeatures.MctIsocVariable = 0; + if (PlatformConfig->PlatformProfile.UseVariableMctIsocPriority) { + Features->PerformanceProfileFeatures.MctIsocVariable = 1; + } + // Indicate if this boot is a warm reset. + Features->PerformanceProfileFeatures.IsWarmReset = 0; + if (IsWarmReset (StdHeader)) { + Features->PerformanceProfileFeatures.IsWarmReset = 1; + } + + // Get L3 Cache present as indicated by CPUID + Features->PerformanceProfileFeatures.L3Cache = 0; + Features->PerformanceProfileFeatures.NoL3Cache = 1; + LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuidDataStruct, StdHeader); + if (((CpuidDataStruct.EDX_Reg & 0xFFFC0000) >> 18) != 0) { + Features->PerformanceProfileFeatures.L3Cache = 1; + Features->PerformanceProfileFeatures.NoL3Cache = 0; + } + + // Get VRM select high speed from build option. + Features->PerformanceProfileFeatures.VrmHighSpeed = 0; + if (PlatformConfig->VrmProperties[CoreVrm].HiSpeedEnable) { + Features->PerformanceProfileFeatures.VrmHighSpeed = 1; + } + + // Get some family, model specific performance type info. + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + ASSERT (FamilySpecificServices != NULL); + + // Is the Northbridge P-State feature enabled + Features->PerformanceProfileFeatures.NbPstates = 0; + if (FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, PlatformConfig, StdHeader)) { + Features->PerformanceProfileFeatures.NbPstates = 1; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the MSR Register Entry. + * + * @TableEntryTypeMethod{::MsrRegister}. + * + * Read - Modify - Write the MSR, clearing masked bits, and setting the data bits. + * + * @param[in] Entry The MSR register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForMsrEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrData; + + // Even for only single bit fields, use those in the mask. "Mask nothing" is a bug, even if just by policy. + ASSERT (Entry->MsrEntry.Mask != 0); + + LibAmdMsrRead (Entry->MsrEntry.Address, &MsrData, StdHeader); + MsrData = MsrData & (~(Entry->MsrEntry.Mask)); + MsrData = MsrData | Entry->MsrEntry.Data; + LibAmdMsrWrite (Entry->MsrEntry.Address, &MsrData, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the PCI Register Entry. + * + * @TableEntryTypeMethod{::PciRegister}. + * + * Make the current core's PCI address with the function and register for the entry. + * Read - Modify - Write the PCI register, clearing masked bits, and setting the data bits. + * + * @param[in] Entry The PCI register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForPciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TempVar32_a; + UINT32 MySocket; + UINT32 MyModule; + UINT32 Ignored; + PCI_ADDR MyPciAddress; + AGESA_STATUS IgnoredSts; + TABLE_ENTRY_DATA PciEntry; + + // Errors: Possible values in unused entry space, extra type features, value range checks. + // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry. + // Even for only single bit fields, use those in the mask. "Mask nothing" is a bug, even if just by policy. + ASSERT ((Entry->InitialValues[4] == 0) && + (Entry->InitialValues[3] == 0) && + (Entry->PciEntry.Mask != 0)); + + LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + PciEntry.PciEntry = Entry->PciEntry; + + IDS_OPTION_HOOK (IDS_SET_PCI_REGISTER_ENTRY, &PciEntry, StdHeader); + + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, MySocket, MyModule, &MyPciAddress, &IgnoredSts); + MyPciAddress.Address.Function = PciEntry.PciEntry.Address.Address.Function; + MyPciAddress.Address.Register = PciEntry.PciEntry.Address.Address.Register; + LibAmdPciRead (AccessWidth32, MyPciAddress, &TempVar32_a, StdHeader); + TempVar32_a = TempVar32_a & (~(PciEntry.PciEntry.Mask)); + TempVar32_a = TempVar32_a | PciEntry.PciEntry.Data; + LibAmdPciWrite (AccessWidth32, MyPciAddress, &TempVar32_a, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the Family Specific Workaround Register Entry. + * + * @TableEntryTypeMethod{::FamSpecificWorkaround}. + * + * Call the function, passing the data. + * + * See if you can use the other entries or make an entry that covers the fix. + * After all, the purpose of having a table entry is to @b NOT have code which + * isn't generic feature code, but is family/model code specific to one case. + * + * @param[in] Entry The Family Specific Workaround register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForFamSpecificWorkaroundEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + ASSERT (Entry->FamSpecificEntry.DoAction != NULL); + + Entry->FamSpecificEntry.DoAction (Entry->FamSpecificEntry.Data, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the Performance Profile PCI Register Entry. + * + * @TableEntryTypeMethod{::ProfileFixup}. + * + * Check the entry's performance profile features to the platform's and do the + * PCI register entry if they match. + * + * @param[in] Entry The Performance Profile register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForPerformanceProfileEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PERFORMANCE_PROFILE_FEATS PlatformProfile; + TABLE_ENTRY_DATA PciEntry; + + // Errors: Possible values in unused entry space, extra type features, value range checks. + // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry. + ASSERT (((Entry->TokenPciEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0) && + (Entry->InitialValues[4] == 0)); + + GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, + Entry->FixupEntry.TypeFeats.PerformanceProfileValue)) { + LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + PciEntry.PciEntry = Entry->FixupEntry.PciEntry; + SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader); + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the Core Counts Performance PCI Register Entry. + * + * @TableEntryTypeMethod{::CoreCountsPciRegister}. + * + * Check the performance profile. + * Check the actual core count to the range pair given, and apply if matched. + * + * @param[in] Entry The PCI register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForCoreCountsPerformanceEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PERFORMANCE_PROFILE_FEATS PlatformProfile; + UINTN ActualCoreCount; + TABLE_ENTRY_DATA PciEntry; + + // Errors: Possible values in unused entry space, extra type features, value range checks. + // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry. + ASSERT (((Entry->CoreCountEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0)); + + GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, Entry->CoreCountEntry.TypeFeats.PerformanceProfileValue)) { + ActualCoreCount = GetActiveCoresInCurrentModule (StdHeader); + // Check if the actual core count is in either range. + if (IsEitherCountInRange (ActualCoreCount, ActualCoreCount, Entry->CoreCountEntry.CoreCounts.CoreRanges)) { + LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + PciEntry.PciEntry = Entry->CoreCountEntry.PciEntry; + SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader); + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the Processor Counts PCI Register Entry. + * + * @TableEntryTypeMethod{::ProcCountsPciRegister}. + * + * Check the performance profile. + * Check the actual processor count (not node count!) to the range pair given, and apply if matched. + * + * @param[in] Entry The PCI register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForProcessorCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PERFORMANCE_PROFILE_FEATS PlatformProfile; + UINTN ProcessorCount; + TABLE_ENTRY_DATA PciEntry; + + // Errors: Possible values in unused entry space, extra type features, value range checks. + // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry. + ASSERT (((Entry->ProcCountEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0)); + + GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, Entry->ProcCountEntry.TypeFeats.PerformanceProfileValue)) { + ProcessorCount = GetNumberOfProcessors (StdHeader); + // Check if the actual processor count is in either range. + if (IsEitherCountInRange (ProcessorCount, ProcessorCount, Entry->ProcCountEntry.ProcessorCounts.ProcessorCountRanges)) { + LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + PciEntry.PciEntry = Entry->ProcCountEntry.PciEntry; + SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader); + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the Compute Unit Counts PCI Register Entry. + * + * @TableEntryTypeMethod{::CompUnitCountsPciRegister}. + * + * Check the entry's performance profile features and the compute unit count + * to the platform's and do the PCI register entry if they match. + * + * @param[in] Entry The PCI register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForComputeUnitCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PERFORMANCE_PROFILE_FEATS PlatformProfile; + UINTN ComputeUnitCount; + TABLE_ENTRY_DATA PciEntry; + + // Errors: Possible values in unused entry space, extra type features, value range checks. + // Check that the entry type is correct and the actual supplied entry data is appropriate for that entry. + ASSERT (((Entry->CompUnitCountEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0)); + + GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, Entry->CompUnitCountEntry.TypeFeats.PerformanceProfileValue)) { + ComputeUnitCount = GetNumberOfCompUnitsInCurrentModule (StdHeader); + // Check if the actual compute unit count is in either range. + if (IsEitherCountInRange (ComputeUnitCount, ComputeUnitCount, Entry->CompUnitCountEntry.ComputeUnitCounts.ComputeUnitRanges)) { + LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + PciEntry.PciEntry = Entry->CompUnitCountEntry.PciEntry; + SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader); + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the Compute Unit Counts MSR Register Entry. + * + * @TableEntryTypeMethod{::CompUnitCountsMsr}. + * + * Check the entry's compute unit count to the platform's and do the + * MSR entry if they match. + * + * @param[in] Entry The PCI register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetMsrForComputeUnitCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN ComputeUnitCount; + TABLE_ENTRY_DATA MsrEntry; + + ComputeUnitCount = GetNumberOfCompUnitsInCurrentModule (StdHeader); + // Check if the actual compute unit count is in either range. + if (IsEitherCountInRange (ComputeUnitCount, ComputeUnitCount, Entry->CompUnitCountMsrEntry.ComputeUnitCounts.ComputeUnitRanges)) { + LibAmdMemFill (&MsrEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + MsrEntry.MsrEntry = Entry->CompUnitCountMsrEntry.MsrEntry; + SetRegisterForMsrEntry (&MsrEntry, PlatformConfig, StdHeader); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * Returns the platform features list of the currently running processor core. + * + * @param[out] Features The Features supported by this platform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Header for library and services + * + */ +VOID +GetPlatformFeatures ( + OUT PLATFORM_FEATS *Features, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + UINT32 CapabilityReg; + UINT32 Link; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + UINT32 CoreCount; + + // Start with none. + Features->PlatformValue = 0; + + switch (PlatformConfig->PlatformProfile.PlatformControlFlowMode) { + case Nfcm: + Features->PlatformFeatures.PlatformNfcm = 1; + break; + case UmaDr: + Features->PlatformFeatures.PlatformUma = 1; + break; + case UmaIfcm: + Features->PlatformFeatures.PlatformUmaIfcm = 1; + break; + case Ifcm: + Features->PlatformFeatures.PlatformIfcm = 1; + break; + case Iommu: + Features->PlatformFeatures.PlatformIommu = 1; + break; + default: + ASSERT (FALSE); + } + // Check - Single Link? + // This is based on the implemented links on the package regardless of their + // connection status. All processors must match the BSP, so we only check it and + // not the current node. We don't care exactly how many links there are, as soon + // as we find more than one we are done. + Link = 0; + PciAddress.AddressValue = MAKE_SBDFO (0, 0, PCI_DEV_BASE, FUNC_0, 0); + // Until either all capabilities are done or until the desired link is found, + // keep looking for HT Host Capabilities. + while (Link < 2) { + LibAmdPciFindNextCap (&PciAddress, StdHeader); + if (PciAddress.AddressValue != ILLEGAL_SBDFO) { + LibAmdPciRead (AccessWidth32, PciAddress, &CapabilityReg, StdHeader); + if ((CapabilityReg & 0xE00000FF) == 0x20000008) { + Link++; + } + // A capability other than an HT capability, keep looking. + } else { + // end of capabilities + break; + } + } + if (Link < 2) { + Features->PlatformFeatures.PlatformSingleLink = 1; + } else { + Features->PlatformFeatures.PlatformMultiLink = 1; + } + + // Set the legacy core count bits. + GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); + switch (CoreCount) { + case 1: + Features->PlatformFeatures.PlatformSingleCore = 1; + break; + case 2: + Features->PlatformFeatures.PlatformDualCore = 1; + break; + default: + Features->PlatformFeatures.PlatformMultiCore = 1; + } + + // + // Get some specific platform type info, VC...etc. + // + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + ASSERT (FamilySpecificServices != NULL); + FamilySpecificServices->GetPlatformTypeSpecificInfo (FamilySpecificServices, Features, StdHeader); + +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Checks if a register table entry applies to the executing core. + * + * This function uses a combination of logical ID and platform features to + * determine whether or not a register table entry applies to the executing core. + * + * @param[in] CoreCpuRevision The current core's logical ID + * @param[in] EntryCpuRevision The entry's desired logical IDs + * @param[in] PlatformFeatures The platform features + * @param[in] EntryFeatures The entry's desired platform features + * + * @retval TRUE This entry should be applied + * @retval FALSE This entry does not apply + * + */ +BOOLEAN +STATIC +DoesEntryMatchPlatform ( + IN CPU_LOGICAL_ID CoreCpuRevision, + IN CPU_LOGICAL_ID EntryCpuRevision, + IN PLATFORM_FEATS PlatformFeatures, + IN PLATFORM_FEATS EntryFeatures + ) +{ + BOOLEAN Result; + + Result = FALSE; + + if (((CoreCpuRevision.Family & EntryCpuRevision.Family) != 0) && + ((CoreCpuRevision.Revision & EntryCpuRevision.Revision) != 0)) { + if (EntryFeatures.PlatformFeatures.AndPlatformFeats == 0) { + // Match if ANY entry feats match a platform feat (an OR test) + if ((EntryFeatures.PlatformValue & PlatformFeatures.PlatformValue) != 0) { + Result = TRUE; + } + } else { + // Match if ALL entry feats match a platform feat (an AND test) + if ((EntryFeatures.PlatformValue & ~(AMD_PF_AND)) == + (EntryFeatures.PlatformValue & PlatformFeatures.PlatformValue)) { + Result = TRUE; + } + } + } + + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Checks register table entry type specific criteria to the platform. + * + * Entry Data Type implementer methods can use this generically to check their own + * specific criteria. The method collects the actual platform characteristics and + * provides them along with the table entry's criteria to this service. + * + * There are a couple considerations for any implementer method using this service. + * The criteria value has to be representable as a UINT32. The MSB, Bit 31, has to + * be used as a AND test request if set in the entry. (The platform value should never + * have that bit set.) + * + * @param[in] PlatformTypeSpecificFeatures The platform features + * @param[in] EntryTypeFeatures The entry's desired platform features + * + * @retval TRUE This entry should be applied + * @retval FALSE This entry does not apply + * + */ +BOOLEAN +DoesEntryTypeSpecificInfoMatch ( + IN UINT32 PlatformTypeSpecificFeatures, + IN UINT32 EntryTypeFeatures + ) +{ + BOOLEAN Result; + + Result = FALSE; + + if ((EntryTypeFeatures & BIT31) == 0) { + // Match if ANY entry feats match a platform feat (an OR test) + if ((EntryTypeFeatures & PlatformTypeSpecificFeatures) != 0) { + Result = TRUE; + } + } else { + // Match if ALL entry feats match a platform feat (an AND test) + if ((EntryTypeFeatures & ~(BIT31)) == (EntryTypeFeatures & PlatformTypeSpecificFeatures)) { + Result = TRUE; + } + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Determine this core's Selector matches. + * + * @param[in] Selector Is the current core this selector type? + * @param[in] StdHeader Config handle for library and services. + * + * @retval TRUE Yes, it is. + * @retval FALSE No, it is not. + */ +BOOLEAN +STATIC +IsCoreSelector ( + IN TABLE_CORE_SELECTOR Selector, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN Result; + AGESA_STATUS CalledStatus; + + Result = TRUE; + ASSERT (Selector < TableCoreSelectorMax); + + if ((Selector == PrimaryCores) && !IsCurrentCorePrimary (StdHeader)) { + Result = FALSE; + } + if ((Selector == ComputeUnitPrimary) && !IsCoreComputeUnitPrimary (FirstCoreIsComputeUnitPrimary, StdHeader)) { + Result = FALSE; + } + if ((Selector == BscCore) && (!IsBsp (StdHeader, &CalledStatus))) { + Result = FALSE; + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Set the registers for this core based on entries in a list of Register Tables. + * + * Determine the platform features and this core's logical id. Get the specific table + * entry type implementations for the logical model, which may be either generic (the ones + * in this file) or specific. + * + * Scan the tables starting the with ones for all cores and progressively narrowing the selection + * based on this core's role (ex. primary core). For a selected table, check for each entry + * matching the current core and platform, and call the implementer method to perform the + * register set operation if it matches. + * + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] TimePoint Time point designator + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegistersFromTables ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT32 TimePoint, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_LOGICAL_ID CpuLogicalId; + PLATFORM_FEATS PlatformFeatures; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + TABLE_ENTRY_FIELDS *Entries; + TABLE_CORE_SELECTOR Selector; + TABLE_ENTRY_TYPE EntryType; + REGISTER_TABLE **TableHandle; + UINTN NumberOfEntries; + UINTN CurrentEntryCount; + TABLE_ENTRY_TYPE_DESCRIPTOR *TypeImplementer; + PF_DO_TABLE_ENTRY DoTableEntry[TableEntryTypeMax]; + + // Did you really mean to increase the size of ALL table entries??!! + // While it is not necessarily a bug to increase the size of table entries: + // - Is this warning a surprise? Please fix it. + // - If expected, is this really a feature which is worth the increase? Then let other entries also use the space. + ASSERT (sizeof (TABLE_ENTRY_DATA) == (MAX_ENTRY_TYPE_ITEMS32 * sizeof (UINT32))); + + PlatformFeatures.PlatformValue = 0; + GetLogicalIdOfCurrentCore (&CpuLogicalId, StdHeader); + GetPlatformFeatures (&PlatformFeatures, PlatformConfig, StdHeader); + GetCpuServicesFromLogicalId (&CpuLogicalId, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + + // Build a non-sparse table of implementer methods, so we don't have to keep searching. + // It is a bug to not include a descriptor for a type that is in the table (but the + // descriptor can point to a non-assert stub). + // Also, it is not a bug to have no register table implementations, but it is a bug to have none and call this routine. + for (EntryType = MsrRegister; EntryType < TableEntryTypeMax; EntryType++) { + DoTableEntry[EntryType] = (PF_DO_TABLE_ENTRY)CommonAssert; + } + TypeImplementer = FamilySpecificServices->TableEntryTypeDescriptors; + ASSERT (TypeImplementer != NULL); + while (TypeImplementer->EntryType < TableEntryTypeMax) { + DoTableEntry[TypeImplementer->EntryType] = TypeImplementer->DoTableEntry; + TypeImplementer++; + } + + for (Selector = AllCores; Selector < TableCoreSelectorMax; Selector++) { + if (IsCoreSelector (Selector, StdHeader)) { + // If the current core is the selected type of core, work the table list for tables for that type of core. + TableHandle = NULL; + Entries = GetNextRegisterTable (FamilySpecificServices, Selector, TimePoint, &TableHandle, &NumberOfEntries, StdHeader); + while (Entries != NULL) { + for (CurrentEntryCount = 0; CurrentEntryCount < NumberOfEntries; CurrentEntryCount++, Entries++) { + if (DoesEntryMatchPlatform (CpuLogicalId, Entries->CpuRevision, PlatformFeatures, Entries->Features)) { + // The entry matches this config, Do It! + // Find the implementer for this entry type and pass the entry data to it. + ASSERT (Entries->EntryType < TableEntryTypeMax); + DoTableEntry[Entries->EntryType] (&Entries->Entry, PlatformConfig, StdHeader); + } + } + Entries = GetNextRegisterTable (FamilySpecificServices, Selector, TimePoint, &TableHandle, &NumberOfEntries, StdHeader); + } + } else { + // Once a selector does not match the current core, quit looking. + break; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Set the registers for this core based on entries in a list of Register Tables. + * + * This function acts as a wrapper for calling the SetRegistersFromTables + * routine at AmdInitEarly. + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[in] EarlyParams Service parameters. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegistersFromTablesBeforeApLaunch ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_TESTPOINT (TpProcCpuProcessRegisterTables, StdHeader); + SetRegistersFromTables (&EarlyParams->PlatformConfig, PERFORM_TP_BEFORE_AP_LAUNCH, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Set the registers for this core based on entries in a list of Register Tables. + * + * This function acts as a wrapper for calling the SetRegistersFromTables + * routine at AmdInitEarly. + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[in] EarlyParams Service parameters. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegistersFromTablesAfterApLaunch ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_TESTPOINT (TpProcCpuProcessRegisterTables, StdHeader); + SetRegistersFromTables (&EarlyParams->PlatformConfig, PERFORM_TP_AFTER_AP_LAUNCH, StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h new file mode 100644 index 0000000000..1f6341abe9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Table.h @@ -0,0 +1,1314 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Register Table Related Functions + * + * Contains code to initialize the CPU MSRs and PCI registers with BKDG recommended values + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_TABLE_H_ +#define _CPU_TABLE_H_ + +#define MAX_ENTRY_TYPE_ITEMS32 6 // The maximum number of initializer items for UINT32 entry data types. + +/** + * @page regtableimpl Register Table Implementation Guide + * + * This register table implementation is modular and extensible, so that support code as + * well as table data can be family specific or built out if not needed, and new types + * of table entries can be added with low overhead. Because many aspects are now generic, + * there can be common implementations for CPU revision and platform feature matching and for + * finding and iterating tables. + * + * @par Adding a new table entry type. + * + * To add a new table entry type follow these steps. + *
    + *
  • Add a member to the enum TABLE_ENTRY_TYPE which is a descriptive name of the entry's purpose + * or distinct characteristics. + * + *
  • Create an entry data struct with the customized data needed. For example, custom register designations, + * data and mask sizes, or feature comparisons. Name your struct by adding "_" and upper-casing the enum name + * and adding "_TYPE_ENTRY_DATA" at the end. + * + *
  • Add the entry data type as a member of the TABLE_ENTRY_DATA union. Be aware of the size of your + * entry data struct; all table entries in all tables will share any size increase you introduce! + * + *
  • If your data entry contains any member types except for UINT32, you can't use the generic first union member + * for the initializers that make up the actual tables (it's just UINT32's). The generic MSR entry is + * an example. Follow the steps below: + * + *
      + *
    • Make a union which has your entry data type as the first member. Use TABLE_ENTRY_DATA as the + * second member. Name this with your register followed by "_DATA_INITIALIZER". + * + *
    • Make a copy of TABLE_ENTRY_FIELDS, and rename it your register "_TYPE_ENTRY_INITIALIZER". Rename + * the TABLE_ENTRY_DATA member of that struct to have the type you created in the previous step. + * This type can be used to declare an array of entries and make a register table in some family specific + * file. + *
    + * + *
  • Add the descriptor that will link table entries of your data type to an implementation for it. + *
      + *
    • Find the options file which instantiates the CPU_SPECIFIC_SERVICES for each logical model that will + * support the new entry type. + * + *
    • From there find the instantiation of its TABLE_ENTRY_TYPE_DESCRIPTOR. Add a descriptor to the + * to the list for your new type. Provide the name of a function which will implement the + * entry data. The function name should reflect that it implements the action for the entry type. + * The function must be an instance of F_DO_TABLE_ENTRY. + *
    + * + *
  • Implement the function for your entry type data. (If parts of it are family specific add methods to + * CPU_SPECIFIC_SERVICES for that and implement them for each family or model required.) @n + * The definition of the function must conform to F_DO_TABLE_ENTRY. + * In the function preamble, include a cross reference to the entry enum: + * @code + * * + * * @TableEntryTypeMethod{::MyRegister} + * * + * @endcode + * + *
+ * + * @par Adding a new Register Table + * + * To add a new register table for a logical CPU model follow the steps below. + * + *
    + *
  • Find the options file which instantiates the CPU_SPECIFIC_SERVICES for the logical model that + * should include the table. + * + *
  • From there find the instantiation of its REGISTER_TABLE list. Add the name of the new register table. + *
+ * + */ + +/*------------------------------------------------------------------------------------------*/ +/* + * Define the supported table entries. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * These are the available types of table entries. + * + * Each type corresponds to: + * - a semantics for the type specific data, for example semantics for a Register value, + * Data value, and Mask value. + * - optionally, including a method for type specific matching criteria + * - a method for writing the desired update to the hardware. + * + * All types share in common a method to match CPU Family and Model and a method to match + * platform feature set. + * + */ +typedef enum { + MsrRegister, ///< Processor MSR registers. + PciRegister, ///< Processor Config Space registers. + FamSpecificWorkaround, ///< Processor Family Specific Workarounds which are @b not practical using the other types. + HtPhyRegister, ///< Processor HT Phy registers. + HtPhyRangeRegister, ///< Processor HT Phy range of contiguous registers (ex. 40h:48h). + DeemphasisRegister, ///< Processor Deemphasis register (HT Phy special case). + HtPhyFreqRegister, ///< Processor Frequency dependent HT Phy settings. + ProfileFixup, ///< Processor Performance Profile fixups to PCI Config Registers. + HtHostPciRegister, ///< Processor Ht Host capability registers (PCI Config). + HtHostPerfPciRegister, ///< Processor Ht Host capability registers which depend on performance features. + HtTokenPciRegister, ///< Processor Ht Link Token count registers. + CoreCountsPciRegister, ///< Processor PCI Config Registers which depend on core counts. + ProcCountsPciRegister, ///< Processor PCI Config Registers which depend on processor counts. + CompUnitCountsPciRegister, ///< Processor PCI Config Registers which depend on compute unit counts. + TokenPciRegister, ///< Processor northbridge Token Count register which may be dependent on connectivity. + HtFeatPciRegister, ///< Processor HT Link feature dependant PCI Config Registers. + HtPhyProfileRegister, ///< Processor HT Phy registers which depend on performance features. + HtLinkPciRegister, ///< Processor HT Link registers (one per link) not part of HT Host capability. + CompUnitCountsMsr, ///< Processor MSRs which depend on compute unit counts. + TableEntryTypeMax ///< Not a valid entry type, use for limit checking. +} TABLE_ENTRY_TYPE; + +/*------------------------------------------------------------------------------------------*/ +/* + * Useful types and defines: Selectors, Platform Features, and type specific features. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * Select tables for the current core. + * + * This allows more efficient register table processing, by allowing cores to skip + * redundantly setting PCI registers, for example. This feature is not intended to + * be relied on for function: it is valid to have a single register table with all settings + * processed by every core; it's just slower. + * + */ +typedef enum { + AllCores, ///< Select only tables which apply to all cores. + ComputeUnitPrimary, ///< Select tables which apply to the primary core of a compute unit (SharedC, SharedNc). + PrimaryCores, ///< Select tables which apply to primary cores. + BscCore, ///< Select tables which apply to the boot core. + TableCoreSelectorMax ///< Not a valid selector, use for limit checking. +} TABLE_CORE_SELECTOR; + +//---------------------------------------------------------------------------- +// CPU PERFORM EARLY INIT ON CORE +// +//---------------------------------------------------------------------------- +/// Flag definition. + +// Condition +#define PERFORM_EARLY_WARM_RESET 0x1 // bit 0 --- the related function needs to be run if it's warm reset +#define PERFORM_EARLY_COLD_BOOT 0x2 // bit 1 --- the related function needs to be run if it's cold boot + +// TimePoint +#define PERFORM_TP_AFTER_AP_LAUNCH 0x40000000ul // bit 30 --- the related function needs to be run after AP launch +#define PERFORM_TP_BEFORE_AP_LAUNCH 0x80000000ul // bit 31 --- the related function needs to be run before AP launch + +#define PERFORM_TP_ALL (PERFORM_TP_AFTER_AP_LAUNCH | PERFORM_TP_BEFORE_AP_LAUNCH) + +#define PERFORM_EARLY_ANY_CONDITION (PERFORM_EARLY_WARM_RESET | PERFORM_EARLY_COLD_BOOT) + +// Initializer bit pattern values for platform features. +// Keep in synch with the PLATFORM_FEATURES struct! + +// The 5 control flow modes. +#define AMD_PF_NFCM BIT0 +#define AMD_PF_UMA BIT1 // UMA_DR +#define AMD_PF_UMA_IFCM BIT2 +#define AMD_PF_IFCM BIT3 +#define AMD_PF_IOMMU BIT4 +// Degree of HT connectivity possible. +#define AMD_PF_SINGLE_LINK BIT5 +#define AMD_PF_MULTI_LINK BIT6 +// For some legacy MSRs, define a couple core count bits. Do not continue adding +// core counts to the platform feats, if you need more than this design a table entry type. +// Here, provide exactly 1, exactly 2, or anything else. +#define AMD_PF_SINGLE_CORE BIT7 +#define AMD_PF_DUAL_CORE BIT8 +#define AMD_PF_MULTI_CORE BIT9 + +// Not a platform type, but treat all others as AND +#define AMD_PF_AND BIT31 + +#define AMD_PF_ALL (AMD_PF_NFCM | \ + AMD_PF_UMA | \ + AMD_PF_UMA_IFCM | \ + AMD_PF_IFCM | \ + AMD_PF_IOMMU | \ + AMD_PF_SINGLE_LINK | \ + AMD_PF_MULTI_LINK | \ + AMD_PF_SINGLE_CORE | \ + AMD_PF_DUAL_CORE | \ + AMD_PF_MULTI_CORE) +// Do not include AMD_PF_AND in AMD_PF_ALL ! + +/** + * The current platform features. + * + * Keep this in sync with defines above that are used in the initializers! + * + * The comments with the bit number are useful for the computing the reserved member size, but + * do not write code that assumes you know what bit number one of these members is. + * + * These platform features are standard for all logical families and models. + */ +typedef struct { + UINT32 PlatformNfcm:1; ///< BIT_0 Normal Flow Control Mode. + UINT32 PlatformUma:1; ///< BIT_1 UMA (Display Refresh) Flow Control. + UINT32 PlatformUmaIfcm:1; ///< BIT_2 UMA using Isochronous Flow Control. + UINT32 PlatformIfcm:1; ///< BIT_3 Isochronous Flow Control Mode (not UMA). + UINT32 PlatformIommu:1; ///< BIT_4 IOMMU (a special case Isochronous mode). + UINT32 PlatformSingleLink:1; ///< BIT_5 The processor is in a package which implements only a single HT Link. + UINT32 PlatformMultiLink:1; ///< BIT_6 The processor is in a package which implements more than one HT Link. + UINT32 PlatformSingleCore:1; ///< BIT_7 Single Core processor, for legacy entries. + UINT32 PlatformDualCore:1; ///< BIT_8 Dual Core processor, for legacy entries. + UINT32 PlatformMultiCore:1; ///< BIT_9 More than dual Core processor, for legacy entries. + UINT32 :(30 - 9); ///< The possibilities are (not quite) endless. + UINT32 AndPlatformFeats:1; ///< BIT_31 +} PLATFORM_FEATURES; + +/** + * Platform Features + */ +typedef union { + UINT32 PlatformValue; ///< Describe Platform Features in UINT32. + ///< This one goes first, because then initializers use it automatically for the union. + PLATFORM_FEATURES PlatformFeatures; ///< Describe Platform Features in structure +} PLATFORM_FEATS; + +// Sublink Types are defined so they can match each attribute against either +// sublink zero or one. The table entry must contain the correct matching +// values based on the register. This is available in the BKDG, for each register +// which sublink it controls. If the register is independent of sublink, OR values +// together or use HT_LINKTYPE_ALL to match if either sublink matches (ex. E0 - E5). +// Sublink 0 types, bits 0 thru 14 +#define HTPHY_LINKTYPE_SL0_HT3 BIT0 +#define HTPHY_LINKTYPE_SL0_HT1 BIT1 +#define HTPHY_LINKTYPE_SL0_COHERENT BIT2 +#define HTPHY_LINKTYPE_SL0_NONCOHERENT BIT3 +#define HTPHY_LINKTYPE_SL0_LINK0 BIT4 +#define HTPHY_LINKTYPE_SL0_LINK1 BIT5 +#define HTPHY_LINKTYPE_SL0_LINK2 BIT6 +#define HTPHY_LINKTYPE_SL0_LINK3 BIT7 +#define HTPHY_LINKTYPE_SL0_INTERNAL BIT8 +#define HTPHY_LINKTYPE_SL0_EXTERNAL BIT9 +#define HTPHY_LINKTYPE_SL0_AND BIT15 + +// SubLink 1 types, bits 16 thru 30 +#define HTPHY_LINKTYPE_SL1_HT3 BIT16 +#define HTPHY_LINKTYPE_SL1_HT1 BIT17 +#define HTPHY_LINKTYPE_SL1_COHERENT BIT18 +#define HTPHY_LINKTYPE_SL1_NONCOHERENT BIT19 +#define HTPHY_LINKTYPE_SL1_LINK4 BIT20 +#define HTPHY_LINKTYPE_SL1_LINK5 BIT21 +#define HTPHY_LINKTYPE_SL1_LINK6 BIT22 +#define HTPHY_LINKTYPE_SL1_LINK7 BIT23 +#define HTPHY_LINKTYPE_SL1_INTERNAL BIT24 +#define HTPHY_LINKTYPE_SL1_EXTERNAL BIT25 +#define HTPHY_LINKTYPE_SL1_AND BIT31 + +#define HTPHY_LINKTYPE_SL0_ALL (HTPHY_LINKTYPE_SL0_HT3 | \ + HTPHY_LINKTYPE_SL0_HT1 | \ + HTPHY_LINKTYPE_SL0_COHERENT | \ + HTPHY_LINKTYPE_SL0_NONCOHERENT | \ + HTPHY_LINKTYPE_SL0_LINK0 | \ + HTPHY_LINKTYPE_SL0_LINK1 | \ + HTPHY_LINKTYPE_SL0_LINK2 | \ + HTPHY_LINKTYPE_SL0_LINK3 | \ + HTPHY_LINKTYPE_SL0_INTERNAL | \ + HTPHY_LINKTYPE_SL0_EXTERNAL) +#define HTPHY_LINKTYPE_SL1_ALL (HTPHY_LINKTYPE_SL1_HT3 | \ + HTPHY_LINKTYPE_SL1_HT1 | \ + HTPHY_LINKTYPE_SL1_COHERENT | \ + HTPHY_LINKTYPE_SL1_NONCOHERENT | \ + HTPHY_LINKTYPE_SL1_LINK4 | \ + HTPHY_LINKTYPE_SL1_LINK5 | \ + HTPHY_LINKTYPE_SL1_LINK6 | \ + HTPHY_LINKTYPE_SL1_LINK7 | \ + HTPHY_LINKTYPE_SL1_INTERNAL | \ + HTPHY_LINKTYPE_SL1_EXTERNAL) +#define HTPHY_LINKTYPE_ALL (HTPHY_LINKTYPE_SL0_ALL | HTPHY_LINKTYPE_SL1_ALL) + +#define HTPHY_REGISTER_MAX 0x0000FFFFul +/** + * HT PHY Link Features + */ +typedef struct { + UINT32 HtPhySL0Ht3:1; ///< Ht Phy Sub-link 0 Ht3 + UINT32 HtPhySL0Ht1:1; ///< Ht Phy Sub-link 0 Ht1 + UINT32 HtPhySL0Coh:1; ///< Ht Phy Sub-link 0 Coherent + UINT32 HtPhySL0NonCoh:1; ///< Ht Phy Sub-link 0 NonCoherent + UINT32 HtPhySL0Link0:1; ///< Ht Phy Sub-link 0 specifically for node link 0. + UINT32 HtPhySL0Link1:1; ///< Ht Phy Sub-link 0 specifically for node link 1. + UINT32 HtPhySL0Link2:1; ///< Ht Phy Sub-link 0 specifically for node link 2. + UINT32 HtPhySL0Link3:1; ///< Ht Phy Sub-link 0 specifically for node link 3. + UINT32 HtPhySL0Internal:1; ///< Ht Phy Sub-link 0 is internal link. Intended for IDS support. + UINT32 HtPhySL0External:1; ///< Ht Phy Sub-link 0 is external link. Intended for IDS support. + UINT32 :(14 - 9); ///< Ht Phy Sub-link 0 Pad + UINT32 HtPhySL0And:1; ///< Ht Phy feature match should match all selected features, for sub-link 0. + UINT32 HtPhySL1Ht3:1; ///< Ht Phy Sub-link 1 Ht3 + UINT32 HtPhySL1Ht1:1; ///< Ht Phy Sub-link 1 Ht1 + UINT32 HtPhySL1Coh:1; ///< Ht Phy Sub-link 1 Coherent + UINT32 HtPhySL1NonCoh:1; ///< Ht Phy Sub-link 1 NonCoherent + UINT32 HtPhySL1Link4:1; ///< Ht Phy Sub-link 1 specifically for node link 4. + UINT32 HtPhySL1Link5:1; ///< Ht Phy Sub-link 1 specifically for node link 5. + UINT32 HtPhySL1Link6:1; ///< Ht Phy Sub-link 1 specifically for node link 6. + UINT32 HtPhySL1Link7:1; ///< Ht Phy Sub-link 1 specifically for node link 7. + UINT32 HtPhySL1Internal:1; ///< Ht Phy Sub-link 1 is internal link. Intended for IDS support. + UINT32 HtPhySL1External:1; ///< Ht Phy Sub-link 1 is external link. Intended for IDS support. + UINT32 :(30 - 25); ///< Ht Phy Sub-link 1 Pad + UINT32 HtPhySL1And:1; ///< Ht Phy feature match should match all selected features, for sub-link 1. +} HT_PHY_LINK_FEATURES; + +/** + * Ht Phy Link Features + */ +typedef union { + UINT32 HtPhyLinkValue; ///< Describe HY Phy Features in UINT32. + ///< This one goes first, because then initializers use it automatically for the union. + HT_PHY_LINK_FEATURES HtPhyLinkFeatures; ///< Describe HT Phy Features in structure. +} HT_PHY_LINK_FEATS; + +// DB Level for initializing Deemphasis +// This must be in sync with DEEMPHASIS_FEATURES and PLATFORM_DEEMPHASIS_LEVEL (agesa.h) +#define DEEMPHASIS_LEVEL_NONE BIT0 +#define DEEMPHASIS_LEVEL__3 BIT1 +#define DEEMPHASIS_LEVEL__6 BIT2 +#define DEEMPHASIS_LEVEL__8 BIT3 +#define DEEMPHASIS_LEVEL__11 BIT4 +#define DEEMPHASIS_LEVEL__11_8 BIT5 +#define DCV_LEVEL_NONE BIT16 +#define DCV_LEVEL__2 BIT17 +#define DCV_LEVEL__3 BIT18 +#define DCV_LEVEL__5 BIT19 +#define DCV_LEVEL__6 BIT20 +#define DCV_LEVEL__7 BIT21 +#define DCV_LEVEL__8 BIT22 +#define DCV_LEVEL__9 BIT23 +#define DCV_LEVEL__11 BIT24 +// Note that an "AND" feature doesn't make any sense, levels are mutually exclusive. + +// An error check value. +#define DEEMPHASIS_LEVELS_ALL (DEEMPHASIS_LEVEL_NONE | \ + DEEMPHASIS_LEVEL__3 | \ + DEEMPHASIS_LEVEL__6 | \ + DEEMPHASIS_LEVEL__8 | \ + DEEMPHASIS_LEVEL__11 | \ + DEEMPHASIS_LEVEL__11_8) + +#define DCV_LEVELS_ALL (DCV_LEVEL_NONE | \ + DCV_LEVEL__2 | \ + DCV_LEVEL__3 | \ + DCV_LEVEL__5 | \ + DCV_LEVEL__6 | \ + DCV_LEVEL__7 | \ + DCV_LEVEL__8 | \ + DCV_LEVEL__9 | \ + DCV_LEVEL__11) + +#define VALID_DEEMPHASIS_LEVELS (DEEMPHASIS_LEVELS_ALL | DCV_LEVELS_ALL) + +/** + * Deemphasis Ht Phy Link Deemphasis. + * + * This must be in sync with defines above and ::PLATFORM_DEEMPHASIS_LEVEL (agesa.h) + */ +typedef struct { + UINT32 DeemphasisLevelNone:1; ///< The deemphasis level None. + UINT32 DeemphasisLevelMinus3:1; ///< The deemphasis level minus 3 db. + UINT32 DeemphasisLevelMinus6:1; ///< The deemphasis level minus 6 db. + UINT32 DeemphasisLevelMinus8:1; ///< The deemphasis level minus 8 db. + UINT32 DeemphasisLevelMinus11:1; ///< The deemphasis level minus 11 db. + UINT32 DeemphasisLevelMinus11w8:1; ///< The deemphasis level minus 11 db, minus 8 precursor. + UINT32 :(15 - 5); ///< reserved. + UINT32 DcvLevelNone:1; ///< The level for DCV None. + UINT32 DcvLevelMinus2:1; ///< The level for DCV minus 2 db. + UINT32 DcvLevelMinus3:1; ///< The level for DCV minus 3 db. + UINT32 DcvLevelMinus5:1; ///< The level for DCV minus 5 db. + UINT32 DcvLevelMinus6:1; ///< The level for DCV minus 6 db. + UINT32 DcvLevelMinus7:1; ///< The level for DCV minus 7 db. + UINT32 DcvLevelMinus8:1; ///< The level for DCV minus 8 db. + UINT32 DcvLevelMinus9:1; ///< The level for DCV minus 9 db. + UINT32 DcvLevelMinus11:1; ///< The level for DCV minus 11 db. + UINT32 :(15 - 8); ///< reserved. +} DEEMPHASIS_FEATURES; + +/** + * Deemphasis Ht Phy Link Features. + */ +typedef union { + UINT32 DeemphasisValues; ///< Initialize HT Deemphasis in UINT32. + DEEMPHASIS_FEATURES DeemphasisLevels; ///< HT Deemphasis levels. +} DEEMPHASIS_FEATS; + +// Initializer bit patterns for PERFORMANCE_PROFILE_FEATS. +#define PERFORMANCE_REFRESH_REQUEST_32B BIT0 +#define PERFORMANCE_PROBEFILTER BIT1 +#define PERFORMANCE_L3_CACHE BIT2 +#define PERFORMANCE_NO_L3_CACHE BIT3 +#define PERFORMANCE_MCT_ISOC_VARIABLE BIT4 +#define PERFORMANCE_IS_WARM_RESET BIT5 +#define PERFORMANCE_VRM_HIGH_SPEED_ENABLE BIT6 +#define PERFORMANCE_NB_PSTATES_ENABLE BIT7 +#define PERFORMANCE_AND BIT31 + +#define PERFORMANCE_PROFILE_ALL (PERFORMANCE_REFRESH_REQUEST_32B | \ + PERFORMANCE_PROBEFILTER | \ + PERFORMANCE_L3_CACHE | \ + PERFORMANCE_NO_L3_CACHE | \ + PERFORMANCE_MCT_ISOC_VARIABLE | \ + PERFORMANCE_IS_WARM_RESET | \ + PERFORMANCE_VRM_HIGH_SPEED_ENABLE | \ + PERFORMANCE_NB_PSTATES_ENABLE) + +/** + * Performance Profile specific Type Features. + * + * Register settings for the different control flow modes can have additional dependencies + */ +typedef struct { + UINT32 RefreshRequest32Byte:1; ///< BIT_0. Display Refresh Requests use 32 bytes (32BE). + UINT32 ProbeFilter:1; ///< BIT_1 Probe Filter will be enabled. + UINT32 L3Cache:1; ///< BIT_2 L3 Cache is present. + UINT32 NoL3Cache:1; ///< BIT_3 L3 Cache is NOT present. + UINT32 MctIsocVariable:1; ///< BIT_4 Mct Isoc Read Priority set to variable. + UINT32 IsWarmReset:1; ///< BIT_5 This boot is on a warm reset, cold reset pass is already completed. + UINT32 VrmHighSpeed:1; ///< BIT_6 Select high speed VRM. + UINT32 NbPstates:1; ///< BIT_7 Northbridge PStates are enabled + UINT32 :(30 - 7); ///< available for future expansion. + UINT32 AndPerformanceFeats:1; ///< BIT_31. AND other selected features. +} PERFORMANCE_PROFILE_FEATURES; + +/** + * Performance Profile features. + */ +typedef union { + UINT32 PerformanceProfileValue; ///< Initializer value. + PERFORMANCE_PROFILE_FEATURES PerformanceProfileFeatures; ///< The performance profile features. +} PERFORMANCE_PROFILE_FEATS; + +/** + * Package Type Features + * + */ +typedef struct { + UINT32 PkgType0:1; ///< Package Type 0 + UINT32 PkgType1:1; ///< Package Type 1 + UINT32 PkgType2:1; ///< Package Type 2 + UINT32 PkgType3:1; ///< Package Type 3 + UINT32 PkgType4:1; ///< Package Type 4 + UINT32 PkgType5:1; ///< Package Type 5 + UINT32 PkgType6:1; ///< Package Type 6 + UINT32 PkgType7:1; ///< Package Type 7 + UINT32 PkgType8:1; ///< Package Type 8 + UINT32 PkgType9:1; ///< Package Type 9 + UINT32 PkgType10:1; ///< Package Type 10 + UINT32 PkgType11:1; ///< Package Type 11 + UINT32 PkgType12:1; ///< Package Type 12 + UINT32 PkgType13:1; ///< Package Type 13 + UINT32 PkgType14:1; ///< Package Type 14 + UINT32 PkgType15:1; ///< Package Type 15 + UINT32 Reserved:15; ///< Package Type Reserved + UINT32 ReservedAndFeats:1; ///< BIT_31. AND other selected features. Always zero here. +} PACKAGE_TYPE_FEATURES; + +// Initializer Values for Package Type +#define PACKAGE_TYPE_ALL 0XFFFF ///< Package Type apply all packages + +// Initializer Values for Ht Host Pci Config Registers +#define HT_HOST_FEAT_COHERENT BIT0 +#define HT_HOST_FEAT_NONCOHERENT BIT1 +#define HT_HOST_FEAT_GANGED BIT2 +#define HT_HOST_FEAT_UNGANGED BIT3 +#define HT_HOST_FEAT_HT3 BIT4 +#define HT_HOST_FEAT_HT1 BIT5 +#define HT_HOST_AND BIT31 + +#define HT_HOST_FEATURES_ALL (HT_HOST_FEAT_COHERENT | \ + HT_HOST_FEAT_NONCOHERENT | \ + HT_HOST_FEAT_GANGED | \ + HT_HOST_FEAT_UNGANGED | \ + HT_HOST_FEAT_HT3 | \ + HT_HOST_FEAT_HT1) + +/** + * HT Host PCI register features. + * + * Links which are not connected do not match any of these features. + */ +typedef struct { + UINT32 Coherent:1; ///< BIT_0 Apply to links with a coherent connection. + UINT32 NonCoherent:1; ///< BIT_1 Apply to links with a non-coherent connection. + UINT32 Ganged:1; ///< BIT_2 Apply to links with a ganged connection. + UINT32 UnGanged:1; ///< BIT_3 Apply to links with a unganged connection. + UINT32 Ht3:1; ///< BIT_4 Apply to links with HT3 frequency (> 1000 MHz) + UINT32 Ht1:1; ///< BIT_5 Apply to links with HT1 frequency (< 1200 MHz) + UINT32 :(30 - 5); ///< Future expansion. + UINT32 AndHtHostFeats:1; ///< BIT_31. AND other selected features. +} HT_HOST_FEATURES; + +/** + * HT Host features for table data. + */ +typedef union { + UINT32 HtHostValue; ///< Initializer value. + HT_HOST_FEATURES HtHostFeatures; ///< The HT Host Features. +} HT_HOST_FEATS; + +// Core Range Initializer values. +#define COUNT_RANGE_LOW 0ul +#define COUNT_RANGE_HIGH 0xFFul + +// A count range matching none is often useful as the second range, matching will then be +// based on the first range. A count range all is provided as a first range for default settings. +#define COUNT_RANGE_NONE ((((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH)) << 16) +#define COUNT_RANGE_ALL (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_LOW)) +#define IGNORE_FREQ_0 (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH)) +#define IGNORE_PROCESSOR_0 (((COUNT_RANGE_HIGH) << 8) | (COUNT_RANGE_HIGH)) + +#define CORE_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min)) +#define CORE_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16) +#define PROCESSOR_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min)) +#define PROCESSOR_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16) +#define DEGREE_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min)) +#define DEGREE_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16) +#define FREQ_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min)) +#define FREQ_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16) +#define COMPUTE_UNIT_RANGE_0(min, max) ((((UINT32)(max)) << 8) | (UINT32)(min)) +#define COMPUTE_UNIT_RANGE_1(min, max) (((((UINT32)(max)) << 8) | (UINT32)(min)) << 16) + +/** + * Count Range Feature, two count ranges for core counts, processor counts, or node counts. + */ +typedef struct { + UINT32 Range0Min:8; ///< The minimum of the first count range. + UINT32 Range0Max:8; ///< The maximum of the first count range. + UINT32 Range1Min:8; ///< The minimum of the second count range. + UINT32 Range1Max:8; ///< The maximum of the second count range. +} COUNT_RANGE_FEATURE; + +/** + * Core Count Ranges for table data. + * + * Provide a pair of core count ranges. If the actual core count is included in either range (OR), + * the feature should be considered a match. + */ +typedef union { + UINT32 CoreRangeValue; ///< Initializer value. + COUNT_RANGE_FEATURE CoreRanges; ///< The Core Counts. +} CORE_COUNT_RANGES; + +/** + * Processor count ranges for table data. + * + * Provide a pair of processor count ranges. If the actual counts are included in either range (OR), + * the feature should be considered a match. + */ +typedef union { + UINT32 ProcessorCountRangeValue; ///< Initializer value. + COUNT_RANGE_FEATURE ProcessorCountRanges; ///< The Processor and Node Counts. +} PROCESSOR_COUNTS; + +/** + * Compute unit count ranges for table data. + * + * Provide a pair of compute unit count ranges. If the actual counts are included in either ranges (OR), + * the feature should be considered a match. + */ +typedef union { + UINT32 ComputeUnitRangeValue; ///< Initializer value. + COUNT_RANGE_FEATURE ComputeUnitRanges; ///< The Processor and Node Counts. +} COMPUTE_UNIT_COUNTS; + +/** + * Connectivity count ranges for table data. + * + * Provide a processor count range and a system degree range. The degree of a system is + * the maximum degree of any node. The degree of a node is the number of nodes to which + * it is directly connected (not considering width or redundant links). If both the actual + * counts are included in each range (AND), the feature should be considered a match. + */ +typedef union { + UINT32 ConnectivityCountRangeValue; ///< Initializer value. + COUNT_RANGE_FEATURE ConnectivityCountRanges; ///< The Processor and Degree Counts. +} CONNECTIVITY_COUNT; + +/** + * HT Frequency Count Range. + * + * Provide a pair of Frequency count ranges, with the frequency encoded as an HT Frequency value + * (such as would be programmed into the HT Host Link Frequency register). By converting a NB freq, + * the same count can be applied for it. If the actual value is included in either range + */ +typedef union { + UINT32 HtFreqCountRangeValue; ///< Initializer value. + COUNT_RANGE_FEATURE HtFreqCountRanges; ///< The HT Freq counts. +} HT_FREQ_COUNTS; + +/*------------------------------------------------------------------------------------------*/ +/* + * The specific data for each table entry. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * Make an extra type so we can use compilers that don't support designated initializers. + * + * All the entry type unions are no more than 5 UINT32's in size. For entry types which are a struct of UINT32's, + * this type can be used so that initializers can be declared TABLE_ENTRY_FIELDS, instead of a special non-union type. + * A non-union type then has to be cast back to TABLE_ENTRY_FIELDS in order to process the table, and you can't mix + * entry types with non-union initializers in the same table with any other type. + * + * If the entry type contains anything but UINT32's, then it must have a non-union initializer type for creating the + * actual tables. For example, MSR entry has UINT64 and workaround entry has a function pointer. + */ +typedef UINT32 GENERIC_TYPE_ENTRY_INITIALIZER[MAX_ENTRY_TYPE_ITEMS32]; + +/** + * Table Entry Data for MSR Registers. + * + * Apply data to register after mask, for MSRs. + */ +typedef struct { + UINT32 Address; ///< MSR address + UINT64 Data; ///< Data to set in the MSR + UINT64 Mask; ///< Mask to be applied to the MSR. Set every bit of all updated fields. +} MSR_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for PCI Registers. + * + * Apply data to register after mask, for PCI Config registers. + */ +typedef struct { + PCI_ADDR Address; ///< Address should contain Function, Offset only. It will apply to all CPUs + UINT32 Data; ///< Data to be written into PCI device + UINT32 Mask; ///< Mask to be used before data write. Set every bit of all updated fields. +} PCI_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for HT Phy Registers. + * + * Apply data to register after mask, for HT Phy registers, repeated for all active links. + */ +typedef struct { + HT_PHY_LINK_FEATS TypeFeats; ///< HT Phy Link Features + UINT32 Address; ///< Address of Ht Phy Register + UINT32 Data; ///< Data to be written into PCI device + UINT32 Mask; ///< Mask to be used before data write. Set every bit of all updated fields. +} HT_PHY_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for HT Phy Register Ranges. + * + * Apply data to register after mask, for a range of HT Phy registers, repeated for all active links. + */ +typedef struct { + HT_PHY_LINK_FEATS TypeFeats; ///< HT Phy Link Features + UINT32 LowAddress; ///< Low address of Ht Phy Register range. + UINT32 HighAddress; ///< High address of register range. + UINT32 Data; ///< Data to be written into PCI device. + UINT32 Mask; ///< Mask to be used before data write. Set every bit of all updated fields. +} HT_PHY_RANGE_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for HT Phy Deemphasis Registers. + * + * Apply data to register after mask, for HT Phy registers, repeated for all active links. + */ +typedef struct { + DEEMPHASIS_FEATS Levels; ///< The DCV and Deemphasis levels to match + HT_PHY_TYPE_ENTRY_DATA HtPhyEntry; ///< The HT Phy Entry to set the deemphasis values +} DEEMPHASIS_HT_PHY_TYPE_ENTRY_DATA; + +/** + * Table Entry Date for HT Phy Frequency Count Register updates. + * + * Compare the NB freq to a range, the HT freq to a range, the link features. + * Apply data to register after mask, if all three matched. + */ +typedef struct { + HT_FREQ_COUNTS HtFreqCounts; ///< Specify the HT Frequency range. + HT_FREQ_COUNTS NbFreqCounts; ///< Specify the NB Frequency range. + HT_PHY_TYPE_ENTRY_DATA HtPhyEntry; ///< The HT Phy register update to perform. +} HT_PHY_FREQ_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for Profile Fixup Registers. + * + * If TypeFeats matches current config, apply data to register after mask for PCI Config registers. + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} PROFILE_FIXUP_TYPE_ENTRY_DATA; + +/** + * A variation of PCI register for the HT Host registers. + * + * A setting to the HT Host buffer counts needs to be made to all the registers for + * all the links. There are also link specific criteria to check. + */ +typedef struct { + HT_HOST_FEATS TypeFeats; ///< Link Features. + PCI_ADDR Address; ///< Address of PCI Register to Fixed Up. + UINT32 Data; ///< Data to be written into PCI device + UINT32 Mask; ///< Mask to be used before data write. Set every bit of all updated fields. +} HT_HOST_PCI_TYPE_ENTRY_DATA; + +/** + * A variation of PCI register for the HT Host performance registers. + * + * A setting to the HT Host buffer counts needs to be made to all the registers for + * all the links. There are also link specific criteria to check. + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS PerformanceFeats; ///< Performance Profile features. + HT_HOST_PCI_TYPE_ENTRY_DATA HtHostEntry; ///< Link Features. +} HT_HOST_PERFORMANCE_PCI_TYPE_ENTRY_DATA; + +/** + * A variation of HT Host PCI register for the Link Token registers. + * + * Use Link Features, Performance Fixup features, and processor counts to match entries. + * Link Features are iterated through the connected links. All the matching Link Token count + * registers are updated. + */ +typedef struct { + CONNECTIVITY_COUNT ConnectivityCount; ///< Specify Processor count and Degree count range. + PERFORMANCE_PROFILE_FEATS PerformanceFeats; ///< Performance Profile features. + HT_HOST_FEATS LinkFeats; ///< Link Features. + PCI_ADDR Address; ///< Address of PCI Register to Fixed Up. + UINT32 Data; ///< Data to be written into PCI device + UINT32 Mask; ///< Mask to be used before data write. Set every bit of all updated fields. +} HT_TOKEN_PCI_REGISTER; + +/** + * Core Count dependent PCI registers. + * + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + CORE_COUNT_RANGES CoreCounts; ///< Specify up to two core count ranges to match. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} CORE_COUNTS_PCI_TYPE_ENTRY_DATA; + +/** + * Processor Count dependent PCI registers. + * + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + PROCESSOR_COUNTS ProcessorCounts; ///< Specify a processor count range. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} PROCESSOR_COUNTS_PCI_TYPE_ENTRY_DATA; + +/** + * Compute Unit Count dependent PCI registers. + * + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + COMPUTE_UNIT_COUNTS ComputeUnitCounts; ///< Specify a compute unit count range. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} COMPUTE_UNIT_COUNTS_PCI_TYPE_ENTRY_DATA; + +/** + * Compute Unit Count dependent MSR registers. + * + */ +typedef struct { + COMPUTE_UNIT_COUNTS ComputeUnitCounts; ///< Specify a compute unit count range. + MSR_TYPE_ENTRY_DATA MsrEntry; ///< The MSR Register entry data. +} COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA; + +/** + * System connectivity dependent PCI registers. + * + * The topology specific recommended settings are based on the different connectivity of nodes + * in each configuration: the more connections, the fewer resources each connection gets. + * The connectivity criteria translate as: + * - 2 Socket, half populated == Degree 1 + * - 4 Socket, half populated == Degree 2 + * - 2 Socket, fully populated == Degree 3 + * - 4 Socket, fully populated == Degree > 3. (4 or 5 if 3P, 6 if 4P) + * + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + CONNECTIVITY_COUNT ConnectivityCount; ///< Specify a system degree range. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} CONNECTIVITY_COUNTS_PCI_TYPE_ENTRY_DATA; + +/** + * A Family Specific Workaround method. + * + * \@TableTypeFamSpecificInstances. + * + * When called, the entry's CPU Logical ID and Platform Features matched the current config. + * The method must implement any specific criteria checking for the workaround. + * + * See if you can use the other entries or make an entry specifically for the fix. + * After all, the purpose of having a table entry is to @b NOT have code which + * isn't generic feature code, but is family/model specific. + * + * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched. + * @param[in] StdHeader Config params for library, services. + */ +typedef VOID F_FAM_SPECIFIC_WORKAROUND ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a method. +typedef F_FAM_SPECIFIC_WORKAROUND *PF_FAM_SPECIFIC_WORKAROUND; + +/** + * Table Entry Data for Family Specific Workarounds. + * + * See if you can use the other entries or make an entry specifically for the fix. + * After all, the purpose of having a table entry is to @b NOT have code which + * isn't generic feature code, but is family/model specific. + * + * Call DoAction passing Data. + */ +typedef struct { + PF_FAM_SPECIFIC_WORKAROUND DoAction; ///< A function implementing the workaround. + UINT32 Data; ///< This data is passed to DoAction(). +} FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA; + +/** + * Package Type Features + * + * FamilyPackageType are various among CPU families. + * + */ +typedef union { + UINT32 PackageTypeValue; ///< Package Type + PACKAGE_TYPE_FEATURES FamilyPackageType; ///< Package Type of CPU family +} PACKAGE_TYPE_FEATS; + +/** + * HT Features dependent Global PCI registers. + * + */ +typedef struct { + HT_HOST_FEATS LinkFeats; ///< Link Features. + PACKAGE_TYPE_FEATS PackageType; ///< Package Type + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} HT_FEATURES_PCI_TYPE_ENTRY_DATA; + +/** + * Table Entry Data for HT Phy Registers which depend on performance profile features. + * + * Match performance profile features and link features. + * Apply data to register after mask, for HT Phy registers, repeated for all active links. + */ +typedef struct { + PERFORMANCE_PROFILE_FEATS TypeFeats; ///< Profile Fixup Features. + HT_PHY_TYPE_ENTRY_DATA HtPhyEntry; ///< The HT Phy Entry to set the deemphasis values +} PROFILE_HT_PHY_TYPE_ENTRY_DATA; + +/** + * HT Link PCI registers that are not in the HT Host capability. + * + * Some HT Link registers have an instance per link, but are just sequential. Specify the base register + * in the table register address (link 0 sublink 0). + */ +typedef struct { + HT_HOST_FEATS LinkFeats; ///< Link Features. + PCI_TYPE_ENTRY_DATA PciEntry; ///< The PCI Register entry data. +} HT_LINK_PCI_TYPE_ENTRY_DATA; + +/*------------------------------------------------------------------------------------------*/ +/* + * A complete register table and table entries. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * All the available entry data types. + */ +typedef union { + GENERIC_TYPE_ENTRY_INITIALIZER InitialValues; ///< Not a valid entry type; as the first union item, + ///< it can be used with initializers. + MSR_TYPE_ENTRY_DATA MsrEntry; ///< Msr entry. + PCI_TYPE_ENTRY_DATA PciEntry; ///< PCI entry. + FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA FamSpecificEntry; ///< Family Specific Workaround entry. + HT_PHY_TYPE_ENTRY_DATA HtPhyEntry; ///< HT Phy entry. + HT_PHY_RANGE_TYPE_ENTRY_DATA HtPhyRangeEntry; ///< A range of Ht Phy Registers + DEEMPHASIS_HT_PHY_TYPE_ENTRY_DATA DeemphasisEntry; ///< A HT Deemphasis level's settings. + HT_PHY_FREQ_TYPE_ENTRY_DATA HtPhyFreqEntry; ///< A frequency dependent Ht Phy Register setting. + PROFILE_FIXUP_TYPE_ENTRY_DATA FixupEntry; ///< Profile Fixup entry. + HT_HOST_PCI_TYPE_ENTRY_DATA HtHostEntry; ///< HT Host PCI entry. + HT_HOST_PERFORMANCE_PCI_TYPE_ENTRY_DATA HtHostPerfEntry; ///< HT Host Performance PCI entry + HT_TOKEN_PCI_REGISTER HtTokenEntry; ///< HT Link Token Count entry. + CORE_COUNTS_PCI_TYPE_ENTRY_DATA CoreCountEntry; ///< Core count dependent settings. + PROCESSOR_COUNTS_PCI_TYPE_ENTRY_DATA ProcCountEntry; ///< Processor count entry. + COMPUTE_UNIT_COUNTS_PCI_TYPE_ENTRY_DATA CompUnitCountEntry; ///< Compute unit count dependent entry. + CONNECTIVITY_COUNTS_PCI_TYPE_ENTRY_DATA TokenPciEntry; ///< System connectivity dependent Token register. + HT_FEATURES_PCI_TYPE_ENTRY_DATA HtFeatPciEntry; ///< HT Features PCI entry. + PROFILE_HT_PHY_TYPE_ENTRY_DATA HtPhyProfileEntry; ///< Performance dependent HT Phy register. + HT_LINK_PCI_TYPE_ENTRY_DATA HtLinkPciEntry; ///< Per Link, non HT Host, PCI registers. + COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA CompUnitCountMsrEntry; ///< Compute unit count dependent MSR entry. +} TABLE_ENTRY_DATA; + +/** + * Register Table Entry common fields. + * + * All the various types of register table entries are subclasses of this object. + */ +typedef struct { + TABLE_ENTRY_TYPE EntryType; ///< The type of table entry this is. + CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria. + PLATFORM_FEATS Features; ///< Common Platform Features match criteria. + TABLE_ENTRY_DATA Entry; ///< The type dependent entry data (ex. register, data, mask). +} TABLE_ENTRY_FIELDS; + +/** + * An entire register table. + */ +typedef struct { + TABLE_CORE_SELECTOR Selector; ///< For efficiency, these cores should process this table + UINT32 TimePoint; ///< Time Point designator + UINTN NumberOfEntries; ///< The number of entries in the table. + CONST TABLE_ENTRY_FIELDS *Table; ///< The table entries. +} REGISTER_TABLE; + +/*------------------------------------------------------------------------------------------*/ +/* + * Describe implementers for table entries. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * Implement the semantics of a Table Entry Type. + * + * @TableEntryTypeInstances. + * + * @param[in] CurrentEntry The type specific entry data to be implemented (that is written). + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config params for library, services. + */ +typedef VOID F_DO_TABLE_ENTRY ( + IN TABLE_ENTRY_DATA *CurrentEntry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a method +typedef F_DO_TABLE_ENTRY *PF_DO_TABLE_ENTRY; + +/** + * Describe the attributes of a Table Entry Type. + */ +typedef struct { + TABLE_ENTRY_TYPE EntryType; ///< The type of table entry this describes. + PF_DO_TABLE_ENTRY DoTableEntry; ///< Provide all semantics associated with TABLE_ENTRY_DATA +} TABLE_ENTRY_TYPE_DESCRIPTOR; + +/*------------------------------------------------------------------------------------------*/ +/* + * Non-union initializers for entry data which is not just UINT32. + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * A union of data types, that can be initialized with MSR data. + * + * This ensures the entry data is the same size as TABLE_ENTRY_DATA. + */ +typedef union { + MSR_TYPE_ENTRY_DATA MsrInitializer; ///< The data in the table initializer is assigned to this member. + TABLE_ENTRY_DATA Reserved; ///< Make sure the size is the same as the real union. +} MSR_DATA_INITIALIZER; + +/** + * A type suitable for an initializer for MSR Table entries. + */ +typedef struct { + TABLE_ENTRY_TYPE Type; ///< The type of table entry this is. + CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria. + PLATFORM_FEATS Features; ///< Common Platform Features match criteria. + MSR_DATA_INITIALIZER EntryData; ///< The special union which accepts msr data initializer. +} MSR_TYPE_ENTRY_INITIALIZER; + +/** + * A union of data types, that can be initialized with MSR CU data. + * + * This ensures the entry data is the same size as TABLE_ENTRY_DATA. + */ +typedef union { + COMPUTE_UNIT_COUNTS_MSR_TYPE_ENTRY_DATA MsrInitializer; ///< The data in the table initializer is assigned to this member. + TABLE_ENTRY_DATA Reserved; ///< Make sure the size is the same as the real union. +} MSR_CU_DATA_INITIALIZER; + +/** + * A type suitable for an initializer for MSR CU count Table entries. + */ +typedef struct { + TABLE_ENTRY_TYPE Type; ///< The type of table entry this is. + CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria. + PLATFORM_FEATS Features; ///< Common Platform Features match criteria. + MSR_CU_DATA_INITIALIZER EntryData; ///< The special union which accepts msr data initializer. +} MSR_CU_TYPE_ENTRY_INITIALIZER; + +/** + * A union of data types, that can be initialized with Family Specific Workaround data. + * + * This ensures the entry data is the same size as TABLE_ENTRY_DATA. + */ +typedef union { + FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_DATA FamSpecificInitializer; ///< The data in the table initializer is assigned to this member. + TABLE_ENTRY_DATA Reserved; ///< Make sure the size is the same as the real union. +} FAM_SPECIFIC_WORKAROUND_DATA_INITIALIZER; + +/** + * A type suitable for an initializer for Family Specific Workaround Table entries. + */ +typedef struct { + TABLE_ENTRY_TYPE Type; ///< The type of table entry this is. + CPU_LOGICAL_ID CpuRevision; ///< Common CPU Logical ID match criteria. + PLATFORM_FEATS Features; ///< Common Platform Features match criteria. + FAM_SPECIFIC_WORKAROUND_DATA_INITIALIZER EntryData; ///< Special union accepts family specific workaround data initializer. +} FAM_SPECIFIC_WORKAROUND_TYPE_ENTRY_INITIALIZER; + +/*------------------------------------------------------------------------------------------*/ +/* + * Table related function prototypes (many are instance of F_DO_TABLE_ENTRY method). + */ +/*------------------------------------------------------------------------------------------*/ + +/** + * Set the registers for this core based on entries in a list of Register Tables. + */ +VOID SetRegistersFromTables ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN UINT32 TimePoint, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Find the features of the running platform. + */ +VOID +GetPlatformFeatures ( + OUT PLATFORM_FEATS *Features, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Checks register table entry type specific criteria to the platform. + */ +BOOLEAN +DoesEntryTypeSpecificInfoMatch ( + IN UINT32 PlatformTypeSpecificFeatures, + IN UINT32 EntryTypeFeatures + ); + +/** + * Perform the MSR Register Entry. + */ +VOID +SetRegisterForMsrEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the PCI Register Entry. + */ +VOID +SetRegisterForPciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Performance Profile PCI Register Entry. + */ +VOID +SetRegisterForPerformanceProfileEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Host PCI Register Entry. + */ +VOID +SetRegisterForHtHostEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Host Performance PCI Register Entry. + */ +VOID +SetRegisterForHtHostPerfEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Set the HT Link Token Count registers. + */ +VOID +SetRegisterForHtLinkTokenEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Core Counts Performance PCI Register Entry. + */ +VOID +SetRegisterForCoreCountsPerformanceEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Processor Counts PCI Register Entry. + */ +VOID +SetRegisterForProcessorCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Compute Unit Counts PCI Register Entry. + */ +VOID +SetRegisterForComputeUnitCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Compute Unit Counts MSR Register Entry. + */ +VOID +SetMsrForComputeUnitCountsEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Family Specific Workaround Register Entry. + */ +VOID +SetRegisterForFamSpecificWorkaroundEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Program HT Phy PCI registers. + */ +VOID +SetRegisterForHtPhyEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Program a range of HT Phy PCI registers. + */ +VOID +SetRegisterForHtPhyRangeEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Program Deemphasis registers, for the platform specified levels. + */ +VOID +SetRegisterForDeemphasisEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Program HT Phy PCI registers which have complex frequency dependencies. + */ +VOID +SetRegisterForHtPhyFreqEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the Processor Token Counts PCI Register Entry. + */ +VOID +SetRegisterForTokenPciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Link Feature PCI Register Entry. + */ +VOID +SetRegisterForHtFeaturePciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Phy Performance Profile Register Entry. + */ +VOID +SetRegisterForHtPhyProfileEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Perform the HT Link PCI Register Entry. + */ +VOID +SetRegisterForHtLinkPciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Compare counts to a pair of ranges. + */ +BOOLEAN +IsEitherCountInRange ( + IN UINTN FirstCount, + IN UINTN SecondCount, + IN COUNT_RANGE_FEATURE Ranges + ); + +/** + * Returns the performance profile features list of the currently running processor core. + */ +VOID +GetPerformanceFeatures ( + OUT PERFORMANCE_PROFILE_FEATS *Features, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_TABLE_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.asm b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.asm new file mode 100644 index 0000000000..a6ca5172b8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.asm @@ -0,0 +1,367 @@ +;/** +; * @file +; * +; * Agesa pre-memory miscellaneous support, including ap halt loop. +; * +; * @xrefitem bom "File Content Label" "Release Content" +; * @e project: AGESA +; * @e sub-project: CPU +; * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ +; */ +;***************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + .XLIST + INCLUDE agesa.inc + INCLUDE cpcarmac.inc + .LIST + + .586P + +;=============================================== +;=============================================== +;== +;== M E M O R Y A B S E N T S E G M E N T +;== +;=============================================== +;=============================================== + .MODEL flat + .CODE +;====================================================================== +; ExecuteFinalHltInstruction: Disables the stack and performs +; a hlt instruction on an AP. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; eax, ebx, ecx, edx, esp +; +;====================================================================== +PUBLIC ExecuteFinalHltInstruction +ExecuteFinalHltInstruction PROC NEAR C USES ESI EDI HaltFlags:DWORD, ApMtrrSettingList:PTR, StandardHeader:PTR + + mov esi, StandardHeader ; The code must reference all parameters to avoid a build warning + mov esi, HaltFlags + mov edi, ApMtrrSettingList + ; Do these special steps in case if the core is part of a compute unit + ; Note: The following bits are family specific flags, that gets set during build time, + ; and indicates things like "family cache control methodology", etc. + ; esi bit0 = 0 -> not a Primary core + ; esi bit0 = 1 -> Primary core + ; esi bit1 = 0 -> Cache disable + ; esi bit1 = 1 -> Cache enable + .if (esi & 2h) + AMD_CPUID CPUID_MODEL + shr eax, 20 ; AL = cpu extended family + cmp al, 05h ; Is this family 15h? + jne not_fam15_skip_combineCr0Cd ; Branch if not family15h + + ; Set CombineCr0Cd bit + mov ecx, CU_CFG3 + _RDMSR + bts edx, (COMBINE_CR0_CD - 32) + _WRMSR + +not_fam15_skip_combineCr0Cd: + ; Clear the CR0.CD bit + mov eax, CR0 ; Make sure cache is enabled for all APs + btr eax, CR0_CD + btr eax, CR0_NW + mov CR0, eax ; Write back to CR0 + .else + mov eax, CR0 ; Make sure cache is disabled for all APs + bts eax, CR0_CD ; Disable cache + bts eax, CR0_NW + mov CR0, eax ; Write back to CR0 + .endif + + .if (esi & 1h) + ; This core is a primary core and needs to do all the MTRRs, including shared MTRRs. + mov esi, edi ; Get ApMtrrSettingList + + ; Configure the MTRRs on the AP so + ; when it runs remote code it will execute + ; out of RAM instead of ROM. + + ; Disable MTRRs and turn on modification enable bit + mov ecx, MTRR_SYS_CFG + _RDMSR + btr eax, MTRR_VAR_DRAM_EN ; Disable + bts eax, MTRR_FIX_DRAM_MOD_EN ; Enable + btr eax, MTRR_FIX_DRAM_EN ; Disable + _WRMSR + + ; Setup default values for Fixed-Sized MTRRs + ; Set 7FFFh-00000h as WB + mov ecx, AMD_AP_MTRR_FIX64k_00000 + mov eax, 1E1E1E1Eh + mov edx, eax + _WRMSR + + ; Set 9FFFFh-80000h also as WB + mov ecx, AMD_AP_MTRR_FIX16k_80000 + _WRMSR + + ; Set BFFFFh-A0000h as Uncacheable Memory-mapped IO + mov ecx, AMD_AP_MTRR_FIX16k_A0000 + xor eax, eax + xor edx, edx + _WRMSR + + ; Set DFFFFh-C0000h as Uncacheable Memory-mapped IO + xor eax, eax + xor edx, edx + mov ecx, AMD_AP_MTRR_FIX4k_C0000 + +CDLoop: + _WRMSR + inc ecx + cmp ecx, AMD_AP_MTRR_FIX4k_D8000 + jbe CDLoop + + ; Set FFFFFh-E0000h as Uncacheable Memory + mov eax, 18181818h + mov edx, eax + + mov ecx, AMD_AP_MTRR_FIX4k_E0000 + +EFLoop: + _WRMSR + inc ecx + cmp ecx, AMD_AP_MTRR_FIX4k_F8000 + jbe EFLoop + + ; If IBV provided settings for Fixed-Sized MTRRs, + ; overwrite the default settings. + .if ((esi != 0) && (esi != 0FFFFFFFFh)) + mov ecx, (AP_MTRR_SETTINGS ptr [esi]).MsrAddr + ; While we are not at the end of the list + .while (ecx != CPU_LIST_TERMINAL) + ; Ensure that the MSR address is valid for Fixed-Sized MTRRs + .if ( ((ecx >= AMD_AP_MTRR_FIX4k_C0000) && (ecx <= AMD_AP_MTRR_FIX4k_F8000)) || \ + (ecx == AMD_AP_MTRR_FIX64k_00000) || (ecx == AMD_AP_MTRR_FIX16k_80000 ) || (ecx == AMD_AP_MTRR_FIX16k_A0000)) + mov eax, dword ptr (AP_MTRR_SETTINGS ptr [esi]).MsrData + mov edx, dword ptr (AP_MTRR_SETTINGS ptr [esi+4]).MsrData + _WRMSR + .endif + add esi, sizeof (AP_MTRR_SETTINGS) + mov ecx, (AP_MTRR_SETTINGS ptr [esi]).MsrAddr + .endw + .endif + + ; Enable fixed-range and variable-range MTRRs + mov ecx, AMD_MTRR_DEFTYPE + _RDMSR + bts eax, MTRR_DEF_TYPE_EN ; MtrrDefTypeEn + bts eax, MTRR_DEF_TYPE_FIX_EN ; MtrrDefTypeFixEn + _WRMSR + + ; Enable Top-of-Memory setting + ; Enable use of RdMem/WrMem bits attributes + mov ecx, MTRR_SYS_CFG + _RDMSR + bts eax, MTRR_VAR_DRAM_EN ; Enable + btr eax, MTRR_FIX_DRAM_MOD_EN ; Disable + bts eax, MTRR_FIX_DRAM_EN ; Enable + _WRMSR + + mov esi, (1 SHL FLAG_IS_PRIMARY) + .else ; end if primary core + xor esi, esi + .endif + ; Make sure not to touch any Shared MSR from this point on + + AMD_DISABLE_STACK_FAMILY_HOOK + + bt esi, FLAG_IS_PRIMARY + .if (carry?) + ; restore variable MTRR6 and MTRR7 to default states + mov ecx, AMD_MTRR_VARIABLE_MASK7 ; clear MTRRPhysBase6 MTRRPhysMask6 + xor eax, eax ; and MTRRPhysBase7 MTRRPhysMask7 + xor edx, edx + .while (cx >= AMD_MTRR_VARIABLE_BASE6) + _WRMSR + dec cx + .endw + .endif + +@@: + cli + hlt + jmp @B ;ExecuteHltInstruction + ret +ExecuteFinalHltInstruction ENDP + +;====================================================================== +; ExecuteHltInstruction: Performs a hlt instruction. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; eax, ebx, ecx, edx, esp +; +;====================================================================== +PUBLIC ExecuteHltInstruction +ExecuteHltInstruction PROC NEAR C + cli + hlt + ret +ExecuteHltInstruction ENDP + +;====================================================================== +; NmiHandler: Simply performs an IRET. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +PUBLIC NmiHandler +NmiHandler PROC NEAR C + iretd +NmiHandler ENDP + +;====================================================================== +; GetCsSelector: Returns the current protected mode CS selector. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +PUBLIC GetCsSelector +GetCsSelector PROC NEAR C, CsSelector:PTR + push ax + push ebx + + call FarCallGetCs + mov ebx, CsSelector + mov [ebx], ax + pop ebx + pop ax + ret +GetCsSelector ENDP + +;====================================================================== +; FarCallGetCs: +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; none +; +;====================================================================== +FarCallGetCs PROC FAR PRIVATE + + mov ax, ss:[esp + 4] + retf + +FarCallGetCs ENDP + +;====================================================================== +; SetIdtr: +; +; In: +; @param[in] IdtPtr Points to IDT table +; +; Out: +; None +; +; Destroyed: +; none +; +;====================================================================== +PUBLIC SetIdtr +SetIdtr PROC NEAR C USES EBX, IdtPtr:PTR + mov ebx, IdtPtr + lidt fword ptr ss:[ebx] + ret +SetIdtr ENDP + +;====================================================================== +; GetIdtr: +; +; In: +; @param[in] IdtPtr Points to IDT table +; +; Out: +; None +; +; Destroyed: +; none +; +;====================================================================== +PUBLIC GetIdtr +GetIdtr PROC NEAR C USES EBX, IdtPtr:PTR + mov ebx, IdtPtr + sidt fword ptr ss:[ebx] + ret +GetIdtr ENDP + +;====================================================================== +; ExecuteWbinvdInstruction: Performs a wbinvd instruction. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +PUBLIC ExecuteWbinvdInstruction +ExecuteWbinvdInstruction PROC NEAR C + wbinvd ; Write back the cache tag RAMs + ret +ExecuteWbinvdInstruction ENDP + +END diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.c new file mode 100644 index 0000000000..bc80453a90 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt.c @@ -0,0 +1,160 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * HyperTransport features and sequence implementation. + * + * Implements the external AmdHtInitialize entry point. + * Contains routines for directing the sequence of available features. + * Mostly, but not exclusively, AGESA_TESTPOINT invocations should be + * contained in this file, and not in the feature code. + * + * From a build option perspective, it may be that a few lines could be removed + * from compilation in this file for certain options. It is considered that + * the code savings from this are too small to be of concern and this file + * should not have any explicit build option implementation. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 35978 $ @e \$Date: 2010-08-07 02:18:50 +0800 (Sat, 07 Aug 2010) $ + * + */ +/* +***************************************************************************** +* +* Copyright (c) 2011, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* *************************************************************************** +* +*/ + +#include "AGESA.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "Filecode.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +// typedef unsigned int uintptr_t; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +ExecuteFinalHltInstruction ( + IN UINT32 SharedCore, + IN AP_MTRR_SETTINGS *ApMtrrSettingsList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +NmiHandler ( + IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr + ); + +VOID +ExecuteHltInstruction ( + IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr + ); + +VOID +ExecuteWbinvdInstruction ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/// Structure needed to load the IDTR using the lidt instruction + +VOID +SetIdtr ( + IN IDT_BASE_LIMIT *IdtInfo, + IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr + ) +{ + __lidt (IdtInfo); +} + +//---------------------------------------------------------------------------- + +VOID +GetCsSelector ( + IN UINT16 *Selector, + IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr + ) +{ + static const UINT8 opcode [] = {0x8C, 0xC8, 0xC3}; // mov eax, cs; ret + *Selector = ((UINT16 (*)(void)) (size_t) opcode) (); +} + +//---------------------------------------------------------------------------- + +VOID +NmiHandler ( + IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr + ) +{ + static const UINT8 opcode [] = {0xCF}; // iret + ((void (*)(void)) (size_t) opcode) (); +} + +//---------------------------------------------------------------------------- + +VOID +ExecuteHltInstruction ( + IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr + ) +{ + _disable (); + __halt (); +} + +//--------------------------------------------------------------------------- + +VOID +ExecuteWbinvdInstruction ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + __wbinvd (); +} + +//---------------------------------------------------------------------------- diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt64.asm b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt64.asm new file mode 100644 index 0000000000..f7a8e3ed2d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahalt64.asm @@ -0,0 +1,173 @@ +;/** +; * @file +; * +; * Agesa pre-memory miscellaneous support, including ap halt loop. +; * +; * @xrefitem bom "File Content Label" "Release Content" +; * @e project: AGESA +; * @e sub-project: CPU +; * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ +; */ +;***************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + text SEGMENT + + +;====================================================================== +; ExecuteFinalHltInstruction: Performs a hlt instruction. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; eax, ebx, ecx, edx, esp +; +;====================================================================== +ExecuteFinalHltInstruction PROC PUBLIC +@@: + cli + hlt + jmp @B ;ExecuteHltInstruction +ExecuteFinalHltInstruction ENDP + +;====================================================================== +; ExecuteHltInstruction: Performs a hlt instruction. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; eax, ebx, ecx, edx, esp +; +;====================================================================== +ExecuteHltInstruction PROC PUBLIC + cli + hlt + ret +ExecuteHltInstruction ENDP + +;====================================================================== +; NmiHandler: Simply performs an IRET. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +NmiHandler PROC PUBLIC + iretq +NmiHandler ENDP + +;====================================================================== +; GetCsSelector: Returns the current protected mode CS selector. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +GetCsSelector PROC PUBLIC + ; This stub function is here to avoid compilation errors. + ; At this time, there is no need to provide a 64 bit function. + ret +GetCsSelector ENDP + +;====================================================================== +; SetIdtr: +; +; In: +; @param[in] IdtPtr Points to IDT table +; +; Out: +; None +; +; Destroyed: +; none +; +;====================================================================== +SetIdtr PROC PUBLIC + ; This stub function is here to avoid compilation errors. + ; At this time, there is no need to provide a 64 bit function. + ret +SetIdtr ENDP + +;====================================================================== +; GetIdtr: +; +; In: +; @param[in] IdtPtr Points to IDT table +; +; Out: +; None +; +; Destroyed: +; none +; +;====================================================================== +GetIdtr PROC PUBLIC + ; This stub function is here to avoid compilation errors. + ; At this time, there is no need to provide a 64 bit function. + ret +GetIdtr ENDP + +;====================================================================== +; ExecuteWbinvdInstruction: Performs a wbinvd instruction. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +ExecuteWbinvdInstruction PROC PUBLIC + wbinvd ; Write back the cache tag RAMs + ret +ExecuteWbinvdInstruction ENDP + +END diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahaltasm.S b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahaltasm.S new file mode 100644 index 0000000000..97f6f16dc3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cahaltasm.S @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2011, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +.include "src/vendorcode/amd/agesa/f16kb/gcccar.inc" + +.code32 +.align 4 +.globl ExecuteFinalHltInstruction + .type ExecuteFinalHltInstruction, @function + +/* This function disables CAR. We don't care about the stack on this CPU */ +ExecuteFinalHltInstruction: + movl 4(%esp), %esi /* HaltFlags*/ + movl 8(%esp), %edi /* ApMtrrSettingList */ + +/* Do these special steps in case if the core is part of a compute unit + * Note: The following bits are family specific flags, that gets set during build time, + * and indicates things like "family cache control methodology", etc. + * esi bit0 = 0 -> not a Primary core + * esi bit0 = 1 -> Primary core + * esi bit1 = 0 -> Cache disable + * esi bit1 = 1 -> Cache enable + */ + + bt $1, %esi /* .if (esi & 2h) */ + jz 0f + /* TODO: Set CombineCr0Cd bit */ + //movl $CU_CFG3, %ecx + //rdmsr + //bts $(COMBINE_CR0_CD - 32), %edx + //wrmsr + /* Clear the CR0.CD bit */ + movl %cr0, %eax /* Make sure cache is enabled for all APs */ + btr $CR0_CD, %eax + btr $CR0_NW, %eax + mov %eax, %cr0 /* Write back to CR0 */ + jmp 1f /* .else */ +0: + movl %cr0, %eax /* Make sure cache is disabled for all APs */ + bts $CR0_CD, %eax /* Disable cache */ + bts $CR0_NW, %eax + movl %eax, %cr0 /* Write back to CR0 */ +1: /* .endif */ + + bt $0, %esi /* .if (esi & 1h) */ + jz 2f + /* This core is a primary core and needs to do all the MTRRs, including shared MTRRs. */ + movl %edi, %esi /* Get ApMtrrSettingList */ + + /* Configure the MTRRs on the AP so + * when it runs remote code it will execute + * out of RAM instead of ROM. + */ + + /* Disable MTRRs and turn on modification enable bit */ + movl $MTRR_SYS_CFG, %ecx + rdmsr + /* TODO: why comment this? */ + btr $MTRR_VAR_DRAM_EN, %eax /* Disable */ + bts $MTRR_FIX_DRAM_MOD_EN, %eax /* Enable */ + btr $MTRR_FIX_DRAM_EN, %eax /* Disable */ + bts $SYS_UC_LOCK_EN, %eax + wrmsr + + /* Setup default values for Fixed-Sized MTRRs */ + /* Set 7FFFh-00000h as WB */ + movl $AMD_AP_MTRR_FIX64k_00000, %ecx + movl $0x1E1E1E1E, %eax + movl %eax, %edx + wrmsr + + /* Set 9FFFFh-80000h also as WB */ + movl $AMD_AP_MTRR_FIX16k_80000, %ecx + wrmsr + + /* Set BFFFFh-A0000h as Uncacheable Memory-mapped IO */ + movl $AMD_AP_MTRR_FIX16k_A0000, %ecx + xorl %eax, %eax + xorl %edx, %edx + wrmsr + + /* Set DFFFFh-C0000h as Uncacheable Memory-mapped IO */ + xorl %eax, %eax + xorl %edx, %edx + movl $AMD_AP_MTRR_FIX4k_C0000, %ecx + +CDLoop: + wrmsr + inc %ecx + cmp $AMD_AP_MTRR_FIX4k_D8000, %ecx + jbe CDLoop + + /* Set FFFFFh-E0000h as Uncacheable Memory */ + movl $0x18181818, %eax + movl %eax, %edx + + mov $AMD_AP_MTRR_FIX4k_E0000, %ecx + +EFLoop: + wrmsr + inc %ecx + cmp $AMD_AP_MTRR_FIX4k_F8000, %ecx + jbe EFLoop + + /* If IBV provided settings for Fixed-Sized MTRRs, + * overwrite the default settings. */ + cmp $0, %esi /*.if ((esi != 0) && (esi != 0FFFFFFFFh)) */ + jz 4f + cmp $0xFFFFFFFF, %esi + jz 4f + 5: + mov (%esi), %ecx /* (AP_MTRR_SETTINGS ptr [esi]).MsrAddr */ + /* While we are not at the end of the list */ + cmp $CPU_LIST_TERMINAL, %ecx /* .while (ecx != CPU_LIST_TERMINAL)*/ + je 4f + /* TODO - coreboot isn't checking for valid data. + * Ensure that the MSR address is valid for Fixed-Sized MTRRs */ + /*.if ( ((ecx >= AMD_AP_MTRR_FIX4k_C0000) && (ecx <= AMD_AP_MTRR_FIX4k_F8000)) || \ + (ecx == AMD_AP_MTRR_FIX64k_00000) || (ecx == AMD_AP_MTRR_FIX16k_80000 ) || \ + (ecx == AMD_AP_MTRR_FIX16k_A0000)) + */ + mov 4(%esi), %eax /* MsrData */ + mov 8(%esi), %edx /* MsrData */ + wrmsr + /* .endif */ + add $12, %esi /* sizeof (AP_MTRR_SETTINGS) */ + jmp 5b /* .endw */ + 4: /* .endif */ + + /* Enable fixed-range and variable-range MTRRs */ + mov $AMD_MTRR_DEFTYPE, %ecx + rdmsr + bts $MTRR_DEF_TYPE_EN, %eax /* MtrrDefTypeEn */ + bts $MTRR_DEF_TYPE_FIX_EN, %eax /* MtrrDefTypeFixEn */ + wrmsr + + /* Enable Top-of-Memory setting */ + /* Enable use of RdMem/WrMem bits attributes */ + mov $MTRR_SYS_CFG, %ecx + rdmsr + /* TODO: */ + bts $MTRR_VAR_DRAM_EN, %eax /* Enable */ + btr $MTRR_FIX_DRAM_MOD_EN, %eax /* Disable */ + bts $MTRR_FIX_DRAM_EN, %eax /* Enable */ + wrmsr + + bts $FLAG_IS_PRIMARY, %esi + jmp 3f /* .else ; end if primary core */ + 2: + xor %esi, %esi + 3: /* .endif*/ + + /* Make sure not to touch any Shared MSR from this point on */ + + AMD_DISABLE_STACK_FAMILY_HOOK + + /* restore variable MTTR6 and MTTR7 to default states */ + bt $FLAG_IS_PRIMARY, %esi /* .if (esi & 1h) */ + jz 6f + movl $AMD_MTRR_VARIABLE_MASK7, %ecx /* clear MTRRPhysBase6 MTRRPhysMask6 */ + xor %eax, %eax /* and MTRRPhysBase7 MTRRPhysMask7 */ + xor %edx, %edx + cmp $AMD_MTRR_VARIABLE_BASE6, %ecx /* .while (cl < 010h) */ + jl 6f + wrmsr + dec %ecx + 6: /* .endw */ + + xor %eax, %eax + +7: + cli + hlt + jmp 7b /* ExecuteHltInstruction */ + + .size ExecuteFinalHltInstruction, .-ExecuteFinalHltInstruction diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.c new file mode 100644 index 0000000000..ac824f3cb9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.c @@ -0,0 +1,1453 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU APIC related utility functions. + * + * Contains code that provides mechanism to invoke and control APIC communication. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuCacheInit.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_CPUAPICUTILITIES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +/* ApFlags bits */ +#define AP_TASK_HAS_INPUT 0x00000001ul +#define AP_TASK_HAS_OUTPUT 0x00000002ul +#define AP_RETURN_PARAMS 0x00000004ul +#define AP_END_AT_HLT 0x00000008ul +#define AP_PASS_EARLY_PARAMS 0x00000010ul + +#define XFER_ELEMENT_SIZE sizeof (UINT32) + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +typedef VOID F_CPU_AMD_NMI_HANDLER ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +typedef F_CPU_AMD_NMI_HANDLER *PF_CPU_AMD_NMI_HANDLER; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +ApUtilSetupIdtForHlt ( + IN IDT_DESCRIPTOR *NmiIdtDescPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +STATIC +ApUtilRemoteRead ( + IN UINT32 TargetApicId, + IN UINT8 RegAddr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +ApUtilLocalWrite ( + IN UINT32 RegAddr, + IN UINT32 Value, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +STATIC +ApUtilLocalRead ( + IN UINT32 RegAddr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +ApUtilGetLocalApicBase ( + OUT UINT64 *ApicBase, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +STATIC +ApUtilCalculateUniqueId ( + IN UINT8 Socket, + IN UINT8 Core, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +ApUtilFireDirectedNmi ( + IN UINT32 TargetApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +ApUtilReceivePointer ( + IN UINT32 TargetApicId, + OUT VOID **ReturnPointer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +ApUtilTransmitPointer ( + IN UINT32 TargetApicId, + IN VOID **Pointer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +PerformFinalHalt ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +LocalApicInitialization ( + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +LocalApicInitializationAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern +VOID +ExecuteHltInstruction ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +extern +VOID +NmiHandler ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +extern +VOID +ExecuteFinalHltInstruction ( + IN UINT32 SharedCore, + IN AP_MTRR_SETTINGS *ApMtrrSettingsList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------*/ +/** + * Initialize the Local APIC. + * + * This function determines and programs the appropriate APIC ID value + * for the executing core. This code must be run after HT initialization + * is complete. + * + * @param[in] CpuEarlyParamsPtr Service parameters. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +LocalApicInitialization ( + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CurrentCore; + UINT32 CurrentNodeNum; + UINT32 CoreIdBits; + UINT32 Mnc; + UINT32 ProcessorCount; + UINT32 ProcessorApicIndex; + UINT32 IoApicNum; + UINT32 StartLocalApicId; + UINT64 LocalApicBase; + UINT32 TempVar_a; + UINT64 MsrData; + UINT64 Address; + CPUID_DATA CpuidData; + + // Local variables default values + IoApicNum = CpuEarlyParamsPtr->PlatformConfig.NumberOfIoApics; + + GetCurrentCore (&CurrentCore, StdHeader); + GetCurrentNodeNum (&CurrentNodeNum, StdHeader); + + // Get Mnc + LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuidData, StdHeader); + CoreIdBits = (CpuidData.ECX_Reg & 0x0000F000) >> 12; + Mnc = 1 << (CoreIdBits & 0x000F); + + // Get ProcessorCount in the system + ProcessorCount = GetNumberOfProcessors (StdHeader); + + // Get the APIC Index of this processor. + ProcessorApicIndex = GetProcessorApicIndex (CurrentNodeNum, StdHeader); + + TempVar_a = (Mnc * ProcessorCount) + IoApicNum; + ASSERT (TempVar_a < 255); + + // Apply apic enumeration rules + // For systems with >= 16 APICs, put the IO-APICs at 0..n and + // put the local-APICs at m..z + // For systems with < 16 APICs, put the Local-APICs at 0..n and + // put the IO-APICs at (n + 1)..z + // This is needed because many IO-APIC devices only have 4 bits + // for their APIC id and therefore must reside at 0..15 + StartLocalApicId = 0; + if (TempVar_a >= 16) { + if (IoApicNum >= 1) { + StartLocalApicId = (IoApicNum - 1) / Mnc; + StartLocalApicId = (StartLocalApicId + 1) * Mnc; + } + } + + // Set local apic id + TempVar_a = (ProcessorApicIndex * Mnc) + CurrentCore + StartLocalApicId; + IDS_HDT_CONSOLE (CPU_TRACE, " Node %d core %d APIC ID = 0x%x\n", CurrentNodeNum, CurrentCore, TempVar_a); + TempVar_a = TempVar_a << APIC20_ApicId; + + // Enable local apic id + LibAmdMsrRead (MSR_APIC_BAR, &MsrData, StdHeader); + MsrData |= APIC_ENABLE_BIT; + LibAmdMsrWrite (MSR_APIC_BAR, &MsrData, StdHeader); + + // Get local apic base Address + ApUtilGetLocalApicBase (&LocalApicBase, StdHeader); + + Address = LocalApicBase + APIC_ID_REG; + LibAmdMemWrite (AccessWidth32, Address, &TempVar_a, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Initialize the Local APIC at the AmdInitEarly entry point. + * + * This function acts as a wrapper for calling the LocalApicInitialization + * routine at AmdInitEarly. + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[in] EarlyParams Service parameters. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +LocalApicInitializationAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_TESTPOINT (TpProcCpuLocalApicInit, StdHeader); + LocalApicInitialization (EarlyParams, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for all APs in the system. + * + * This routine puts the AP cores in an infinite loop in which the cores + * will poll their masters, waiting to be told to perform a task. At early, + * all socket-relative core zeros will receive their tasks from the BSC. + * All others will receive their tasks from the core zero of their local + * processor. At the end of AmdInitEarly, all cores will switch to receiving + * their tasks from the BSC. + * + * @param[in] StdHeader Handle to config for library and services. + * @param[in] CpuEarlyParams AMD_CPU_EARLY_PARAMS pointer. + * + */ +VOID +ApEntry ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ) +{ + UINT8 RemoteCmd; + UINT8 SourceSocket; + UINT8 CommandStart; + UINT32 ApFlags; + UINT32 FuncType; + UINT32 ReturnCode; + UINT32 CurrentSocket; + UINT32 CurrentCore; + UINT32 *InputDataPtr; + UINT32 BscSocket; + UINT32 Ignored; + UINT32 TargetApicId; + AP_FUNCTION_PTR FuncAddress; + IDT_DESCRIPTOR IdtDesc[32]; + AP_DATA_TRANSFER DataTransferInfo; + AGESA_STATUS IgnoredSts; + + ASSERT (!IsBsp (StdHeader, &IgnoredSts)); + + // Initialize local variables + ReturnCode = 0; + DataTransferInfo.DataTransferFlags = 0; + InputDataPtr = NULL; + + // Determine the executing core's socket and core numbers + IdentifyCore (StdHeader, &CurrentSocket, &Ignored, &CurrentCore, &IgnoredSts); + + IDS_HDT_CONSOLE (CPU_TRACE, " Socket %d core %d begin AP tasking engine\n", CurrentSocket, CurrentCore); + + // Determine the BSC's socket number + GetSocketModuleOfNode ((UINT32) 0x00000000, &BscSocket, &Ignored, StdHeader); + + // Setup Interrupt Descriptor Table for sleep mode + ApUtilSetupIdtForHlt (&IdtDesc[2], StdHeader); + + // Indicate to the BSC that we have reached the tasking engine + ApUtilWriteControlByte (CORE_IDLE, StdHeader); + + if (CurrentCore == 0) { + // Core 0s receive their tasks from the BSC + SourceSocket = (UINT8) BscSocket; + } else { + // All non-zero cores receive their tasks from the core 0 of their socket + SourceSocket = (UINT8) CurrentSocket; + } + + GetLocalApicIdForCore (SourceSocket, 0, &TargetApicId, StdHeader); + + // Determine the unique value that the master will write when it has a task + // for this core to perform. + CommandStart = ApUtilCalculateUniqueId ( + (UINT8)CurrentSocket, + (UINT8)CurrentCore, + StdHeader + ); + for (;;) { + RemoteCmd = ApUtilReadRemoteControlByte (TargetApicId, StdHeader); + if (RemoteCmd == CommandStart) { + ApFlags = ApUtilReadRemoteDataDword (TargetApicId, StdHeader); + + ApUtilReceivePointer (TargetApicId, (VOID **) &FuncAddress, StdHeader); + + FuncType = ApFlags & (UINT32) (AP_TASK_HAS_INPUT | AP_TASK_HAS_OUTPUT | AP_PASS_EARLY_PARAMS); + if ((ApFlags & AP_TASK_HAS_INPUT) != 0) { + DataTransferInfo.DataSizeInDwords = 0; + DataTransferInfo.DataPtr = NULL; + DataTransferInfo.DataTransferFlags = 0; + if (ApUtilReceiveBuffer (SourceSocket, 0, &DataTransferInfo, StdHeader) == AGESA_ERROR) { + // There is not enough space to put the input data on the heap. Undefined behavior is about + // to result. + IDS_ERROR_TRAP; + } + InputDataPtr = (UINT32 *) DataTransferInfo.DataPtr; + } + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); + switch (FuncType) { + case 0: + FuncAddress.PfApTask (StdHeader); + break; + case AP_TASK_HAS_INPUT: + FuncAddress.PfApTaskI (InputDataPtr, StdHeader); + break; + case AP_PASS_EARLY_PARAMS: + FuncAddress.PfApTaskC (StdHeader, CpuEarlyParams); + break; + case (AP_TASK_HAS_INPUT | AP_PASS_EARLY_PARAMS): + FuncAddress.PfApTaskIC (InputDataPtr, StdHeader, CpuEarlyParams); + break; + case AP_TASK_HAS_OUTPUT: + ReturnCode = FuncAddress.PfApTaskO (StdHeader); + break; + case (AP_TASK_HAS_INPUT | AP_TASK_HAS_OUTPUT): + ReturnCode = FuncAddress.PfApTaskIO (InputDataPtr, StdHeader); + break; + case (AP_TASK_HAS_OUTPUT | AP_PASS_EARLY_PARAMS): + ReturnCode = FuncAddress.PfApTaskOC (StdHeader, CpuEarlyParams); + break; + case (AP_TASK_HAS_INPUT | AP_TASK_HAS_OUTPUT | AP_PASS_EARLY_PARAMS): + ReturnCode = FuncAddress.PfApTaskIOC (InputDataPtr, StdHeader, CpuEarlyParams); + break; + default: + ReturnCode = 0; + break; + } + if (((ApFlags & AP_RETURN_PARAMS) != 0)) { + ApUtilTransmitBuffer (SourceSocket, 0, &DataTransferInfo, StdHeader); + } + if ((ApFlags & AP_TASK_HAS_OUTPUT) != 0) { + ApUtilWriteDataDword (ReturnCode, StdHeader); + } + if ((ApFlags & AP_END_AT_HLT) != 0) { + RemoteCmd = CORE_IDLE_HLT; + } else { + ApUtilWriteControlByte (CORE_IDLE, StdHeader); + } + } + if (RemoteCmd == CORE_IDLE_HLT) { + SourceSocket = (UINT8) BscSocket; + GetLocalApicIdForCore (SourceSocket, 0, &TargetApicId, StdHeader); + ApUtilWriteControlByte (CORE_IDLE_HLT, StdHeader); + ExecuteHltInstruction (StdHeader); + ApUtilWriteControlByte (CORE_IDLE, StdHeader); + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Reads the 'control byte' on the designated remote core. + * + * This function will read the current contents of the control byte + * on the designated core using the APIC remote read inter- + * processor interrupt sequence. + * + * @param[in] TargetApicId Local APIC ID of the desired core + * @param[in] StdHeader Configuration parameters pointer + * + * @return The current value of the remote cores control byte + * + */ +UINT8 +ApUtilReadRemoteControlByte ( + IN UINT32 TargetApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 ControlByte; + UINT32 ApicRegister; + + ApicRegister = ApUtilRemoteRead (TargetApicId, APIC_CTRL_DWORD, StdHeader); + ControlByte = (UINT8) ((ApicRegister & APIC_CTRL_MASK) >> APIC_CTRL_SHIFT); + return (ControlByte); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Writes the 'control byte' on the executing core. + * + * This function writes data to a local APIC offset used in inter- + * processor communication. + * + * @param[in] Value + * @param[in] StdHeader + * + */ +VOID +ApUtilWriteControlByte ( + IN UINT8 Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ApicRegister; + + ApicRegister = ApUtilLocalRead (APIC_CTRL_REG, StdHeader); + ApicRegister = ((ApicRegister & ~APIC_CTRL_MASK) | (UINT32) (Value << APIC_CTRL_SHIFT)); + ApUtilLocalWrite (APIC_CTRL_REG, ApicRegister, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Reads the 'data dword' on the designated remote core. + * + * This function will read the current contents of the data dword + * on the designated core using the APIC remote read inter- + * processor interrupt sequence. + * + * @param[in] TargetApicId Local APIC ID of the desired core + * @param[in] StdHeader Configuration parameters pointer + * + * @return The current value of the remote core's data dword + * + */ +UINT32 +ApUtilReadRemoteDataDword ( + IN UINT32 TargetApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return (ApUtilRemoteRead (TargetApicId, APIC_DATA_DWORD, StdHeader)); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Writes the 'data dword' on the executing core. + * + * This function writes data to a local APIC offset used in inter- + * processor communication. + * + * @param[in] Value Value to write + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +ApUtilWriteDataDword ( + IN UINT32 Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + ApUtilLocalWrite (APIC_DATA_REG, Value, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Runs the given task on the specified local core. + * + * This function is used to invoke an AP to run a specified AGESA + * procedure. It can only be called by cores that have subordinate + * APs -- the BSC at POST, or any socket-relative core 0s at Early. + * + * @param[in] Socket Socket number of the target core + * @param[in] Core Core number of the target core + * @param[in] TaskPtr Function descriptor + * @param[in] StdHeader Configuration parameters pointer + * + * @return Return value of the task that the AP core ran, + * or zero if the task was VOID. + * + */ +UINT32 +ApUtilRunCodeOnSocketCore ( + IN UINT8 Socket, + IN UINT8 Core, + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 CoreId; + UINT8 CurrentStatus; + UINT8 WaitStatus[3]; + UINT32 ApFlags; + UINT32 ReturnCode; + UINT32 TargetApicId; + AP_WAIT_FOR_STATUS WaitForStatus; + + ApFlags = 0; + ReturnCode = 0; + + CoreId = ApUtilCalculateUniqueId (Socket, Core, StdHeader); + + GetLocalApicIdForCore (Socket, Core, &TargetApicId, StdHeader); + + if (TaskPtr->DataTransfer.DataSizeInDwords != 0) { + ApFlags |= AP_TASK_HAS_INPUT; + if (((TaskPtr->ExeFlags & RETURN_PARAMS) != 0) && + ((TaskPtr->DataTransfer.DataTransferFlags & DATA_IN_MEMORY) == 0)) { + ApFlags |= AP_RETURN_PARAMS; + } + } + + if ((TaskPtr->ExeFlags & TASK_HAS_OUTPUT) != 0) { + ApFlags |= AP_TASK_HAS_OUTPUT; + } + + if ((TaskPtr->ExeFlags & END_AT_HLT) != 0) { + ApFlags |= AP_END_AT_HLT; + } + + if ((TaskPtr->ExeFlags & PASS_EARLY_PARAMS) != 0) { + ApFlags |= AP_PASS_EARLY_PARAMS; + } + + WaitStatus[0] = CORE_IDLE; + WaitStatus[1] = CORE_IDLE_HLT; + WaitStatus[2] = CORE_UNAVAILABLE; + WaitForStatus.Status = WaitStatus; + WaitForStatus.NumberOfElements = 3; + WaitForStatus.RetryCount = WAIT_INFINITELY; + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + CurrentStatus = ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + + if (CurrentStatus != CORE_UNAVAILABLE) { + ApUtilWriteDataDword (ApFlags, StdHeader); + ApUtilWriteControlByte (CoreId, StdHeader); + + if (CurrentStatus == CORE_IDLE_HLT) { + ApUtilFireDirectedNmi (TargetApicId, StdHeader); + } + + ApUtilTransmitPointer (TargetApicId, (VOID **) &TaskPtr->FuncAddress, StdHeader); + + if ((ApFlags & AP_TASK_HAS_INPUT) != 0) { + ApUtilTransmitBuffer (Socket, Core, &TaskPtr->DataTransfer, StdHeader); + } + + if ((TaskPtr->ExeFlags & WAIT_FOR_CORE) != 0) { + if (((ApFlags & AP_TASK_HAS_INPUT) != 0) && + ((ApFlags & AP_RETURN_PARAMS) != 0) && + ((TaskPtr->DataTransfer.DataTransferFlags & DATA_IN_MEMORY) == 0)) { + if (ApUtilReceiveBuffer (Socket, Core, &TaskPtr->DataTransfer, StdHeader) == AGESA_ERROR) { + // There is not enough space to put the return data. This should never occur. If it + // does, this would point to strange heap corruption. + IDS_ERROR_TRAP; + } + } + + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + if ((ApFlags & AP_TASK_HAS_OUTPUT) != 0) { + ReturnCode = ApUtilReadRemoteDataDword (TargetApicId, StdHeader); + } + } + } else { + ReturnCode = 0; + } + return (ReturnCode); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Waits for a remote core's control byte value to either be equal or + * not equal to any number of specified values. + * + * This function will loop doing remote read IPIs until the remote core's + * control byte becomes one of the values in the input array if the input + * flags are set for equality. Otherwise, the loop will continue until + * the control byte value is not equal to one of the elements in the + * array. The caller can also specify an iteration count for timeout + * purposes. + * + * @param[in] TargetApicId Local APIC ID of the desired core + * @param[in] WaitParamsPtr Wait parameter structure + * @param[in] StdHeader Configuration parameteres pointer + * + * @return The current value of the remote core's control byte + * + */ +UINT8 +ApUtilWaitForCoreStatus ( + IN UINT32 TargetApicId, + IN AP_WAIT_FOR_STATUS *WaitParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN IsEqual; + UINT8 CoreStatus; + UINT8 i; + UINT8 j; + + CoreStatus = 0; + for (i = 0; (WaitParamsPtr->RetryCount == WAIT_INFINITELY) || + (i < WaitParamsPtr->RetryCount); ++i) { + CoreStatus = ApUtilReadRemoteControlByte (TargetApicId, StdHeader); + // Determine whether or not the current remote status is equal + // to an element in the array. + IsEqual = FALSE; + for (j = 0; !IsEqual && j < WaitParamsPtr->NumberOfElements; ++j) { + if (CoreStatus == WaitParamsPtr->Status[j]) { + IsEqual = TRUE; + } + } + if ((((WaitParamsPtr->WaitForStatusFlags & WAIT_STATUS_EQUALITY) != 0) && IsEqual) || + (((WaitParamsPtr->WaitForStatusFlags & WAIT_STATUS_EQUALITY) == 0) && !IsEqual)) { + break; + } + } + return (CoreStatus); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Runs the AP task on the executing core. + * + * @param[in] TaskPtr Function descriptor + * @param[in] StdHeader Configuration parameters pointer + * @param[in] ConfigParams Entry point CPU parameters pointer + * + * @return Return value of the task, or zero if the task + * was VOID. + * + */ +UINT32 +ApUtilTaskOnExecutingCore ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ConfigParams + ) +{ + UINT32 InvocationOptions; + UINT32 ReturnCode; + + ReturnCode = 0; + InvocationOptions = 0; + + if (TaskPtr->DataTransfer.DataSizeInDwords != 0) { + InvocationOptions |= AP_TASK_HAS_INPUT; + } + if ((TaskPtr->ExeFlags & TASK_HAS_OUTPUT) != 0) { + InvocationOptions |= AP_TASK_HAS_OUTPUT; + } + if ((TaskPtr->ExeFlags & PASS_EARLY_PARAMS) != 0) { + InvocationOptions |= AP_PASS_EARLY_PARAMS; + } + + switch (InvocationOptions) { + case 0: + TaskPtr->FuncAddress.PfApTask (StdHeader); + break; + case AP_TASK_HAS_INPUT: + TaskPtr->FuncAddress.PfApTaskI (TaskPtr->DataTransfer.DataPtr, StdHeader); + break; + case AP_PASS_EARLY_PARAMS: + TaskPtr->FuncAddress.PfApTaskC (StdHeader, ConfigParams); + break; + case (AP_TASK_HAS_INPUT | AP_PASS_EARLY_PARAMS): + TaskPtr->FuncAddress.PfApTaskIC (TaskPtr->DataTransfer.DataPtr, StdHeader, ConfigParams); + break; + case AP_TASK_HAS_OUTPUT: + ReturnCode = TaskPtr->FuncAddress.PfApTaskO (StdHeader); + break; + case (AP_TASK_HAS_INPUT | AP_TASK_HAS_OUTPUT): + ReturnCode = TaskPtr->FuncAddress.PfApTaskIO (TaskPtr->DataTransfer.DataPtr, StdHeader); + break; + case (AP_TASK_HAS_OUTPUT | AP_PASS_EARLY_PARAMS): + ReturnCode = TaskPtr->FuncAddress.PfApTaskOC (StdHeader, ConfigParams); + break; + case (AP_TASK_HAS_INPUT | AP_TASK_HAS_OUTPUT | AP_PASS_EARLY_PARAMS): + ReturnCode = TaskPtr->FuncAddress.PfApTaskIOC (TaskPtr->DataTransfer.DataPtr, StdHeader, ConfigParams); + break; + default: + ReturnCode = 0; + break; + } + return (ReturnCode); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Sets up the AP's IDT with NMI (INT2) being the only valid descriptor + * + * This function prepares the executing AP core for recovering from a hlt + * instruction by initializing its IDTR. + * + * @param[in] NmiIdtDescPtr Pointer to a writable IDT entry to + * be used for NMIs + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilSetupIdtForHlt ( + IN IDT_DESCRIPTOR *NmiIdtDescPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 DescSize; + UINT64 HandlerOffset; + UINT64 EferRegister; + IDT_BASE_LIMIT IdtInfo; + + LibAmdMsrRead (MSR_EXTENDED_FEATURE_EN, &EferRegister, StdHeader); + if ((EferRegister & 0x100) != 0) { + DescSize = 16; + } else { + DescSize = 8; + } + + HandlerOffset = (UINT64) (UINTN) NmiHandler; + NmiIdtDescPtr->OffsetLo = (UINT16) HandlerOffset & 0xFFFF; + NmiIdtDescPtr->OffsetHi = (UINT16) (HandlerOffset >> 16); + GetCsSelector (&NmiIdtDescPtr->Selector, StdHeader); + NmiIdtDescPtr->Flags = IDT_DESC_PRESENT | IDT_DESC_TYPE_INT32; + NmiIdtDescPtr->Rsvd = 0; + NmiIdtDescPtr->Offset64 = (UINT32) (HandlerOffset >> 32); + NmiIdtDescPtr->Rsvd64 = 0; + IdtInfo.Limit = (UINT16) ((DescSize * 3) - 1); + IdtInfo.Base = (UINT64) (UINTN) NmiIdtDescPtr - (DescSize * 2); + IDS_EXCEPTION_TRAP (IDS_IDT_UPDATE_EXCEPTION_VECTOR_FOR_AP, &IdtInfo, StdHeader); + SetIdtr (&IdtInfo , StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Calculate the APIC ID for a given core. + * + * Get the current node's apic id and deconstruct it to the base id of local apic id space. + * Then construct the target's apic id using that base. + * @b Assumes: The target Socket and Core exist! + * Other Notes: + * - Must run after HT initialization is complete. + * - Code sync: This calculation MUST match the assignment + * calculation done above in LocalApicInitializationAtEarly function. + * - Assumes family homogeneous population of all sockets. + * + * @param[in] TargetSocket The socket in which the Core's Processor is installed. + * @param[in] TargetCore The Core on that Processor + * @param[out] LocalApicId Its APIC Id + * @param[in] StdHeader Handle to header for library and services. + * + */ +VOID +GetLocalApicIdForCore ( + IN UINT32 TargetSocket, + IN UINT32 TargetCore, + OUT UINT32 *LocalApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CoreIdBits; + UINT32 CurrentNode; + UINT32 CurrentCore; + UINT32 TargetNode; + UINT32 MaxCoresInProcessor; + UINT32 TotalCores; + UINT32 CurrentLocalApicId; + UINT64 LocalApicBase; + UINT32 TempVar_a; + UINT64 Address; + UINT32 ProcessorApicIndex; + BOOLEAN ReturnResult; + CPUID_DATA CpuidData; + + TargetNode = 0; + + // Get local apic base Address + ApUtilGetLocalApicBase (&LocalApicBase, StdHeader); + Address = LocalApicBase + APIC_ID_REG; + + LibAmdMemRead (AccessWidth32, Address, &TempVar_a, StdHeader); + + // ApicId [7:0] + CurrentLocalApicId = (TempVar_a >> APIC20_ApicId) & 0x000000FF; + + GetCurrentNodeAndCore (&CurrentNode, &CurrentCore, StdHeader); + LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuidData, StdHeader); + CoreIdBits = (CpuidData.ECX_Reg & 0x0000F000) >> 12; + MaxCoresInProcessor = (1 << CoreIdBits); + + // Get the APIC Index of this processor. + ProcessorApicIndex = GetProcessorApicIndex (CurrentNode, StdHeader); + + TotalCores = (MaxCoresInProcessor * ProcessorApicIndex) + CurrentCore; + CurrentLocalApicId -= TotalCores; + + // Use the Node Id of TargetSocket, Module 0. No socket transitions are missed or added, + // even if the TargetCore is not on Module 0 in that processor and that's all that matters now. + ReturnResult = GetNodeId (TargetSocket, 0, (UINT8 *)&TargetNode, StdHeader); + ASSERT (ReturnResult); + + // Get the APIC Index of this processor. + ProcessorApicIndex = GetProcessorApicIndex (TargetNode, StdHeader); + + CurrentLocalApicId += ((MaxCoresInProcessor * ProcessorApicIndex) + TargetCore); + *LocalApicId = CurrentLocalApicId; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Securely passes a buffer to the designated remote core. + * + * This function uses a sequence of remote reads to transmit a data + * buffer, one UINT32 at a time. + * + * @param[in] Socket Socket number of the remote core + * @param[in] Core Core number of the remote core + * @param[in] BufferInfo Information about the buffer to pass, and + * how to pass it + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +ApUtilTransmitBuffer ( + IN UINT8 Socket, + IN UINT8 Core, + IN AP_DATA_TRANSFER *BufferInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 TargetCore; + UINT8 MyUniqueId; + UINT8 CurrentStatus; + UINT32 *CurrentPtr; + UINT32 i; + UINT32 MyCore; + UINT32 MySocket; + UINT32 Ignored; + UINT32 TargetApicId; + AP_WAIT_FOR_STATUS WaitForStatus; + AGESA_STATUS IgnoredSts; + + GetLocalApicIdForCore ((UINT32) Socket, (UINT32) Core, &TargetApicId, StdHeader); + + if ((BufferInfo->DataTransferFlags & DATA_IN_MEMORY) != 0) { + ApUtilWriteDataDword ((UINT32) 0x00000000, StdHeader); + } else { + ApUtilWriteDataDword ((UINT32) BufferInfo->DataSizeInDwords, StdHeader); + } + TargetCore = ApUtilCalculateUniqueId (Socket, Core, StdHeader); + + ApUtilWriteControlByte (TargetCore, StdHeader); + + IdentifyCore (StdHeader, &MySocket, &Ignored, &MyCore, &IgnoredSts); + + MyUniqueId = ApUtilCalculateUniqueId ((UINT8)MySocket, (UINT8)MyCore, StdHeader); + + WaitForStatus.Status = &MyUniqueId; + WaitForStatus.NumberOfElements = 1; + WaitForStatus.RetryCount = WAIT_INFINITELY; + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + ApUtilWriteDataDword (BufferInfo->DataTransferFlags, StdHeader); + + ApUtilWriteControlByte (CORE_DATA_FLAGS_READY, StdHeader); + WaitForStatus.WaitForStatusFlags = 0; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + if ((BufferInfo->DataTransferFlags & DATA_IN_MEMORY) != 0) { + ApUtilTransmitPointer (TargetApicId, (VOID **) &BufferInfo->DataPtr, StdHeader); + } else { + ApUtilWriteControlByte (CORE_STS_DATA_READY_1, StdHeader); + CurrentStatus = CORE_STS_DATA_READY_0; + WaitForStatus.Status = &CurrentStatus; + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + WaitForStatus.WaitForStatusFlags = 0; + CurrentPtr = (UINT32 *) BufferInfo->DataPtr; + for (i = 0; i < BufferInfo->DataSizeInDwords; ++i) { + ApUtilWriteDataDword (*CurrentPtr++, StdHeader); + ApUtilWriteControlByte (CurrentStatus, StdHeader); + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + CurrentStatus ^= 0x01; + } + } + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Securely receives a buffer from the designated remote core. + * + * This function uses a sequence of remote reads to receive a data + * buffer, one UINT32 at a time. + * + * @param[in] Socket Socket number of the remote core + * @param[in] Core Core number of the remote core + * @param[in] BufferInfo Information about where to place the buffer + * @param[in] StdHeader Configuration parameters pointer + * + * @retval AGESA_SUCCESS Transaction was successful + * @retval AGESA_ALERT The non-NULL desired location to place + * the buffer was not used as the buffer + * resides in a shared memory space. The + * input data pointer has changed. + * @retval AGESA_ERROR There is not enough room to receive the + * buffer. + * + */ +AGESA_STATUS +ApUtilReceiveBuffer ( + IN UINT8 Socket, + IN UINT8 Core, + IN OUT AP_DATA_TRANSFER *BufferInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MyUniqueId; + UINT8 SourceUniqueId; + UINT8 CurrentStatus; + UINT32 i; + UINT32 MySocket; + UINT32 MyCore; + UINT32 Ignored; + UINT32 *CurrentPtr; + UINT32 TransactionSize; + UINT32 TargetApicId; + AGESA_STATUS ReturnStatus; + ALLOCATE_HEAP_PARAMS HeapMalloc; + AP_WAIT_FOR_STATUS WaitForStatus; + + ReturnStatus = AGESA_SUCCESS; + IdentifyCore (StdHeader, &MySocket, &Ignored, &MyCore, &ReturnStatus); + + MyUniqueId = ApUtilCalculateUniqueId ((UINT8)MySocket, (UINT8)MyCore, StdHeader); + + GetLocalApicIdForCore ((UINT32) Socket, (UINT32) Core, &TargetApicId, StdHeader); + + WaitForStatus.Status = &MyUniqueId; + WaitForStatus.NumberOfElements = 1; + WaitForStatus.RetryCount = WAIT_INFINITELY; + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + TransactionSize = ApUtilReadRemoteDataDword (TargetApicId, StdHeader); + + if (BufferInfo->DataPtr == NULL && TransactionSize != 0) { + HeapMalloc.BufferHandle = AMD_CPU_AP_TASKING_HANDLE; + HeapMalloc.Persist = HEAP_LOCAL_CACHE; + // Deallocate the general purpose heap structure, if it exists. Ignore + // the status in case it does not exist. + HeapDeallocateBuffer (HeapMalloc.BufferHandle, StdHeader); + HeapMalloc.RequestedBufferSize = (TransactionSize * XFER_ELEMENT_SIZE); + if (HeapAllocateBuffer (&HeapMalloc, StdHeader) == AGESA_SUCCESS) { + BufferInfo->DataPtr = (UINT32 *) HeapMalloc.BufferPtr; + BufferInfo->DataSizeInDwords = (UINT16) (HeapMalloc.RequestedBufferSize / XFER_ELEMENT_SIZE); + } else { + BufferInfo->DataSizeInDwords = 0; + } + } + + if (TransactionSize <= BufferInfo->DataSizeInDwords) { + SourceUniqueId = ApUtilCalculateUniqueId (Socket, Core, StdHeader); + ApUtilWriteControlByte (SourceUniqueId, StdHeader); + CurrentStatus = CORE_DATA_FLAGS_READY; + WaitForStatus.Status = &CurrentStatus; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + BufferInfo->DataTransferFlags = ApUtilReadRemoteDataDword (TargetApicId, StdHeader); + ApUtilWriteControlByte (CORE_DATA_FLAGS_ACKNOWLEDGE, StdHeader); + if ((BufferInfo->DataTransferFlags & DATA_IN_MEMORY) != 0) { + if (BufferInfo->DataPtr != NULL) { + ReturnStatus = AGESA_ALERT; + } + ApUtilReceivePointer (TargetApicId, (VOID **) &BufferInfo->DataPtr, StdHeader); + } else { + CurrentStatus = CORE_STS_DATA_READY_1; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + CurrentStatus = CORE_STS_DATA_READY_0; + ApUtilWriteControlByte (CurrentStatus, StdHeader); + CurrentPtr = BufferInfo->DataPtr; + for (i = 0; i < TransactionSize; ++i) { + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + *CurrentPtr++ = ApUtilReadRemoteDataDword (TargetApicId, StdHeader); + CurrentStatus ^= 0x01; + ApUtilWriteControlByte (CurrentStatus, StdHeader); + } + } + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); + } else { + BufferInfo->DataSizeInDwords = (UINT16) TransactionSize; + ReturnStatus = AGESA_ERROR; + } + return (ReturnStatus); +} + + +VOID +RelinquishControlOfAllAPs ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 BscSocket; + UINT32 Ignored; + UINT32 BscCoreNum; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + AP_TASK TaskPtr; + AGESA_STATUS IgnoredSts; + + ASSERT (IsBsp (StdHeader, &IgnoredSts)); + + TaskPtr.FuncAddress.PfApTask = PerformFinalHalt; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &Core, StdHeader)) { + while (Core-- > 0) { + if ((Socket != BscSocket) || (Core != BscCoreNum)) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); + } + } + } + } +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * The last AGESA code that an AP performs + * + * This function, run only by APs, breaks down their cache subsystem, sets up + * for memory to be present upon wake (from IBV Init/Startup IPIs), and halts. + * + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +STATIC +PerformFinalHalt ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PrimaryCore; + UINT32 HaltFlags; + UINT32 CacheEnDis; + CPU_SPECIFIC_SERVICES *FamilyServices; + CONST CACHE_INFO *CacheInfoPtr; + UINT8 NumberOfElements; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + // CacheEnDis is a family specific flag, that lets the code to decide whether to + // keep the cache control bits set or cleared. + CacheEnDis = FamilyServices->InitCacheDisabled; + + // Determine if the current core has the primary core role. The first core to execute + // in each compute unit has the primary role. + PrimaryCore = (UINT32) IsCoreComputeUnitPrimary (FirstCoreIsComputeUnitPrimary, StdHeader); + + // If the core is not PrimaryCore, check if VarMTRRs are not shared among cores in a compute unit, + // low 32bits of VarMTRR mask is 0xFFFFFFFF. Treat each AP as primary core for setting MTRRs. + if (PrimaryCore != TRUE) { + FamilyServices->GetCacheInfo (FamilyServices, (CONST VOID **) &CacheInfoPtr, &NumberOfElements, StdHeader); + if (((UINT32) CacheInfoPtr->VariableMtrrHeapMask) == 0xFFFFFFFF) { + PrimaryCore = TRUE; + } + } + + // Aggregate the flags for the halt service. + HaltFlags = PrimaryCore | (CacheEnDis << 1); + + ApUtilWriteControlByte (CORE_UNAVAILABLE, StdHeader); + ExecuteFinalHltInstruction (HaltFlags, UserOptions.CfgApMtrrSettingsList, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Reads the APIC register on the designated remote core. + * + * This function uses the remote read inter-processor interrupt protocol + * to read an APIC register from the remote core + * + * @param[in] TargetApicId Local APIC ID of the desired core + * @param[in] RegAddr APIC register to read + * @param[in] StdHeader Configuration parameters pointer + * + * @return The current value of the remote core's desired APIC register + * + */ +UINT32 +STATIC +ApUtilRemoteRead ( + IN UINT32 TargetApicId, + IN UINT8 RegAddr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ApicRegister; + UINT64 ApicBase; + UINT64 ApicAddr; + + ApUtilGetLocalApicBase (&ApicBase, StdHeader); + TargetApicId <<= LOCAL_APIC_ID; + + do { + ApicAddr = ApicBase + APIC_CMD_HI_REG; + LibAmdMemWrite (AccessWidth32, ApicAddr, &TargetApicId, StdHeader); + ApicAddr = ApicBase + APIC_CMD_LO_REG; + ApicRegister = CMD_REG_TO_READ | (UINT32) RegAddr; + LibAmdMemWrite (AccessWidth32, ApicAddr, &ApicRegister, StdHeader); + do { + LibAmdMemRead (AccessWidth32, ApicAddr, &ApicRegister, StdHeader); + } while ((ApicRegister & CMD_REG_DELIVERY_STATUS) != 0); + while ((ApicRegister & CMD_REG_REMOTE_RD_STS_MSK) == CMD_REG_REMOTE_DELIVERY_PENDING) { + LibAmdMemRead (AccessWidth32, ApicAddr, &ApicRegister, StdHeader); + } + } while ((ApicRegister & CMD_REG_REMOTE_RD_STS_MSK) != CMD_REG_REMOTE_DELIVERY_DONE); + ApicAddr = ApicBase + APIC_REMOTE_READ_REG; + LibAmdMemRead (AccessWidth32, ApicAddr, &ApicRegister, StdHeader); + return (ApicRegister); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Writes an APIC register on the executing core. + * + * This function gets the base address of the executing core's local APIC, + * and writes a UINT32 value to a specified offset. + * + * @param[in] RegAddr APIC register to write to + * @param[in] Value Data to be written to the desired APIC register + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilLocalWrite ( + IN UINT32 RegAddr, + IN UINT32 Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 ApicAddr; + + ApUtilGetLocalApicBase (&ApicAddr, StdHeader); + ApicAddr += RegAddr; + + LibAmdMemWrite (AccessWidth32, ApicAddr, &Value, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Reads an APIC register on the executing core. + * + * This function gets the base address of the executing core's local APIC, + * and reads a UINT32 value from a specified offset. + * + * @param[in] RegAddr APIC register to read from + * @param[in] StdHeader Configuration parameters pointer + * + * @return The current value of the local APIC register + * + */ +UINT32 +STATIC +ApUtilLocalRead ( + IN UINT32 RegAddr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ApicRegister; + UINT64 ApicAddr; + + ApUtilGetLocalApicBase (&ApicAddr, StdHeader); + ApicAddr += RegAddr; + LibAmdMemRead (AccessWidth32, ApicAddr, &ApicRegister, StdHeader); + + return (ApicRegister); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the 64-bit base address of the executing core's local APIC. + * + * This function reads the APICBASE MSR and isolates the programmed address. + * + * @param[out] ApicBase Base address + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilGetLocalApicBase ( + OUT UINT64 *ApicBase, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LibAmdMsrRead (MSR_APIC_BAR, ApicBase, StdHeader); + *ApicBase &= LAPIC_BASE_ADDR_MASK; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the unique ID of the input Socket/Core. + * + * This routine converts a socket-core combination to to a number + * that will be used to directly address a particular core. This + * unique value must be less than 128 because we only have a byte + * to use for status. APIC IDs are not guaranteed to be below + * 128. + * + * @param[in] Socket Socket number of the remote core + * @param[in] Core Core number of the remote core + * @param[in] StdHeader Configuration parameters pointer + * + * @return The unique ID of the desired core + * + */ +UINT8 +STATIC +ApUtilCalculateUniqueId ( + IN UINT8 Socket, + IN UINT8 Core, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 UniqueId; + + UniqueId = ((Core << 3) | Socket); + ASSERT ((UniqueId & 0x80) == 0); + return (UniqueId); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Wakes up a core from the halted state. + * + * This function sends a directed NMI inter-processor interrupt to + * the input Socket/Core. + * + * @param[in] TargetApicId Local APIC ID of the desired core + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilFireDirectedNmi ( + IN UINT32 TargetApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + TargetApicId <<= LOCAL_APIC_ID; + + ApUtilLocalWrite ((UINT32) APIC_CMD_HI_REG, TargetApicId, StdHeader); + ApUtilLocalWrite ((UINT32) APIC_CMD_LO_REG, (UINT32) CMD_REG_TO_NMI, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Securely receives a pointer from the designated remote core. + * + * This function uses a sequence of remote reads to receive a pointer, + * one UINT32 at a time. + * + * @param[in] TargetApicId Local APIC ID of the desired core + * @param[out] ReturnPointer Pointer passed from remote core + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilReceivePointer ( + IN UINT32 TargetApicId, + OUT VOID **ReturnPointer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 WaitStatus; + UINT32 *AddressScratchPtr; + AP_WAIT_FOR_STATUS WaitForStatus; + + WaitStatus = CORE_STS_DATA_READY_0; + WaitForStatus.Status = &WaitStatus; + WaitForStatus.NumberOfElements = 1; + WaitForStatus.RetryCount = WAIT_INFINITELY; + AddressScratchPtr = (UINT32 *) ReturnPointer; + for (i = 0; i < SIZE_IN_DWORDS (AddressScratchPtr); ++i) { + ApUtilWriteControlByte (CORE_NEEDS_PTR, StdHeader); + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + *AddressScratchPtr++ = ApUtilReadRemoteDataDword (TargetApicId, StdHeader); + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); + WaitForStatus.WaitForStatusFlags = 0; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Securely transmits a pointer to the designated remote core. + * + * This function uses a sequence of remote reads to transmit a pointer, + * one UINT32 at a time. + * + * @param[in] TargetApicId Local APIC ID of the desired core + * @param[out] Pointer Pointer passed from remote core + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilTransmitPointer ( + IN UINT32 TargetApicId, + IN VOID **Pointer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 WaitStatus; + UINT32 *AddressScratchPtr; + AP_WAIT_FOR_STATUS WaitForStatus; + + WaitStatus = CORE_NEEDS_PTR; + WaitForStatus.Status = &WaitStatus; + WaitForStatus.NumberOfElements = 1; + WaitForStatus.RetryCount = WAIT_INFINITELY; + + AddressScratchPtr = (UINT32 *) Pointer; + + for (i = 0; i < SIZE_IN_DWORDS (AddressScratchPtr); i++) { + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + ApUtilWriteDataDword (*AddressScratchPtr++, StdHeader); + ApUtilWriteControlByte (CORE_STS_DATA_READY_0, StdHeader); + WaitForStatus.WaitForStatusFlags = 0; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.h new file mode 100644 index 0000000000..ee1a5647da --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuApicUtilities.h @@ -0,0 +1,303 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU APIC related utility functions and structures + * + * Contains code that provides mechanism to invoke and control APIC communication. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_APIC_UTILITIES_H_ +#define _CPU_APIC_UTILITIES_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ +#define APIC_CTRL_DWORD 0xF +#define APIC_CTRL_REG (APIC_CTRL_DWORD << 4) +#define APIC_CTRL_MASK 0xFF +#define APIC_CTRL_SHIFT 0 + +#define APIC_DATA_DWORD 0x38 +#define APIC_DATA_REG (APIC_DATA_DWORD << 4) + +#define APIC_REMOTE_READ_REG 0xC0 +#define APIC_CMD_LO_REG 0x300 +#define APIC_CMD_HI_REG 0x310 + +// APIC_CMD_LO_REG bits +#define CMD_REG_DELIVERY_STATUS 0x1000 +#define CMD_REG_TO_READ 0x300 +#define CMD_REG_REMOTE_RD_STS_MSK 0x30000ul +#define CMD_REG_REMOTE_DELIVERY_PENDING 0x10000ul +#define CMD_REG_REMOTE_DELIVERY_DONE 0x20000ul +#define CMD_REG_TO_NMI 0x400 + +// ExeFlags bits +#define WAIT_FOR_CORE 0x00000001ul +#define TASK_HAS_OUTPUT 0x00000002ul +#define RETURN_PARAMS 0x00000004ul +#define END_AT_HLT 0x00000008ul +#define PASS_EARLY_PARAMS 0x00000010ul + +// Control Byte Values +// bit 7 indicates the type of message +// 1 - control message +// 0 - launch + APIC ID = message to go +// +#define CORE_UNAVAILABLE 0xFF +#define CORE_IDLE 0xFE +#define CORE_IDLE_HLT 0xFD +#define CORE_ACTIVE 0xFC +#define CORE_NEEDS_PTR 0xFB +#define CORE_NEEDS_DATA_SIZE 0xFA +#define CORE_STS_DATA_READY_1 0xF9 +#define CORE_STS_DATA_READY_0 0xF8 +#define CORE_DATA_FLAGS_READY 0xF7 +#define CORE_DATA_FLAGS_ACKNOWLEDGE 0xF6 +#define CORE_DATA_PTR_READY 0xF5 + +// Macro used to determine the number of dwords to transmit to the AP as input +#define SIZE_IN_DWORDS(sInput) ((UINT32) (((sizeof (sInput)) + 3) >> 2)) + +// IDT table +#define IDT_DESC_PRESENT 0x80 + +#define IDT_DESC_TYPE_LDT 0x02 +#define IDT_DESC_TYPE_CALL16 0x04 +#define IDT_DESC_TYPE_TASK 0x05 +#define IDT_DESC_TYPE_INT16 0x06 +#define IDT_DESC_TYPE_TRAP16 0x07 +#define IDT_DESC_TYPE_CALL32 0x0C +#define IDT_DESC_TYPE_INT32 0x0E +#define IDT_DESC_TYPE_TRAP32 0x0F +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +typedef VOID (*PF_AP_TASK) (AMD_CONFIG_PARAMS *StdHeader); +typedef VOID (*PF_AP_TASK_I) (VOID *, AMD_CONFIG_PARAMS *StdHeader); +typedef VOID (*PF_AP_TASK_C) (AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *); +typedef VOID (*PF_AP_TASK_IC) (VOID *, AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *); +typedef UINT32 (*PF_AP_TASK_O) (AMD_CONFIG_PARAMS *StdHeader); +typedef UINT32 (*PF_AP_TASK_IO) (VOID *, AMD_CONFIG_PARAMS *StdHeader); +typedef UINT32 (*PF_AP_TASK_OC) (AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *); +typedef UINT32 (*PF_AP_TASK_IOC) (VOID *, AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *); + +/// Function pointer union representing the eight different +/// types of functions that an AP can be asked to perform. +typedef union { + PF_AP_TASK PfApTask; ///< AMD_CONFIG_PARAMS * input with no output + PF_AP_TASK_I PfApTaskI; ///< VOID * + AMD_CONFIG_PARAMS * input with no output + PF_AP_TASK_C PfApTaskC; ///< AMD_CONFIG_PARAMS * + AMD_CPU_EARLY_PARAMS * input with no output + PF_AP_TASK_IC PfApTaskIC; ///< VOID * + AMD_CONFIG_PARAMS * + AMD_CPU_EARLY_PARAMS * input with no output + PF_AP_TASK_O PfApTaskO; ///< AMD_CONFIG_PARAMS * input with UINT32 output + PF_AP_TASK_IO PfApTaskIO; ///< VOID * + AMD_CONFIG_PARAMS * input with UINT32 output + PF_AP_TASK_OC PfApTaskOC; ///< AMD_CONFIG_PARAMS * + AMD_CPU_EARLY_PARAMS * input with UINT32 output + PF_AP_TASK_IOC PfApTaskIOC; ///< VOID * + AMD_CONFIG_PARAMS * + AMD_CPU_EARLY_PARAMS * input with UINT32 output +} AP_FUNCTION_PTR; + +/// Input structure for ApUtilTransmitBuffer and ApUtilReceiveBuffer +/// containing information about the data transfer from one core +/// to another. +typedef struct { + IN OUT UINT16 DataSizeInDwords; ///< Size of the data to be transferred rounded up to the nearest dword + IN OUT VOID *DataPtr; ///< Pointer to the data + IN UINT32 DataTransferFlags; ///< Flags dictating certain aspects of the data transfer +} AP_DATA_TRANSFER; + +/// Input structure for ApUtilRunCodeOnSocketCore. +typedef struct _AP_TASK { + AP_FUNCTION_PTR FuncAddress; ///< Pointer to the function that the AP will run + AP_DATA_TRANSFER DataTransfer; ///< Data transfer struct for optionally passing data that the AP should use as input to the function + UINT32 ExeFlags; ///< Flags dictating certain aspects of the AP tasking sequence +} AP_TASK; + +/// Input structure for ApUtilWaitForCoreStatus. +typedef struct { + IN UINT8 *Status; ///< Pointer to the 1st element of an array of values to wait for + IN UINT8 NumberOfElements; ///< Number of elements in the array + IN UINT32 RetryCount; ///< Number of remote read cycles to complete before quitting + IN UINT32 WaitForStatusFlags; ///< Flags dictating certain aspects of ApUtilWaitForCoreStatus +} AP_WAIT_FOR_STATUS; + +/// Interrupt Descriptor Table entry +typedef struct { + UINT16 OffsetLo; ///< Lower 16 bits of the interrupt handler routine's offset + UINT16 Selector; ///< Interrupt handler routine's selector + UINT8 Rsvd; ///< Reserved + UINT8 Flags; ///< Interrupt flags + UINT16 OffsetHi; ///< Upper 16 bits of the interrupt handler routine's offset + UINT32 Offset64; ///< High order 32 bits of the handler's offset needed when in 64 bit mode + UINT32 Rsvd64; ///< Reserved +} IDT_DESCRIPTOR; + +/// Structure needed to load the IDTR using the lidt instruction +typedef struct { + UINT16 Limit; ///< Interrupt Descriptor Table size + UINT64 Base; ///< Interrupt Descriptor Table base address +} IDT_BASE_LIMIT; + +#define WAIT_STATUS_EQUALITY 0x00000001ul +#define WAIT_INFINITELY 0 + +// Data Transfer Flags +#define DATA_IN_MEMORY 0x00000001ul + + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +// These are P U B L I C functions, used by AGESA +UINT8 +ApUtilReadRemoteControlByte ( + IN UINT32 TargetApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +ApUtilWriteControlByte ( + IN UINT8 Value, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +ApUtilReadRemoteDataDword ( + IN UINT32 TargetApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +ApUtilWriteDataDword ( + IN UINT32 Value, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +ApUtilRunCodeOnSocketCore ( + IN UINT8 Socket, + IN UINT8 Core, + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +ApUtilWaitForCoreStatus ( + IN UINT32 TargetApicId, + IN AP_WAIT_FOR_STATUS *WaitParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +ApEntry ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ); + +UINT32 +ApUtilTaskOnExecutingCore ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ConfigParams + ); + +VOID +ApUtilTransmitBuffer ( + IN UINT8 Socket, + IN UINT8 Core, + IN AP_DATA_TRANSFER *BufferInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +ApUtilReceiveBuffer ( + IN UINT8 Socket, + IN UINT8 Core, + IN OUT AP_DATA_TRANSFER *BufferInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetLocalApicIdForCore ( + IN UINT32 TargetSocket, + IN UINT32 TargetCore, + OUT UINT32 *LocalApicId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +ApUtilRunCodeOnAllLocalCoresAtEarly ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ); + +VOID +RelinquishControlOfAllAPs ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetCsSelector ( + IN UINT16 *Selector, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SetIdtr ( + IN IDT_BASE_LIMIT *IdtInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetIdtr ( + IN IDT_BASE_LIMIT *IdtInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif /* _CPU_APIC_UTILITIES_H_ */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuBist.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuBist.c new file mode 100644 index 0000000000..14dcd054d1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuBist.c @@ -0,0 +1,171 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU BIST Status Check Implementation. + * + * Implement CPU BIST Status checking + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuApicUtilities.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) +#define FILECODE PROC_CPU_CPUBIST_FILECODE + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +UINT32 +STATIC +GetBistResults ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + + /*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + /*---------------------------------------------------------------------------------------*/ + /** + * + * This function checks the status of BIST and places the error status in the event log + * if there are any errors + * + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS No BIST errors have been logged. + * @retval AGESA_ALERT BIST errors have been detected and added to the + * event log. + */ +AGESA_STATUS +CheckBistStatus ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Core; + UINT32 BscSocket; + UINT32 BscCoreNum; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + UINT32 Ignored; + UINT32 ReturnCode; + AGESA_STATUS IgnoredSts; + AGESA_STATUS AgesaStatus; + AP_TASK TaskPtr; + + // Make sure that Standard Header is valid + ASSERT (StdHeader != NULL); + ASSERT (IsBsp (StdHeader, &IgnoredSts)); + + AgesaStatus = AGESA_SUCCESS; + + // Get the BscSocket, BscCoreNum and NumberOfSockets in the system + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + // Setup TaskPtr struct to execute routine on APs + TaskPtr.FuncAddress.PfApTaskO = GetBistResults; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = TASK_HAS_OUTPUT | WAIT_FOR_CORE; + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCoreNum)) { + ReturnCode = ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8)Core, &TaskPtr, StdHeader); + } else { + ReturnCode = TaskPtr.FuncAddress.PfApTaskO (StdHeader); + } + + // If BIST value is non-zero, add to BSP's event log + if (ReturnCode != 0) { + IDS_HDT_CONSOLE (CPU_TRACE, " BIST failure: socket %d core %d, status = 0x%x\n", Socket, Core, ReturnCode); + AgesaStatus = AGESA_ALERT; + PutEventLog (AGESA_ALERT, + CPU_EVENT_BIST_ERROR, + ReturnCode, Socket, Core, 0, StdHeader); + } + } + } + } + + return AgesaStatus; +} + +/*---------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- +*/ + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Reads the lower 32 bits of the BIST register + * + * @param[in] StdHeader Header for library and services + * + * @retval Value of the BIST register +*/ +UINT32 +STATIC +GetBistResults ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 BistResults; + + // Read MSRC001_0060 BIST Results Register + LibAmdMsrRead (MSR_BIST, &BistResults, StdHeader); + + return (UINT32) (BistResults & 0xFFFFFFFF); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.c new file mode 100644 index 0000000000..832fa7ea03 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.c @@ -0,0 +1,469 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Reset API, and related functions. + * + * Contains code that initialized the CPU after early reset. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "Table.h" +#include "cpuApicUtilities.h" +#include "cpuEarlyInit.h" +#include "Topology.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_CPUEARLYINIT_FILECODE + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +GetPerformEarlyFlag ( + IN OUT UINT32 *PerformEarlyFlag, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PerformEarlyInitTable ( + IN S_PERFORM_EARLY_INIT_ON_CORE *EarlyInitTable, + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +McaInitializationAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +EarlyTableAfterApLaunch ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/*------------------------------------------------------------------------------------*/ +/** + * Initializer routine that will be invoked by AmdCpuEarly to initialize the input + * structure for the Cpu Init @ Early routine. + * + * @param[in] StdHeader Opaque handle to standard config header + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in,out] CpuEarlyParamsPtr Service Interface structure to initialize. + * + * @retval AGESA_SUCCESS Always Succeeds + */ +VOID +AmdCpuEarlyInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ) +{ + ASSERT (CpuEarlyParamsPtr != NULL); + + CpuEarlyParamsPtr->MemInitPState = (UINT8) UserOptions.CfgMemInitPstate; + CpuEarlyParamsPtr->PlatformConfig = *PlatformConfig; +} +/*---------------------------------------------------------------------------------------*/ +/** + * Performs CPU related initialization at the early entry point + * + * This function performs a large list of initialization items. These items + * include: + * + * -1 local APIC initialization + * -2 MSR table initialization + * -3 PCI table initialization + * -4 HT Phy PCI table initialization + * -5 microcode patch loading + * -6 namestring determination/programming + * -7 AP initialization + * -8 power management initialization + * -9 core leveling + * + * This routine must be run by all cores in the system. Please note that + * all APs that enter will never exit. + * + * @param[in] StdHeader Config handle for library and services + * @param[in] PlatformConfig Config handle for platform specific information + * + * @retval AGESA_SUCCESS + * + */ +AGESA_STATUS +AmdCpuEarly ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig + ) +{ + UINT8 WaitStatus; + UINT8 i; + UINT8 StartCore; + UINT8 EndCore; + UINT32 NodeNum; + UINT32 PrimaryCore; + UINT32 SocketNum; + UINT32 ModuleNum; + UINT32 HighCore; + UINT32 ApHeapIndex; + UINT32 TargetApicId; + AP_WAIT_FOR_STATUS WaitForStatus; + AGESA_STATUS Status; + AGESA_STATUS CalledStatus; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + S_PERFORM_EARLY_INIT_ON_CORE *EarlyTableOnCore; + AP_TASK TaskPtr; + + Status = AGESA_SUCCESS; + CalledStatus = AGESA_SUCCESS; + + AmdCpuEarlyInitializer (StdHeader, PlatformConfig, &CpuEarlyParams); + + IDS_OPTION_HOOK (IDS_CPU_Early_Override, &CpuEarlyParams, StdHeader); + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + EarlyTableOnCore = NULL; + FamilySpecificServices->GetEarlyInitBeforeApLaunchOnCoreTable (FamilySpecificServices, (CONST S_PERFORM_EARLY_INIT_ON_CORE **)&EarlyTableOnCore, &CpuEarlyParams, StdHeader); + + PerformEarlyInitTable (EarlyTableOnCore, FamilySpecificServices, &CpuEarlyParams, StdHeader); + + IDS_OPTION_HOOK (IDS_AFTER_EARLY_INIT_ONCORE, &CpuEarlyParams, StdHeader); + + // B S P C O D E T O I N I T I A L I Z E A Ps + // ------------------------------------------------------- + // ------------------------------------------------------- + // IMPORTANT: Here we determine if we are BSP or AP + if (IsBsp (StdHeader, &CalledStatus)) { + // Clear BSP's Status Byte + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); + + NodeNum = 0; + ApHeapIndex = 1; + while (NodeNum < MAX_NODES && + GetSocketModuleOfNode (NodeNum, &SocketNum, &ModuleNum, StdHeader)) { + GetCpuServicesOfSocket (SocketNum, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + GetGivenModuleCoreRange (SocketNum, ModuleNum, &PrimaryCore, &HighCore, StdHeader); + if (NodeNum == 0) { + StartCore = (UINT8) PrimaryCore + 1; + } else { + StartCore = (UINT8) PrimaryCore; + } + + EndCore = (UINT8) HighCore; + for (i = StartCore; i <= EndCore; i++) { + FamilySpecificServices->SetApCoreNumber (FamilySpecificServices, SocketNum, ModuleNum, ApHeapIndex, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " Launch socket %d core %d\n", SocketNum, i); + if (FamilySpecificServices->LaunchApCore (FamilySpecificServices, SocketNum, ModuleNum, i, PrimaryCore, StdHeader)) { + IDS_HDT_CONSOLE (CPU_TRACE, " Waiting for socket %d core %d\n", SocketNum, i); + GetLocalApicIdForCore (SocketNum, i, &TargetApicId, StdHeader); + WaitStatus = CORE_IDLE; + WaitForStatus.Status = &WaitStatus; + WaitForStatus.NumberOfElements = 1; + WaitForStatus.RetryCount = WAIT_INFINITELY; + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + ApUtilWaitForCoreStatus (TargetApicId, &WaitForStatus, StdHeader); + ApHeapIndex++; + } + } + NodeNum++; + } + + // B S P P h a s e - 1 E N D + // + // Launch all APs to implment early init table (after AP launch) in parallel + // + TaskPtr.FuncAddress.PfApTaskC = EarlyTableAfterApLaunch; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, &CpuEarlyParams); + + IDS_OPTION_HOOK (IDS_BEFORE_PM_INIT, &CpuEarlyParams, StdHeader); + + AGESA_TESTPOINT (TpProcCpuBeforePMFeatureInit, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features before early power mgmt init\n"); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_BEFORE_PM_INIT, PlatformConfig, StdHeader); + if (CalledStatus > Status) { + Status = CalledStatus; + } + + AGESA_TESTPOINT (TpProcCpuPowerMgmtInit, StdHeader); + CalledStatus = PmInitializationAtEarly (&CpuEarlyParams, StdHeader); + if (CalledStatus > Status) { + Status = CalledStatus; + } + + AGESA_TESTPOINT (TpProcCpuEarlyFeatureInit, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features after early power mgmt init\n"); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_AFTER_PM_INIT, PlatformConfig, StdHeader); + + IDS_OPTION_HOOK (IDS_BEFORE_AP_EARLY_HALT, &CpuEarlyParams, StdHeader); + + // Sleep all APs + IDS_HDT_CONSOLE (CPU_TRACE, " Halting all APs\n"); + ApUtilWriteControlByte (CORE_IDLE_HLT, StdHeader); + } else { + ApEntry (StdHeader, &CpuEarlyParams); + } + + if (CalledStatus > Status) { + Status = CalledStatus; + } + + return (Status); +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * Perform early init table + * + * @param[in] EarlyInitTable Early init table. + * @param[in] FamilyServices The current Family Specific Services. + * @param[in] CpuEarlyParams Service Interface structure to initialize. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +PerformEarlyInitTable ( + IN S_PERFORM_EARLY_INIT_ON_CORE *EarlyInitTable, + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT32 CurrentPerformEarlyFlag; + + if (EarlyInitTable != NULL) { + GetPerformEarlyFlag (&CurrentPerformEarlyFlag, StdHeader); + for (i = 0; EarlyInitTable[i].PerformEarlyInitOnCore != NULL; i++) { + if ((EarlyInitTable[i].PerformEarlyInitFlag & CurrentPerformEarlyFlag) != 0) { + IDS_HDT_CONSOLE (CPU_TRACE, " Perform core init step %d\n", i); + EarlyInitTable[i].PerformEarlyInitOnCore (FamilyServices, CpuEarlyParams, StdHeader); + } + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Initialize Machine Check Architecture registers + * + * This function initializes the MCA MSRs. On cold reset, these registers + * have an invalid data that must be cleared on all cores. + * + * @param[in] StdHeader Config handle for library and services + * + *--------------------------------------------------------------------------------------- + */ +VOID +McaInitialization ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 TempVar16_a; + UINT32 MsrAddress; + UINT64 MsrData; + CPUID_DATA CpuIdDataStruct; + + if (!(IsWarmReset (StdHeader))) { + // Run CPUID to verify that the processor supports MCE and MCA + // i.e. edx[7], and edx[14] + // CPUID_MODEL = 1 + LibAmdCpuidRead (1, &CpuIdDataStruct, StdHeader); + if ((CpuIdDataStruct.EDX_Reg & 0x4080) != 0) { + // Check to see if the MCG_CTL_P bit is set + // MCG = Global Machine Check Exception Reporting Control Register + LibAmdMsrRead (MSR_MCG_CAP, &MsrData, StdHeader); + if ((MsrData & MCG_CTL_P) != 0) { + TempVar16_a = (UINT16) ((MsrData & 0x000000FF) << 2); + TempVar16_a += MSR_MC0_CTL; + + // Initialize the data + MsrData = 0; + for (MsrAddress = MSR_MC0_CTL; MsrAddress < TempVar16_a; MsrAddress++) { + LibAmdMsrWrite (MsrAddress, &MsrData, StdHeader); + } + } + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform early init table after AP launch + * + * @param[in] StdHeader Config handle for library and services. + * @param[in] CpuEarlyParams Service Interface structure to initialize. + * + */ +VOID +EarlyTableAfterApLaunch ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + S_PERFORM_EARLY_INIT_ON_CORE *EarlyTableOnCore; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + EarlyTableOnCore = NULL; + FamilySpecificServices->GetEarlyInitAfterApLaunchOnCoreTable (FamilySpecificServices, (CONST S_PERFORM_EARLY_INIT_ON_CORE **)&EarlyTableOnCore, CpuEarlyParams, StdHeader); + PerformEarlyInitTable (EarlyTableOnCore, FamilySpecificServices, CpuEarlyParams, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Initialize Machine Check Architecture registers + * + * This function acts as a wrapper for calling the McaInitialization + * routine at AmdInitEarly. + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[in] EarlyParams Service parameters. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +McaInitializationAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + McaInitialization (StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Runs the given task on all cores (including self) on the socket of the executing + * core 0. + * + * This function is used to invoke all APs on the socket of the executing core 0 to + * run a specified AGESA procedure. + * + * @param[in] TaskPtr Function descriptor + * @param[in] StdHeader Config handle for library and services + * @param[in] CpuEarlyParamsPtr Required input parameters for early CPU initialization + * + */ +VOID +ApUtilRunCodeOnAllLocalCoresAtEarly ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ) +{ + UINT32 Core; + UINT32 Socket; + UINT32 IgnoredModule; + UINT32 IgnoredCore; + UINT32 ActiveCores; + AGESA_STATUS IgnoredSts; + + IdentifyCore (StdHeader, &Socket, &IgnoredModule, &IgnoredCore, &IgnoredSts); + GetActiveCoresInCurrentSocket (&ActiveCores, StdHeader); + + for (Core = 1; Core < (UINT8) ActiveCores; ++Core) { + ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8)Core, TaskPtr, StdHeader); + } + ApUtilTaskOnExecutingCore (TaskPtr, StdHeader, (VOID *) CpuEarlyParamsPtr); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get current condition, such as warm/cold reset, to determine if related function + * need to be performed at early stage + * + * @param[in, out] PerformEarlyFlag Perform early flag. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +GetPerformEarlyFlag ( + IN OUT UINT32 *PerformEarlyFlag, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *PerformEarlyFlag = 0; + if (IsWarmReset (StdHeader)) { + *PerformEarlyFlag |= PERFORM_EARLY_WARM_RESET; + } else { + *PerformEarlyFlag |= PERFORM_EARLY_COLD_BOOT; + } + return; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.h new file mode 100644 index 0000000000..ddbb571e3b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEarlyInit.h @@ -0,0 +1,290 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Reset API, and related functions and structures. + * + * Contains code that initialized the CPU after early reset. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_EARLY_INIT_H_ +#define _CPU_EARLY_INIT_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ +AGESA_FORWARD_DECLARATION (CPU_CORE_LEVELING_FAMILY_SERVICES); + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ +//---------------------------------------------------------------------------- +// CPU BRAND ID TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +#define CPU_BRAND_ID_LENGTH 48 // Total number of characters supported +#define LOW_NODE_DEVICEID 24 +#define NB_CAPABILITIES 0xE8 //Function 3 Registers +//---------------------------------------------------------------------------- +// CPU MICROCODE PATCH TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/* All lengths are in bytes */ +#define MICROCODE_TRIADE_SIZE 28 +#define MICROCODE_HEADER_LENGTH 64 + +/** + * @page ucodeflag Microcode Patches Signature Guide + * + * We mark patches in the ROM with a signature so that they can be easily found + * + * @anchor Microcode Patch Signature + * @li @e Microcode Patch Signature @n + * Microcode patches are marked by adding a signature before patches in the ROM image to + * help identify where they are located. + * There're two kind of signatures. One is '$UCODE2K', it indicates there's a following patch with 2K size. + * The other is '$UCODE4K', it indicates there's a following patch with 4K size. + * If you want to know the patch level / equivalent ID, please consult the BKDG for patch header format. + * + * + */ +/// Microcode patch flag for replacement +typedef struct { + IN UINT8 MicrocodePatchesFlag[8]; ///< a flag followed by microcode +} MICROCODE_PATCHES_FLAG; + +#define UCODE_2K_FLAG(x) STATIC CONST MICROCODE_PATCHES_FLAG ROMDATA UcodeFlag##x = {{'$', 'U', 'C', 'O', 'D', 'E', '2', 'K'}}; +#define UCODE_4K_FLAG(x) STATIC CONST MICROCODE_PATCHES_FLAG ROMDATA UcodeFlag##x = {{'$', 'U', 'C', 'O', 'D', 'E', '4', 'K'}}; +#define UCODE_VS_FLAG(x) STATIC CONST MICROCODE_PATCHES_FLAG ROMDATA UcodeFlag##x = {{'$', 'U', 'C', 'O', 'D', 'E', 'V', 'S'}}; + +/* Offsets in UCODE PATCH Header */ +/* Note: Header is 64 bytes */ +#define DATE_CODE_OFFSET 0 // 4 bytes +#define PATCH_ID 4 // 4 bytes +#define MICROCODE_PATH_DATA_ID 8 // 2 bytes +#define MICROCODE_PATCH_DATA_LENGTH 10 // 1 byte +#define MICROCODE_PATCH_DATA_CHECKSUM 12 // 4 bytes +#define CHIPSET_1_DEVICE_ID 16 // 4 bytes +#define CHIPSET_2_DEVICE_ID 20 // 4 bytes +#define PROCESSOR_REV_ID 24 // 2 bytes +#define CHIPSET_1_REV_ID 26 // 1 byte +#define CHIPSET_2_REV_ID 27 // 1 byte + +#define MICROCODE_PATCH_2K_SIZE 2048 +#define MICROCODE_PATCH_4K_SIZE 4096 +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +//---------------------------------------------------------------------------- +// CPU BRAND ID TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/// A structure representing BrandId[15:0] from +/// CPUID Fn8000_0001_EBX +typedef struct { + UINT8 String1:4; ///< An index to a string value used to create the name string + UINT8 String2:4; ///< An index to a string value used to create the name string + UINT8 Page:1; ///< An index to the appropriate page for the String1, String2, and Model values + UINT8 Model:7; ///< A field used to create the model number in the name string + UINT8 Socket:4; ///< Specifies the package type + UINT8 Cores:4; ///< Identifies how many physical cores are present +} AMD_CPU_BRAND_DATA; + +/// A structure containing string1 and string2 values +/// as well as information pertaining to their usage +typedef struct { + IN UINT8 Cores; ///< Appropriate number of physical cores + IN UINT8 Page; ///< This string's page number + IN UINT8 Index; ///< String index + IN UINT8 Socket; ///< Package type information + IN CONST CHAR8 *Stringstart; ///< The literal string + IN UINT8 Stringlength; ///< Number of characters in the string +} AMD_CPU_BRAND; + +/// An entire CPU brand table. +typedef struct { + UINT8 NumberOfEntries; ///< The number of entries in the table. + CONST AMD_CPU_BRAND *Table; ///< The table entries. +} CPU_BRAND_TABLE; + +//---------------------------------------------------------------------------- +// CPU MICROCODE PATCH TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/// Microcode patch field definitions +typedef struct { + UINT32 DateCode; ///< Date of patch creation + UINT32 PatchID; ///< Patch level + UINT16 dummy0; + UINT8 dummy1; + UINT8 dummy2; + UINT32 MicrocodePatchDataChecksum; ///< Doubleword sum of data block + UINT32 Chipset1DeviceID; ///< Device ID of 1st HT device to match + UINT32 Chipset2DeviceID; ///< Device ID of 2nd HT device to match + UINT16 ProcessorRevisionID; ///< Equivalent ID + UINT8 Chipset1RevisionID; ///< Revision level of 1st HT device to match + UINT8 Chipset2RevisionID; ///< Revision level of 2nd HT device to match + UINT8 BiosApiRevision; ///< BIOS INT 15 API revision required + UINT8 Reserved1[3]; ///< Reserved + UINT32 dummy3; + UINT32 dummy4; + UINT32 dummy5; + UINT32 dummy6; + UINT32 dummy7; + UINT32 dummy8; + UINT32 dummy9; + UINT32 dummy10; + UINT8 PatchDataBlock[896]; ///< Raw patch data + UINT8 Reserved2[896]; ///< Reserved + UINT8 X86CodePresent; ///< Boolean to determine if executable code exists + UINT8 X86CodeEntry[191]; ///< Code to execute if X86CodePresent != 0 +} MICROCODE_PATCH; + +/// Two kilobyte array containing the raw +/// microcode patch binary data +typedef struct { + IN UINT8 MicrocodePatches[MICROCODE_PATCH_2K_SIZE]; ///< 2k UINT8 elements +} MICROCODE_PATCHES; + +/// Four kilobyte array containing the raw +/// microcode patch binary data +typedef struct { + IN UINT8 MicrocodePatches[MICROCODE_PATCH_4K_SIZE]; ///< 4k UINT8 elements +} MICROCODE_PATCHES_4K; + +/** + * Set down core register + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] Socket Socket ID. + * @param[in] Module Module ID in socket. + * @param[in] LeveledCores Number of core. + * @param[in] CoreLevelMode Core level mode. + * @param[in] StdHeader Header for library and services. + * + * @retval TRUE Down Core register is updated. + * @retval FALSE Down Core register is not updated. + */ +typedef BOOLEAN (F_CPU_SET_DOWN_CORE_REGISTER) ( + IN CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices, + IN UINT32 *Socket, + IN UINT32 *Module, + IN UINT32 *LeveledCores, + IN CORE_LEVELING_TYPE CoreLevelMode, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CPU_SET_DOWN_CORE_REGISTER *PF_CPU_SET_DOWN_CORE_REGISTER; + +/** + * Provide the interface to the Core Leveling Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _CPU_CORE_LEVELING_FAMILY_SERVICES { // See Forward Declaration above + UINT16 Revision; ///< Interface version + // Public Methods. + PF_CPU_SET_DOWN_CORE_REGISTER SetDownCoreRegister; ///< Method: Set down core register. +}; + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +// These are P U B L I C functions, used by IBVs +AGESA_STATUS +AmdCpuEarly ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig + ); + +// These are P U B L I C functions, used by AGESA +AGESA_STATUS +PmInitializationAtEarly ( + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +LoadMicrocodePatch ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetPatchEquivalentId ( + IN OUT UINT16 *ProcessorEquivalentId, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +ValidateMicrocode ( + IN MICROCODE_PATCH *MicrocodePatchPtr, + IN UINT16 ProcessorEquivalentId, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetMicrocodeVersion ( + OUT UINT32 *pMicrocodeVersion, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +AmdCpuEarlyInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ); + +VOID +McaInitialization ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_EARLY_INIT_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEnvInit.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEnvInit.h new file mode 100644 index 0000000000..9b7b234cf2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEnvInit.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Env Init API functions Prototypes. + * + * Contains code for doing any Env CPU initialization + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_ENV_INIT_H_ +#define _CPU_ENV_INIT_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ +// HobTransfer +AGESA_STATUS +CopyHeapToMainRamAtPost ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_ENV_INIT_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEventLog.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEventLog.c new file mode 100644 index 0000000000..4b6a9f9fb9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuEventLog.c @@ -0,0 +1,396 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Event (Error) Log APIs, and related functions. + * + * Contains code that records and returns the events and errors. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "heapManager.h" +#include "GeneralServices.h" +#include "Ids.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_CPUEVENTLOG_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +#define TOTAL_EVENT_LOG_BUFFERS 16 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/** + * A wrapper for each Event Log entry. + */ +typedef struct { + UINT16 Count; ///< Entry number + AGESA_EVENT AgesaEvent; ///< The entry itself. +} AGESA_EVENT_STRUCT; + +/** + * The Event Log. + */ +typedef struct { + UINT16 ReadWriteFlag; ///< Read Write flag. + UINT16 Count; ///< The total number of active entries. + UINT16 ReadRecordPtr; ///< The next entry to read. + UINT16 WriteRecordPtr; ///< The next entry to write. + AGESA_EVENT_STRUCT AgesaEventStruct[TOTAL_EVENT_LOG_BUFFERS]; ///< The entries. +} AGESA_STRUCT_BUFFER; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +GetEventLogHeapPointer ( + OUT AGESA_STRUCT_BUFFER **EventLog, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * External AGESA interface to read an Event from the Event Log. + * + * This is the implementation of the external AGESA interface entry, as a thin wrapper + * around the internal log services. + * + * @param[in] Event The event class, id, and any associated data. + * + * @retval AGESA_SUCCESS Always Succeeds. + */ +AGESA_STATUS +AmdReadEventLog ( + IN EVENT_PARAMS *Event + ) +{ + AGESA_EVENT LogEvent; + AGESA_STATUS Status; + + AGESA_TESTPOINT (TpIfAmdReadEventLogEntry, &Event->StdHeader); + + ASSERT (Event != NULL); + Event->StdHeader.HeapBasePtr = HeapGetBaseAddress (&Event->StdHeader); + Status = GetEventLog (&LogEvent, &Event->StdHeader); + + Event->EventClass = LogEvent.EventClass; + Event->EventInfo = LogEvent.EventInfo; + Event->DataParam1 = LogEvent.DataParam1; + Event->DataParam2 = LogEvent.DataParam2; + Event->DataParam3 = LogEvent.DataParam3; + Event->DataParam4 = LogEvent.DataParam4; + + AGESA_TESTPOINT (TpIfAmdReadEventLogExit, &Event->StdHeader); + return Status; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function prepares the Event Log for use. + * + * Allocate the memory for an event log on the heap. Set the read pointer, write pointer, + * and count to reflect the log is empty. + * + * @param[in] StdHeader Our configuration, for passing to services. + * + * @retval AGESA_SUCCESS The event log is initialized. + * @retval AGESA_ERROR Allocate Heap Buffer returned an error. + * + */ +AGESA_STATUS +EventLogInitialization ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + ALLOCATE_HEAP_PARAMS AllocateHeapParams; + AGESA_STRUCT_BUFFER *AgesaEventAlloc; + AGESA_STATUS Status; + + AllocateHeapParams.BufferHandle = EVENT_LOG_BUFFER_HANDLE; + AllocateHeapParams.RequestedBufferSize = sizeof (AGESA_STRUCT_BUFFER); + AllocateHeapParams.Persist = HEAP_SYSTEM_MEM; + Status = HeapAllocateBuffer (&AllocateHeapParams, StdHeader); + AgesaEventAlloc = (AGESA_STRUCT_BUFFER *) AllocateHeapParams.BufferPtr; + AgesaEventAlloc->Count = 0; + AgesaEventAlloc->ReadRecordPtr = 0; + AgesaEventAlloc->WriteRecordPtr = 0; + AgesaEventAlloc->ReadWriteFlag = 1; + + return Status; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function logs AGESA events into the event log. + * + * It will put the information in a circular buffer consisting of 16 such log + * entries. If the buffer gets full, then the next event log entry will be written + * over the oldest event log entry. + * + * @param[in] EventClass The severity of the event, its associated AGESA_STATUS. + * @param[in] EventInfo Uniquely identifies the event. + * @param[in] DataParam1 Event specific additional data + * @param[in] DataParam2 Event specific additional data + * @param[in] DataParam3 Event specific additional data + * @param[in] DataParam4 Event specific additional data + * @param[in] StdHeader Header for library and services + * + */ +VOID +PutEventLog ( + IN AGESA_STATUS EventClass, + IN UINT32 EventInfo, + IN UINT32 DataParam1, + IN UINT32 DataParam2, + IN UINT32 DataParam3, + IN UINT32 DataParam4, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 Index; + AGESA_STRUCT_BUFFER *AgesaEventAlloc; + + IDS_HDT_CONSOLE (MAIN_FLOW, "\n * %s Event: %08x Data: %x, %x, %x, %x\n\n", + (EventClass == AGESA_FATAL) ? "FATAL" : + (EventClass == AGESA_CRITICAL) ? "CRITICAL" : + (EventClass == AGESA_ERROR) ? "ERROR" : + (EventClass == AGESA_WARNING) ? "WARNING" : + (EventClass == AGESA_ALERT) ? "ALERT" : + (EventClass == AGESA_BOUNDS_CHK) ? "BOUNDS_CHK" : + (EventClass == AGESA_UNSUPPORTED) ? "UNSUPPORTED" : + "SUCCESS", EventInfo, DataParam1, DataParam2, DataParam3, DataParam4); + + AgesaEventAlloc = NULL; + GetEventLogHeapPointer (&AgesaEventAlloc, StdHeader); + ASSERT (AgesaEventAlloc != NULL); + Index = AgesaEventAlloc->WriteRecordPtr; + + // Add the new event log data into a circular buffer + AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.EventClass = EventClass; + AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.EventInfo = EventInfo; + AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.DataParam1 = DataParam1; + AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.DataParam2 = DataParam2; + AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.DataParam3 = DataParam3; + AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.DataParam4 = DataParam4; + + if ((AgesaEventAlloc->WriteRecordPtr == AgesaEventAlloc->ReadRecordPtr) && + (AgesaEventAlloc->ReadWriteFlag == 0)) { + AgesaEventAlloc->WriteRecordPtr += 1; + AgesaEventAlloc->ReadRecordPtr += 1; + if (AgesaEventAlloc->WriteRecordPtr == TOTAL_EVENT_LOG_BUFFERS) { + AgesaEventAlloc->WriteRecordPtr = 0; + AgesaEventAlloc->ReadRecordPtr = 0; + } + } else { + AgesaEventAlloc->WriteRecordPtr += 1; + if (AgesaEventAlloc->WriteRecordPtr == TOTAL_EVENT_LOG_BUFFERS) { + AgesaEventAlloc->WriteRecordPtr = 0; + } + AgesaEventAlloc->ReadWriteFlag = 0; + } + AgesaEventAlloc->Count = AgesaEventAlloc->Count + 1; + + if (AgesaEventAlloc->Count <= TOTAL_EVENT_LOG_BUFFERS) { + AgesaEventAlloc->AgesaEventStruct[Index].Count = Index; + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function gets event logs from the circular buffer. + * + * It will read the oldest entry from the circular buffer and place that information to the structure + * pointed to by the parameter. The read pointers will be incremented to remove the entry from buffer + * so that a subsequent call will return the next entry from the buffer. If the buffer is empty the + * returned log event will have EventInfo zero, which is not a valid event id. + * + * @param[out] EventRecord The next log event. + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +GetEventLog ( + OUT AGESA_EVENT *EventRecord, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 Index; + AGESA_STRUCT_BUFFER *AgesaEventAlloc; + + AgesaEventAlloc = NULL; + + GetEventLogHeapPointer (&AgesaEventAlloc, StdHeader); + ASSERT (AgesaEventAlloc != NULL); + + if ((AgesaEventAlloc->ReadRecordPtr == AgesaEventAlloc->WriteRecordPtr) && + (AgesaEventAlloc->ReadWriteFlag == 1)) { + // EventInfo == zero, means no more data. + LibAmdMemFill (EventRecord, 0, sizeof (AGESA_EVENT), StdHeader); + } else { + Index = AgesaEventAlloc->ReadRecordPtr; + EventRecord->EventClass = AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.EventClass; + EventRecord->EventInfo = AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.EventInfo; + EventRecord->DataParam1 = AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.DataParam1; + EventRecord->DataParam2 = AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.DataParam2; + EventRecord->DataParam3 = AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.DataParam3; + EventRecord->DataParam4 = AgesaEventAlloc->AgesaEventStruct[Index].AgesaEvent.DataParam4; + if (AgesaEventAlloc->ReadRecordPtr == (TOTAL_EVENT_LOG_BUFFERS - 1)) { + AgesaEventAlloc->ReadRecordPtr = 0; + } else { + AgesaEventAlloc->ReadRecordPtr = AgesaEventAlloc->ReadRecordPtr + 1; + } + if (AgesaEventAlloc->ReadRecordPtr == AgesaEventAlloc->WriteRecordPtr) { + AgesaEventAlloc->ReadWriteFlag = 1; + } + } + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function gets event logs from the circular buffer without flushing the entry. + * + * It will read the desired entry from the circular buffer and place that information to the structure + * pointed to by the parameter. The read pointers will not be incremented to remove the entry from the + * buffer. If the buffer is empty, or the desired entry does not exist, FALSE will be returned. + * + * @param[out] EventRecord The next log event. + * @param[in] Index Zero-based unread entry index + * @param[in] StdHeader Header for library and services + * + * @retval TRUE Entry exists + * @retval FALSE Entry does not exist + * + */ +BOOLEAN +PeekEventLog ( + OUT AGESA_EVENT *EventRecord, + IN UINT16 Index, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 ActualIndex; + UINT16 UnreadEntries; + AGESA_STRUCT_BUFFER *AgesaEventAlloc; + + AgesaEventAlloc = NULL; + + GetEventLogHeapPointer (&AgesaEventAlloc, StdHeader); + ASSERT (AgesaEventAlloc != NULL); + + if ((AgesaEventAlloc->ReadRecordPtr == AgesaEventAlloc->WriteRecordPtr) && + (AgesaEventAlloc->ReadWriteFlag == 1)) { + // EventInfo == zero, means no more data. + return FALSE; + } + if (AgesaEventAlloc->ReadRecordPtr < AgesaEventAlloc->WriteRecordPtr) { + UnreadEntries = AgesaEventAlloc->WriteRecordPtr - AgesaEventAlloc->ReadRecordPtr; + } else { + UnreadEntries = TOTAL_EVENT_LOG_BUFFERS - (AgesaEventAlloc->ReadRecordPtr - AgesaEventAlloc->WriteRecordPtr); + } + if (Index >= UnreadEntries) { + return FALSE; + } + ActualIndex = Index + AgesaEventAlloc->ReadRecordPtr; + if (ActualIndex >= TOTAL_EVENT_LOG_BUFFERS) { + ActualIndex -= TOTAL_EVENT_LOG_BUFFERS; + } + + EventRecord->EventClass = AgesaEventAlloc->AgesaEventStruct[ActualIndex].AgesaEvent.EventClass; + EventRecord->EventInfo = AgesaEventAlloc->AgesaEventStruct[ActualIndex].AgesaEvent.EventInfo; + EventRecord->DataParam1 = AgesaEventAlloc->AgesaEventStruct[ActualIndex].AgesaEvent.DataParam1; + EventRecord->DataParam2 = AgesaEventAlloc->AgesaEventStruct[ActualIndex].AgesaEvent.DataParam2; + EventRecord->DataParam3 = AgesaEventAlloc->AgesaEventStruct[ActualIndex].AgesaEvent.DataParam3; + EventRecord->DataParam4 = AgesaEventAlloc->AgesaEventStruct[ActualIndex].AgesaEvent.DataParam4; + + return TRUE; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This function gets the Event Log pointer. + * + * It will locate the Event Log on the heap using the heap locate service. If the Event + * Log is not located, NULL is returned. + * + * @param[out] EventLog Pointer to the Event Log, or NULL. + * @param[in] StdHeader Our Configuration, for passing to services. + * + */ +VOID +STATIC +GetEventLogHeapPointer ( + OUT AGESA_STRUCT_BUFFER **EventLog, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LOCATE_HEAP_PTR LocateHeapStruct; + + LocateHeapStruct.BufferHandle = EVENT_LOG_BUFFER_HANDLE; + LocateHeapStruct.BufferPtr = NULL; + if ((HeapLocateBuffer (&LocateHeapStruct, StdHeader)) == AGESA_SUCCESS) { + *EventLog = (AGESA_STRUCT_BUFFER *)LocateHeapStruct.BufferPtr; + } else { + *EventLog = NULL; + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuFamilyTranslation.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuFamilyTranslation.c new file mode 100644 index 0000000000..54eceec084 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuFamilyTranslation.c @@ -0,0 +1,485 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Family Translation functions. + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Interface + * @e \$Revision: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "CommonReturns.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_CPUFAMILYTRANSLATION_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +CONST CPU_SPECIFIC_SERVICES ROMDATA cpuNullServices = +{ + 0, + (PF_CPU_DISABLE_PSTATE) CommonReturnAgesaSuccess, + (PF_CPU_TRANSITION_PSTATE) CommonReturnAgesaSuccess, + (PF_CPU_GET_IDD_MAX) CommonReturnFalse, + (PF_CPU_GET_TSC_RATE) CommonReturnAgesaSuccess, + (PF_CPU_GET_NB_FREQ) CommonReturnAgesaSuccess, + (PF_CPU_GET_MIN_MAX_NB_FREQ) CommonReturnAgesaSuccess, + (PF_CPU_GET_NB_PSTATE_INFO) CommonReturnFalse, + (PF_CPU_IS_NBCOF_INIT_NEEDED) CommonReturnAgesaSuccess, + (PF_CPU_GET_NB_IDD_MAX) CommonReturnFalse, + (PF_CPU_AP_INITIAL_LAUNCH) CommonReturnFalse, + (PF_CPU_NUMBER_OF_PHYSICAL_CORES) CommonReturnZero8, + (PF_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE) CommonReturnAgesaSuccess, + (PF_CPU_SET_AP_CORE_NUMBER) CommonVoid, + (PF_CPU_GET_AP_CORE_NUMBER) CommonReturnZero32, + (PF_CPU_TRANSFER_AP_CORE_NUMBER) CommonVoid, + (PF_CPU_GET_STORED_NODE_NUMBER) CommonReturnZero32, + (PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID) CommonReturnAgesaSuccess, + (PF_CPU_SAVE_FEATURES) CommonReturnAgesaSuccess, + (PF_CPU_WRITE_FEATURES) CommonReturnAgesaSuccess, + (PF_CPU_SET_WARM_RESET_FLAG) CommonReturnAgesaSuccess, + (PF_CPU_GET_WARM_RESET_FLAG) CommonReturnAgesaSuccess, + GetEmptyArray, + GetEmptyArray, + GetEmptyArray, + GetEmptyArray, + GetEmptyArray, + GetEmptyArray, + GetEmptyArray, + (PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO) CommonReturnAgesaSuccess, + (PF_IS_NB_PSTATE_ENABLED) CommonReturnFalse, + (PF_NEXT_LINK_HAS_HTPHY_FEATS) CommonReturnFalse, + (PF_SET_HT_PHY_REGISTER) CommonVoid, + (PF_GET_NEXT_HT_LINK_FEATURES) CommonVoid, + NULL, + NULL, + NULL, + NULL, + InitCacheDisabled, + (PF_GET_EARLY_INIT_TABLE) CommonVoid, + (PF_GET_EARLY_INIT_TABLE) CommonVoid +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +GetCpuServices ( + IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable, + IN UINT64 *MatchData, + OUT CONST VOID **CpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE CpuSupportedFamiliesTable; +extern CPU_FAMILY_ID_XLAT_TABLE CpuSupportedFamilyIdTable; + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Returns the logical ID of the desired processor. This will be obtained by + * reading the CPUID and converting it into a "logical ID" which is not package + * dependent. + * + * @param[in] Socket Socket + * @param[out] LogicalId The Processor's Logical ID + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetLogicalIdOfSocket ( + IN UINT32 Socket, + OUT CPU_LOGICAL_ID *LogicalId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 RawCpuid; + PCI_ADDR PciAddress; + AGESA_STATUS AssumedSuccess; + + RawCpuid = 0; + + if (GetPciAddress (StdHeader, (UINT8)Socket, 0, &PciAddress, &AssumedSuccess)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = CPUID_FMR; + LibAmdPciRead (AccessWidth32, PciAddress, &RawCpuid, StdHeader); + GetLogicalIdFromCpuid (RawCpuid, LogicalId, StdHeader); + } else { + LogicalId->Family = 0; + LogicalId->Revision = 0; + // Logical ID was not found. + IDS_ERROR_TRAP; + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Returns the logical ID of the executing core. This will be obtained by reading + * the CPUID and converting it into a "logical ID" which is not package dependent. + * + * @param[out] LogicalId The Processor's Logical ID + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetLogicalIdOfCurrentCore ( + OUT CPU_LOGICAL_ID *LogicalId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPUID_DATA CpuidDataStruct; + + LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuidDataStruct, StdHeader); + GetLogicalIdFromCpuid (CpuidDataStruct.EAX_Reg, LogicalId, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Returns the logical ID of a processor with the given CPUID value. This + * will be obtained by converting it into a "logical ID" which is not package + * dependent. + * + * @param[in] RawCpuid The unprocessed CPUID value to be translated + * @param[out] LogicalId The Processor's Logical ID + * @param[in] StdHeader Handle of Header for calling lib functions and services + * + */ +VOID +GetLogicalIdFromCpuid ( + IN UINT32 RawCpuid, + OUT CPU_LOGICAL_ID *LogicalId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 k; + UINT8 NumberOfFamiliesSupported; + UINT8 NumberOfLogicalSubFamilies; + UINT8 LogicalIdEntries; + UINT32 j; + UINT32 RawFamily; + UINT32 CpuModelAndExtendedModel; + UINT64 LogicalFamily; + BOOLEAN IdNotFound; + BOOLEAN FamilyNotFound; + CONST PF_CPU_GET_SUBFAMILY_ID_ARRAY *SubFamilyIdPtr; + CPU_LOGICAL_ID_XLAT *CpuLogicalIdAndRevPtr; + CONST CPU_LOGICAL_ID_FAMILY_XLAT *ImageSupportedId; + + IdNotFound = TRUE; + FamilyNotFound = TRUE; + CpuLogicalIdAndRevPtr = NULL; + ImageSupportedId = CpuSupportedFamilyIdTable.FamilyIdTable; + NumberOfFamiliesSupported = CpuSupportedFamilyIdTable.Elements; + + RawFamily = ((RawCpuid & 0xF00) >> 8) + ((RawCpuid & 0xFF00000) >> 20); + RawCpuid &= (UINT32) CPU_FMS_MASK; + CpuModelAndExtendedModel = (UINT16) ((RawCpuid >> 8) | RawCpuid); + + LogicalId->Family = 0; + LogicalId->Revision = 0; + + for (i = 0; i < NumberOfFamiliesSupported && FamilyNotFound; i++) { + if (ImageSupportedId[i].Family == RawFamily) { + FamilyNotFound = FALSE; + LogicalId->Family = ImageSupportedId[i].UnknownRevision.Family; + LogicalId->Revision = ImageSupportedId[i].UnknownRevision.Revision; + + NumberOfLogicalSubFamilies = ImageSupportedId[i].Elements; + SubFamilyIdPtr = ImageSupportedId[i].SubFamilyIdTable; + for (j = 0; j < NumberOfLogicalSubFamilies && IdNotFound; j++) { + SubFamilyIdPtr[j] ((CONST CPU_LOGICAL_ID_XLAT **)&CpuLogicalIdAndRevPtr, &LogicalIdEntries, &LogicalFamily, StdHeader); + ASSERT (CpuLogicalIdAndRevPtr != NULL); + for (k = 0; k < LogicalIdEntries; k++) { + if (CpuLogicalIdAndRevPtr[k].RawId == CpuModelAndExtendedModel) { + IdNotFound = FALSE; + LogicalId->Family = LogicalFamily; + LogicalId->Revision = CpuLogicalIdAndRevPtr[k].LogicalId; + break; + } + } + } + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Retrieves a pointer to the desired processor's family specific services structure. + * + * @param[in] Socket The Processor in this Socket. + * @param[out] FunctionTable The Processor's Family Specific services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetCpuServicesOfSocket ( + IN UINT32 Socket, + OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GetFeatureServicesOfSocket (&CpuSupportedFamiliesTable, + Socket, + (CONST VOID **) FunctionTable, + StdHeader); + if (*FunctionTable == NULL) { + *FunctionTable = (CPU_SPECIFIC_SERVICES *)&cpuNullServices; + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Retrieves a pointer to the desired processor's family specific services structure. + * + * @param[in] FamilyTable The table to search in. + * @param[in] Socket The Processor in this Socket. + * @param[out] CpuServices The Processor's Family Specific services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetFeatureServicesOfSocket ( + IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable, + IN UINT32 Socket, + OUT CONST VOID **CpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_LOGICAL_ID CpuFamilyRevision; + + GetLogicalIdOfSocket (Socket, &CpuFamilyRevision, StdHeader); + GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Retrieves a pointer to the executing core's family specific services structure. + * + * @param[out] FunctionTable The Processor's Family Specific services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetCpuServicesOfCurrentCore ( + OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GetFeatureServicesOfCurrentCore (&CpuSupportedFamiliesTable, + (CONST VOID **) FunctionTable, + StdHeader); + if (*FunctionTable == NULL) { + *FunctionTable = (CPU_SPECIFIC_SERVICES *)&cpuNullServices; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Retrieves a pointer to the family specific services structure for a processor + * with the given logical ID. + * + * @param[in] FamilyTable The table to search in. + * @param[out] CpuServices The Processor's Family Specific services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetFeatureServicesOfCurrentCore ( + IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable, + OUT CONST VOID **CpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_LOGICAL_ID CpuFamilyRevision; + + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetFeatureServicesFromLogicalId (FamilyTable, &CpuFamilyRevision, CpuServices, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Retrieves a pointer to the family specific services structure for a processor + * with the given logical ID. + * + * @param[in] LogicalId The Processor's logical ID. + * @param[out] FunctionTable The Processor's Family Specific services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetCpuServicesFromLogicalId ( + IN CPU_LOGICAL_ID *LogicalId, + OUT CONST CPU_SPECIFIC_SERVICES **FunctionTable, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GetFeatureServicesFromLogicalId (&CpuSupportedFamiliesTable, + LogicalId, + (CONST VOID **) FunctionTable, + StdHeader); + if (*FunctionTable == NULL) { + *FunctionTable = &cpuNullServices; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Retrieves a pointer to the family specific services structure for a processor + * with the given logical ID. + * + * @param[in] FamilyTable The table to search in. + * @param[in] LogicalId The Processor's logical ID. + * @param[out] CpuServices The Processor's Family Specific services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetFeatureServicesFromLogicalId ( + IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable, + IN CPU_LOGICAL_ID *LogicalId, + OUT CONST VOID **CpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GetCpuServices (FamilyTable, &LogicalId->Family, CpuServices, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Finds a family match in the given table, and returns the pointer to the + * appropriate table. If no match is found in the table, NULL will be returned. + * + * @param[in] FamilyTable The table to search in. + * @param[in] MatchData Family data that must match. + * @param[out] CpuServices The Processor's Family Specific services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +STATIC +GetCpuServices ( + IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable, + IN UINT64 *MatchData, + OUT CONST VOID **CpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN IsFamily; + UINT8 i; + UINT8 NumberOfFamiliesSupported; + CONST CPU_SPECIFIC_SERVICES_XLAT *ImageSupportedFamiliesPtr; + + ImageSupportedFamiliesPtr = FamilyTable->FamilyTable; + NumberOfFamiliesSupported = FamilyTable->Elements; + IsFamily = FALSE; + for (i = 0; i < NumberOfFamiliesSupported; i++) { + if ((ImageSupportedFamiliesPtr[i].Family & *MatchData) != 0) { + IsFamily = TRUE; + break; + } + } + if (IsFamily) { + *CpuServices = ImageSupportedFamiliesPtr[i].TablePtr; + } else { + *CpuServices = NULL; + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Used to stub out various family specific tables of information. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] Empty NULL, to indicate no data. + * @param[out] NumberOfElements Zero, to indicate no data. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +GetEmptyArray ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **Empty, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = 0; + *Empty = NULL; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuFamilyTranslation.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuFamilyTranslation.h new file mode 100644 index 0000000000..309fc18041 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuFamilyTranslation.h @@ -0,0 +1,1052 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Family Translation functions. + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 85962 $ @e \$Date: 2013-01-14 20:12:29 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_FAMILY_TRANSLATION_H_ +#define _CPU_FAMILY_TRANSLATION_H_ + +/** + * @page cpuimplfss CPU Family Specific Services Implementation Guide + * + * CPU Family Specific Services provides access to supported family service functions and data, + * in a manner that isolates calling code from knowledge about particular families or which + * families are supported in the current build. + * + * @par Adding a Method to Family Specific Services + * + * To add a new method to Family Specific Services, follow these steps. + *
    + *
  • Create a typedef for the Method with the correct parameters and return type. + * + *
      + *
    • Name the method typedef (*PF_METHOD_NAME)(), where METHOD_NAME is the same name as the method table item, + * but with "_"'s and UPPERCASE, rather than mixed case. + * @n typedef VOID (*PF_METHOD_NAME)(); @n + * + *
    • [Optionally make the type F_ and provide a separate: + * @n typedef F_METHOD_NAME *PF_METHOD_NAME> @n + * and provide a single line "///" doxygen comment brief description on the PF_ type.] + *
    + * + *
  • The first parameter to @b all Family Specific Service Methods is @b required to be a reference to + * their Family Service struct. + * @n IN CPU_SPECIFIC_SERVICES *FamilySpecificServices @n + * + *
  • Provide a standard doxygen function preamble for the Method typedef. Begin the + * detailed description by provide a reference to the method instances page by including + * the lines below: + * @code + * * + * * @CpuServiceInstances + * * + * @endcode + * @note It is important to provide documentation for the method type, because the method may not + * have an implementation in any families supported by the current package. @n + * + *
  • Add to the CPU_SPECIFIC_SERVICES struct an item for the Method: + * @n PF_METHOD_NAME MethodName; ///< Method: description. @n + *
+ * + * @par Implementing a Family Specific Instance of the method. + * + * To implement an instance of a method for a specific family follow these steps. + * + * - In appropriate files in the family specific directory, implement the method with the return type + * and parameters matching the method typedef. + * + * - Name the function FnnMethodName(), where nn is the family number. + * + * - Create a doxygen function preamble for the method instance. Begin the detailed description with + * an Implements command to reference the method type and add this instance to the Method Instances page. + * @code + * * + * * @CpuServiceMethod{::F_METHOD_NAME}. + * * + * @endcode + * + * - To access other family specific services as part of the method implementation, the function + * @b must use FamilySpecificServices->OtherMethod(). Do not directly call other family specific + * routines, because in the table there may be overrides or this routine may be shared by multiple families. + * + * - Do @b not call Family translation services from a family specific instance. Use the parameter. + * + * - Add the instance to the family specific CPU_SPECIFIC_SERVICES instance. + * + * - If a family does not need an instance of the method use one of the CommonReturns from + * CommonReturns.h with the same return type. + * + * @par Invoking Family Specific Services. + * + * The following example shows how to invoke a family specific method. + * @n @code + * CPU_SPECIFIC_SERVICES *FamilyServices; + * + * GetCpuServicesOfCurrentCore (&FamilyServices, StdHeader); + * ASSERT (FamilyServices != NULL); + * FamilyServices->MethodName (FamilyServices, StdHeader); + * @endcode + * + */ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ +#include "cpuPostInit.h" +#include "cpuEnvInit.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "Table.h" +#include "Ids.h" +#include "Topology.h" + +// Forward declaration needed for multi-structure mutual references. +AGESA_FORWARD_DECLARATION (CPU_SPECIFIC_SERVICES); +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +/** + * Disable the desired P-state. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StateNumber Hardware P-state number. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_DISABLE_PSTATE ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_DISABLE_PSTATE *PF_CPU_DISABLE_PSTATE; + +/** + * Transition the current core to the desired P-state. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StateNumber Software P-state number. + * @param[in] WaitForChange Wait/don't wait for P-state change to complete. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_TRANSITION_PSTATE ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN BOOLEAN WaitForChange, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_TRANSITION_PSTATE *PF_CPU_TRANSITION_PSTATE; + +/** + * Get the desired P-state's maximum current required in milliamps. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StateNumber The desired hardware P-state number. + * @param[out] ProcIddMax The P-state's maximum current. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE The P-state is enabled, and ProcIddMax is valid. + * @retval FALSE The P-state is disabled. + * + */ +typedef BOOLEAN F_CPU_GET_IDD_MAX ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + OUT UINT32 *ProcIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_IDD_MAX *PF_CPU_GET_IDD_MAX; + + +/** + * Returns the rate at which the current core's timestamp counter increments in megahertz. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] FreqInMHz The rate at which the TSC increments in megahertz. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_TSC_RATE ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *FreqInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_TSC_RATE *PF_CPU_GET_TSC_RATE; + +/** + * Returns the processor north bridge's clock rate in megahertz. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] FreqInMHz The desired node's frequency in megahertz. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_SUCCESS FreqInMHz is valid. + */ +typedef AGESA_STATUS F_CPU_GET_NB_FREQ ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *FreqInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_NB_FREQ *PF_CPU_GET_NB_FREQ; + +/** + * Returns the node's minimum and maximum northbridge frequency. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] PciAddress The segment, bus, and device numbers of the CPU in question. + * @param[out] MinFreqInMHz The minimum north bridge frequency. + * @param[out] MaxFreqInMHz The maximum north bridge frequency. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_STATUS Northbridge frequency is valid + */ +typedef AGESA_STATUS F_CPU_GET_MIN_MAX_NB_FREQ ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PCI_ADDR *PciAddress, + OUT UINT32 *MinFreqInMHz, + OUT UINT32 *MaxFreqInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_MIN_MAX_NB_FREQ *PF_CPU_GET_MIN_MAX_NB_FREQ; + +/** + * Returns the processor north bridge's P-state settings. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] PciAddress The segment, bus, and device numbers of the CPU in question. + * @param[in] NbPstate The NB P-state number to check. + * @param[out] FreqNumeratorInMHz The desired node's frequency numerator in megahertz. + * @param[out] FreqDivisor The desired node's frequency divisor. + * @param[out] VoltageInuV The desired node's voltage in microvolts. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE NbPstate is valid + * @retval FALSE NbPstate is disabled or invalid + */ +typedef BOOLEAN F_CPU_GET_NB_PSTATE_INFO ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN PCI_ADDR *PciAddress, + IN UINT32 NbPstate, + OUT UINT32 *FreqNumeratorInMHz, + OUT UINT32 *FreqDivisor, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_NB_PSTATE_INFO *PF_CPU_GET_NB_PSTATE_INFO; + +/** + * Returns whether or not the NB frequency initialization sequence is required + * to be performed by the BIOS. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PciAddress The northbridge to query by pci base address. + * @param[out] NbVidUpdateAll Do all NbVids need to be updated as well. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef BOOLEAN F_CPU_IS_NBCOF_INIT_NEEDED ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT BOOLEAN *NbVidUpdateAll, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_IS_NBCOF_INIT_NEEDED *PF_CPU_IS_NBCOF_INIT_NEEDED; + +/** + * Get the desired NB P-state's maximum current required in milliamps. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StateNumber The desired hardware P-state number. + * @param[out] NbIddMax The NB P-state's maximum current. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE The NB P-state is enabled, and NbIddMax is valid. + * @retval FALSE The NB P-state is disabled. + * + */ +typedef BOOLEAN F_CPU_GET_NB_IDD_MAX ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + OUT UINT32 *NbIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_NB_IDD_MAX *PF_CPU_GET_NB_IDD_MAX; + +/** + * Launches the desired core from the reset vector. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] SocketNumber The desired core's socket number. + * @param[in] ModuleNumber The desired core's die number. + * @param[in] CoreNumber The desired core's die relative core number. + * @param[in] PrimaryCoreNumber SocketNumber / ModuleNumber's primary core number. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE The core was launched successfully. + * @retval FALSE The core was previously launched, or has a problem. + */ +typedef BOOLEAN F_CPU_AP_INITIAL_LAUNCH ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 SocketNumber, + IN UINT32 ModuleNumber, + IN UINT32 CoreNumber, + IN UINT32 PrimaryCoreNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_AP_INITIAL_LAUNCH *PF_CPU_AP_INITIAL_LAUNCH; + +/** + * Returns the appropriate number of physical processor cores + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @return One-based number of physical cores on current processor + */ +typedef UINT8 F_CPU_NUMBER_OF_PHYSICAL_CORES ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_NUMBER_OF_PHYSICAL_CORES *PF_CPU_NUMBER_OF_PHYSICAL_CORES; + +/** + * Returns a family specific table of information pointer and size. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] FamilySpecificArray Pointer to the appropriate list for the core. + * @param[out] NumberOfElements Number of valid entries FamilySpecificArray. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef VOID F_CPU_GET_FAMILY_SPECIFIC_ARRAY ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **FamilySpecificArray, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_FAMILY_SPECIFIC_ARRAY *PF_CPU_GET_FAMILY_SPECIFIC_ARRAY; + +/** + * Returns a model specific list of logical IDs. + * + * @param[out] LogicalIdXlat Installed logical ID table. + * @param[out] NumberOfElements Number of entries in the Logical ID translate table. + * @param[out] LogicalFamily Base logical family bit mask. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef VOID F_CPU_GET_SUBFAMILY_ID_ARRAY ( + OUT CONST CPU_LOGICAL_ID_XLAT **LogicalIdXlat, + OUT UINT8 *NumberOfElements, + OUT UINT64 *LogicalFamily, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method. +typedef F_CPU_GET_SUBFAMILY_ID_ARRAY *PF_CPU_GET_SUBFAMILY_ID_ARRAY; + +/** + * Use the Mailbox Register to get the Ap Mailbox info for the current core. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] ApMailboxInfo The AP Mailbox info + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef VOID (F_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT AP_MAILBOXES *ApMailboxInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE *PF_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE; + +/** + * Set the AP core number in the AP's Mailbox. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] Socket The AP's socket + * @param[in] Module The AP's module + * @param[in] ApCoreNumber The AP's unique core number + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef VOID (F_CPU_SET_AP_CORE_NUMBER) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 Socket, + IN UINT32 Module, + IN UINT32 ApCoreNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CPU_SET_AP_CORE_NUMBER *PF_CPU_SET_AP_CORE_NUMBER; + +/** + * Get the AP core number from hardware. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @return The AP's unique core number + */ +typedef UINT32 (F_CPU_GET_AP_CORE_NUMBER) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CPU_GET_AP_CORE_NUMBER *PF_CPU_GET_AP_CORE_NUMBER; + +/** + * Move the AP's core number from the mailbox to hardware. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @return The AP's unique core number + */ +typedef VOID (F_CPU_TRANSFER_AP_CORE_NUMBER) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CPU_TRANSFER_AP_CORE_NUMBER *PF_CPU_TRANSFER_AP_CORE_NUMBER; + +/** + * Get the stored node number from hardware. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @return The current core's zero based node number + */ +typedef UINT32 (F_CPU_GET_STORED_NODE_NUMBER) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CPU_GET_STORED_NODE_NUMBER *PF_CPU_GET_STORED_NODE_NUMBER; + +/** + * Core ID position in the initial APIC ID, reflected as a number zero or one. + */ +typedef enum { + CoreIdPositionZero, ///< Zero, the Core Id bits are the Most Significant bits. + CoreIdPositionOne, ///< One, the Core Id bits are the Least Significant bits. + CoreIdPositionMax ///< Limit check. +} CORE_ID_POSITION; + +/** + * Return a number zero or one, based on the Core ID position in the initial APIC Id. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval CoreIdPositionZero Core Id is not low + * @retval CoreIdPositionOne Core Id is low + */ +typedef CORE_ID_POSITION F_CORE_ID_POSITION_IN_INITIAL_APIC_ID ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CORE_ID_POSITION_IN_INITIAL_APIC_ID *PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID; + +/** + * Get least common features set of all CPUs and save them to CPU_FEATURES_LIST + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in,out] cpuFeatureListPtr The CPU Features List + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef VOID (F_CPU_SAVE_FEATURES) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT CPU_FEATURES_LIST *cpuFeatureListPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CPU_SAVE_FEATURES *PF_CPU_SAVE_FEATURES; + +/** + * Get least common features from CPU_FEATURES_LIST and write them to CPU + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in,out] cpuFeatureListPtr The CPU Features List + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef VOID (F_CPU_WRITE_FEATURES) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT CPU_FEATURES_LIST *cpuFeatureListPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_CPU_WRITE_FEATURES *PF_CPU_WRITE_FEATURES; + +/** + * Set Warm Reset Flag + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Header for library and services. + * @param[in] Request Value to set the flags to. + * + */ +typedef VOID (F_CPU_SET_WARM_RESET_FLAG) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader, + IN WARM_RESET_REQUEST *Request + ); + +/// Reference to a method +typedef F_CPU_SET_WARM_RESET_FLAG *PF_CPU_SET_WARM_RESET_FLAG; + +/** + * Get Warm Reset Flag + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Header for library and services. + * @param[out] BiosRstDet Indicate warm reset status. + * + */ +typedef VOID (F_CPU_GET_WARM_RESET_FLAG) ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader, + OUT WARM_RESET_REQUEST *Request + ); + +/// Reference to a method +typedef F_CPU_GET_WARM_RESET_FLAG *PF_CPU_GET_WARM_RESET_FLAG; + + +/** + * Get CPU Specific Platform Type Info. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in,out] FeaturesUnion The Features supported by this platform. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT PLATFORM_FEATS *FeaturesUnion, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO *PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO; + +/** + * Is the Northbridge PState feature enabled? + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE The NB PState feature is enabled. + * @retval FALSE The NB PState feature is not enabled. + */ +typedef BOOLEAN F_IS_NB_PSTATE_ENABLED ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_IS_NB_PSTATE_ENABLED *PF_IS_NB_PSTATE_ENABLED; + +/** + * Gets the next link with features matching the HT phy register table entry type features. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in,out] HtHostCapability Initially the PCI bus, device, function=0, offset=0; + * Each call returns the HT Host Capability function and offset; + * Caller may use it to access registers, but must @b not modify it; + * Each new call passes the previous value as input. + * @param[in,out] Link Initially zero, each call returns the link number; caller passes it back unmodified each call. + * @param[in] HtPhyLinkType Link type field from a register table entry to compare against + * @param[out] MatchedSublink1 TRUE: It is actually just sublink 1 that matches, FALSE: any other condition. + * @param[out] Frequency0 The frequency of sublink0 (200 MHz if not connected). + * @param[out] Frequency1 The frequency of sublink1 (200 MHz if not connected). + * @param[in] StdHeader Standard Head Pointer + * + * @retval TRUE Link matches + * @retval FALSE No more links + * + */ +typedef BOOLEAN F_NEXT_LINK_HAS_HTPHY_FEATS ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT PCI_ADDR *HtHostCapability, + IN OUT UINT32 *Link, + IN HT_PHY_LINK_FEATS *HtPhyLinkType, + OUT BOOLEAN *MatchedSublink1, + OUT HT_FREQUENCIES *Frequency0, + OUT HT_FREQUENCIES *Frequency1, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a Method. +typedef F_NEXT_LINK_HAS_HTPHY_FEATS *PF_NEXT_LINK_HAS_HTPHY_FEATS; + +/** + * Applies an HT Phy read-modify-write based on an HT Phy register table entry. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] HtPhyEntry HT Phy register table entry to apply + * @param[in] CapabilitySet The link's HT Host base address. + * @param[in] Link Zero based, node, link number (not package link), always a sublink0 link. + * @param[in] StdHeader Config handle for library and services + * + */ +typedef VOID F_SET_HT_PHY_REGISTER ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN HT_PHY_TYPE_ENTRY_DATA *HtPhyEntry, + IN PCI_ADDR CapabilitySet, + IN UINT32 Link, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a Method. +typedef F_SET_HT_PHY_REGISTER *PF_SET_HT_PHY_REGISTER; + +/** + * Performs an early initialization function on the executing core. + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[in] EarlyParams CPU module early paramters. + * @param[in] StdHeader Config handle for library and services + * + */ +typedef VOID F_PERFORM_EARLY_INIT_ON_CORE ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a Method. +typedef F_PERFORM_EARLY_INIT_ON_CORE *PF_PERFORM_EARLY_INIT_ON_CORE; + +/** + * A struct that contains function pointer and function flag + * + * the flag indicates if the function need to be run. + */ +typedef struct _S_PERFORM_EARLY_INIT_ON_CORE { + PF_PERFORM_EARLY_INIT_ON_CORE PerformEarlyInitOnCore; ///< Function Pointer, which points to the function need to be run at early stage + UINT32 PerformEarlyInitFlag; ///< Function Flag, which indicates if the function need to be run. +} S_PERFORM_EARLY_INIT_ON_CORE; + +/** + * Returns the initialization steps that the executing core should + * perform at AmdInitEarly. + * + * @CpuServiceInstances + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[out] Table Table of appropriate init steps for the executing core. + * @param[in] EarlyParams CPU module early paramters. + * @param[in] StdHeader Config handle for library and services + * + */ +typedef VOID F_GET_EARLY_INIT_TABLE ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST S_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a Method. +typedef F_GET_EARLY_INIT_TABLE *PF_GET_EARLY_INIT_TABLE; + +/** + * Provide the features of the next HT link. + * + * @CpuServiceInstances + * + * This method is different than the HT Phy Features method, because for the phy registers + * sublink 1 matches and should be programmed if the link is ganged but for PCI config + * registers sublink 1 is reserved if the link is ganged. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in,out] Link The link number, for accessing non-capability set registers. + * Zero on initial call, and passed back unmodified on each subsequent call. + * @param[in,out] LinkBase IN: initially the node's PCI config base address, passed back on each call. + * OUT: the base HT Host capability PCI address for the link. + * @param[out] HtHostFeats The link's features. + * @param[in] StdHeader Standard Head Pointer + * + * @retval TRUE Valid link and features found. + * @retval FALSE No more links. + */ +typedef BOOLEAN F_GET_NEXT_HT_LINK_FEATURES ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT UINTN *Link, + IN OUT PCI_ADDR *LinkBase, + OUT HT_HOST_FEATS *HtHostFeats, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a Method. +typedef F_GET_NEXT_HT_LINK_FEATURES *PF_GET_NEXT_HT_LINK_FEATURES; + +/// Cache Enable / Disable policy before giving control back to OS. +typedef enum { + InitCacheDisabled, ///StdHeader); + AmdParamApic->StdHeader.HeapBasePtr = HeapGetBaseAddress (&AmdParamApic->StdHeader); + + AmdParamApic->IsPresent = GetApicId ( + &AmdParamApic->StdHeader, + AmdParamApic->Socket, + AmdParamApic->Core, + &AmdParamApic->ApicAddress, + &AgesaStatus + ); + + AGESA_TESTPOINT (TpIfAmdGetApicIdExit, &AmdParamApic->StdHeader); + return AgesaStatus; +} + +/** + * Get Processor Module's PCI Config Space address. + * + * Invoke corresponding Cpu Service for external user. + * + * @param[in,out] AmdParamGetPci Our interface struct + * + * @return The most severe status of any called service. + */ +AGESA_STATUS +AmdGetPciAddress ( + IN OUT AMD_GET_PCI_PARAMS *AmdParamGetPci + ) +{ + AGESA_STATUS AgesaStatus; + + AGESA_TESTPOINT (TpIfAmdGetPciAddressEntry, &AmdParamGetPci->StdHeader); + AmdParamGetPci->StdHeader.HeapBasePtr = HeapGetBaseAddress (&AmdParamGetPci->StdHeader); + + AmdParamGetPci->IsPresent = GetPciAddress ( + &AmdParamGetPci->StdHeader, + AmdParamGetPci->Socket, + AmdParamGetPci->Module, + &AmdParamGetPci->PciAddress, + &AgesaStatus + ); + + AGESA_TESTPOINT (TpIfAmdGetPciAddressExit, &AmdParamGetPci->StdHeader); + return AgesaStatus; +} + +/** + * "Who am I" for the current running core. + * + * Invoke corresponding Cpu Service for external user. + * + * @param[in,out] AmdParamIdentify Our interface struct + * + * @return The most severe status of any called service. + */ +AGESA_STATUS +AmdIdentifyCore ( + IN OUT AMD_IDENTIFY_PARAMS *AmdParamIdentify + ) +{ + AGESA_STATUS AgesaStatus; + UINT32 Socket; + UINT32 Module; + UINT32 Core; + + AGESA_TESTPOINT (TpIfAmdIdentifyCoreEntry, &AmdParamIdentify->StdHeader); + AmdParamIdentify->StdHeader.HeapBasePtr = HeapGetBaseAddress (&AmdParamIdentify->StdHeader); + + IdentifyCore ( + &AmdParamIdentify->StdHeader, + &Socket, + &Module, + &Core, + &AgesaStatus + ); + AmdParamIdentify->Socket = (UINT8)Socket; + AmdParamIdentify->Module = (UINT8)Module; + AmdParamIdentify->Core = (UINT8)Core; + + AGESA_TESTPOINT (TpIfAmdIdentifyCoreExit, &AmdParamIdentify->StdHeader); + return AgesaStatus; +} + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S - AGESA common General Services + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Get a specified Core's APIC ID. + * + * Code sync: This calculation MUST match the assignment + * calculation done in LocalApicInitializationAtEarly function. + * + * @param[in] StdHeader Header for library and services. + * @param[in] Socket The socket in which the Core's Processor is installed. + * @param[in] Core The Core id. + * @param[out] ApicAddress The Core's APIC ID. + * @param[out] AgesaStatus Aggregates AGESA_STATUS for external interface, Always Succeeds. + * + * @retval TRUE The core is present, APIC Id valid + * @retval FALSE The core is not present, APIC Id not valid. +*/ +BOOLEAN +GetApicId ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT32 Socket, + IN UINT32 Core, + OUT UINT8 *ApicAddress, + OUT AGESA_STATUS *AgesaStatus + ) +{ + BOOLEAN ReturnValue; + UINT32 CoreCount; + UINT32 ApicID; + + ReturnValue = FALSE; + if (GetActiveCoresInGivenSocket (Socket, &CoreCount, StdHeader)) { + if (Core < CoreCount) { + ReturnValue = TRUE; + GetLocalApicIdForCore (Socket, Core, &ApicID, StdHeader); + *ApicAddress = (UINT8) ApicID; + } + } + + // Always Succeeds. + *AgesaStatus = AGESA_SUCCESS; + + return ReturnValue; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get Processor Module's PCI Config Space address. + * + * @param[in] StdHeader Header for library and services. + * @param[in] Socket The Core's Socket. + * @param[in] Module The Module in that Processor + * @param[out] PciAddress The Processor's PCI Config Space address (Function 0, Register 0) + * @param[out] AgesaStatus Aggregates AGESA_STATUS for external interface, Always Succeeds. + * + * @retval TRUE The core is present, PCI Address valid + * @retval FALSE The core is not present, PCI Address not valid. + */ +BOOLEAN +GetPciAddress ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT32 Socket, + IN UINT32 Module, + OUT PCI_ADDR *PciAddress, + OUT AGESA_STATUS *AgesaStatus + ) +{ + UINT8 Node; + BOOLEAN Result; + + ASSERT (Socket < MAX_SOCKETS); + ASSERT (Module < MAX_DIES); + + Result = TRUE; + // Always Succeeds. + *AgesaStatus = AGESA_SUCCESS; + + if (GetNodeId (Socket, Module, &Node, StdHeader)) { + // socket is populated + PciAddress->AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); + PciAddress->Address.Device = PciAddress->Address.Device + Node; + } else { + // socket is not populated + PciAddress->AddressValue = ILLEGAL_SBDFO; + Result = FALSE; + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * "Who am I" for the current running core. + * + * @param[in] StdHeader Header for library and services. + * @param[out] Socket The current Core's Socket + * @param[out] Module The current Core's Processor Module + * @param[out] Core The current Core's core id. + * @param[out] AgesaStatus Aggregates AGESA_STATUS for external interface, Always Succeeds. + * + */ +VOID +IdentifyCore ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT UINT32 *Socket, + OUT UINT32 *Module, + OUT UINT32 *Core, + OUT AGESA_STATUS *AgesaStatus + ) +{ + AP_MAIL_INFO ApMailboxInfo; + UINT32 CurrentCore; + + // Always Succeeds. + *AgesaStatus = AGESA_SUCCESS; + + GetApMailbox (&ApMailboxInfo.Info, StdHeader); + ASSERT (ApMailboxInfo.Fields.Socket < MAX_SOCKETS); + ASSERT (ApMailboxInfo.Fields.Module < MAX_DIES); + *Socket = (UINT8)ApMailboxInfo.Fields.Socket; + *Module = (UINT8)ApMailboxInfo.Fields.Module; + + // Get Core Id + GetCurrentCore (&CurrentCore, StdHeader); + *Core = (UINT8)CurrentCore; +} + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S - cpu component General Services + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Get the current Platform's number of Sockets, regardless of how many are populated. + * + * The Options component can provide how many sockets are available in system. + * This can be used to avoid testing presence of Processors in Sockets which don't exist. + * The result can be one socket to the maximum possible sockets of any supported processor family. + * You cannot assume that all sockets contain a processor or that the sockets have processors + * installed in any particular order. Do not convert this number to a number of nodes. + * + * @return The number of available sockets for the platform. + * + */ +UINT32 +GetPlatformNumberOfSockets ( VOID ) +{ + return TopologyConfiguration.PlatformNumberOfSockets; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get the number of Modules to check presence in each Processor. + * + * The Options component can provide how many modules need to be check for presence in each + * processor, regardless whether all, or any, processor have that many modules present on this boot. + * The result can be one module to the maximum possible modules of any supported processor family. + * You cannot assume that Modules are in any particular order, especially with respect to node id. + * + * @return The maximum number of modules in each processor. + * + */ +UINT32 +GetPlatformNumberOfModules ( VOID ) +{ + return TopologyConfiguration.PlatformNumberOfModules; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Is a processor present in Socket? + * + * Check to see if any possible module of the processor is present. This provides + * support for a few cases where a PCI address isn't needed, but code still needs to + * iterate by Socket. + * + * @param[in] Socket The socket which is being tested + * @param[in] StdHeader Header for library and services. + * + * @retval TRUE The socket has a processor installed + * @retval FALSE The socket is empty (or the processor is dead). + * + */ +BOOLEAN +IsProcessorPresent ( + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + SOCKET_DIE_TO_NODE_MAP pSocketDieMap; + LOCATE_HEAP_PTR SocketDieHeapDataBlock; + BOOLEAN Result; + UINT32 Module; + AGESA_STATUS Status; + + ASSERT (Socket < MAX_SOCKETS); + Result = FALSE; + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + + // Get data block from heap + Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT ((pSocketDieMap != NULL) && (Status == AGESA_SUCCESS)); + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if ((*pSocketDieMap)[Socket][Module].Node != 0xFF) { + Result = TRUE; + break; + } + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Provide the number of installed processors (not Nodes! and not Sockets!) + * + * Iterate over the Socket, Module to Node Map, counting the number of present nodes. + * Do not use this as a Node Count! Do not use this as the number of Sockets! (This + * is for APIC ID utilities.) + * + * @param[in] StdHeader Header for library and services. + * + * @return the number of processors installed + * + */ +UINT32 +GetNumberOfProcessors ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + SOCKET_DIE_TO_NODE_MAP pSocketDieMap; + LOCATE_HEAP_PTR SocketDieHeapDataBlock; + UINT32 Result; + UINT32 Socket; + UINT32 Module; + AGESA_STATUS Status; + + Result = 0; + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + + // Get data block from heap + Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT ((pSocketDieMap != NULL) && (Status == AGESA_SUCCESS)); + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if ((*pSocketDieMap)[Socket][Module].Node != 0xFF) { + Result++; + break; + } + } + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * For a specific Node, get its Socket and Module ids. + * + * If asking for the current running Node, read the mailbox socket, module. Specific Node, + * locate the Node to Socket/Module Map in heap, and return the ids, if present. + * + * @param[in] Node What Socket and Module is this Node? + * @param[out] Socket The Socket containing that Node. + * @param[out] Module The Processor Module of that Node. + * @param[in] StdHeader Header for library and services. + * + * @retval TRUE Node is present, Socket, Module are valid. + * @retval FALSE Node is not present, why do you ask? + */ +BOOLEAN +GetSocketModuleOfNode ( + IN UINT32 Node, + OUT UINT32 *Socket, + OUT UINT32 *Module, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + NODE_TO_SOCKET_DIE_MAP pNodeMap; + LOCATE_HEAP_PTR SocketDieHeapDataBlock; + BOOLEAN Result; + AGESA_STATUS Status; + + Result = FALSE; + + ASSERT (Node < MAX_NODES); + + // Get Map from heap + SocketDieHeapDataBlock.BufferHandle = NODE_ID_MAP_HANDLE; + Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pNodeMap = (NODE_TO_SOCKET_DIE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT ((pNodeMap != NULL) && (Status == AGESA_SUCCESS)); + *Socket = (*pNodeMap)[Node].Socket; + *Module = (*pNodeMap)[Node].Die; + if ((*pNodeMap)[Node].Socket != 0xFF) { + Result = TRUE; + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get the current core's Processor APIC Index. + * + * The Processor APIC Index is the position of the current processor in the APIC id + * assignment. Processors are ordered in node id order. This is not the same, however, + * as the node id of the current socket and module or the current socket id. + * + * @param[in] Node The current desired core's node id (usually the current core). + * @param[in] StdHeader Header for library and services. + * + * @return Processor APIC Index + * + */ +UINT32 +GetProcessorApicIndex ( + IN UINT32 Node, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ProcessorApicIndex; + UINT32 PreviousSocket; + UINT32 CurrentSocket; + UINT32 Ignored; + UINT32 i; + + ASSERT (Node < MAX_NODES); + + // Calculate total APIC devices up to Current Node, Core. + ProcessorApicIndex = 0; + PreviousSocket = 0xFF; + for (i = 0; i < (Node + 1); i++) { + GetSocketModuleOfNode (i, &CurrentSocket, &Ignored, StdHeader); + if (CurrentSocket != PreviousSocket) { + ProcessorApicIndex++; + PreviousSocket = CurrentSocket; + } + } + // Convert to Index (zero based) from count (one based). + ProcessorApicIndex--; + return ProcessorApicIndex; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns current node number + * + * @param[out] Node This Core's Node id + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetCurrentNodeNum ( + OUT UINT32 *Node, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_MAIL_INFO ApMailboxInfo; + + // Get the Node Id from the Mailbox. + GetApMailbox (&ApMailboxInfo.Info, StdHeader); + ASSERT (ApMailboxInfo.Fields.Node < MAX_NODES); + *Node = ApMailboxInfo.Fields.Node; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns Total number of active cores in the current socket + * + * @param[out] CoreCount The cores in this processor. + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetActiveCoresInCurrentSocket ( + OUT UINT32 *CoreCount, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPUID_DATA CpuidDataStruct; + UINT32 TotalCoresCount; + + LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuidDataStruct, StdHeader); + TotalCoresCount = (CpuidDataStruct.ECX_Reg & 0x000000FF) + 1; + *CoreCount = TotalCoresCount; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Provides the Total number of active cores in the current core's node. + * + * @param[in] StdHeader Header for library and services. + * + * @return The current node core count + */ +UINTN +GetActiveCoresInCurrentModule ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 Core; + UINT32 LowCore; + UINT32 HighCore; + UINT32 ProcessorCoreCount; + AGESA_STATUS AgesaStatus; + + ProcessorCoreCount = 0; + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &AgesaStatus); + if (GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader)) { + ProcessorCoreCount = ((HighCore - LowCore) + 1); + } + return ProcessorCoreCount; +} + +/** + * Provide the number of compute units on current module. + * + * + * @param[in] StdHeader Header for library and services. + * + * @return The current compute unit counts. + * + */ +UINTN +GetNumberOfCompUnitsInCurrentModule ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 CurrentCore; + UINT32 ComputeUnitCount; + UINT32 Enabled; + COMPUTE_UNIT_MAPPING ComputeUnitMapping; + AGESA_STATUS IgnoredSts; + LOCATE_HEAP_PTR SocketDieHeapDataBlock; + SOCKET_DIE_TO_NODE_MAP pSocketDieMap; + + ComputeUnitCount = 0; + ComputeUnitMapping = GetComputeUnitMapping (StdHeader); + ASSERT ((ComputeUnitMapping == AllCoresMapping) || + (ComputeUnitMapping == EvenCoresMapping) || + (ComputeUnitMapping == TripleCoresMapping) || + (ComputeUnitMapping == QuadCoresMapping)); + + IdentifyCore (StdHeader, &Socket, &Module, &CurrentCore, &IgnoredSts); + // Get data block from heap + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + IgnoredSts = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT ((pSocketDieMap != NULL) && (IgnoredSts == AGESA_SUCCESS)); + // Current Core's socket, module must be present. + ASSERT ((*pSocketDieMap)[Socket][Module].Node != 0xFF); + // Process compute unit info + Enabled = (*pSocketDieMap)[Socket][Module].EnabledComputeUnits; + + while (Enabled > 0) { + if ((Enabled & 0x1) != 0) { + ComputeUnitCount++; + } + Enabled >>= 1; + } + + return ComputeUnitCount; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Provides the Total number of active cores in the given socket. + * + * @param[in] Socket Get a core count for the processor in this socket. + * @param[out] CoreCount Its core count + * @param[in] StdHeader Header for library and services. + * + * @retval TRUE A processor is present in the Socket and the CoreCount is valid. + * @retval FALSE The Socket does not have a Processor + */ +BOOLEAN +GetActiveCoresInGivenSocket ( + IN UINT32 Socket, + OUT UINT32 *CoreCount, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Module; + UINT32 LowCore; + UINT32 HighCore; + UINT32 ProcessorCoreCount; + BOOLEAN Result; + + Result = FALSE; + ProcessorCoreCount = 0; + + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader)) { + ProcessorCoreCount = ProcessorCoreCount + ((HighCore - LowCore) + 1); + Result = TRUE; + } else { + break; + } + } + *CoreCount = ProcessorCoreCount; + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Provides the range of Cores in a Processor which are in a Module. + * + * Cores are named uniquely in a processor, 0 to TotalCores. Any module in the processor has + * a set of those cores, named from LowCore to HighCore. + * + * @param[in] Socket Get a core range for the processor in this socket. + * @param[in] Module Get a core range for this Module in the processor. + * @param[out] LowCore The lowest Processor Core in the Module. + * @param[out] HighCore The highest Processor Core in the Module. + * @param[in] StdHeader Header for library and services. + * + * @retval TRUE A processor is present in the Socket and the Core Range is valid. + * @retval FALSE The Socket does not have a Processor + */ +BOOLEAN +GetGivenModuleCoreRange ( + IN UINT32 Socket, + IN UINT32 Module, + OUT UINT32 *LowCore, + OUT UINT32 *HighCore, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + SOCKET_DIE_TO_NODE_MAP pSocketDieMap; + LOCATE_HEAP_PTR SocketDieHeapDataBlock; + BOOLEAN Result; + AGESA_STATUS Status; + + ASSERT (Socket < MAX_SOCKETS); + ASSERT (Module < MAX_DIES); + Result = FALSE; + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + + // Get data block from heap + Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT ((pSocketDieMap != NULL) && (Status == AGESA_SUCCESS)); + *LowCore = (*pSocketDieMap)[Socket][Module].LowCore; + *HighCore = (*pSocketDieMap)[Socket][Module].HighCore; + if ((*pSocketDieMap)[Socket][Module].Node != 0xFF) { + Result = TRUE; + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the current running core number. + * + * @param[out] Core The core id. + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetCurrentCore ( + OUT UINT32 *Core, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPUID_DATA CpuidDataStruct; + UINT32 LocalApicId; + UINT32 ApicIdCoreIdSize; + CORE_ID_POSITION InitApicIdCpuIdLo; + CPU_SPECIFIC_SERVICES *FamilyServices; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + // Read CPUID ebx[31:24] to get initial APICID + LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuidDataStruct, StdHeader); + LocalApicId = (CpuidDataStruct.EBX_Reg & 0xFF000000) >> 24; + + // Find the core ID size. + LibAmdCpuidRead (AMD_CPUID_ASIZE_PCCOUNT, &CpuidDataStruct, StdHeader); + ApicIdCoreIdSize = (CpuidDataStruct.ECX_Reg & 0x0000F000) >> 12; + + InitApicIdCpuIdLo = FamilyServices->CoreIdPositionInInitialApicId (FamilyServices, StdHeader); + ASSERT (InitApicIdCpuIdLo < CoreIdPositionMax); + + // Now extract the core ID from the Apic ID by right justifying the id and masking off non-core Id bits. + *Core = ((LocalApicId >> ((1 - (UINT32)InitApicIdCpuIdLo) * (MAX_CORE_ID_SIZE - ApicIdCoreIdSize))) & + (MAX_CORE_ID_MASK >> (MAX_CORE_ID_SIZE - ApicIdCoreIdSize))); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns current node, and core number. + * + * @param[out] Node The node id of the current core's node. + * @param[out] Core The core id if the current core. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +GetCurrentNodeAndCore ( + OUT UINT32 *Node, + OUT UINT32 *Core, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // Get Node Id + GetCurrentNodeNum (Node, StdHeader); + + // Get Core Id + GetCurrentCore (Core, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Is the current core a primary core of it's node? + * + * @param[in] StdHeader Config handle for library and services. + * + * @retval TRUE Is Primary Core + * @retval FALSE Is not Primary Core + * + */ +BOOLEAN +IsCurrentCorePrimary ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN Result; + UINT32 Core; + UINT32 Socket; + UINT32 Module; + UINT32 PrimaryCore; + UINT32 IgnoredCore; + AGESA_STATUS IgnoredSts; + + Result = FALSE; + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + GetGivenModuleCoreRange (Socket, Module, &PrimaryCore, &IgnoredCore, StdHeader); + if (Core == PrimaryCore) { + Result = TRUE; + } + return Result; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns node id based on SocketId and ModuleId. + * + * @param[in] SocketId The socket to look up + * @param[in] ModuleId The module in that socket + * @param[out] NodeId Provide the corresponding Node Id. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval TRUE The socket is populated + * @retval FALSE The socket is not populated + * + */ +BOOLEAN +GetNodeId ( + IN UINT32 SocketId, + IN UINT32 ModuleId, + OUT UINT8 *NodeId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + SOCKET_DIE_TO_NODE_MAP pSocketDieMap; + LOCATE_HEAP_PTR SocketDieHeapDataBlock; + BOOLEAN Result; + AGESA_STATUS Status; + + Result = FALSE; + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + + // Get data block from heap + Status = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT ((pSocketDieMap != NULL) && (Status == AGESA_SUCCESS)); + *NodeId = (*pSocketDieMap)[SocketId][ModuleId].Node; + if ((*pSocketDieMap)[SocketId][ModuleId].Node != 0xFF) { + Result = TRUE; + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get the cached AP Mailbox Info if available, or read the info from the hardware. + * + * Locate the known AP Mailbox Info Cache buffer in this core's local heap. If it + * doesn't exist, read the hardware to get the info. + * This routine gets the main AP mailbox, not the system degree. + * + * @param[out] ApMailboxInfo Provide the info in this AP core's mailbox + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +GetApMailbox ( + OUT UINT32 *ApMailboxInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Node; + BOOLEAN IamBsp; + AGESA_STATUS Ignored; + AP_MAILBOXES ApMailboxes; + LOCATE_HEAP_PTR ApMailboxCache; + CPU_SPECIFIC_SERVICES *FamilyServices; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader); + IamBsp = IsBsp (StdHeader, &Ignored); + ASSERT (FamilyServices != NULL); + ApMailboxCache.BufferHandle = AP_MAIL_BOX_CACHE_HANDLE; + if (HeapLocateBuffer (&ApMailboxCache, StdHeader) == AGESA_SUCCESS) { + // If during HEAP_LOCAL_CACHE stage, we get ApMailbox from the local heap. + // If after HEAP_LOCAL_CACHE stage, we get ApMailbox from the BSP's heap (since + // it maintains a copy of each Node's mailboxes. Note: All cores on each node + // share the same data stored in each node's ApMailbox struct. + Node = FamilyServices->GetStoredNodeNumber (FamilyServices, StdHeader); + ASSERT (Node < MAX_NODES); + *ApMailboxInfo = ((AP_MAILBOXES *) ApMailboxCache.BufferPtr)[Node].ApMailInfo.Info; + ASSERT (*ApMailboxInfo != 0xFFFFFFFF); + } else if (!IamBsp) { + // If this is an AP, the hardware register should be good. + ASSERT (StdHeader->HeapStatus == HEAP_LOCAL_CACHE); + FamilyServices->GetApMailboxFromHardware (FamilyServices, &ApMailboxes, StdHeader); + *ApMailboxInfo = ApMailboxes.ApMailInfo.Info; + } else { + // This is the BSC. The hardware mailbox has not been set up yet. + ASSERT (FALSE); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Cache the Ap Mailbox info in our local heap for later use. + * + * This enables us to use the info even after the mailbox register is initialized + * with operational values. Get all the AP mailboxes and keep them in one buffer. + * + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +CacheApMailbox ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN MboxIndex; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + AP_MAILBOXES ApMailboxes; + CPU_SPECIFIC_SERVICES *FamilyServices; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + // Get mailbox from hardware. + FamilyServices->GetApMailboxFromHardware (FamilyServices, &ApMailboxes, StdHeader); + + // Allocate heap for the info + AllocHeapParams.RequestedBufferSize = (sizeof (AP_MAILBOXES)) * MAX_NODES; + AllocHeapParams.BufferHandle = AP_MAIL_BOX_CACHE_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + for (MboxIndex = 0; MboxIndex < MAX_NODES; MboxIndex++) { + // Replicate the same data for each entry in this array, just to make sure + // each index in this array is initialized...and also to prevent us + // from accidentally reading incorrect data. + ((AP_MAILBOXES *) AllocHeapParams.BufferPtr)[MboxIndex] = ApMailboxes; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Cache the mailboxes for all nodes and store them in the BSP's heap + * + * This enables us to use the info even after the mailbox register is initialized + * with operational values. Get all the AP mailboxes and keep them in one buffer. + * + * @param[in] StdHeader Config handle for library and services. + * @param[in] ApMailboxes Pointer to the array which contains the mbox info for ALL + * available nodes. + * @param[in] NumberOfNodes Number of nodes discovered in the system. + * + */ +VOID +CacheBspMailbox ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AP_MAILBOXES *ApMailboxes, + IN UINT8 NumberOfNodes + ) +{ + UINTN MboxIndex; + UINT32 Socket; + UINT32 Module; + AP_MAILBOXES InvalidMailbox; + AP_MAILBOXES *MailboxInHeap; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + // Even though the bsc does not need to send itself a heap index, this sequence performs other important initialization. + // Use '0' as a dummy heap index value. + GetSocketModuleOfNode (0, &Socket, &Module, StdHeader); + GetCpuServicesOfSocket (Socket, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->SetApCoreNumber (FamilySpecificServices, Socket, Module, 0, StdHeader); + FamilySpecificServices->TransferApCoreNumber (FamilySpecificServices, StdHeader); + + // Allocate heap for the info + AllocHeapParams.RequestedBufferSize = (sizeof (AP_MAILBOXES)) * MAX_NODES; + AllocHeapParams.BufferHandle = AP_MAIL_BOX_CACHE_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + MailboxInHeap = (AP_MAILBOXES *) AllocHeapParams.BufferPtr; + // Go through each entry in the Node/Mbox array and write it out to the BSP's heap. + for (MboxIndex = 0; MboxIndex < NumberOfNodes; MboxIndex++) { + MailboxInHeap[MboxIndex] = ApMailboxes[MboxIndex]; + } + InvalidMailbox.ApMailInfo.Info = 0xFFFFFFFF; + InvalidMailbox.ApMailExtInfo.Info = 0xFFFFFFFF; + for (; MboxIndex < MAX_NODES; MboxIndex++) { + MailboxInHeap[MboxIndex] = InvalidMailbox; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Compute the degree of the system. + * + * The degree of a system is the maximum degree of any node. The degree of a node is the + * number of nodes to which it is directly connected (not considering width or redundant + * links). + * + * @param[in] StdHeader Config handle for library and services. + * + */ +UINTN +GetSystemDegree ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Node; + UINT32 Core; + UINT32 Socket; + UINT32 Module; + BOOLEAN NodeStatus; + AGESA_STATUS IdStatus; + AP_MAILBOXES *ApMailboxes; + LOCATE_HEAP_PTR ApMailboxCache; + AGESA_STATUS Status; + + // Identify current core + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IdStatus); + NodeStatus = GetNodeId (Socket, Module, &Node, StdHeader); + // Get data block from heap + ApMailboxCache.BufferHandle = AP_MAIL_BOX_CACHE_HANDLE; + Status = HeapLocateBuffer (&ApMailboxCache, StdHeader); + // non-Success handled by ASSERT not NULL below. + ApMailboxes = (AP_MAILBOXES *) ApMailboxCache.BufferPtr; + ASSERT ((ApMailboxes != NULL) && (Status == AGESA_SUCCESS) && (IdStatus == AGESA_SUCCESS) && NodeStatus); + return ApMailboxes[Node].ApMailExtInfo.Fields.SystemDegree; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Spins until the number of microseconds specified have + * expired regardless of CPU operational frequency. + * + * @param[in] Microseconds Wait time in microseconds + * @param[in] StdHeader Header for library and services + * + */ +VOID +WaitMicroseconds ( + IN UINT32 Microseconds, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TscRateInMhz; + UINT64 NumberOfTicks; + UINT64 InitialTsc; + UINT64 CurrentTsc; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + LibAmdMsrRead (TSC, &InitialTsc, StdHeader); + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetTscRate (FamilySpecificServices, &TscRateInMhz, StdHeader); + NumberOfTicks = Microseconds * TscRateInMhz; + do { + LibAmdMsrRead (TSC, &CurrentTsc, StdHeader); + } while ((CurrentTsc - InitialTsc) < NumberOfTicks); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * A boolean function determine executed CPU is BSP core. + * + * @param[in,out] StdHeader Header for library and services + * @param[out] AgesaStatus Aggregates AGESA_STATUS for external interface, Always Succeeds. + * + */ +BOOLEAN +IsBsp ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + OUT AGESA_STATUS *AgesaStatus + ) +{ + UINT64 MsrData; + + // Always Succeeds. + *AgesaStatus = AGESA_SUCCESS; + + // Read APIC_BASE register (0x1B), bit[8] returns 1 for BSP + LibAmdMsrRead (MSR_APIC_BAR, &MsrData, StdHeader); + if ((MsrData & BIT8) != 0 ) { + return TRUE; + } else { + return FALSE; + } + +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get the compute unit mapping algorithm. + * + * Look up the compute unit values for the current core's socket/module and find the matching + * core pair map item. This will tell us how to determine the core's status. + * + * @param[in] StdHeader Header for library and services + * + * @retval AllCoresMapping Each core is in a compute unit of its own. + * @retval EvenCoresMapping Even/Odd pairs of cores are in each compute unit. + */ +COMPUTE_UNIT_MAPPING +GetComputeUnitMapping ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CurrentCore; + UINT32 Module; + UINT32 Socket; + UINT8 Enabled; + UINT8 DualCore; + UINT8 TripleCore; + UINT8 QuadCore; + AGESA_STATUS IgnoredSts; + SOCKET_DIE_TO_NODE_MAP pSocketDieMap; + LOCATE_HEAP_PTR SocketDieHeapDataBlock; + CPU_SPECIFIC_SERVICES *FamilyServices; + COMPUTE_UNIT_MAP *ComputeUnitMap; + COMPUTE_UNIT_MAPPING Result; + + // Invalid mapping, unless we find one. + Result = MaxComputeUnitMapping; + + IdentifyCore (StdHeader, &Socket, &Module, &CurrentCore, &IgnoredSts); + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + // Get data block from heap + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + IgnoredSts = HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT ((pSocketDieMap != NULL) && (IgnoredSts == AGESA_SUCCESS)); + // Current Core's socket, module must be present. + ASSERT ((*pSocketDieMap)[Socket][Module].Node != 0xFF); + + // Process compute unit info + Enabled = (*pSocketDieMap)[Socket][Module].EnabledComputeUnits; + DualCore = (*pSocketDieMap)[Socket][Module].DualCoreComputeUnits; + TripleCore = (*pSocketDieMap)[Socket][Module].TripleCoreComputeUnits; + QuadCore = (*pSocketDieMap)[Socket][Module].QuadCoreComputeUnits; + ComputeUnitMap = FamilyServices->ComputeUnitMap; + if ((Enabled != 0) && (ComputeUnitMap != NULL)) { + while (ComputeUnitMap->Mapping != MaxComputeUnitMapping) { + if ((Enabled == ComputeUnitMap->Enabled) && + ((DualCore == ComputeUnitMap->DualCore) || (ComputeUnitMap->DualCore == 'x')) && + ((TripleCore == ComputeUnitMap->TripleCore) || (ComputeUnitMap->TripleCore == 'x')) && + ((QuadCore == ComputeUnitMap->QuadCore) || (ComputeUnitMap->QuadCore == 'x'))) { + break; + } + ComputeUnitMap++; + } + // The assert is for finding a processor configured in a way the compute unit map doesn't support. + ASSERT (ComputeUnitMap->Mapping != MaxComputeUnitMapping); + Result = ComputeUnitMap->Mapping; + } else { + // Families that don't have compute units act as though each core is in its own compute unit + // and all cores are primary + Result = AllCoresMapping; + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Is current core the primary core of its compute unit? + * + * Get the mapping algorithm and the current core number. Selecting First/Last ordering for + * primary @b ASSUMES cores are launched in ascending core number order. + * + * @param[in] Selector Select whether first or last core has the primary core role. + * @param[in] StdHeader Header for library and services + * + * @retval TRUE This is the primary core of a compute unit. + * @retval FALSE This is the second shared core of a compute unit. + * + */ +BOOLEAN +IsCoreComputeUnitPrimary ( + IN COMPUTE_UNIT_PRIMARY_SELECTOR Selector, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN Result; + UINT32 CurrentCore; + UINT32 Module; + UINT32 Socket; + AGESA_STATUS IgnoredSts; + + IdentifyCore (StdHeader, &Socket, &Module, &CurrentCore, &IgnoredSts); + + Result = FALSE; + switch (GetComputeUnitMapping (StdHeader)) { + case AllCoresMapping: + // All cores are primaries + Result = TRUE; + break; + case EvenCoresMapping: + // Even core numbers are first to execute, odd cores are last to execute + if (Selector == FirstCoreIsComputeUnitPrimary) { + Result = (BOOLEAN) ((CurrentCore & 1) == 0); + } else { + Result = (BOOLEAN) ((CurrentCore & 1) != 0); + } + break; + case TripleCoresMapping: + if (Selector == FirstCoreIsComputeUnitPrimary) { + Result = (BOOLEAN) ((CurrentCore % 3) == 0); + } else { + Result = (BOOLEAN) ((CurrentCore % 3) == 2); + } + break; + case QuadCoresMapping: + if (Selector == FirstCoreIsComputeUnitPrimary) { + Result = (BOOLEAN) ((CurrentCore % 4) == 0); + } else { + Result = (BOOLEAN) ((CurrentCore % 4) == 3); + } + break; + default: + ASSERT (FALSE); + } + return Result; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * This routine programs the registers necessary to get the PCI MMIO mechanism + * up and functioning. + * + * @param[in] StdHeader Pointer to structure containing the function call + * whose parameter structure is to be created, the + * allocation method, and a pointer to the newly + * created structure. + * + */ +VOID +InitializePciMmio ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 EncodedSize; + UINT64 LocalMsrRegister; + + // Make sure that Standard header is valid + ASSERT (StdHeader != NULL); + + if ((UserOptions.CfgPciMmioAddress != 0) && (UserOptions.CfgPciMmioSize != 0)) { + EncodedSize = LibAmdBitScanForward (UserOptions.CfgPciMmioSize); + LocalMsrRegister = ((UserOptions.CfgPciMmioAddress | BIT0) | (EncodedSize << 2)); + LibAmdMsrWrite (MSR_MMIO_Cfg_Base, &LocalMsrRegister, StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuLateInit.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuLateInit.c new file mode 100644 index 0000000000..9e0451d0ac --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuLateInit.c @@ -0,0 +1,289 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Late Init API + * + * Contains code for doing any late CPU initialization. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuServices.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_CPU_CPULATEINIT_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +DisableCf8ExtCfg ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * Performs CPU related initialization at the late entry point + * + * This function should be the last function run by the AGESA + * CPU module and prepares the processor for the operating system + * bootstrap load process. + * + * @param[in] StdHeader Config handle for library and services + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * + * @retval AGESA_SUCCESS + * + */ +AGESA_STATUS +AmdCpuLate ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig + ) +{ + DisableCf8ExtCfg (StdHeader); + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Clear EnableCf8ExtCfg on all socket + * + * Clear F3x8C bit 14 EnableCf8ExtCfg + * + * @param[in] StdHeader Config handle for library and services + * + * + */ +VOID +DisableCf8ExtCfg ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + PCI_ADDR PciAddress; + UINT32 Socket; + UINT32 Module; + UINT32 PciData; + UINT32 LegacyPciAccess; + + ASSERT (IsBsp (StdHeader, &AgesaStatus)); + + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NB_CFG_HIGH_REG; + LegacyPciAccess = ((1 << 31) + (PciAddress.Address.Register & 0xFC) + (PciAddress.Address.Function << 8) + (PciAddress.Address.Device << 11) + (PciAddress.Address.Bus << 16) + ((PciAddress.Address.Register & 0xF00) << (24 - 8))); + // read from PCI register + LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader); + LibAmdIoRead (AccessWidth32, IOCFC, &PciData, StdHeader); + // Disable Cf8ExtCfg + PciData &= 0xFFFFBFFF; + // write to PCI register + LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader); + LibAmdIoWrite (AccessWidth32, IOCFC, &PciData, StdHeader); + } + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Calculate an ACPI style checksum + * + * Computes the checksum and stores the value to the checksum + * field of the passed in ACPI table's header. + * + * @param[in] Table ACPI table to checksum + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +ChecksumAcpiTable ( + IN OUT ACPI_TABLE_HEADER *Table, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *BuffTempPtr; + UINT8 Checksum; + UINT32 BufferOffset; + + Table->Checksum = 0; + Checksum = 0; + BuffTempPtr = (UINT8 *) Table; + for (BufferOffset = 0; BufferOffset < Table->TableLength; BufferOffset++) { + Checksum = Checksum - *(BuffTempPtr + BufferOffset); + } + + Table->Checksum = Checksum; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Run code on every AP in the system. + * + * @param[in] ApParams AP task pointer. + * @param[in] StdHeader Handle to config for library and services + * + * @return The most severe AGESA_STATUS returned by an AP. + * + */ +AGESA_STATUS +RunLateApTaskOnAllAPs ( + IN AP_EXE_PARAMS *ApParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + UINT8 Socket; + UINT8 Core; + UINT8 ApicId; + UINT32 BscSocket; + UINT32 Ignored; + UINT32 BscCoreNum; + AGESA_STATUS CalledStatus; + AGESA_STATUS IgnoredStatus; + AGESA_STATUS AgesaStatus; + + ASSERT (IsBsp (StdHeader, &IgnoredStatus)); + + AgesaStatus = AGESA_SUCCESS; + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredStatus); + NumberOfSockets = GetPlatformNumberOfSockets (); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCoreNum)) { + GetApicId (StdHeader, Socket, Core, &ApicId, &IgnoredStatus); + AGESA_TESTPOINT (TpIfBeforeRunApFromAllAps, StdHeader); + CalledStatus = AgesaRunFcnOnAp ((UINTN) ApicId, ApParams); + AGESA_TESTPOINT (TpIfAfterRunApFromAllAps, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + } + } + } + } + return AgesaStatus; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Run code on core 0 of every socket in the system. + * + * @param[in] ApParams AP task pointer. + * @param[in] StdHeader Handle to config for library and services + * + * @return The most severe AGESA_STATUS returned by an AP. + * + */ +AGESA_STATUS +RunLateApTaskOnAllCore0s ( + IN AP_EXE_PARAMS *ApParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 NumberOfSockets; + UINT8 Socket; + UINT8 ApicId; + UINT32 BscSocket; + UINT32 IgnoredModule; + UINT32 IgnoredCore; + AGESA_STATUS CalledStatus; + AGESA_STATUS IgnoredStatus; + AGESA_STATUS AgesaStatus; + + ASSERT (IsBsp (StdHeader, &IgnoredStatus)); + + AgesaStatus = AGESA_SUCCESS; + + IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &IgnoredCore, &IgnoredStatus); + NumberOfSockets = GetPlatformNumberOfSockets (); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + if (Socket != BscSocket) { + GetApicId (StdHeader, Socket, 0, &ApicId, &IgnoredStatus); + AGESA_TESTPOINT (TpIfBeforeRunApFromAllCore0s, StdHeader); + CalledStatus = AgesaRunFcnOnAp ((UINTN) ApicId, ApParams); + AGESA_TESTPOINT (TpIfAfterRunApFromAllCore0s, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + } + } + } + return AgesaStatus; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuLateInit.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuLateInit.h new file mode 100644 index 0000000000..b27ed00057 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuLateInit.h @@ -0,0 +1,1137 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Late Init API functions Prototypes. + * + * Contains code for doing any late CPU initialization + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_LATE_INIT_H_ +#define _CPU_LATE_INIT_H_ + +#include "Filecode.h" + +// Forward declaration needed for multi-structure mutual references. +AGESA_FORWARD_DECLARATION (PROC_FAMILY_TABLE); +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +//---------------------------------------------------------------------------- +// DMI DEFINITIONS AND MACROS +// +//---------------------------------------------------------------------------- +#define AP_LATE_TASK_GET_TYPE4_TYPE7 (PROC_CPU_FEATURE_CPUDMI_FILECODE) +// SMBIOS constant definition +#define CENTRAL_PROCESSOR 0x03 +#define EXTERNAL_CLOCK_DFLT 200 +#define EXTERNAL_CLOCK_100MHZ 100 +#define P_FAMILY_UNKNOWN 0x02 +#define P_ENGINEERING_SAMPLE 0x00 +#define P_CHARACTERISTICS 0x4 +#define CACHE_CFG_L1 0x180 +#define CACHE_CFG_L2 0x181 +#define CACHE_CFG_L3 0x182 +#define SRAM_TYPE 0x10 +#define ERR_CORRECT_TYPE 0x06 +#define CACHE_TYPE 0x05 +#define DMI_ASSOCIATIVE_OTHER 0x01 +#define DMI_ASSOCIATIVE_UNKNOWN 0x02 +#define DMI_ASSOCIATIVE_DIRECT_MAPPED 0x03 +#define DMI_ASSOCIATIVE_2_WAY 0x04 +#define DMI_ASSOCIATIVE_4_WAY 0x05 +#define DMI_ASSOCIATIVE_FULLY 0x06 +#define DMI_ASSOCIATIVE_8_WAY 0x07 +#define DMI_ASSOCIATIVE_16_WAY 0x08 +#define DMI_ASSOCIATIVE_12_WAY 0x09 +#define DMI_ASSOCIATIVE_24_WAY 0x0A +#define DMI_ASSOCIATIVE_32_WAY 0x0B +#define DMI_ASSOCIATIVE_48_WAY 0x0C +#define DMI_ASSOCIATIVE_64_WAY 0x0D +#define DMI_ASSOCIATIVE_20_WAY 0x0E +#define SOCKET_POPULATED 0x40 +#define CPU_STATUS_UNKNOWN 0x00 +#define CPU_STATUS_ENABLED 0x01 + +// Processor Upgrade Definition +#define P_UPGRADE_UNKNOWN 0x02 +#define P_UPGRADE_NONE 0x06 +#define P_UPGRADE_S1GX 0x16 +#define P_UPGRADE_AM2 0x17 +#define P_UPGRADE_F1207 0x18 +#define P_UPGRADE_G34 0x1A +#define P_UPGRADE_AM3 0x1B +#define P_UPGRADE_C32 0x1C +#define P_UPGRADE_FS1 0x27 +#define P_UPGRADE_FM1 0x29 +#define P_UPGRADE_FM2 0x2A + +//---------------------------------------------------------------------------- +// SRAT DEFINITIONS AND MACROS +// +//---------------------------------------------------------------------------- +#define NorthbridgeCapabilities 0xE8 +#define DRAMBase0 0x40 +#define MMIOBase0 0x80 +#define TOP_MEM 0xC001001Aul +#define LOW_NODE_DEVICEID 24 +#define LOW_APICID 0 + + +// Miscellaneous AMD related values +#define MAX_NUMBER_NODES 8 + +// Flags +#define ENABLED 1 // Bit 0 +#define DISABLED 0 // Bit 0 +#define HOTPLUGGABLE 2 // Bit 1 + +// Affinity Entry Structures +#define AE_APIC 0 +#define AE_MEMORY 1 + + +// Memory Types +#define TYPE_MEMORY 1 +#define TYPE_RESERVED 2 +#define TYPE_ACPI 3 +#define TYPE_NVS 4 + +//---------------------------------------------------------------------------- +// SLIT DEFINITIONS AND MACROS +// +//---------------------------------------------------------------------------- +#define PROBE_FILTER_CTRL_REG 0x1D4 +#define AMD_ACPI_SLIT_SOCKET_NUM_LENGTH 8 + +//---------------------------------------------------------------------------- +// CDIT DEFINITIONS AND MACROS +// +//---------------------------------------------------------------------------- +#define AMD_ACPI_CDIT_NUM_DOMAINS_LENGTH 4 // Num domains is a 4-bytes unsigned integer + + +//---------------------------------------------------------------------------- +// P-STATE DEFINITIONS AND MACROS +// +//---------------------------------------------------------------------------- +//------------------------------------- +// ERROR Codes +//------------------------------------- +#define NO_ERROR 0x0 +#define USER_DISABLE_ERROR 0x01 // User disabled SSDT generation +#define CORES_MISSMATCH_PSS_ERROR 0x02 // No PSS match +#define PNOW_SUPPORT_ERROR 0x04 // One of the Cores do not support PNOW! +#define PWR_FREQ_MATCH_ERROR 0x08 // FREQ and PWR mismatch +#define NO_PSS_SIZE_ERROR 0x10 // Error in PSS Size +#define INVALID_PSTATE_ERROR 0x20 // Invalid Max or only 1 P-State available +#define NO_PSS_ENTRY 0x0FFFFul +#define INVALID_FREQ 0x0FFFFFFFFul + +//------------------------- +// Default definitions +// AMD BKDG default values +//------------------------- +#define DEFAULT_ISOCH_RELIEF_TIME IRT_80uS +#define DEFAULT_RAMP_VOLTAGE_OFFSET RVO_50mV +#define DEFAULT_MAX_VOLTAGE_STEP MVS_25mV +#define DEFAULT_PERF_PRESENT_CAP 0 // default for Desktop +#define DEFAULT_VOLTAGE_STABLE_TIME (100 / 20) // 100uS +#define DEFAULT_PLL_LOCK_TIME 2 // 2uS +#define DEFAULT_TRANSITION_LATENCY 100 // 100uS +#define DEFAULT_BUS_MASTER_LATENCY 9 // 9uS +#define DEFAULT_CPU_SCOPE_NUMBER "0UPC" + +// Defines for Common ACPI +// ----------------------------- +#define SCOPE_OPCODE 0x10 +#define NAME_OPCODE 0x08 +#define METHOD_OPCODE 0x14 +#define PACKAGE_OPCODE 0x12 +#define BUFFER_OPCODE 0x11 +#define BYTE_PREFIX_OPCODE 0x0A +#define WORD_PREFIX_OPCODE 0x0B +#define DWORD_PREFIX_OPCODE 0x0C +#define RETURN_OPCODE 0xA4 +#define ACPI_BUFFER 0x080A0B11ul + +// Generic Register Descriptor (GDR) Fields +#define GDR_ASI_SYSTEM_IO 0x01 // Address Space ID +#define GDR_ASZ_BYTE_ACCESS 0x01 // Address Size + +// Defines for ACPI Scope Table +// ---------------------------- +#define SCOPE_LENGTH (SCOPE_STRUCT_SIZE + \ + PCT_STRUCT_SIZE + \ + PSS_HEADER_STRUCT_SIZE + \ + PSS_BODY_STRUCT_SIZE + \ + PPC_HEADER_BODY_STRUCT_SIZE) +#define SCOPE_VALUE1 0x5C +#define SCOPE_VALUE2 0x2E +#define SCOPE_NAME__ '_' +#define SCOPE_NAME_P 'P' +#define SCOPE_NAME_R 'R' +#define SCOPE_NAME_S 'S' +#define SCOPE_NAME_B 'B' +#define SCOPE_NAME_C 'C' +#define SCOPE_NAME_U 'U' +#define SCOPE_NAME_0 '0' +#define SCOPE_NAME_1 '1' +#define SCOPE_NAME_2 '2' +#define SCOPE_NAME_3 '3' +#define SCOPE_NAME_A 'A' + +#ifdef OEM_SCOPE_NAME + #if (OEM_SCOPE_NAME > 'Z') || (OEM_SCOPE_NAME < 'A') + #error "OEM_SCOPE_NAME: it should be only one char long AND a valid letter (A~Z)" + #endif + #define SCOPE_NAME_VALUE OEM_SCOPE_NAME +#else + #define SCOPE_NAME_VALUE SCOPE_NAME_C +#endif // OEM_SCOPE_NAME + +#ifdef OEM_SCOPE_NAME1 + #if (!(((OEM_SCOPE_NAME1 >= 'A') && (OEM_SCOPE_NAME1 <= 'Z')) || \ + ((OEM_SCOPE_NAME1 >= '0') && (OEM_SCOPE_NAME1 <= '9')) || \ + (OEM_SCOPE_NAME1 == '_'))) + #error "OEM_SCOPE_NAME1: it should be only one char long AND a valid letter (0~9, A~F)" + #endif + #define SCOPE_NAME_VALUE1 OEM_SCOPE_NAME1 +#else + #define SCOPE_NAME_VALUE1 SCOPE_NAME_0 +#endif // OEM_SCOPE_NAME + +// Defines for PCT Control and Status Table +// ---------------------------------------- +#define PCT_NAME__ '_' +#define PCT_NAME_P 'P' +#define PCT_NAME_C 'C' +#define PCT_NAME_T 'T' +#define PCT_VALUE1 0x11022C12ul +#define PCT_VALUE2 0x0A14 +#define PCT_VALUE3 0x11 +#define GENERIC_REG_DESCRIPTION 0x82 +#define PCT_LENGTH 0x0C +#define PCT_ADDRESS_SPACE_ID 0x7F +#define PCT_REGISTER_BIT_WIDTH 0x40 +#define PCT_REGISTER_BIT_OFFSET 0x00 +#define PCT_RESERVED 0x00 +#define PCT_CONTROL_REG_LO 0xC0010062ul +#define PCT_CONTROL_REG_HI 0x00 +#define PCT_VALUE4 0x14110079ul +#define PCT_VALUE5 0x110A +#define PCT_STATUS_REG_LO 0x00 +#define PCT_STATUS_REG_HI 0x00 +#define PCT_VALUE6 0x0079 + + +// Defines for PSS Header Table +// ---------------------------- +#define PSS_NAME__ '_' +#define PSS_NAME_X 'X' +#define PSS_NAME_P 'P' +#define PSS_NAME_S 'S' +#define PSS_LENGTH (sizeof pssBodyStruct + 3) +#define NUM_OF_ITEMS_IN_PSS 0x00 + + +// Defines for PSS Header Table +// ---------------------------- +#define PSS_PKG_LENGTH 0x20 // PSS_BODY_STRUCT_SIZE - 1 +#define PSS_NUM_OF_ELEMENTS 0x06 +#define PSS_FREQUENCY 0x00 +#define PSS_POWER 0x00 +#define PSS_TRANSITION_LATENCY DEFAULT_TRANSITION_LATENCY +#define PSS_BUS_MASTER_LATENCY DEFAULT_BUS_MASTER_LATENCY +#define PSS_CONTROL ((DEFAULT_ISOCH_RELIEF_TIME << 30) + \ + (DEFAULT_RAMP_VOLTAGE_OFFSET << 28) + \ + (DEFAULT_EXT_TYPE << 27) + \ + (DEFAULT_PLL_LOCK_TIME << 20) + \ + (DEFAULT_MAX_VOLTAGE_STEP << 18) + \ + (DEFAULT_VOLTAGE_STABLE_TIME << 11) + \ + (PSS_VID << 6) + PSS_FID) +#define PSS_STATUS (DEFAULT_EXTENDED_TYPE << 11) + (PSS_VID << 6) + (PSS_FID) + +// Defines for XPSS Header Table +// ---------------------------- +#define XPSS_PKG_LENGTH 0x47 // XPSS_BODY_STRUCT_SIZE - 1 +#define XPSS_NUM_OF_ELEMENTS 0x08 +#define XPSS_ACPI_BUFFER 0x080A0B11ul + + +// Defines for PPC Header Table +// ---------------------------- +#define PPC_NAME__ '_' +#define PPC_NAME_P 'P' +#define PPC_NAME_C 'C' +#define PPC_NAME_V 'V' +#define PPC_METHOD_FLAGS 0x00; +#define PPC_VALUE1 0x0A; + +// Defines for PSD Header Table +// ---------------------------- +#define PSD_NAME__ '_' +#define PSD_NAME_P 'P' +#define PSD_NAME_S 'S' +#define PSD_NAME_D 'D' +#define PSD_HEADER_LENGTH (PSD_BODY_STRUCT_SIZE + 2) +#define PSD_VALUE1 0x01 + + +// Defines for PSD Header Table +// ---------------------------- +#define PSD_PKG_LENGTH (PSD_BODY_STRUCT_SIZE - 1) +#define NUM_OF_ENTRIES 0x05 +#define PSD_NUM_OF_ENTRIES 0x05 +#define PSD_REVISION 0x00 +#define PSD_DEPENDENCY_DOMAIN 0x00 +#define PSD_COORDINATION_TYPE_HW_ALL 0xFE +#define PSD_COORDINATION_TYPE_SW_ANY 0xFD +#define PSD_COORDINATION_TYPE_SW_ALL 0xFC +#define PSD_NUM_OF_PROCESSORS 0x01 +#define PSD_TWO_CORES_PER_COMPUTE_UNIT 0x02 +#define PSD_THREE_CORES_PER_COMPUTE_UNIT 0x03 +#define PSD_FOUR_CORES_PER_COMPUTE_UNIT 0x04 + + +#define CUSTOM_PSTATE_FLAG 0x55 +#define PSTATE_FLAG_1 0x55 +#define TARGET_PSTATE_FLAG 0xAA +#define PSTATE_FLAG_2 0xAA + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *---------------------------------------------------------------------------------------- + */ +//---------------------------------------------------------------------------- +// ACPI P-States AML TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- + +//-------------------------------------------- +// AML code definition +// (Scope) +//--------------------------------------------- +/// SCOPE +typedef struct _SCOPE { + UINT8 ScopeOpcode; ///< Opcode + UINT16 ScopeLength; ///< Scope Length + UINT8 ScopeValue1; ///< Value1 + UINT8 ScopeValue2; ///< Value2 + UINT8 ScopeNamePt1a__; ///< Name Pointer + UINT8 ScopeNamePt1a_P; ///< Name Pointer + UINT8 ScopeNamePt1a_R; ///< Name Pointer + UINT8 ScopeNamePt1b__; ///< Name Pointer + UINT8 ScopeNamePt2a_C; ///< Name Pointer + UINT8 ScopeNamePt2a_P; ///< Name Pointer + UINT8 ScopeNamePt2a_U; ///< Name Pointer + UINT8 ScopeNamePt2a_0; ///< Name Pointer +} SCOPE; +#define SCOPE_STRUCT_SIZE 13 // 13 Bytes + +//-------------------------------------------- +// AML code definition +// (PCT Header and Body) +//--------------------------------------------- + +///Performance Control Header +typedef struct _PCT_HEADER_BODY { + UINT8 NameOpcode; ///< Opcode + UINT8 PctName_a__; ///< String "_" + UINT8 PctName_a_P; ///< String "P" + UINT8 PctName_a_C; ///< String "C" + UINT8 PctName_a_T; ///< String "T" + UINT32 Value1; ///< Value1 + UINT16 Value2; ///< Value2 + UINT8 Value3; ///< Value3 + UINT8 GenericRegDescription1; ///< Generic Reg Description + UINT16 Length1; ///< Length1 + UINT8 AddressSpaceId1; ///< PCT Address Space ID + UINT8 RegisterBitWidth1; ///< PCT Register Bit Width + UINT8 RegisterBitOffset1; ///< PCT Register Bit Offset + UINT8 Reserved1; ///< Reserved + UINT32 ControlRegAddressLo; ///< Control Register Address Low + UINT32 ControlRegAddressHi; ///< Control Register Address High + UINT32 Value4; ///< Value4 + UINT16 Value5; ///< Value 5 + UINT8 GenericRegDescription2; ///< Generic Reg Description + UINT16 Length2; ///< Length2 + UINT8 AddressSpaceId2; ///< PCT Address Space ID + UINT8 RegisterBitWidth2; ///< PCT Register Bit Width + UINT8 RegisterBitOffset2; ///< PCT Register Bit Offset + UINT8 Reserved2; ///< Reserved + UINT32 StatusRegAddressLo; ///< Control Register Address Low + UINT32 StatusRegAddressHi; ///< Control Register Address High + UINT16 Value6; ///< Values +} PCT_HEADER_BODY; +#define PCT_STRUCT_SIZE 50 // 50 Bytes + + +//-------------------------------------------- +// AML code definition +// (PSS Header) +//-------------------------------------------- +///Performance Supported States Header +typedef struct _PSS_HEADER { + UINT8 NameOpcode; ///< Opcode + UINT8 PssName_a__; ///< String "_" + UINT8 PssName_a_P; ///< String "P" + UINT8 PssName_a_S; ///< String "S" + UINT8 PssName_b_S; ///< String "S" + UINT8 PkgOpcode; ///< Package Opcode + UINT16 PssLength; ///< PSS Length + UINT8 NumOfItemsInPss; ///< Number of Items in PSS +} PSS_HEADER; +#define PSS_HEADER_STRUCT_SIZE 9 // 9 Bytes + + +//-------------------------------------------- +// AML code definition +// (PSS Body) +//-------------------------------------------- +///Performance Supported States Body +typedef struct _PSS_BODY { + UINT8 PkgOpcode; ///< Package Opcode + UINT8 PkgLength; ///< Package Length + UINT8 NumOfElements; ///< Number of Elements + UINT8 DwordPrefixOpcode1; ///< Prefix Opcode1 + UINT32 Frequency; ///< Frequency + UINT8 DwordPrefixOpcode2; ///< Prefix Opcode2 + UINT32 Power; ///< Power + UINT8 DwordPrefixOpcode3; ///< Prefix Opcode3 + UINT32 TransitionLatency; ///< Transition Latency + UINT8 DwordPrefixOpcode4; ///< Prefix Opcode4 + UINT32 BusMasterLatency; ///< Bus Master Latency + UINT8 DwordPrefixOpcode5; ///< Prefix Opcode5 + UINT32 Control; ///< Control + UINT8 DwordPrefixOpcode6; ///< Prefix Opcode6 + UINT32 Status; ///< Status +} PSS_BODY; +#define PSS_BODY_STRUCT_SIZE 33 // 33 Bytes + + +/*-------------------------------------------- + * AML code definition + * (XPSS Header) + *-------------------------------------------- + */ +/// Extended PSS Header +typedef struct _XPSS_HEADER { + UINT8 NameOpcode; ///< 08h + UINT8 XpssName_a_X; ///< String "X" + UINT8 XpssName_a_P; ///< String "P" + UINT8 XpssName_a_S; ///< String "S" + UINT8 XpssName_b_S; ///< String "S" + UINT8 PkgOpcode; ///< 12h + UINT16 XpssLength; ///< XPSS Length + UINT8 NumOfItemsInXpss; ///< Number of Items in XPSS +} XPSS_HEADER; +#define XPSS_HEADER_STRUCT_SIZE 9 // 9 Bytes + +/*-------------------------------------------- + * AML code definition + * (XPSS Body) + *-------------------------------------------- + */ +/// Extended PSS Body +typedef struct _XPSS_BODY { + UINT8 PkgOpcode; ///< 12h + UINT8 PkgLength; ///< Package Length + UINT8 XpssValueTbd; ///< XPSS Value + UINT8 NumOfElements; ///< Number of Elements + UINT8 DwordPrefixOpcode1; ///< Prefix Opcode1 + UINT32 Frequency; ///< Frequency + UINT8 DwordPrefixOpcode2; ///< Prefix Opcode2 + UINT32 Power; ///< Power + UINT8 DwordPrefixOpcode3; ///< Prefix Opcode3 + UINT32 TransitionLatency; ///< Transition Latency + UINT8 DwordPrefixOpcode4; ///< Prefix Opcode4 + UINT32 BusMasterLatency; ///< Bus Master Latency + UINT32 ControlBuffer; ///< Control Buffer + UINT32 ControlLo; ///< Control Low + UINT32 ControlHi; ///< Control High + UINT32 StatusBuffer; ///< Status Buffer + UINT32 StatusLo; ///< Status Low + UINT32 StatusHi; ///< Status High + UINT32 ControlMaskBuffer; ///< Control Mask Buffer + UINT32 ControlMaskLo; ///< Control Mask Low + UINT32 ControlMaskHi; ///< Control Mask High + UINT32 StatusMaskBuffer; ///< Status Mask Buffer + UINT32 StatusMaskLo; ///< Status Mask Low + UINT32 StatusMaskHi; ///< Status Mask High +} XPSS_BODY; +#define XPSS_BODY_STRUCT_SIZE 72 // 72 Bytes + +/*-------------------------------------------- + * AML code definition + * (PPC Header and Body) + *-------------------------------------------- + */ +/// Performance Present Capabilities Header +typedef struct _PPC_HEADER_BODY { + UINT8 NameOpcode; ///< Name Opcode + UINT8 PpcName_a_P; ///< String "P" + UINT8 PpcName_b_P; ///< String "P" + UINT8 PpcName_a_C; ///< String "C" + UINT8 PpcName_a_V; ///< String "V" + UINT8 Value1; ///< Value + UINT8 DefaultPerfPresentCap; ///< Default Perf Present Cap + UINT8 MethodOpcode; ///< Method Opcode + UINT8 PpcLength; ///< Method Length + UINT8 PpcName_a__; ///< String "_" + UINT8 PpcName_c_P; ///< String "P" + UINT8 PpcName_d_P; ///< String "P" + UINT8 PpcName_b_C; ///< String "C" + UINT8 MethodFlags; ///< Method Flags + UINT8 ReturnOpcode; ///< Return Opcoce + UINT8 PpcName_e_P; ///< String "P" + UINT8 PpcName_f_P; ///< String "P" + UINT8 PpcName_c_C; ///< String "C" + UINT8 PpcName_b_V; ///< String "V" + +} PPC_HEADER_BODY; +#define PPC_HEADER_BODY_STRUCT_SIZE 19 // 19 Bytes +#define PPC_METHOD_LENGTH 11 // 11 Bytes + + +/*-------------------------------------------- + * AML code definition + * (PSD Header) + *-------------------------------------------- + */ +/// P-State Dependency Header +typedef struct _PSD_HEADER { + UINT8 NameOpcode; ///< Name Opcode + UINT8 PsdName_a__; ///< String "_" + UINT8 PsdName_a_P; ///< String "P" + UINT8 PsdName_a_S; ///< String "S" + UINT8 PsdName_a_D; ///< String "D" + UINT8 PkgOpcode; ///< Package Opcode + UINT8 PsdLength; ///< PSD Length + UINT8 Value1; ///< Value +} PSD_HEADER; +#define PSD_HEADER_STRUCT_SIZE 8 // 8 Bytes + +/*-------------------------------------------- + * AML code definition + * (PSD Body) + *-------------------------------------------- + */ +/// P-State Dependency Body +typedef struct _PSD_BODY { + UINT8 PkgOpcode; ///< Package Opcode + UINT8 PkgLength; ///< Package Length + UINT8 NumOfEntries; ///< Number of Entries + UINT8 BytePrefixOpcode1; ///< Prefix Opcode1 in Byte + UINT8 PsdNumOfEntries; ///< PSD Number of Entries + UINT8 BytePrefixOpcode2; ///< Prefix Opcode2 in Byte + UINT8 PsdRevision; ///< PSD Revision + UINT8 DwordPrefixOpcode1; ///< Prefix Opcode1 in DWord + UINT32 DependencyDomain; ///< Dependency Domain + UINT8 DwordPrefixOpcode2; ///< Prefix Opcode2 in DWord + UINT32 CoordinationType; ///< (0xFC = SW_ALL, 0xFD = SW_ANY, 0xFE = HW_ALL) + UINT8 DwordPrefixOpcode3; ///< Prefix Opcode3 in DWord + UINT32 NumOfProcessors; ///< Number of Processors +} PSD_BODY; +#define PSD_BODY_STRUCT_SIZE 22 // 22 Bytes + +//---------------------------------------------------------------------------- +// WHEA TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- + +/// HEST MCE TABLE +typedef struct _AMD_HEST_MCE_TABLE { + UINT16 TblLength; ///< Length, in bytes, of entire AMD_HEST_MCE structure. + UINT32 GlobCapInitDataLSD; ///< Holds the value that the OS will program into + UINT32 GlobCapInitDataMSD; ///< the machine check global capability register(MCG_CAP). + UINT32 GlobCtrlInitDataLSD; ///< Holds the value that the OS will program into + UINT32 GlobCtrlInitDataMSD; ///< the machine check global control register(MCG_CTL). + UINT8 NumHWBanks; ///< The number of hardware error reporting banks. + UINT8 Rsvd[7]; ///< reserve 7 bytes as spec's required +} AMD_HEST_MCE_TABLE; + +/// HEST CMC TABLE +typedef struct _AMD_HEST_CMC_TABLE { + UINT16 TblLength; ///< Length, in bytes, of entire AMD_HEST_CMC structure. + UINT8 NumHWBanks; ///< The number of hardware error reporting banks. + UINT8 Rsvd[3]; ///< reserve 3 bytes as spec's required +} AMD_HEST_CMC_TABLE; + +/// HEST BANK +typedef struct _AMD_HEST_BANK { + UINT8 BankNum; ///< Zero-based index identifies the machine check error bank. + UINT8 ClrStatusOnInit; ///< Indicates if the status information in this machine check bank + ///< is to be cleared during system initialization. + UINT8 StatusDataFormat; ///< Indicates the format of the data in the status register + UINT8 ConfWriteEn; ///< This field indicates whether configuration parameters may be + ///< modified by the OS. If the bit for the associated parameter is + ///< set, the parameter is writable by the OS. + UINT32 CtrlRegMSRAddr; ///< Address of the hardware bank's control MSR. Ignored if zero. + + UINT32 CtrlInitDataLSD; ///< This is the value the OS will program into the machine check + UINT32 CtrlInitDataMSD; ///< bank's control register + UINT32 StatRegMSRAddr; ///< Address of the hardware bank's MCi_STAT MSR. Ignored if zero. + UINT32 AddrRegMSRAddr; ///< Address of the hardware bank's MCi_ADDR MSR. Ignored if zero. + UINT32 MiscRegMSRAddr; ///< Address of the hardware bank's MCi_MISC MSR. Ignored if zero. +} AMD_HEST_BANK; + +/// Initial data of AMD_HEST_BANK +typedef struct _AMD_HEST_BANK_INIT_DATA { + UINT32 CtrlInitDataLSD; ///< Initial data of CtrlInitDataLSD + UINT32 CtrlInitDataMSD; ///< Initial data of CtrlInitDataMSD + UINT32 CtrlRegMSRAddr; ///< Initial data of CtrlRegMSRAddr + UINT32 StatRegMSRAddr; ///< Initial data of StatRegMSRAddr + UINT32 AddrRegMSRAddr; ///< Initial data of AddrRegMSRAddr + UINT32 MiscRegMSRAddr; ///< Initial data of MiscRegMSRAddr +} AMD_HEST_BANK_INIT_DATA; + +/// MSR179 Global Machine Check Capabilities data struct +typedef struct _MSR_MCG_CAP_STRUCT { + UINT64 Count:8; ///< Indicates the number of + ///< error-reporting banks visible to each core + UINT64 McgCtlP:1; ///< 1=The machine check control registers + UINT64 Rsvd:55; ///< reserved +} MSR_MCG_CAP_STRUCT; + +/// Initial data of WHEA +typedef struct _AMD_WHEA_INIT_DATA { + UINT32 GlobCapInitDataLSD; ///< Holds the value that the OS will program into the machine + UINT32 GlobCapInitDataMSD; ///< Check global capability register + UINT32 GlobCtrlInitDataLSD; ///< Holds the value that the OS will grogram into the machine + UINT32 GlobCtrlInitDataMSD; ///< Check global control register + UINT8 ClrStatusOnInit; ///< Indicates if the status information in this machine check + ///< bank is to be cleared during system initialization + UINT8 StatusDataFormat; ///< Indicates the format of the data in the status register + UINT8 ConfWriteEn; ///< This field indicates whether configuration parameters may be + ///< modified by the OS. If the bit for the associated parameter is + ///< set, the parameter is writable by the OS. + UINT8 HestBankNum; ///< Number of HEST Bank + AMD_HEST_BANK_INIT_DATA *HestBankInitData; ///< Pointer to Initial data of HEST Bank +} AMD_WHEA_INIT_DATA; + +//---------------------------------------------------------------------------- +// DMI TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/// DMI brand information +typedef struct { + UINT16 String1:4; ///< String1 + UINT16 String2:4; ///< String2 + UINT16 Model:7; ///< Model + UINT16 Pg:1; ///< Page +} BRAND_ID; + +/// DMI cache information +typedef struct { + UINT32 L1CacheSize; ///< L1 cache size + UINT8 L1CacheAssoc; ///< L1 cache associativity + UINT32 L2CacheSize; ///< L2 cache size + UINT8 L2CacheAssoc; ///< L2 cache associativity + UINT32 L3CacheSize; ///< L3 cache size + UINT8 L3CacheAssoc; ///< L3 cache associativity +} CPU_CACHE_INFO; + +/// DMI processor information +typedef struct { + UINT8 ExtendedFamily; ///< Extended Family + UINT8 ExtendedModel; ///< Extended Model + UINT8 BaseFamily; ///< Base Family + UINT8 BaseModel; ///< Base Model + UINT8 Stepping; ///< Stepping + UINT8 PackageType; ///< PackageType + BRAND_ID BrandId; ///< BrandId which contains information about String1, String2, Model and Page + UINT8 TotalCoreNumber; ///< Number of total cores + UINT8 EnabledCoreNumber; ///< Number of enabled cores + UINT8 ProcUpgrade; ///< ProcUpdrade + CPU_CACHE_INFO CacheInfo; ///< CPU cache info +} CPU_TYPE_INFO; + +/// A structure containing processor name string and +/// the value that should be provide to DMI type 4 processor family +typedef struct { + IN CONST CHAR8 *Stringstart; ///< The literal string + IN UINT8 T4ProcFamilySetting; ///< The value set to DMI type 4 processor family +} CPU_T4_PROC_FAMILY; + +/// DMI ECC information +typedef struct { + BOOLEAN EccCapable; ///< ECC Capable +} CPU_GET_MEM_INFO; + +/* Transfer vectors for DMI family specific routines */ +typedef VOID OPTION_DMI_GET_CPU_INFO ( + IN OUT CPU_TYPE_INFO *CpuInfoPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef VOID OPTION_DMI_GET_PROC_FAMILY ( + IN OUT UINT8 *T4ProcFamily, + IN PROC_FAMILY_TABLE *CpuDmiProcFamilyTable, + IN CPU_TYPE_INFO *CpuInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef UINT8 OPTION_DMI_GET_VOLTAGE ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef UINT16 OPTION_DMI_GET_MAX_SPEED ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef UINT16 OPTION_DMI_GET_EXT_CLOCK ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef VOID OPTION_DMI_GET_MEM_INFO ( + IN OUT CPU_GET_MEM_INFO *CpuGetMemInfoPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Brand table entry format +typedef struct { + UINT8 PackageType; ///< Package type + UINT8 PgOfBrandId; ///< Page + UINT8 NumberOfCores; ///< Number of cores + UINT8 String1ofBrandId; ///< String1 + UINT8 ValueSetToDmiTable; ///< The value which will should be set to DMI table +} DMI_BRAND_ENTRY; + +/// Family specific data table structure +struct _PROC_FAMILY_TABLE { + UINT64 ProcessorFamily; ///< processor + OPTION_DMI_GET_CPU_INFO *DmiGetCpuInfo; ///< transfer vectors + OPTION_DMI_GET_PROC_FAMILY *DmiGetT4ProcFamily; ///< Get DMI type 4 processor family information + OPTION_DMI_GET_VOLTAGE *DmiGetVoltage; ///< vector for reading voltage + OPTION_DMI_GET_MAX_SPEED *DmiGetMaxSpeed; ///< vector for reading speed + OPTION_DMI_GET_EXT_CLOCK *DmiGetExtClock; ///< vector for reading external clock speed + OPTION_DMI_GET_MEM_INFO *DmiGetMemInfo; ///< Get memory information + UINT8 LenBrandList; ///< size of brand table + CONST DMI_BRAND_ENTRY *DmiBrandList; ///< translate brand info to DMI identifier +}; + +//---------------------------------------------------------------------------- +// SLIT TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/// Format for SRAT Header +typedef struct { + UINT8 Sign[4]; ///< Signature + UINT32 TableLength; ///< Table Length + UINT8 Revision; ///< Revision + UINT8 Checksum; ///< Checksum + UINT8 OemId[6]; ///< OEM ID + UINT8 OemTableId[8]; ///< OEM Tabled ID + UINT32 OemRev; ///< OEM Revision + UINT8 CreatorId[4]; ///< Creator ID + UINT32 CreatorRev; ///< Creator Revision +} ACPI_TABLE_HEADER; + +//---------------------------------------------------------------------------- +// SRAT TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/// Format for SRAT Header +typedef struct _CPU_SRAT_HEADER { + UINT8 Sign[4]; ///< Signature + UINT32 TableLength; ///< Table Length + UINT8 Revision; ///< Revision + UINT8 Checksum; ///< Checksum + UINT8 OemId[6]; ///< OEM ID + UINT8 OemTableId[8]; ///< OEM Tabled ID + UINT32 OemRev; ///< OEM Revision + UINT8 CreatorId[4]; ///< Creator ID + UINT32 CreatorRev; ///< Creator Revision + UINT32 TableRev; ///< Table Revision + UINT8 Reserved[8]; ///< Reserved +} CPU_SRAT_HEADER; + + +/// Format for SRAT APIC Affinity Entry +typedef struct _CPU_SRAT_APIC_ENTRY { + UINT8 Type; ///< Type + UINT8 Length; ///< Length + UINT8 Domain; ///< Domain + UINT8 ApicId; ///< Apic ID + UINT32 Flags; ///< Flags + UINT8 LSApicEid; ///< Local SAPIC EID + UINT8 Reserved[7]; ///< Reserved +} CPU_SRAT_APIC_ENTRY; + + +/// Format for SRAT Memory Affinity Entry +typedef struct _CPU_SRAT_MEMORY_ENTRY { + UINT8 Type; ///< 0: Memory affinity = 1 + UINT8 Length; ///< 1: Length = 40 bytes + UINT32 Domain; ///< 2: Proximity domain + UINT8 Reserved1[2]; ///< 6: Reserved + UINT32 BaseAddrLow; ///< 8: Low 32bits address base + UINT32 BaseAddrHigh; ///< 12: High 32bits address base + UINT32 LengthAddrLow; ///< 16: Low 32bits address limit + UINT32 LengthAddrHigh; ///< 20: High 32bits address limit + UINT8 Reserved2[4]; ///< 24: Memory Type + UINT32 Flags; ///< 28: Flags + UINT8 Reserved3[8]; ///< 32: Reserved +} CPU_SRAT_MEMORY_ENTRY; + +//---------------------------------------------------------------------------- +// CRAT TYPEDEFS, STRUCTURES, ENUMS +// Component Resource Affinity Table +//---------------------------------------------------------------------------- +/// Format for CRAT Header +typedef struct { + UINT8 Sign[4]; ///< CRAT, Signature for the Component Resource Affinity Table. + UINT32 Length; ///< Length, in bytes, of the entire CRAT + UINT8 Revision; ///< 0 + UINT8 Checksum; ///< Entire table must sum to zero. + UINT8 OemId[6]; ///< OEM ID + UINT8 OemTableId[8]; ///< OEM Tabled ID + UINT32 OemRev; ///< OEM Revision + UINT8 CreatorId[4]; ///< Creator ID + UINT32 CreatorRev; ///< Creator Revision + UINT32 TotalEntries; ///< total number[n] of entries in the CRAT + UINT16 NumDomains; ///< Number of HSA proximity domains + UINT8 Reserved[6]; ///< Reserved +} CRAT_HEADER; + +/// Flags field of the CRAT HSA Processing Unit Affinity Structure +typedef struct { + UINT32 Enabled:1; ///< Enabled + UINT32 HotPluggable:1; ///< Hot Pluggable + UINT32 CpuPresent:1; ///< Cpu Present + UINT32 GpuPresent:1; ///< Gpu Present + UINT32 IommuPresent:1; ///< IOMMU Present + UINT32 :27; ///< Reserved +} CRAT_HSA_PROCESSING_UNIT_FLAG; + +/// CRAT HSA Processing Unit Affinity Structure +typedef struct { + UINT8 Type; ///< 0 - CRAT HSA Processing Unit Structure + UINT8 Length; ///< 40 + UINT16 Reserved; ///< Reserved + CRAT_HSA_PROCESSING_UNIT_FLAG Flags; ///< Flags - HSA Processing Unit Affinity Structure + UINT32 ProximityDomain; ///< Integer that represents the proximity domain to which the node belongs to + UINT32 ProcessorIdLow; ///< Low value of the logical processor included in this HSA proximity domain + UINT16 NumCPUCores; ///< Indicates count of CCompute execution units present in this APU node. + UINT16 NumSIMDCores; ///< Indicates maximum count of HCompute SIMD cores present in this node. + UINT16 MaxWavesSIMD; ///< This identifies the max. number of launched waves per SIMD. + UINT16 IoCount; ///< Number of discoverable IO Interfaces connecting this node to other components. + UINT16 HSACapability; ///< Must be 0 + UINT16 LDSSizeInKB; ///< Size of LDS memory per SIMD Wavefront + UINT8 WaveFrontSize; ///< 64, may be 32 for some FSA based architectures + UINT8 NumBanks; ///< Number of Banks or "Shader Engines", typically 1 or 2 + UINT16 uEngineIdentifier; ///< Identifier (Rev) of the GPU uEngine or firmware + UINT8 NumArrays; ///< Number of SIMD Arrays per Engine + UINT8 NumCUPerArray; ///< Number of Compute Units (CU) per SIMD Array + UINT8 NumSIMDPerCU; ///< Number of SIMD representing a Compute Unit + UINT8 MaxSlotsScratchCU; ///< Max. Number of temp. memory ("scratch") wave slots + ///< available to access, may be 0 if HW has no restrictions + UINT8 Reserved1[4]; ///< Reserved +} CRAT_HSA_PROCESSING_UNIT; + +/// Flags field of the CRAT Memory Affinity Structure +typedef struct { + UINT32 Enabled:1; ///< Enabled + UINT32 HotPluggable:1; ///< Hot Pluggable + UINT32 NonVolatile:1; ///< If set, the memory region represents Non-Volatile memory + UINT32 :29; ///< Reserved +} CRAT_MEMORY_FLAG; + +/// CRAT Memory Affinity Structure +typedef struct { + UINT8 Type; ///< 1 - CRAT Memory Affinity Structure + UINT8 Length; ///< 40 + UINT16 Reserved; ///< Reserved + CRAT_MEMORY_FLAG Flags; ///< Flags - Memory Affinity Structure. Indicates whether the region of memory is enabled and can be hot plugged + UINT32 ProximityDomain; ///< Integer that represents the proximity domain to which the node belongs to + UINT32 BaseAddressLow; ///< Low 32Bits of the Base Address of the memory range + UINT32 BaseAddressHigh; ///< High 32Bits of the Base Address of the memory range + UINT32 LengthLow; ///< Low 32Bits of the length of the memory range + UINT32 LengthHigh; ///< High 32Bits of the length of the memory range + UINT32 Width; ///< Memory width - Specifies the number of parallel bits of the memory interface + UINT8 Reserved1[8]; ///< Reserved +} CRAT_MEMORY; + +/// Flags field of the CRAT Cache Affinity structure +typedef struct { + UINT32 Enabled:1; ///< Enabled + UINT32 DataCache:1; ///< 1 if cache includes data + UINT32 InstructionCache:1; ///< 1 if cache includes instructions + UINT32 CpuCache:1; ///< 1 if cache is part of CPU functionality + UINT32 SimdCache:1; ///< 1 if cache is part of SIMD functionality + UINT32 :27; ///< Reserved +} CRAT_CACHE_FLAG; + +/// CRAT Cache Affinity Structure +typedef struct { + UINT8 Type; ///< 2 - CRAT Cache Affinity Structure + UINT8 Length; ///< 64 + UINT16 Reserved; ///< Reserved + CRAT_CACHE_FLAG Flags; ///< Flags - Cache Affinity Structure. Indicates whether the region of cache is enabled + UINT32 ProcessorIdLow; ///< Low value of a logical processor which includes this component + UINT8 SiblingMap[32]; ///< Bitmask of Processor Id sharing this component. 1 bit per logical processor + UINT32 CacheSize; ///< Cache size in KB + UINT8 CacheLevel; ///< Integer representing level: 1, 2, 3, 4, etc. + UINT8 LinesPerTag; ///< Cache Lines per tag + UINT16 CacheLineSize; ///< Cache line size in bytes + UINT8 Associativity; ///< Cache associativity + ///< The associativity fields are encoded as follows: + ///< 00h: Reserved. + ///< 01h: Direct mapped. + ///< 02h-FEh: Associativity. (e.g., 04h = 4-way associative.) + ///< FFh: Fully associative + UINT8 CacheProperties; ///< Cache Properties bits [2:0] represent Inclusive/Exclusive property encoded. + ///< 0: Cache is strictly exclusive to lower level caches. + ///< 1: Cache is mostly exclusive to lower level caches. + ///< 2: Cache is strictly inclusive to lower level caches. + ///< 3: Cache is mostly inclusive to lower level caches. + ///< 4: Cache is a "constant cache" (= explicit update) + ///< 5: Cache is a "specialty cache" (e.g. Texture cache) + ///< 6-7: Reserved + ///< CacheProperties bits [7:3] are reserved + UINT16 CacheLatency; ///< Cost of time to access cache described in nanoseconds. + UINT8 Reserved1[8]; ///< Reserved +} CRAT_CACHE; + +/// Flags field of the CRAT TLB Affinity structure +typedef struct { + UINT32 Enabled:1; ///< Enabled + UINT32 DataTLB:1; ///< 1 if TLB includes translation information for data. + UINT32 InstructionTLB:1; ///< 1 if TLB includes translation information for instructions. + UINT32 CpuTLB:1; ///< 1 if TLB is part of CPU functionality + UINT32 SimdTLB:1; ///< 1 if TLB is part of SIMD functionality + UINT32 :27; ///< Reserved +} CRAT_TLB_FLAG; + +/// CRAT TLB Affinity Structure +typedef struct { + UINT8 Type; ///< 3 - CRAT TLB Affinity Structure + UINT8 Length; ///< 64 + UINT16 Reserved; ///< Reserved + CRAT_TLB_FLAG Flags; ///< Flags - TLB Affinity Structure. Indicates whether the TLB is enabled and defined + UINT32 ProcessorIdLow; ///< Low value of a logical processor which includes this component. + UINT8 SiblingMap[32]; ///< Bitmask of Processor Id sharing this component. 1 bit per logical processor + UINT32 TLBLevel; ///< Integer representing level: 1, 2, 3, 4, etc. + UINT8 DataTLBAssociativity2MB; ///< Data TLB associativity for 2MB pages + ///< The associativity fields are encoded as follows: + ///< 00h: Reserved. + ///< 01h: Direct mapped. + ///< 02h-FEh: Associativity. (e.g., 04h = 4-way associative.) + ///< FFh: Fully associative. + UINT8 DataTLBSize2MB; ///< Data TLB number of entries for 2MB. + UINT8 InstructionTLBAssoc2MB; ///< Instruction TLB associativity for 2MB pages + ///< The associativity fields are encoded as follows: + ///< 00h: Reserved. + ///< 01h: Direct mapped. + ///< 02h-FEh: Associativity. (e.g., 04h = 4-way associative.) + ///< FFh: Fully associative. + UINT8 InstructionTLBSize2MB; ///< Instruction TLB number of entries for 2MB pages. + UINT8 DTLB4KAssoc; ///< Data TLB Associativity for 4KB pages + UINT8 DTLB4KSize; ///< Data TLB number of entries for 4KB pages + UINT8 ITLB4KAssoc; ///< Instruction TLB Associativity for 4KB pages + UINT8 ITLB4KSize; ///< Instruction TLB number of entries for 4KB pages + UINT8 DTLB1GAssoc; ///< Data TLB Associativity for 1GB pages + UINT8 DTLB1GSize; ///< Data TLB number of entries for 1GB pages + UINT8 ITLB1GAssoc; ///< Instruction TLB Associativity for 1GB pages + UINT8 ITLB1GSize; ///< Instruction TLB number of entries for 1GB pages + UINT8 Reserved1[4]; ///< Reserved +} CRAT_TLB; + +/// Flags field of the CRAT FPU Affinity structure +typedef struct { + UINT32 Enabled:1; ///< Enabled + UINT32 :31; ///< Reserved +} CRAT_FPU_FLAG; + +/// CRAT FPU Affinity Structure +typedef struct { + UINT8 Type; ///< 4 - CRAT FPU Affinity Structure + UINT8 Length; ///< 64 + UINT16 Reserved; ///< Reserved + CRAT_FPU_FLAG Flags; ///< Flags - FPU Affinity Structure. Indicates whether the region of FPU affinity structure is enabled and defined + UINT32 ProcessorIdLow; ///< Low value of a logical processor which includes this component. + UINT8 SiblingMap[32]; ///< Bitmask of Processor Id sharing this component. 1 bit per logical processor + UINT32 FPUSize; ///< Product specific + UINT8 Reserved1[16]; ///< Reserved +} CRAT_FPU; + +/// Flags field of the CRAT IO Affinity structure +typedef struct { + UINT32 Enabled:1; ///< Enabled + UINT32 Coherency:1; ///< If set, IO interface supports coherent transactions (natively or through protocol extensions) + UINT32 :30; ///< Reserved +} CRAT_IO_FLAG; + +/// CRAT IO Affinity Structure +typedef struct { + UINT8 Type; ///< 5 - CRAT IO Affinity Structure + UINT8 Length; ///< 64 + UINT16 Reserved; ///< Reserved + CRAT_IO_FLAG Flags; ///< Flags - IO Affinity Structure. Indicates whether the region of IO affinity structure is enabled and defined. + UINT32 ProximityDomainFrom; ///< Integer that represents the proximity domain to which the IO Interface belongs to + UINT32 ProximityDomainTo; ///< Integer that represents the other proximity domain to which the IO Interface belongs to + UINT8 IoType; ///< IO Interface type. Values defined are + ///< 0: Undefined + ///< 1: Hypertransport + ///< 2: PCI Express + ///< 3: Other (e.g. internal) + ///< 4-255: Reserved + UINT8 VersionMajor; ///< Major version of the Bus interface + UINT16 VersionMinor; ///< Minor version of the Bus interface ((optional) + UINT32 MinimumLatency; ///< Cost of time to transfer, described in nanoseconds. + UINT32 MaximumLatency; ///< Cost of time to transfer, described in nanoseconds. + UINT32 MinimumBandwidth; ///< Minimum interface Bandwidth in MB/s + UINT32 MaximumBandwidth; ///< Maximum interface Bandwidth in MB/s + UINT32 RecommendedTransferSize; ///< Recommended transfer size to reach maximum interface bandwidth in Bytes + UINT8 Reserved1[24]; ///< Reserved +} CRAT_IO; + +#define CRAT_MAX_LENGTH 0x400ul ///< Reserve 1K for CRAT +/// CRAT entry type +typedef enum { + CRAT_TYPE_HSA_PROC_UNIT = 0, ///< 0 - CRAT HSA Processing Unit Structure + CRAT_TYPE_MEMORY, ///< 1 - CRAT Memory Affinity Structure + CRAT_TYPE_CACHE, ///< 2 - CRAT Cache Affinity Structure + CRAT_TYPE_TLB, ///< 3 - CRAT TLB Affinity Structure + CRAT_TYPE_FPU, ///< 4 - CRAT FPU Affinity Structure + CRAT_TYPE_IO, ///< 5 - CRAT IO Affinity Structure +} CRAT_ENTRY_TYPE; + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +AmdCpuLate ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig + ); + +AGESA_STATUS +CreateAcpiWhea ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **WheaMcePtr, + IN OUT VOID **WheaCmcPtr + ); + +AGESA_STATUS +CreateDmiRecords ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT DMI_INFO **DmiTable + ); + +AGESA_STATUS +GetType4Type7Info ( + IN AP_EXE_PARAMS *ApExeParams + ); + +VOID +DmiGetT4ProcFamilyFromBrandId ( + IN OUT UINT8 *T4ProcFamily, + IN PROC_FAMILY_TABLE *CpuDmiProcFamilyTable, + IN CPU_TYPE_INFO *CpuInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetNameString ( + IN OUT CHAR8 *String, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +IsSourceStrContainTargetStr ( + IN OUT CHAR8 *SourceStr, + IN OUT CONST CHAR8 *TargetStr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +CreateAcpiCrat ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **CratPtr + ); + +AGESA_STATUS +CreateAcpiCdit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT VOID **CditPtr + ); + +AGESA_STATUS +CreateAcpiSrat ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT VOID **SratPtr + ); + +AGESA_STATUS +CreateAcpiSlit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SlitPtr + ); + +VOID +ChecksumAcpiTable ( + IN OUT ACPI_TABLE_HEADER *Table, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +RunLateApTaskOnAllAPs ( + IN AP_EXE_PARAMS *ApParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +RunLateApTaskOnAllCore0s ( + IN AP_EXE_PARAMS *ApParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_LATE_INIT_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuMicrocodePatch.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuMicrocodePatch.c new file mode 100644 index 0000000000..b3db8869af --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuMicrocodePatch.c @@ -0,0 +1,431 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Microcode Patch Related Functions + * + * Contains code to program a microcode into the CPU + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*--------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *--------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuEarlyInit.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_CPUMICROCODEPATCH_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +typedef union { + UINT64 RawData; + PATCH_LOADER_MSR BitFields; +} PATCH_LOADER; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +LoadMicrocode ( + IN MICROCODE_PATCH *MicrocodePatchPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +LoadMicrocodePatchAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/* -----------------------------------------------------------------------------*/ +/** + * Update microcode patch in current processor. + * + * Then reads the patch id, and compare it to the expected, in the Microprocessor + * patch block. + * + * @param[in] StdHeader - Config handle for library and services. + * + * @retval TRUE - Patch Loaded Successfully. + * @retval FALSE - Patch Did Not Get Loaded. + * + */ +BOOLEAN +LoadMicrocodePatch ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PatchNumber; + UINT8 TotalPatches; + UINT16 ProcessorEquivalentId; + BOOLEAN Status; + MICROCODE_PATCH **MicrocodePatchPtr; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + MICROCODE_PATCH *ForceLoadMicrocodePatchPtr; + Status = FALSE; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + + if ((!(FamilySpecificServices->PatchLoaderIsSharedByCU)) || (IsCoreComputeUnitPrimary (FirstCoreIsComputeUnitPrimary, StdHeader))) { + // Get the patch pointer + FamilySpecificServices->GetMicroCodePatchesStruct (FamilySpecificServices, (CONST VOID **) &MicrocodePatchPtr, &TotalPatches, StdHeader); + ForceLoadMicrocodePatchPtr = NULL; + IDS_SKIP_HOOK (IDS_UCODE, &ForceLoadMicrocodePatchPtr, StdHeader) { + if (ForceLoadMicrocodePatchPtr == NULL) { + // Get the processor microcode path equivalent ID + if (GetPatchEquivalentId (&ProcessorEquivalentId, StdHeader)) { + // parse the patch table to see if we have one for the current cpu + for (PatchNumber = 0; PatchNumber < TotalPatches; PatchNumber++) { + if (ValidateMicrocode (MicrocodePatchPtr[PatchNumber], ProcessorEquivalentId, StdHeader)) { + if (LoadMicrocode (MicrocodePatchPtr[PatchNumber], StdHeader)) { + Status = TRUE; + } else { + PutEventLog (AGESA_ERROR, + CPU_ERROR_MICRO_CODE_PATCH_IS_NOT_LOADED, + 0, 0, 0, 0, StdHeader); + } + break; // Once we find a microcode patch that matches the processor, exit the for loop + } + } + } + } else { + IDS_HDT_CONSOLE (CPU_TRACE, " Force Ucode loaded from offset %x\n", ForceLoadMicrocodePatchPtr); + if (LoadMicrocode (ForceLoadMicrocodePatchPtr, StdHeader)) { + Status = TRUE; + } else { + PutEventLog (AGESA_ERROR, + CPU_ERROR_MICRO_CODE_PATCH_IS_NOT_LOADED, + 0, 0, 0, 0, StdHeader); + } + } + } + } + return Status; +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * LoadMicrocode + * + * Update microcode patch in current processor, then reads the + * patch id, and compare it to the expected, in the Microprocessor + * patch block. + * + * @param[in] MicrocodePatchPtr - Pointer to Microcode Patch. + * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + * @retval TRUE - Patch Loaded Successfully. + * @retval FALSE - Patch Did Not Get Loaded. + * + */ +BOOLEAN +STATIC +LoadMicrocode ( + IN MICROCODE_PATCH *MicrocodePatchPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MicrocodeVersion; + PATCH_LOADER PatchLoaderMsr; + + // Load microcode patch into CPU + PatchLoaderMsr.RawData = (UINT64) (UINTN) MicrocodePatchPtr; + PatchLoaderMsr.BitFields.SBZ = 0; + LibAmdMsrWrite (0xC0010020ul, &PatchLoaderMsr.RawData, StdHeader); + + // Do ucode patch Authentication + // Read microcode version back from CPU, determine if + // it is the same patch level as contained in the source + // microprocessor patch block passed in + GetMicrocodeVersion (&MicrocodeVersion, StdHeader); + if (MicrocodeVersion == MicrocodePatchPtr->PatchID) { + return (TRUE); + } else { + return (FALSE); + } +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * GetPatchEquivalentId + * + * Return the equivalent ID for microcode patching + * + * @param[in,out] ProcessorEquivalentId - Pointer to Processor Equivalent ID table. + * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + * @retval TRUE - ID Found. + * @retval FALSE - ID Not Found. + * + */ +BOOLEAN +GetPatchEquivalentId ( + IN OUT UINT16 *ProcessorEquivalentId, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 EquivalencyEntries; + UINT16 ProcessorRevisionId; + UINT16 *MicrocodeEquivalenceTable; + CPUID_DATA CpuIdData; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + // + // compute the processor revision ID + // + LibAmdCpuidRead (AMD_CPUID_FMF, &CpuIdData, StdHeader); + // high byte contains extended model and extended family + ProcessorRevisionId = (UINT16) ((CpuIdData.EAX_Reg & (CPU_EMODEL | CPU_EFAMILY)) >> 8); + // low byte contains model and family + ProcessorRevisionId |= (CpuIdData.EAX_Reg & (CPU_STEPPING | CPU_MODEL)); + + // + // find the equivalent ID for microcode purpose using the equivalence table + // + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + + FamilySpecificServices->GetMicrocodeEquivalenceTable (FamilySpecificServices, + (CONST VOID **) &MicrocodeEquivalenceTable, + &EquivalencyEntries, + StdHeader); + + // parse the equivalence table + for (i = 0; i < (EquivalencyEntries * 2); i += 2) { + // check for equivalence + if (ProcessorRevisionId == MicrocodeEquivalenceTable[i]) { + *ProcessorEquivalentId = MicrocodeEquivalenceTable[i + 1]; + return (TRUE); + } + } + // end of table reach, this processor is not supported + *ProcessorEquivalentId = 0x0000; + return (FALSE); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * ValidateMicrocode + * + * Determine if the microcode patch block, currently pointed to + * is valid, and is appropriate for the current processor + + * @param[in] MicrocodePatchPtr - Pointer to Microcode Patch. + * @param[in] ProcessorEquivalentId - Pointer to Processor Equivalent ID table. + * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + * @retval TRUE - Patch Found. + * @retval FALSE - Patch Not Found. + * + */ +BOOLEAN +ValidateMicrocode ( + IN MICROCODE_PATCH *MicrocodePatchPtr, + IN UINT16 ProcessorEquivalentId, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN Chipset1Matched; + BOOLEAN Chipset2Matched; + PCI_ADDR PciAddress; + UINT32 PciDeviceVidDid; + UINT8 PciDeviceRevision; + UINT8 DevCount; + UINT8 FunCount; + UINT32 Chipset1DeviceID; + UINT32 Chipset2DeviceID; + UINT8 MulitFunction; + + Chipset1Matched = FALSE; + Chipset2Matched = FALSE; + PciDeviceVidDid = 0; + PciDeviceRevision = 0; + Chipset1DeviceID = MicrocodePatchPtr->Chipset1DeviceID; + Chipset2DeviceID = MicrocodePatchPtr->Chipset2DeviceID; + MulitFunction = 0; + + // + // parse the supplied microcode to see if it is compatible with the processor + // + if (MicrocodePatchPtr->ProcessorRevisionID != ProcessorEquivalentId) { + return (FALSE); + } + + if (Chipset1DeviceID == 0) { + Chipset1Matched = TRUE; + } + if (Chipset2DeviceID == 0) { + Chipset2Matched = TRUE; + } + + if ((!Chipset1Matched) || (!Chipset2Matched)) { + // + // Scan all PCI devices in Bus 0, try to find out matched case. + // + for (DevCount = 0; DevCount < 32; DevCount++) { + for (FunCount = 0; FunCount < 8; FunCount++) { + PciAddress.AddressValue = MAKE_SBDFO (0, 0, DevCount, FunCount, 0); + LibAmdPciRead (AccessWidth32, PciAddress, &PciDeviceVidDid, StdHeader); + if (PciDeviceVidDid == 0xFFFFFFFF) { + if (FunCount == 0) { + break; + } else { + continue; + } + } + PciAddress.Address.Register = 0x8; + LibAmdPciRead (AccessWidth8, PciAddress, &PciDeviceRevision, StdHeader); + if ((!Chipset1Matched) && (PciDeviceVidDid == Chipset1DeviceID)) { + if (PciDeviceRevision == MicrocodePatchPtr->Chipset1RevisionID) { + Chipset1Matched = TRUE; + } + } + if ((!Chipset2Matched) && (PciDeviceVidDid == Chipset2DeviceID)) { + if (PciDeviceRevision == MicrocodePatchPtr->Chipset2RevisionID) { + Chipset2Matched = TRUE; + } + } + if (Chipset1Matched && Chipset2Matched) { + break; + } + // + // Check multi-function. If it doesen't exist, we don't have to loop functions to 7. + // + if (FunCount == 0) { + MulitFunction = 0; + PciAddress.Address.Register = 0xE; + LibAmdPciRead (AccessWidth8, PciAddress, &MulitFunction, StdHeader); + if ((MulitFunction & 0x80) == 0) { + break; + } + } + } // end FunCount for loop. + + if (Chipset1Matched && Chipset2Matched) { + break; + } + } // end DevCount for loop. + } + + return (Chipset1Matched && Chipset2Matched); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * + * GetMicrocodeVersion + * + * Return the version of the currently loaded microcode patch, if any. + * Read from the patch level MSR, return the value in eax. If no patch + * has been loaded, 0 will be returned. + * + * @param[out] pMicrocodeVersion - Pointer to Microcode Version. + * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + */ +VOID +GetMicrocodeVersion ( + OUT UINT32 *pMicrocodeVersion, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrData; + + MsrData = 0; + LibAmdMsrRead (0x0000008Bul, &MsrData, StdHeader); + + *pMicrocodeVersion = (UINT32) MsrData; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Update microcode patch in current processor. + * + * This function acts as a wrapper for calling the LoadMicrocodePatch + * routine at AmdInitEarly. + * + * @param[in] FamilyServices The current Family Specific Services. + * @param[in] EarlyParams Service parameters. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +LoadMicrocodePatchAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_TESTPOINT (TpProcCpuLoadUcode, StdHeader); + LoadMicrocodePatch (StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPostInit.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPostInit.c new file mode 100644 index 0000000000..605e0c4325 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPostInit.c @@ -0,0 +1,416 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU POST API, and related functions. + * + * Contains code that initialized the CPU after memory init. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + **************************************************************************** + * AMD Generic Encapsulated Software Architecture + * + * Description: cpuPostInit.c - Cpu POST Initialization Functions. + * + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Options.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "heapManager.h" +#include "cpuServices.h" +#include "cpuFeatures.h" +#include "GeneralServices.h" +#include "cpuPostInit.h" +#include "cpuPstateTables.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) +#define FILECODE PROC_CPU_CPUPOSTINIT_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +SyncVariableMTRR ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; +extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable; + +extern +VOID +ExecuteWbinvdInstruction ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PstateCreateHeapInfo ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Performs CPU related initialization at the POST entry point + * + * This function performs a large list of initialization items. These items + * include: + * + * -1 AP MTRR sync + * -2 feature leveling + * -3 P-state data gather + * -4 P-state leveling + * -5 AP cache breakdown & release + * + * @param[in] StdHeader Config handle for library and services + * @param[in] PlatformConfig Config handle for platform specific information + * + * @retval AGESA_SUCCESS + * + */ +AGESA_STATUS +AmdCpuPost ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS CalledStatus; + + AgesaStatus = AGESA_SUCCESS; + // + // Sync variable MTRR + // + AGESA_TESTPOINT (TpProcCpuApMtrrSync, StdHeader); + SyncVariableMTRR (StdHeader); + + AGESA_TESTPOINT (TpProcCpuPostFeatureInit, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features after AP MTRR sync\n"); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_AFTER_POST_MTRR_SYNC, PlatformConfig, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + // + // Feature Leveling + // + AGESA_TESTPOINT (TpProcCpuFeatureLeveling, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " Perform feature leveling\n"); + FeatureLeveling (StdHeader); + // + // P-state Gathered and set heap info + // + IDS_HDT_CONSOLE (CPU_TRACE, " Create P-state info in the heap\n"); + PstateCreateHeapInfo (PlatformConfig, StdHeader); + + // Dispatch CPU features before relinquishing control of APs + AGESA_TESTPOINT (TpProcCpuBeforeRelinquishAPsFeatureInit, StdHeader); + IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features before Relinquishing control of APs\n"); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_BEFORE_RELINQUISH_AP, PlatformConfig, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + + // Relinquish control of all APs to IBV. + IDS_HDT_CONSOLE (CPU_TRACE, " Relinquish control of APs\n"); + RelinquishControlOfAllAPs (StdHeader); + + return (AgesaStatus); +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the address in system DRAM that should be used for p-state data + * gather and leveling. + * + * @param[out] Ptr Address to utilize + * @param[in] StdHeader Config handle for library and services + * + * @retval AGESA_SUCCESS + * + */ +AGESA_STATUS +GetPstateGatherDataAddressAtPost ( + OUT UINT64 **Ptr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 AddressValue; + + AddressValue = P_STATE_DATA_GATHER_TEMP_ADDR; + + *Ptr = (UINT64 *)(UINT32)(AddressValue); + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * AP task to sync memory subsystem MSRs with the BSC + * + * This function processes a list of MSRs and the BSC's current values for those + * MSRs. This will allow the APs to see system RAM. + * + * @param[in] MtrrTable Memory related MSR table + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +SyncAllApMtrrToBsc ( + IN VOID *MtrrTable, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + + for (i = 0; ((BSC_AP_MSR_SYNC *) MtrrTable)[i].RegisterAddress != 0; i++) { + LibAmdMsrWrite (((BSC_AP_MSR_SYNC *) MtrrTable)[i].RegisterAddress, + &((BSC_AP_MSR_SYNC *) MtrrTable)[i].RegisterValue, + StdHeader); + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Creates p-state information on the heap + * + * This function gathers p-state information from all processors in the system, + * determines a level set of p-states, and places that information into the + * heap. This heap data will be used by GenerateSsdt to generate the + * final _PSS and XPSS objects. + * + * @param[in] PlatformConfig Pointer to runtime configuration options + * @param[in] StdHeader Config handle for library and services + * + * @retval AGESA_SUCCESS No error + * @retval AGESA_ERROR CPU_ERROR_PSTATE_HEAP_NOT_AVAILABLE + */ +AGESA_STATUS +PstateCreateHeapInfo ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + S_CPU_AMD_PSTATE *PStateBufferPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + UINT8 *PStateBufferPtrInHeap; + + ASSERT (IsBsp (StdHeader, &AgesaStatus)); + + // + //Get proper address for gather data pool address + //Zero P-state gather data pool + // + GetPstateGatherDataAddressAtPost ((UINT64 **)&PStateBufferPtr, StdHeader); + LibAmdMemFill (PStateBufferPtr, 0, sizeof (S_CPU_AMD_PSTATE), StdHeader); + + // + //Get all the CPUs P-States and fill the PStateBufferPtr for each core + // + AgesaStatus = PStateGatherData (PlatformConfig, PStateBufferPtr, StdHeader); + if (AgesaStatus != AGESA_SUCCESS) { + return AgesaStatus; + } + + // + //Do Pstate Leveling for each core if needed. + // + AgesaStatus = PStateLeveling (PStateBufferPtr, StdHeader); + + // + //Create Heap and store p-state data for ACPI table in CpuLate + // + AllocHeapParams.RequestedBufferSize = PStateBufferPtr->SizeOfBytes; + AllocHeapParams.BufferHandle = AMD_PSTATE_DATA_BUFFER_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + AgesaStatus = HeapAllocateBuffer (&AllocHeapParams, StdHeader); + if (AgesaStatus == AGESA_SUCCESS) { + // + // Zero Buffer + // + PStateBufferPtrInHeap = (UINT8 *) AllocHeapParams.BufferPtr; + LibAmdMemFill (PStateBufferPtrInHeap, 0, PStateBufferPtr->SizeOfBytes, StdHeader); + LibAmdMemCopy (PStateBufferPtrInHeap, PStateBufferPtr, PStateBufferPtr->SizeOfBytes, StdHeader); + + } else { + PutEventLog (AGESA_ERROR, + CPU_ERROR_PSTATE_HEAP_NOT_AVAILABLE, + 0, 0, 0, 0, StdHeader); + } + + return AgesaStatus; +} + +VOID +SyncApMsrsToBsc ( + IN OUT BSC_AP_MSR_SYNC *ApMsrSync, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + UINT16 i; + UINT32 BscSocket; + UINT32 Ignored; + UINT32 BscCoreNum; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + AGESA_STATUS IgnoredSts; + + ASSERT (IsBsp (StdHeader, &IgnoredSts)); + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + // + //Sync all MTRR settings with BSP + // + for (i = 0; ApMsrSync[i].RegisterAddress != 0; i++) { + LibAmdMsrRead (ApMsrSync[i].RegisterAddress, &ApMsrSync[i].RegisterValue, StdHeader); + } + + TaskPtr.FuncAddress.PfApTaskI = SyncAllApMtrrToBsc; + TaskPtr.DataTransfer.DataSizeInDwords = (UINT16) ((((sizeof (BSC_AP_MSR_SYNC)) * i) + 4) >> 2); + TaskPtr.ExeFlags = WAIT_FOR_CORE; + TaskPtr.DataTransfer.DataPtr = ApMsrSync; + TaskPtr.DataTransfer.DataTransferFlags = 0; + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCoreNum)) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); + } + } + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * SyncVariableMTRR + * + * Sync variable MTRR + * + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +STATIC +SyncVariableMTRR ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BSC_AP_MSR_SYNC ApMsrSync[20]; + + ApMsrSync[0].RegisterAddress = SYS_CFG; + ApMsrSync[1].RegisterAddress = TOP_MEM; + ApMsrSync[2].RegisterAddress = TOP_MEM2; + ApMsrSync[3].RegisterAddress = 0x200; + ApMsrSync[4].RegisterAddress = 0x201; + ApMsrSync[5].RegisterAddress = 0x202; + ApMsrSync[6].RegisterAddress = 0x203; + ApMsrSync[7].RegisterAddress = 0x204; + ApMsrSync[8].RegisterAddress = 0x205; + ApMsrSync[9].RegisterAddress = 0x206; + ApMsrSync[10].RegisterAddress = 0x207; + ApMsrSync[11].RegisterAddress = 0x208; + ApMsrSync[12].RegisterAddress = 0x209; + ApMsrSync[13].RegisterAddress = 0x20A; + ApMsrSync[14].RegisterAddress = 0x20B; + ApMsrSync[15].RegisterAddress = 0xC0010016; + ApMsrSync[16].RegisterAddress = 0xC0010017; + ApMsrSync[17].RegisterAddress = 0xC0010018; + ApMsrSync[18].RegisterAddress = 0xC0010019; + ApMsrSync[19].RegisterAddress = 0; + SyncApMsrsToBsc (ApMsrSync, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * The function suppose to do any thing need to be done at the end of AmdInitPost. + * + * @param[in] StdHeader Config handle for library and services + * + * @retval AGESA_SUCCESS + * + */ +AGESA_STATUS +FinalizeAtPost ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // + // Execute wbinvd to ensure heap data in cache write back to memory. + // + ExecuteWbinvdInstruction (StdHeader); + + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPostInit.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPostInit.h new file mode 100644 index 0000000000..2d192fec3e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPostInit.h @@ -0,0 +1,233 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Reset API, and related functions and structures. + * + * Contains code that initialized the CPU after early reset. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_POST_INIT_H_ +#define _CPU_POST_INIT_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (CPU_CFOH_FAMILY_SERVICES); + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ +#define P_STATE_DATA_GATHER_TEMP_ADDR 0x200000ul ///< Fixed the row data at 2M memory address. +#define GLOBAL_CPU_FEATURE_LIST_TEMP_ADDR 0x200000ul ///< Fixed the row data at 2M memory address. +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +//---------------------------------------------------------------------------- +// CPU FEATURE LEVELING TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/// CPU FEATURE LIST +typedef struct { + UINT8 ABM:1; ///< byte 0 bit 0 + UINT8 AES:1; ///< byte 0 bit 1 + UINT8 AltMovCr8:1; ///< byte 0 bit 2 + UINT8 APIC:1; ///< byte 0 bit 3 + UINT8 AVX:1; ///< byte 0 bit 4 + UINT8 CLFSH:1; ///< byte 0 bit 5 + UINT8 CMOV:1; ///< byte 0 bit 6 + UINT8 CmpLegacy:1; ///< byte 0 bit 7 + UINT8 CMPXCHG8B:1; ///< byte 1 bit 0 + UINT8 CMPXCHG16B:1; ///< byte 1 bit 1 + UINT8 CVT16:1; ///< byte 1 bit 2 + UINT8 DE:1; ///< byte 1 bit 3 + UINT8 ExtApicSpace:1; ///< byte 1 bit 4 + UINT8 FFXSR:1; ///< byte 1 bit 5 + UINT8 FMA:1; ///< byte 1 bit 6 + UINT8 FMA4:1; ///< byte 1 bit 7 + UINT8 FPU:1; ///< byte 2 bit 0 + UINT8 FXSR:1; ///< byte 2 bit 1 + UINT8 HTT:1; ///< byte 2 bit 2 + UINT8 IBS:1; ///< byte 2 bit 3 + UINT8 LahfSahf:1; ///< byte 2 bit 4 + UINT8 LM:1; ///< byte 2 bit 5 + UINT8 LWP:1; ///< byte 2 bit 6 + UINT8 MCA:1; ///< byte 2 bit 7 + UINT8 MCE:1; ///< byte 3 bit 0 + UINT8 MisAlignSse:1; ///< byte 3 bit 1 + UINT8 MMX:1; ///< byte 3 bit 2 + UINT8 MmxExt:1; ///< byte 3 bit 3 + UINT8 Monitor:1; ///< byte 3 bit 4 + UINT8 MSR:1; ///< byte 3 bit 5 + UINT8 MTRR:1; ///< byte 3 bit 6 + UINT8 NodeId:1; ///< byte 3 bit 7 + UINT8 NX:1; ///< byte 4 bit 0 + UINT8 OSVW:1; ///< byte 4 bit 1 + UINT8 OSXSAVE:1; ///< byte 4 bit 2 + UINT8 PAE:1; ///< byte 4 bit 3 + UINT8 Page1GB:1; ///< byte 4 bit 4 + UINT8 PAT:1; ///< byte 4 bit 5 + UINT8 PCLMULQDQ:1; ///< byte 4 bit 6 + UINT8 PGE:1; ///< byte 4 bit 7 + UINT8 POPCNT:1; ///< byte 5 bit 0 + UINT8 PSE:1; ///< byte 5 bit 1 + UINT8 PSE36:1; ///< byte 5 bit 2 + UINT8 RDTSCP:1; ///< byte 5 bit 3 + UINT8 SKINIT:1; ///< byte 5 bit 4 + UINT8 SSE:1; ///< byte 5 bit 5 + UINT8 SSE2:1; ///< byte 5 bit 6 + UINT8 SSE3:1; ///< byte 5 bit 7 + UINT8 SSE4A:1; ///< byte 6 bit 0 + UINT8 SSE41:1; ///< byte 6 bit 1 + UINT8 SSE42:1; ///< byte 6 bit 2 + UINT8 SSE5:1; ///< byte 6 bit 3 + UINT8 SSSE3:1; ///< byte 6 bit 4 + UINT8 SVM:1; ///< byte 6 bit 5 + UINT8 SysCallSysRet:1; ///< byte 6 bit 6 + UINT8 SysEnterSysExit:1; ///< byte 6 bit 7 + UINT8 TBM0:1; ///< byte 7 bit 0 + UINT8 TCE:1; ///< byte 7 bit 1 + UINT8 ThreeDNow:1; ///< byte 7 bit 2 + UINT8 ThreeDNowExt:1; ///< byte 7 bit 3 + UINT8 ThreeDNowPrefetch:1; ///< byte 7 bit 4 + UINT8 TimeStampCounter:1; ///< byte 7 bit 5 + UINT8 VME:1; ///< byte 7 bit 6 + UINT8 WDT:1; ///< byte 7 bit 7 + UINT8 X2APIC:1; ///< byte 8 bit 0 + UINT8 XOP:1; ///< byte 8 bit 1 + UINT8 XSAVE:1; ///< byte 8 bit 2 + UINT8 Reserve:5; ///< Reserved +} CPU_FEATURES_LIST; + +//---------------------------------------------------------------------------- +// POST INIT TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/// BSC to AP MSR sync up +typedef struct { + UINT32 RegisterAddress; ///< MSR Address + UINT64 RegisterValue; ///< BSC's MSR Value +} BSC_AP_MSR_SYNC; + +/** + * Set Cache Flush On Halt Register. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef VOID (F_CPU_SET_CFOH_REG) ( + IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + /// Reference to a Method. +typedef F_CPU_SET_CFOH_REG *PF_CPU_SET_CFOH_REG; + +/** + * Provide the interface to the Cache Flush On Halt Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _CPU_CFOH_FAMILY_SERVICES { // See forward reference above + UINT16 Revision; ///< Interface version + // Public Methods. + PF_CPU_SET_CFOH_REG SetCacheFlushOnHaltRegister; ///< Method: Set Cache Flush On Halt register. +}; + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +// These are P U B L I C functions, used by IBVs +AGESA_STATUS +AmdCpuPost ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig + ); + +// These are P U B L I C functions, used by AGESA + +VOID +FeatureLeveling ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +CopyHeapToTempRamAtPost ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SyncApMsrsToBsc ( + IN OUT BSC_AP_MSR_SYNC *ApMsrSync, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +FinalizeAtPost ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GetPstateGatherDataAddressAtPost ( + OUT UINT64 **Ptr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SyncAllApMtrrToBsc ( + IN VOID *MtrrTable, + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif // _CPU_POST_INIT_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmt.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmt.c new file mode 100644 index 0000000000..303e8d7a9d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmt.c @@ -0,0 +1,275 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Power Management functions. + * + * Contains code for doing early power management + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + **************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "OptionMultiSocket.h" +#include "cpuApicUtilities.h" +#include "cpuEarlyInit.h" +#include "cpuPowerMgmtSystemTables.h" +#include "cpuServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_CPUPOWERMGMT_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +STATIC +PerformThisPmStep ( + IN VOID *Step, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ); + +VOID +STATIC +GoToMemInitPstateCore0 ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ); + +VOID +STATIC +GoToMemInitPstateCore ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the "BIOS Requirements for P-State Initialization and Transitions." + * + * This is the generic arbiter code to be executed by the BSC. The system power + * management init tables will be traversed. This must be run by the system BSC + * only. + * + * @param[in] CpuEarlyParams Required input parameters for early CPU initialization + * @param[in] StdHeader Config handle for library and services + * + * @return Most severe AGESA_STATUS level that any system processor encountered + * + */ +AGESA_STATUS +PmInitializationAtEarly ( + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 NumberOfSystemWideSteps; + AP_TASK TaskPtr; + AGESA_STATUS ReturnCode; + WARM_RESET_REQUEST Request; + + // Determine the number of steps to perform + OptionMultiSocketConfiguration.GetNumberOfSystemPmSteps (&NumberOfSystemWideSteps, StdHeader); + + // Traverse the PM init table + TaskPtr.FuncAddress.PfApTaskIC = PerformThisPmStep; + TaskPtr.DataTransfer.DataSizeInDwords = 1; + TaskPtr.DataTransfer.DataPtr = &i; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS; + for (i = 0; i < NumberOfSystemWideSteps; ++i) { + IDS_HDT_CONSOLE (CPU_TRACE, " Perform PM init step %d\n", i); + OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, CpuEarlyParams); + } + + // GoToMemInitPstateCore0 only if there is no pending warm reset. + GetWarmResetFlag (StdHeader, &Request); + if (Request.RequestBit == FALSE) { + TaskPtr.FuncAddress.PfApTaskC = GoToMemInitPstateCore0; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS; + IDS_HDT_CONSOLE (CPU_TRACE, " Transition all cores to POST P-state\n"); + OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, CpuEarlyParams); + } + + // Retrieve/Process any errors + ReturnCode = OptionMultiSocketConfiguration.BscRetrievePmEarlyInitErrors (StdHeader); + + return (ReturnCode); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Performs the next step in the executing core 0's family specific power + * management table. + * + * This function determines if the input step is valid, and invokes the power + * management step if appropriate. This must be run by processor core 0s only. + * + * @param[in] Step Zero based step number + * @param[in] StdHeader Config handle for library and services + * @param[in] CpuEarlyParamsPtr Required input parameters for early CPU initialization + * + */ +VOID +STATIC +PerformThisPmStep ( + IN VOID *Step, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ) +{ + UINT8 MyNumberOfSteps; + UINT32 ExeResetFlags; + SYS_PM_TBL_STEP *FamilyTablePtr; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + BOOLEAN ThisIsWarmReset; + BOOLEAN NoResetLimit; + BOOLEAN NotConflictResetLimit; + BOOLEAN WarmResetOnly; + BOOLEAN ColdResetOnly; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &FamilyTablePtr, &MyNumberOfSteps, StdHeader); + + if (*(UINT8 *)Step < MyNumberOfSteps) { + if (FamilyTablePtr[*(UINT8 *)Step].FuncPtr != NULL) { + ExeResetFlags = FamilyTablePtr[*(UINT8 *)Step].ExeFlags & (PM_EXEFLAGS_COLD_ONLY | PM_EXEFLAGS_WARM_ONLY); + ThisIsWarmReset = IsWarmReset (StdHeader); + NoResetLimit = (ExeResetFlags == 0) ? TRUE : FALSE; + NotConflictResetLimit = (BOOLEAN) (ExeResetFlags != (PM_EXEFLAGS_COLD_ONLY | PM_EXEFLAGS_WARM_ONLY)); + WarmResetOnly = (BOOLEAN) ((ExeResetFlags & PM_EXEFLAGS_WARM_ONLY) == PM_EXEFLAGS_WARM_ONLY); + ColdResetOnly = (BOOLEAN) ((ExeResetFlags & PM_EXEFLAGS_COLD_ONLY) == PM_EXEFLAGS_COLD_ONLY); + + IDS_HDT_CONSOLE (CPU_TRACE, " \tIsWarmReset = %d.\n", ThisIsWarmReset); + IDS_HDT_CONSOLE (CPU_TRACE, " \tNoResetLimit = %d\n", NoResetLimit); + IDS_HDT_CONSOLE (CPU_TRACE, " \tNotConflictResetLimit = %d\n", NotConflictResetLimit); + IDS_HDT_CONSOLE (CPU_TRACE, " \tWarmResetOnly = %d\n", WarmResetOnly); + IDS_HDT_CONSOLE (CPU_TRACE, " \tColdResetOnly = %d\n", ColdResetOnly); + + ASSERT (NotConflictResetLimit); + + if (NoResetLimit || + (NotConflictResetLimit && + ((WarmResetOnly && ThisIsWarmReset) || (ColdResetOnly && !ThisIsWarmReset)))) { + FamilyTablePtr[*(UINT8 *)Step].FuncPtr (FamilySpecificServices, CpuEarlyParamsPtr, StdHeader); + } else { + IDS_HDT_CONSOLE (CPU_TRACE, " \t\tThis PM init step was skipped!\n"); + } + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Transitions the executing processor to the desired P-state. + * + * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is + * run by all processor core 0s. + * + * @param[in] StdHeader Config handle for library and services + * @param[in] CpuEarlyParamsPtr Required input parameters for early CPU initialization + * + */ +VOID +STATIC +GoToMemInitPstateCore0 ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ) +{ + AP_TASK TaskPtr; + + TaskPtr.FuncAddress.PfApTaskC = GoToMemInitPstateCore; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE | PASS_EARLY_PARAMS; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Transitions the executing core to the desired P-state. + * + * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is + * run by all system cores. + * + * @param[in] StdHeader Config handle for library and services + * @param[in] CpuEarlyParamsPtr Required input parameters for early CPU initialization + * + */ +VOID +STATIC +GoToMemInitPstateCore ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->TransitionPstate (FamilySpecificServices, CpuEarlyParamsPtr->MemInitPState, (BOOLEAN) FALSE, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.c new file mode 100644 index 0000000000..4009972634 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.c @@ -0,0 +1,332 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Power Management Single Socket Functions. + * + * Contains code for doing power management for single socket CPU + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "GeneralServices.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "cpuPowerMgmtSystemTables.h" +#include "cpuPowerMgmtSingleSocket.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_CPUPOWERMGMTSINGLESOCKET_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Single socket BSC call to start all system core 0s to perform a standard AP_TASK. + * + * This function will simply invoke the task on the executing core. This must be + * run by the system BSC only. + * + * @param[in] TaskPtr Function descriptor + * @param[in] StdHeader Config handle for library and services + * @param[in] ConfigParams AMD entry point's CPU parameter structure + * + * @return The severe error code from AP_TASK + * + */ +AGESA_STATUS +RunCodeOnAllSystemCore0sSingle ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ConfigParams + ) +{ + AGESA_STATUS CalledStatus; + + CalledStatus = ApUtilTaskOnExecutingCore (TaskPtr, StdHeader, ConfigParams); + return CalledStatus; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Single socket BSC call to determine the maximum number of steps that any single + * processor needs to execute. + * + * This function simply returns the number of steps that the BSC needs. + * + * @param[out] NumSystemSteps Maximum number of system steps required + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +GetNumberOfSystemPmStepsPtrSingle ( + OUT UINT8 *NumSystemSteps, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + SYS_PM_TBL_STEP *Ignored; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &Ignored, NumSystemSteps, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Single socket call to determine the frequency that the northbridges must run. + * + * This function simply returns the executing core's NB frequency, and that all + * NB frequencies are equivalent. + * + * @param[in] NbPstate NB P-state number to check (0 = fastest) + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[out] SystemNbCofNumerator NB frequency numerator for the system in MHz + * @param[out] SystemNbCofDenominator NB frequency denominator for the system + * @param[out] SystemNbCofsMatch Whether or not all NB frequencies are equivalent + * @param[out] NbPstateIsEnabledOnAllCPUs Whether or not NbPstate is valid on all CPUs + * @param[in] StdHeader Config handle for library and services + * + * @retval TRUE At least one processor has NbPstate enabled. + * @retval FALSE NbPstate is disabled on all CPUs + * + */ +BOOLEAN +GetSystemNbCofSingle ( + IN UINT32 NbPstate, + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT UINT32 *SystemNbCofNumerator, + OUT UINT32 *SystemNbCofDenominator, + OUT BOOLEAN *SystemNbCofsMatch, + OUT BOOLEAN *NbPstateIsEnabledOnAllCPUs, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Ignored; + PCI_ADDR PciAddress; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); + *SystemNbCofsMatch = TRUE; + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + *NbPstateIsEnabledOnAllCPUs = FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices, + PlatformConfig, + &PciAddress, + NbPstate, + SystemNbCofNumerator, + SystemNbCofDenominator, + &Ignored, + StdHeader); + return *NbPstateIsEnabledOnAllCPUs; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Single socket call to determine if the BIOS is responsible for updating the + * northbridge operating frequency and voltage. + * + * This function simply returns whether or not the executing core needs NB COF + * VID programming. + * + * @param[in] StdHeader Config handle for library and services + * + * @retval TRUE BIOS needs to set up NB frequency and voltage + * @retval FALSE BIOS does not need to set up NB frequency and voltage + * + */ +BOOLEAN +GetSystemNbCofVidUpdateSingle ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN Ignored; + PCI_ADDR PciAddress; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + return (FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &Ignored, StdHeader)); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Single socket call to determine the most severe AGESA_STATUS return value after + * processing the power management initialization tables. + * + * This function searches the event log for the most severe error and returns + * the status code. This function must be called by the BSC only. + * + * @param[in] StdHeader Config handle for library and services + * + * @return The most severe error code from power management init + * + */ +AGESA_STATUS +GetEarlyPmErrorsSingle ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 i; + AGESA_EVENT EventLogEntry; + AGESA_STATUS ReturnCode; + + ASSERT (IsBsp (StdHeader, &ReturnCode)); + + ReturnCode = AGESA_SUCCESS; + for (i = 0; PeekEventLog (&EventLogEntry, i, StdHeader); i++) { + if ((EventLogEntry.EventInfo & CPU_EVENT_PM_EVENT_MASK) == CPU_EVENT_PM_EVENT_CLASS) { + if (EventLogEntry.EventClass > ReturnCode) { + ReturnCode = EventLogEntry.EventClass; + } + } + } + + return (ReturnCode); +} + +/** + * Single socket call to loop through all Nb Pstates, comparing the NB frequencies + * to determine the slowest in the system. This routine also returns the NB P0 frequency. + * + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[out] MinSysNbFreq NB frequency numerator for the system in MHz + * @param[out] MinP0NbFreq NB frequency numerator for P0 in MHz + * @param[in] StdHeader Config handle for library and services + */ +VOID +GetMinNbCofSingle ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT UINT32 *MinSysNbFreq, + OUT UINT32 *MinP0NbFreq, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + AGESA_STATUS AgesaStatus; + + PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + AgesaStatus = FamilySpecificServices->GetMinMaxNbFrequency (FamilySpecificServices, + PlatformConfig, + &PciAddress, + MinSysNbFreq, + MinP0NbFreq, + StdHeader); + ASSERT (AgesaStatus == AGESA_SUCCESS); + ASSERT ((MinSysNbFreq != 0) && (MinP0NbFreq != 0)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get PCI Config Space Address for the current running core. + * + * @param[out] PciAddress The Processor's PCI Config Space address (Function 0, Register 0) + * @param[in] StdHeader Header for library and services. + * + * @retval TRUE The core is present, PCI Address valid + * @retval FALSE The core is not present, PCI Address not valid. + */ +BOOLEAN +GetCurrPciAddrSingle ( + OUT PCI_ADDR *PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PciAddress->AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); + + return TRUE; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Writes to all nodes on the executing core's socket. + * + * @param[in] PciAddress The Function and Register to update + * @param[in] Mask The bitwise AND mask to apply to the current register value + * @param[in] Data The bitwise OR mask to apply to the current register value + * @param[in] StdHeader Header for library and services. + * + */ +VOID +ModifyCurrSocketPciSingle ( + IN PCI_ADDR *PciAddress, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 LocalPciRegister; + PCI_ADDR Reg; + + Reg.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); + Reg.Address.Function = PciAddress->Address.Function; + Reg.Address.Register = PciAddress->Address.Register; + LibAmdPciRead (AccessWidth32, Reg, &LocalPciRegister, StdHeader); + LocalPciRegister &= Mask; + LocalPciRegister |= Data; + LibAmdPciWrite (AccessWidth32, Reg, &LocalPciRegister, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.h new file mode 100644 index 0000000000..0a3024c610 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSingleSocket.h @@ -0,0 +1,127 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Power Management Single Socket Functions. + * + * Contains code for doing power management for single socket CPU + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_POWER_MGMT_SINGLE_SOCKET_H_ +#define _CPU_POWER_MGMT_SINGLE_SOCKET_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +RunCodeOnAllSystemCore0sSingle ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ConfigParams + ); + +VOID +GetNumberOfSystemPmStepsPtrSingle ( + OUT UINT8 *NumSystemSteps, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetSystemNbCofSingle ( + IN UINT32 NbPstate, + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT UINT32 *SystemNbCofNumerator, + OUT UINT32 *SystemNbCofDenominator, + OUT BOOLEAN *SystemNbCofsMatch, + OUT BOOLEAN *NbPstateIsEnabledOnAllCPUs, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetSystemNbCofVidUpdateSingle ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetMinNbCofSingle ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + OUT UINT32 *MinSysNbFreq, + OUT UINT32 *MinP0NbFreq, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetCurrPciAddrSingle ( + OUT PCI_ADDR *PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +ModifyCurrSocketPciSingle ( + IN PCI_ADDR *PciAddress, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GetEarlyPmErrorsSingle ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_POWER_MGMT_SINGLE_SOCKET_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSystemTables.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSystemTables.h new file mode 100644 index 0000000000..64baf46f4e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuPowerMgmtSystemTables.h @@ -0,0 +1,93 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Power Management Table declarations. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_POWER_MGMT_SYSTEM_TABLES_H_ +#define _CPU_POWER_MGMT_SYSTEM_TABLES_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ +#define PM_EXEFLAGS_WARM_ONLY 0x00000001ul /* Skip step if set && cold reset */ +#define PM_EXEFLAGS_COLD_ONLY 0x00000002ul /* Skip step if set && warm reset */ +#define PM_EXEFLAGS_NOT_ON_S3 0x00000004ul /* Skip step if S3 resume */ +#define PM_EXEFLAGS_SYSTEM_TASK 0x00000008ul /* Future use */ +#define PM_EXEFLAGS_SERIAL_EXE 0x00000010ul /* BSC will wait for remote core 0 to complete the step*/ + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +typedef VOID F_PM_STEP_FUNCTION ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_PM_STEP_FUNCTION *PF_PM_STEP_FUNCTION; + + +/// A structure representing a step in a power management +/// initialization process to be invoked at AmdInitEarly +typedef struct { + UINT32 ExeFlags; ///< Execution flags + PF_PM_STEP_FUNCTION FuncPtr; ///< Function pointer +} SYS_PM_TBL_STEP; + + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + + +#endif // _CPU_POWER_MGMT_SYSTEM_TABLES_H_/ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuRegisters.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuRegisters.h new file mode 100644 index 0000000000..e59bb88d7e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuRegisters.h @@ -0,0 +1,498 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Register Table Related Functions + * + * Contains the definition of the CPU CPUID MSRs and PCI registers with BKDG recommended values + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 85246 $ @e \$Date: 2013-01-04 13:05:13 -0600 (Fri, 04 Jan 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_REGISTERS_H_ +#define _CPU_REGISTERS_H_ + +#include "cpuFamRegisters.h" +/* + *-------------------------------------------------------------- + * + * M O D U L E S U S E D + * + *--------------------------------------------------------------- + */ + +/* + *-------------------------------------------------------------- + * + * D E F I N I T I O N S / M A C R O S + * + *--------------------------------------------------------------- + */ + +#undef BIT0 +#undef BIT1 +#undef BIT2 +#undef BIT3 +#undef BIT4 +#undef BIT5 +#undef BIT6 +#undef BIT7 +#undef BIT8 +#undef BIT9 +#undef BIT10 +#undef BIT10 +#undef BIT11 +#undef BIT12 +#undef BIT13 +#undef BIT14 +#undef BIT15 +#undef BIT16 +#undef BIT17 +#undef BIT18 +#undef BIT19 +#undef BIT20 +#undef BIT21 +#undef BIT22 +#undef BIT23 +#undef BIT24 +#undef BIT25 +#undef BIT26 +#undef BIT27 +#undef BIT28 +#undef BIT29 +#undef BIT30 +#undef BIT31 +#undef BIT32 +#undef BIT33 +#undef BIT34 +#undef BIT35 +#undef BIT36 +#undef BIT37 +#undef BIT38 +#undef BIT39 +#undef BIT40 +#undef BIT41 +#undef BIT42 +#undef BIT43 +#undef BIT44 +#undef BIT45 +#undef BIT46 +#undef BIT47 +#undef BIT48 +#undef BIT49 +#undef BIT40 +#undef BIT41 +#undef BIT42 +#undef BIT43 +#undef BIT44 +#undef BIT45 +#undef BIT46 +#undef BIT47 +#undef BIT48 +#undef BIT49 +#undef BIT50 +#undef BIT51 +#undef BIT52 +#undef BIT53 +#undef BIT54 +#undef BIT55 +#undef BIT56 +#undef BIT57 +#undef BIT58 +#undef BIT59 +#undef BIT60 +#undef BIT61 +#undef BIT62 +#undef BIT63 + +#define BIT0 0x0000000000000001ull +#define BIT1 0x0000000000000002ull +#define BIT2 0x0000000000000004ull +#define BIT3 0x0000000000000008ull +#define BIT4 0x0000000000000010ull +#define BIT5 0x0000000000000020ull +#define BIT6 0x0000000000000040ull +#define BIT7 0x0000000000000080ull +#define BIT8 0x0000000000000100ull +#define BIT9 0x0000000000000200ull +#define BIT10 0x0000000000000400ull +#define BIT11 0x0000000000000800ull +#define BIT12 0x0000000000001000ull +#define BIT13 0x0000000000002000ull +#define BIT14 0x0000000000004000ull +#define BIT15 0x0000000000008000ull +#define BIT16 0x0000000000010000ull +#define BIT17 0x0000000000020000ull +#define BIT18 0x0000000000040000ull +#define BIT19 0x0000000000080000ull +#define BIT20 0x0000000000100000ull +#define BIT21 0x0000000000200000ull +#define BIT22 0x0000000000400000ull +#define BIT23 0x0000000000800000ull +#define BIT24 0x0000000001000000ull +#define BIT25 0x0000000002000000ull +#define BIT26 0x0000000004000000ull +#define BIT27 0x0000000008000000ull +#define BIT28 0x0000000010000000ull +#define BIT29 0x0000000020000000ull +#define BIT30 0x0000000040000000ull +#define BIT31 0x0000000080000000ull +#define BIT32 0x0000000100000000ull +#define BIT33 0x0000000200000000ull +#define BIT34 0x0000000400000000ull +#define BIT35 0x0000000800000000ull +#define BIT36 0x0000001000000000ull +#define BIT37 0x0000002000000000ull +#define BIT38 0x0000004000000000ull +#define BIT39 0x0000008000000000ull +#define BIT40 0x0000010000000000ull +#define BIT41 0x0000020000000000ull +#define BIT42 0x0000040000000000ull +#define BIT43 0x0000080000000000ull +#define BIT44 0x0000100000000000ull +#define BIT45 0x0000200000000000ull +#define BIT46 0x0000400000000000ull +#define BIT47 0x0000800000000000ull +#define BIT48 0x0001000000000000ull +#define BIT49 0x0002000000000000ull +#define BIT50 0x0004000000000000ull +#define BIT51 0x0008000000000000ull +#define BIT52 0x0010000000000000ull +#define BIT53 0x0020000000000000ull +#define BIT54 0x0040000000000000ull +#define BIT55 0x0080000000000000ull +#define BIT56 0x0100000000000000ull +#define BIT57 0x0200000000000000ull +#define BIT58 0x0400000000000000ull +#define BIT59 0x0800000000000000ull +#define BIT60 0x1000000000000000ull +#define BIT61 0x2000000000000000ull +#define BIT62 0x4000000000000000ull +#define BIT63 0x8000000000000000ull + +/// CPUID related registers +#define AMD_CPUID_FMF 0x80000001ul // Family Model Features information +#define AMD_CPUID_APICID_LPC_BID 0x00000001ul // Local APIC ID, Logical Processor Count, Brand ID +#define AMD_CPUID_L2L3Cache_L2TLB 0x80000006ul +#define CPUID_ASSOCIATIVITY_DISABLED 0x00 +#define CPUID_ASSOCIATIVITY_1_WAY 0x01 +#define CPUID_ASSOCIATIVITY_2_WAY 0x02 +#define CPUID_ASSOCIATIVITY_4_WAY 0x04 +#define CPUID_ASSOCIATIVITY_8_WAY 0x06 +#define CPUID_ASSOCIATIVITY_16_WAY 0x08 +#define CPUID_ASSOCIATIVITY_32_WAY 0x0A +#define CPUID_ASSOCIATIVITY_48_WAY 0x0B +#define CPUID_ASSOCIATIVITY_64_WAY 0x0C +#define CPUID_ASSOCIATIVITY_96_WAY 0x0D +#define CPUID_ASSOCIATIVITY_128_WAY 0x0E +#define CPUID_ASSOCIATIVITY_FULLY 0x0F +#define AMD_CPUID_TLB_L1Cache 0x80000005ul +#define AMD_CPUID_APM 0x80000007ul +#define LOCAL_APIC_ID 24 +#define LOGICAL_PROCESSOR_COUNT 16 +#define AMD_CPUID_ASIZE_PCCOUNT 0x80000008ul // Address Size, Physical Core Count + +/// CPU Logical ID Transfer +typedef struct { + UINT32 RawId; ///< RawID + UINT64 LogicalId; ///< LogicalID +} CPU_LOGICAL_ID_XLAT; + +/// Logical CPU ID Table +typedef struct { + IN UINT32 Elements; ///< Number of Elements + IN CPU_LOGICAL_ID_XLAT *LogicalIdTable; ///< CPU Logical ID Transfer table Pointer +} LOGICAL_ID_TABLE; + +// MSRs +// ------------------------ +#define MCG_CTL_P 0x00000100ul // bit 8 for MCG_CTL_P under MSRR +#define MSR_MCG_CAP 0x00000179ul +#define MSR_MC0_CTL 0x00000400ul +#define MSR_MC0_STATUS 0x00000401ul +#define MSR_MC4_MISC 0x00000413ul +#define MSR_MC5_STATUS 0x00000415ul + +#define MSR_APIC_BAR 0x0000001Bul + +#define CPUID_LONG_MODE_ADDR 0x80000008ul + +#define MSR_EXTENDED_FEATURE_EN 0xC0000080ul +#define MSR_MC_MISC_L3_THRESHOLD 0xC0000409ul + +/// Patch Loader Register +typedef struct { + UINT64 PatchBase:32; ///< Linear address of patch header address block + UINT64 SBZ:32; ///< Should be zero +} PATCH_LOADER_MSR; + +#define MSR_SYS_CFG 0xC0010010ul // SYSCFG - F15 Shared +#define MSR_TOM2 0xC001001Dul // TOP_MEM2 - F15 Shared +#define MSR_MC0_CTL_MASK 0xC0010044ul // MC0 Control Mask +#define MSR_MC1_CTL_MASK 0xC0010045ul // MC1 Control Mask +#define MSR_MC2_CTL_MASK 0xC0010046ul // MC2 Control Mask +#define MSR_MC4_CTL_MASK 0xC0010048ul // MC4 Control Mask + +#define MSR_CPUID_FEATS 0xC0011004ul // CPUID Features +#define MSR_CPUID_EXT_FEATS 0xC0011005ul // CPUID Extended Features +#define MSR_HWCR 0xC0010015ul +#define MSR_NB_CFG 0xC001001Ful // NB Config +#define MSR_CpuWdtCfg 0xC0010074ul // CPU Watchdog Timer +#define ENABLE_CF8_EXT_CFG 0x00004000ul // [46] +#define INIT_APIC_CPUID_LO 0x00400000ul // [54] +#define MSR_LS_CFG 0xC0011020ul +#define MSR_IC_CFG 0xC0011021ul // ICache Config - F15 Shared +#define MSR_DC_CFG 0xC0011022ul +#define MSR_ME_CFG 0xC0011029ul +#define MSR_BU_CFG 0xC0011023ul +#define MSR_CU_CFG 0xC0011023ul // F15 Shared +#define MSR_DE_CFG 0xC0011029ul // F15 Shared +#define MSR_BU_CFG2 0xC001102Aul +#define MSR_CU_CFG2 0xC001102Aul // F15 Shared +#define MSR_BU_CFG3 0xC001102Bul +#define MSR_CU_CFG3 0xC001102Bul // F15 Shared +#define MSR_IBS_OP_DATA3 0xC0011037ul +#define MSR_L2I_CFG 0xC00110A0ul // F16 shared + + +#define MSR_CPUID_NAME_STRING0 0xC0010030ul // First CPUID namestring register +#define MSR_CPUID_NAME_STRING1 0xC0010031ul +#define MSR_CPUID_NAME_STRING2 0XC0010032ul +#define MSR_CPUID_NAME_STRING3 0xC0010033ul +#define MSR_CPUID_NAME_STRING4 0xC0010034ul +#define MSR_CPUID_NAME_STRING5 0xC0010035ul // Last CPUID namestring register +#define MSR_MMIO_Cfg_Base 0xC0010058ul // MMIO Configuration Base Address Register +#define MSR_BIST 0xC0010060ul // BIST Results register +#define MSR_OSVW_ID_Length 0xC0010140ul +#define MSR_OSVW_Status 0xC0010141ul +#define MSR_NB_PERF_CTL0 0xC0010240ul +#define MSR_NB_PERF_CTR0 0xC0010241ul +#define MSR_NB_PERF_CTL1 0xC0010242ul +#define MSR_NB_PERF_CTR1 0xC0010243ul +#define MSR_NB_PERF_CTL2 0xC0010244ul +#define MSR_NB_PERF_CTR2 0xC0010245ul +#define MSR_NB_PERF_CTL3 0xC0010246ul +#define MSR_NB_PERF_CTR3 0xC0010247ul +#define MSR_PERF_CONTROL3 0xC0010003ul // Performance control register number 3 +#define MSR_PERF_COUNTER3 0xC0010007ul // Performance counter register number 3 +#define PERF_RESERVE_BIT_MASK 0x030FFFDFFFFFull // Mask of the Performance control Reserve bits +#define PERF_CAR_CORRUPTION_EVENT 0x040040F0E2ul // Configure the controller to capture the + // CAR Corruption +// FUNC_0 registers +// ---------------- +#define HT_LINK_FREQ_OFFSET 8 // Link HT Frequency from capability base +#define HT_LINK_CONTROL_REG_OFFSET 4 +#define HT_LINK_TYPE_REG_OFFSET 0x18 +#define HT_LINK_EXTENDED_FREQ 0x1C +#define HT_LINK_HOST_CAP_MAX 0x20 // HT Host Capability offsets are less than its size. +#define HT_CAPABILITIES_POINTER 0x34 +#define NODE_ID 0x60 +#define HT_INIT_CTRL 0x6C +#define HT_INIT_CTRL_REQ_DIS 0x02 // [1] = ReqDis +#define HT_INIT_COLD_RST_DET BIT4 +#define HT_INIT_BIOS_RST_DET_0 BIT5 +#define HT_INIT_BIOS_RST_DET_1 BIT9 +#define HT_INIT_BIOS_RST_DET_2 BIT10 +#define HT_INIT_BIOS_RST_DET BIT9 | BIT10 +#define HT_TRANS_CTRL 0x68 +#define HT_TRANS_CTRL_CPU1_EN 0x00000020ul // [5] = CPU1 Enable +#define HT_LINK_CONTROL_0 0x84 +#define HT_LINK_FREQ_0 0x88 // Link HT Frequency +#define EXTENDED_NODE_ID 0x160 +#define ECS_HT_TRANS_CTRL 0x168 +#define ECS_HT_TRANS_CTRL_CPU2_EN 0x00000001ul // [0] = CPU2 Enable +#define ECS_HT_TRANS_CTRL_CPU3_EN 0x00000002ul // [1] = CPU3 Enable +#define ECS_HT_TRANS_CTRL_CPU4_EN 0x00000004ul // [2] = CPU4 Enable +#define ECS_HT_TRANS_CTRL_CPU5_EN 0x00000008ul // [3] = CPU5 Enable + +#define CORE_CTRL 0x1DC +#define CORE_CTRL_CORE1_EN 0x00000002ul +#define CORE_CTRL_CORE2_EN 0x00000004ul +#define CORE_CTRL_CORE3_EN 0x00000008ul +#define CORE_CTRL_CORE4_EN 0x00000010ul +#define CORE_CTRL_CORE5_EN 0x00000020ul +#define CORE_CTRL_CORE6_EN 0x00000040ul +#define CORE_CTRL_CORE7_EN 0x00000080ul +#define CORE_CTRL_CORE8_EN 0x00000100ul +#define CORE_CTRL_CORE9_EN 0x00000200ul + +// FUNC_3 registers +// ---------------- +#define HARDWARE_THERMAL_CTRL_REG 0x64 +#define SOFTWARE_THERMAL_CTRL_REG 0x68 + +#define ACPI_PSC_0_REG 0x80 // ACPI Power State Control Registers +#define ACPI_PSC_4_REG 0x84 + +#define NB_CFG_HIGH_REG 0x8C +#define POWER_CTRL_MISCELLANEOUS_REG 0xA0 +#define CLOCK_POWER_TIMING_CTRL2_REG 0xDC +#define NORTH_BRIDGE_CAPABILITIES_REG 0xE8 +#define CPUID_FMR 0xFC // Family / Model registers +#define DOWNCORE_CTRL 0x190 // Downcore Control Register + +#define LINK_TO_XCS_TOKEN_COUNT_REG_3X148 0x148 +#define REG_HT4_PHY_OFFSET_BASE_4X180 0x180 +#define REG_HT4_PHY_DATA_PORT_BASE_4X184 0x184 + +#define HTPHY_OFFSET_MASK 0xE00001FFul +#define HTPHY_WRITE_CMD 0x40000000ul +#define HTPHY_IS_COMPLETE_MASK 0x80000000ul +#define HTPHY_DIRECT_MAP 0x20000000ul +#define HTPHY_DIRECT_OFFSET_MASK 0x6000FFFFul + +// FUNC_5 registers +// ---------------- +#define COMPUTE_UNIT_STATUS 0x80 +#define NORTH_BRIDGE_CAPABILITIES_2_REG 0x84 + + +// Misc. defines. +#define PCI_DEV_BASE 24 + +#define CPU_STEPPING 0x0000000Ful +#define CPU_MODEL 0x000000F0ul +#define CPU_EMODEL 0x000F0000ul +#define CPU_EFAMILY 0x00F00000ul +#define CPU_FMS_MASK CPU_EFAMILY | CPU_EMODEL | CPU_MODEL | CPU_STEPPING + +#define HTPHY_SELECT 2 +#define PCI_SELECT 1 +#define MSR_SELECT 0 + +#define LOGICAL_ID 1 +#define F_SCHEME 0 +#define DR_SCHEME 1 +#define GR_SCHEME 2 + +#define DR_NO_STRING 0 +#define DR_SOCKET_C32 5 +#define DR_SOCKET_ASB2 4 +#define DR_SOCKET_G34 3 +#define DR_SOCKET_S1G3 2 +#define DR_SOCKET_S1G4 2 +#define DR_SOCKET_AM3 1 +#define DR_SOCKET_1207 0 +#define LN_SOCKET_FM1 2 +#define LN_SOCKET_FS1 1 +#define LN_SOCKET_FP1 0 +#define ON_SOCKET_FT1 0 +#define OR_SOCKET_AM3 1 +#define OR_SOCKET_G34 3 +#define OR_SOCKET_C32 5 +#define TN_SOCKET_FP2 0 +#define TN_SOCKET_FS1 1 +#define TN_SOCKET_FM2 2 +#define KB_SOCKET_FT3 0 +#define SOCKET_IGNORE 0xF + +#define LAPIC_BASE_ADDR_MASK 0x0000FFFFFFFFF000ull +#define APIC_EXT_BRDCST_MASK 0x000E0000ul +#define APIC_ENABLE_BIT 0x00000800ul +#ifndef LOCAL_APIC_ADDR +#define LOCAL_APIC_ADDR 0xFEE00000ul +#endif +#define INT_CMD_REG_LO 0x300 +#define INT_CMD_REG_HI 0x310 +#define REMOTE_MSG_REG 0x380 +#define REMOTE_READ_REG 0xC0 +#define APIC_ID_REG 0x20 +#define APIC20_ApicId 24 + +#define MAX_CORE_ID_SIZE 8 +#define MAX_CORE_ID_MASK ((1 << MAX_CORE_ID_SIZE) - 1) + +/*------------------------- + * Default definitions + *------------------------- + */ +#define DOWNCORE_MASK_SINGLE 0xFFFFFFFEul +#define DOWNCORE_MASK_DUAL 0xFFFFFFFCul +#define DOWNCORE_MASK_TRI 0xFFFFFFF8ul +#define DOWNCORE_MASK_FOUR 0xFFFFFFF0ul +#define DOWNCORE_MASK_FIVE 0xFFFFFFE0ul +#define DOWNCORE_MASK_SIX 0xFFFFFFC0ul +#define DOWNCORE_MASK_SEVEN 0xFFFFFF80ul +#define DOWNCORE_MASK_EIGHT 0xFFFFFF00ul +#define DOWNCORE_MASK_TEN 0xFFFFFC00ul +#define DOWNCORE_MASK_TWELVE 0xFFFFF000ul +#define DOWNCORE_MASK_FOURTEEN 0xFFFFC000ul +#define DOWNCORE_MASK_DUAL_COMPUTE_UNIT 0xFFFFFFFAul +#define DOWNCORE_MASK_TRI_COMPUTE_UNIT 0xFFFFFFEAul +#define DOWNCORE_MASK_FOUR_COMPUTE_UNIT 0xFFFFFFAAul +#define DOWNCORE_MASK_FIVE_COMPUTE_UNIT 0xFFFFFEAAul +#define DOWNCORE_MASK_SIX_COMPUTE_UNIT 0xFFFFFAAAul +#define DOWNCORE_MASK_SEVEN_COMPUTE_UNIT 0xFFFFEAAAul +#define DOWNCORE_MASK_EIGHT_COMPUTE_UNIT 0xFFFFAAAAul + +#define DELIVERY_STATUS BIT13 +#define REMOTE_READ_STAT_MASK 0x00030000ul +#define REMOTE_DELIVERY_PENDING 0x00010000ul +#define REMOTE_DELIVERY_DONE 0x00020000ul + +/* + * -------------------------------------------------------------------------------------- + * + * D E F I N E S / T Y P E D E F S / S T R U C T U R E S + * + * -------------------------------------------------------------------------------------- + */ + +/// CpuEarly param type +typedef struct { + IN UINT8 MemInitPState; ///< Pstate value during memory initial + IN PLATFORM_CONFIGURATION PlatformConfig; ///< Runtime configurable user options +} AMD_CPU_EARLY_PARAMS; + +/// Enum - Will be used to access each structure +/// related to each CPU family +typedef enum { + REVF, ///< NPT, RevF + REVG, ///< NPT, RevG + DEERHOUND, ///< Family 10h, Deerhound + GRIFFIN ///< Family 11h, Griffin +} CPU_FAMILY; + +/// CPUID +typedef enum { + REG_EAX, ///< EAX + REG_EBX, ///< EBX + REG_ECX, ///< ECX + REG_EDX ///< EDX +} CPUID_REG; + +#endif // _CPU_REGISTERS_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuServices.h new file mode 100644 index 0000000000..7e68e3f3fc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuServices.h @@ -0,0 +1,342 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Services + * + * Related to the General Services API's, but for the CPU component. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CPU_SERVICES_H_ +#define _CPU_SERVICES_H_ + +#include "Topology.h" + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + /// WARM RESET STATE_BITS +#define WR_STATE_COLD 00 +#define WR_STATE_RESET 01 +#define WR_STATE_EARLY 02 +#define WR_STATE_POST 03 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *---------------------------------------------------------------------------------------- + */ + +/** + * The role of primary core for each compute unit can be relative to the cores' launch order. + * + * One core of a compute unit is always given the role as primary. In different feature algorithms + * the core performing the primary core role can be designated relative to compute order. In most cases, + * the primary core is the first core of a compute unit to execute. However, in some cases the primary core + * role is associated with the last core to execute. + * + * If the launch order is strictly ascending, then first core is the lowest number and last core is highest. + * But if the launch order is not ascending, the first and last core follow the launch order, not the numbering order. + * + * Note that for compute units with only one core (AllCoresMapping), that core is primary for both orderings. + * (This includes processors without hardware compute units.) + * + */ +typedef enum { + FirstCoreIsComputeUnitPrimary, ///< the primary core role associates with the first core. + LastCoreIsComputeUnitPrimary, ///< the primary core role associates with the last core. + MaxComputeUnitPrimarySelector, ///< limit check. +} COMPUTE_UNIT_PRIMARY_SELECTOR; + +/** + * The supported Core to Compute unit mappings. + */ +typedef enum { + AllCoresMapping, ///< All Cores are primary cores + EvenCoresMapping, ///< Compute units are even/odd core pairs. + TripleCoresMapping, ///< Compute units has three cores enabled. + QuadCoresMapping, ///< Compute units has four cores enabled. + BitMapMapping, ///< Currently not supported by any family, arbitrary core + ///< to compute unit mapping. + MaxComputeUnitMapping ///< Not a mapping, use for limit check. +} COMPUTE_UNIT_MAPPING; + +/** + * Compute unit status register. + */ + +/** + * Compute Unit Map entry. + * Provide for interpreting the core pairing for the processor's compute units. + * + * HT_LIST_TERMINAL as an Enabled value means the end of a list of map structs. + * Zero as an Enabled value implies Compute Units are not supported by the processor + * and the mapping is assumed to be AllCoresMapping. + * + */ +typedef struct { + UINT8 Enabled; ///< The value of the Enabled Compute Units + UINT8 DualCore; ///< The value of the Dual Core Compute Units + UINT8 TripleCore; ///< the value of the Triple Core Compute Units + UINT8 QuadCore; ///< the value of the Quad Core Compute Units + COMPUTE_UNIT_MAPPING Mapping; ///< When the processor module matches these values, use this mapping method. +} COMPUTE_UNIT_MAP; + +//---------------------------------------------------------------------------- +// CPU SYSTEM INFO TYPEDEFS, STRUCTURES, ENUMS +// +//---------------------------------------------------------------------------- +/// SYSTEM INFO +typedef struct _SYSTEM_INFO { + UINT32 TotalNumberOfSockets; ///< Total Number of Sockets + UINT32 TotalNumberOfCores; ///< Total Number Of Cores + UINT32 CurrentSocketNum; ///< Current Socket Number + UINT32 CurrentCoreNum; ///< Current Core Number + UINT32 CurrentCoreApicId; ///< Current Core Apic ID + UINT32 CurrentLogicalCpuId; ///< Current Logical CPU ID +} SYSTEM_INFO; + +/// WARM_RESET_REQUEST +typedef struct _WARM_RESET_REQUEST { + UINT8 RequestBit:1; ///< Request Bit + UINT8 StateBits:2; ///< State Bits + UINT8 PostStage:2; ///< Post Stage + UINT8 Reserved:(8 - 5); ///< Reserved +} WARM_RESET_REQUEST; +/*---------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +VOID +GetCurrentNodeNum ( + OUT UINT32 *Node, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Get the current Platform's number of Sockets, regardless of how many are populated. + * + */ +UINT32 +GetPlatformNumberOfSockets ( VOID ); + +/** + * Get the number of Modules to check presence in each Processor. + * + */ +UINT32 +GetPlatformNumberOfModules ( VOID ); + +BOOLEAN +IsProcessorPresent ( + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * For a specific Node, get its Socket and Module ids. + * + */ +BOOLEAN +GetSocketModuleOfNode ( + IN UINT32 Node, + OUT UINT32 *Socket, + OUT UINT32 *Module, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Get the current core's Processor APIC Index. + */ +UINT32 +GetProcessorApicIndex ( + IN UINT32 Node, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Provide the number of installed processors (not Nodes! and not Sockets!) + */ +UINT32 +GetNumberOfProcessors ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetActiveCoresInCurrentSocket ( + OUT UINT32 *CoreCount, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetActiveCoresInGivenSocket ( + IN UINT32 Socket, + OUT UINT32 *CoreCount, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINTN +GetActiveCoresInCurrentModule ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINTN +GetNumberOfCompUnitsInCurrentModule ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetGivenModuleCoreRange ( + IN UINT32 Socket, + IN UINT32 Module, + OUT UINT32 *LowCore, + OUT UINT32 *HighCore, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetCurrentCore ( + OUT UINT32 *Core, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetCurrentNodeAndCore ( + OUT UINT32 *Node, + OUT UINT32 *Core, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +IsCurrentCorePrimary ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GetApMailbox ( + OUT UINT32 *ApMailboxInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +CacheApMailbox ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +CacheBspMailbox ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AP_MAILBOXES *ApMailboxes, + IN UINT8 NumberOfNodes + ); + +UINTN +GetSystemDegree ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetNodeId ( + IN UINT32 SocketId, + IN UINT32 ModuleId, + OUT UINT8 *NodeId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +WaitMicroseconds ( + IN UINT32 Microseconds, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Get the compute unit mapping algorithm. + */ +COMPUTE_UNIT_MAPPING +GetComputeUnitMapping ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Does the current core have the role of primary core for the compute unit? + */ +BOOLEAN +IsCoreComputeUnitPrimary ( + IN COMPUTE_UNIT_PRIMARY_SELECTOR Selector, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SetWarmResetFlag ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN WARM_RESET_REQUEST *Request + ); + +VOID +GetWarmResetFlag ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT WARM_RESET_REQUEST *Request + ); + +BOOLEAN +IsWarmReset ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +CheckBistStatus ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SetWarmResetAtEarly ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader +); + +#ifndef CPU_DEADLOOP + #define CPU_DEADLOOP() { volatile UINTN __i; __i = 1; while (__i); } +#endif + +#endif // _CPU_SERVICES_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuWarmReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuWarmReset.c new file mode 100644 index 0000000000..6aa5a76faf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/cpuWarmReset.c @@ -0,0 +1,234 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD CPU Warm Reset Implementation. + * + * Implement Warm Reset Interface. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_CPUWARMRESET_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will set the CPU register warm reset bits. + * + * Note: This function will be called by UEFI BIOS's + * The UEFI wrapper code should register this function, to be called back later point + * in time, before the wrapper code does warm reset. + * + * @param[in] StdHeader Config handle for library and services + * @param[in] Request Indicate warm reset status + * + *--------------------------------------------------------------------------------------- + **/ +VOID +SetWarmResetFlag ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN WARM_RESET_REQUEST *Request + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + FamilySpecificServices = NULL; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->SetWarmResetFlag (FamilySpecificServices, StdHeader, Request); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will get the CPU register warm reset bits. + * + * Note: This function will be called by UEFI BIOS's + * The UEFI wrapper code should register this function, to be called back later point + * in time, before the wrapper code does warm reset. + * + * @param[in] StdHeader Config handle for library and services + * @param[out] Request Indicate warm reset status + * + *--------------------------------------------------------------------------------------- + **/ +VOID +GetWarmResetFlag ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT WARM_RESET_REQUEST *Request + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + FamilySpecificServices = NULL; + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, Request); + + switch (StdHeader->Func) { + case AMD_INIT_RESET: + Request->PostStage = (UINT8) WR_STATE_RESET; + break; + case AMD_INIT_EARLY: + Request->PostStage = (UINT8) WR_STATE_EARLY; + break; + case AMD_INIT_POST: + // Fall through to default case + default: + Request->PostStage = (UINT8) WR_STATE_POST; + break; + } +} +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S - (AGESA ONLY) + *---------------------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------------------*/ +/** + * Is this boot a warm reset? + * + * This function reads the CPU register warm reset bit that is preserved after a warm reset. + * Which in fact gets set before issuing warm reset. We just use the BSP's register always. + * + * @param[in] StdHeader Config handle for library and services + * + * @retval TRUE Warm Reset + * @retval FALSE Not Warm Reset + * + */ +BOOLEAN +IsWarmReset ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PostStage; + WARM_RESET_REQUEST Request; + BOOLEAN WarmReset; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + FamilySpecificServices = NULL; + + switch (StdHeader->Func) { + case AMD_INIT_RESET: + PostStage = WR_STATE_RESET; + break; + case AMD_INIT_EARLY: + PostStage = WR_STATE_EARLY; + break; + case AMD_INIT_POST: + default: + PostStage = WR_STATE_POST; + break; + } + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, &Request); + + if (Request.StateBits >= PostStage) { + WarmReset = TRUE; + } else { + WarmReset = FALSE; + } + + return WarmReset; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will set the CPU register warm reset bits at AmdInitEarly if it is + * currently in cold boot. To request for a warm reset, set the RequestBit to TRUE + * and the StateBits to (current poststage - 1) + * + * @param[in] Data The table data value (unused in this routine) + * @param[in] StdHeader Config handle for library and services + * + *--------------------------------------------------------------------------------------- + **/ +VOID +SetWarmResetAtEarly ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + WARM_RESET_REQUEST Request; + + if (!IsWarmReset (StdHeader)) { + GetWarmResetFlag (StdHeader, &Request); + + Request.RequestBit = TRUE; + Request.StateBits = (Request.PostStage - 1); + + SetWarmResetFlag (StdHeader, &Request); + } +} + +/*---------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/heapManager.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/heapManager.c new file mode 100644 index 0000000000..42a6afa10f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/heapManager.c @@ -0,0 +1,889 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Heap Manager and Heap Allocation APIs, and related functions. + * + * Contains code that initialize, maintain, and allocate the heap space. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/******************************************************************************* + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "heapManager.h" +#include "cpuCacheInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_CPU_HEAPMANAGER_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +UINT64 +STATIC +HeapGetCurrentBase ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +DeleteFreeSpaceNode ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT32 OffsetOfDeletedNode + ); + +VOID +STATIC +InsertFreeSpaceNode ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT32 OffsetOfInsertNode + ); + +/*---------------------------------------------------------------------------------------- + * P U B L I C F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +UINT64 +HeapGetBaseAddressInTempMem ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * This function initializes the heap for each CPU core. + * + * Check for already initialized. If not, determine offset of local heap in CAS and + * setup initial heap markers and bookkeeping status. Initialize a couple heap items + * all cores need, for convenience. Currently these are caching the AP mailbox info and + * an initial event log. + * + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_SUCCESS This core's heap is initialized + * @retval AGESA_FATAL This core's heap cannot be initialized due to any reasons below: + * - current processor family cannot be identified. + * + */ +AGESA_STATUS +HeapManagerInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // First Time Initialization + // Note: First 16 bytes of buffer is reserved for Heap Manager use + UINT16 HeapAlreadyInitSizeDword; + UINT32 HeapAlreadyRead; + UINT8 L2LineSize; + UINT8 *HeapBufferPtr; + UINT8 *HeapInitPtr; + UINT32 *HeapDataPtr; + UINT64 MsrData; + UINT64 MsrMask; + UINT8 Ignored; + CPUID_DATA CpuId; + BUFFER_NODE *FreeSpaceNode; + CACHE_INFO *CacheInfoPtr; + AGESA_STATUS IgnoredSts; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + CPU_LOGICAL_ID CpuFamilyRevision; + + // Check whether this is a known processor family. + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + if ((CpuFamilyRevision.Family == 0) && (CpuFamilyRevision.Revision == 0)) { + IDS_ERROR_TRAP; + return AGESA_FATAL; + } + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **) &CacheInfoPtr, &Ignored, StdHeader); + HeapBufferPtr = (UINT8 *)(UINT32) StdHeader->HeapBasePtr; + + // Check whether the heap manager is already initialized + LibAmdMsrRead (AMD_MTRR_VARIABLE_HEAP_MASK, &MsrData, StdHeader); + if (MsrData == (CacheInfoPtr->VariableMtrrMask & AMD_HEAP_MTRR_MASK)) { + LibAmdMsrRead (AMD_MTRR_VARIABLE_HEAP_BASE, &MsrData, StdHeader); + if ((MsrData & CacheInfoPtr->HeapBaseMask) == ((UINT64) (UINTN) HeapBufferPtr & CacheInfoPtr->HeapBaseMask)) { + if (((HEAP_MANAGER *) HeapBufferPtr)->Signature == HEAP_SIGNATURE_VALID) { + // This is not a bug, there are multiple premem basic entry points, + // and each will call heap init to make sure create struct will succeed. + // If that is later deemed a problem, there needs to be a reasonable test + // for the calling code to make to determine if it needs to init heap or not. + // In the mean time, add this to the event log + PutEventLog (AGESA_SUCCESS, + CPU_ERROR_HEAP_IS_ALREADY_INITIALIZED, + 0, 0, 0, 0, StdHeader); + return AGESA_SUCCESS; + } + } + } + + // Set variable MTRR base and mask + MsrData = ((UINT64) (UINTN) HeapBufferPtr & CacheInfoPtr->HeapBaseMask); + MsrMask = CacheInfoPtr->VariableMtrrHeapMask & AMD_HEAP_MTRR_MASK; + + MsrData |= 0x06; + LibAmdMsrWrite (AMD_MTRR_VARIABLE_HEAP_BASE, &MsrData, StdHeader); + LibAmdMsrWrite (AMD_MTRR_VARIABLE_HEAP_MASK, &MsrMask, StdHeader); + + // Set top of memory to a temp value + MsrData = (UINT64) (AMD_TEMP_TOM); + LibAmdMsrWrite (TOP_MEM, &MsrData, StdHeader); + + // Enable variable MTTRs + LibAmdMsrRead (SYS_CFG, &MsrData, StdHeader); + MsrData |= AMD_VAR_MTRR_ENABLE_BIT; + LibAmdMsrWrite (SYS_CFG, &MsrData, StdHeader); + + // Initialize Heap Space + // BIOS may store to a line only after it has been allocated by a load + LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuId, StdHeader); + L2LineSize = (UINT8) (CpuId.ECX_Reg); + HeapInitPtr = HeapBufferPtr ; + for (HeapAlreadyRead = 0; HeapAlreadyRead < AMD_HEAP_SIZE_PER_CORE; + (HeapAlreadyRead = HeapAlreadyRead + L2LineSize)) { + Ignored = *HeapInitPtr; + HeapInitPtr += L2LineSize; + } + + HeapDataPtr = (UINT32 *) HeapBufferPtr; + for (HeapAlreadyInitSizeDword = 0; HeapAlreadyInitSizeDword < AMD_HEAP_SIZE_DWORD_PER_CORE; HeapAlreadyInitSizeDword++) { + *HeapDataPtr = 0; + HeapDataPtr++; + } + + // Note: We are reserving the first 16 bytes for Heap Manager use + // UsedSize indicates the size of heap spaced is used for HEAP_MANAGER, BUFFER_NODE, + // Pad for 16-byte alignment, buffer data, and IDS SENTINEL. + // FirstActiveBufferOffset is initalized as invalid heap offset, AMD_HEAP_INVALID_HEAP_OFFSET. + // FirstFreeSpaceOffset is initalized as the byte right after HEAP_MANAGER header. + // Then we set Signature of HEAP_MANAGER header as valid, HEAP_SIGNATURE_VALID. + ((HEAP_MANAGER*) HeapBufferPtr)->UsedSize = sizeof (HEAP_MANAGER); + ((HEAP_MANAGER*) HeapBufferPtr)->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET; + ((HEAP_MANAGER*) HeapBufferPtr)->FirstFreeSpaceOffset = sizeof (HEAP_MANAGER); + ((HEAP_MANAGER*) HeapBufferPtr)->Signature = HEAP_SIGNATURE_VALID; + // Create free space link + FreeSpaceNode = (BUFFER_NODE *) (HeapBufferPtr + sizeof (HEAP_MANAGER)); + FreeSpaceNode->BufferSize = AMD_HEAP_SIZE_PER_CORE - sizeof (HEAP_MANAGER) - sizeof (BUFFER_NODE); + FreeSpaceNode->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET; + + StdHeader->HeapStatus = HEAP_LOCAL_CACHE; + if (!IsBsp (StdHeader, &IgnoredSts)) { + // The BSP's hardware mailbox has not been initialized, so only APs + // can do this at this point. + CacheApMailbox (StdHeader); + } + EventLogInitialization (StdHeader); + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Allocates space for a new buffer in the heap + * + * This function will allocate new buffer either by using internal 'AGESA' heapmanager + * or by using externa (IBV) heapmanager. This function will also determine if whether or not + * there is enough space for the new structure. If so, it will zero out the buffer, + * and return a pointer to the region. + * + * @param[in,out] AllocateHeapParams structure pointer containing the size of the + * desired new region, its handle, and the + * return pointer. + * @param[in,out] StdHeader Config handle for library and services. + * + * @retval AGESA_SUCCESS No error + * @retval AGESA_BOUNDS_CHK Handle already exists, or not enough + * free space + * @retval AGESA_UNSUPPORTED Do not support this kind of heap allocation + * @retval AGESA_ERROR Heap is invaild + * + */ +AGESA_STATUS +HeapAllocateBuffer ( + IN OUT ALLOCATE_HEAP_PARAMS *AllocateHeapParams, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *BaseAddress; + UINT8 AlignTo16Byte; + UINT8 CalloutFcnData; + UINT32 RemainSize; + UINT32 OffsetOfSplitNode; + UINT32 OffsetOfNode; + HEAP_MANAGER *HeapManager; + BUFFER_NODE *FreeSpaceNode; + BUFFER_NODE *SplitFreeSpaceNode; + BUFFER_NODE *CurrentBufferNode; + BUFFER_NODE *NewBufferNode; + AGESA_BUFFER_PARAMS AgesaBuffer; + + ASSERT (StdHeader != NULL); + if (AllocateHeapParams->Persist == HEAP_RUNTIME_SYSTEM_MEM) { + ASSERT (StdHeader->HeapStatus == HEAP_SYSTEM_MEM); + if (StdHeader->HeapStatus != HEAP_SYSTEM_MEM) { + return AGESA_UNSUPPORTED; + } + } + + // At this stage we will decide to either use external (IBV) heap manger + // or internal (AGESA) heap manager. + + // If (HeapStatus == HEAP_SYSTEM_MEM), then use the call function to call + // external heap manager + if (StdHeader->HeapStatus == HEAP_SYSTEM_MEM) { + AgesaBuffer.StdHeader = *StdHeader; + AgesaBuffer.BufferHandle = AllocateHeapParams->BufferHandle; + AgesaBuffer.BufferLength = AllocateHeapParams->RequestedBufferSize; + + if (AllocateHeapParams->Persist == HEAP_RUNTIME_SYSTEM_MEM) { + CalloutFcnData = HEAP_CALLOUT_RUNTIME; + } else { + CalloutFcnData = HEAP_CALLOUT_BOOTTIME; + } + AGESA_TESTPOINT (TpIfBeforeAllocateHeapBuffer, StdHeader); + if (AgesaAllocateBuffer (CalloutFcnData, &AgesaBuffer) != AGESA_SUCCESS) { + AllocateHeapParams->BufferPtr = NULL; + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpIfAfterAllocateHeapBuffer, StdHeader); + + AllocateHeapParams->BufferPtr = (UINT8 *) (AgesaBuffer.BufferPointer); + return AGESA_SUCCESS; + } + + // If (StdHeader->HeapStatus != HEAP_SYSTEM_MEM), then allocated buffer + // using following AGESA Heap Manager code. + + // Buffer pointer is NULL unless we return a buffer. + AlignTo16Byte = 0; + AllocateHeapParams->BufferPtr = NULL; + AllocateHeapParams->RequestedBufferSize += NUM_OF_SENTINEL * SIZE_OF_SENTINEL; + + // Get base address + BaseAddress = (UINT8 *) (UINTN) StdHeader->HeapBasePtr; + HeapManager = (HEAP_MANAGER *) BaseAddress; + + // Check Heap database is valid + if ((BaseAddress == NULL) || (HeapManager->Signature != HEAP_SIGNATURE_VALID)) { + // The base address in StdHeader is incorrect, get base address by itself + BaseAddress = (UINT8 *)(UINT32) HeapGetBaseAddress (StdHeader); + HeapManager = (HEAP_MANAGER *) BaseAddress; + if ((BaseAddress == NULL) || (HeapManager->Signature != HEAP_SIGNATURE_VALID)) { + // Heap is not available, ASSERT here + ASSERT (FALSE); + return AGESA_ERROR; + } + StdHeader->HeapBasePtr = (UINT64)(UINT32) BaseAddress; + } + + // Allocate + CurrentBufferNode = (BUFFER_NODE *) (BaseAddress + sizeof (HEAP_MANAGER)); + // If there already has been a heap with the incoming BufferHandle, we return AGESA_BOUNDS_CHK. + if (HeapManager->FirstActiveBufferOffset != AMD_HEAP_INVALID_HEAP_OFFSET) { + CurrentBufferNode = (BUFFER_NODE *) (BaseAddress + HeapManager->FirstActiveBufferOffset); + while (CurrentBufferNode->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET) { + if (CurrentBufferNode->BufferHandle == AllocateHeapParams->BufferHandle) { + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_BUFFER_HANDLE_IS_ALREADY_USED, + AllocateHeapParams->BufferHandle, 0, 0, 0, StdHeader); + return AGESA_BOUNDS_CHK; + } else { + CurrentBufferNode = (BUFFER_NODE *) (BaseAddress + CurrentBufferNode->OffsetOfNextNode); + } + } + if (CurrentBufferNode->BufferHandle == AllocateHeapParams->BufferHandle) { + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_BUFFER_HANDLE_IS_ALREADY_USED, + AllocateHeapParams->BufferHandle, 0, 0, 0, StdHeader); + return AGESA_BOUNDS_CHK; + } + } + + // Find the buffer size that first matches the requested buffer size (i.e. the first free buffer of greater size). + OffsetOfNode = HeapManager->FirstFreeSpaceOffset; + FreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfNode); + while (OffsetOfNode != AMD_HEAP_INVALID_HEAP_OFFSET) { + AlignTo16Byte = (UINT8) ((0x10 - (((UINTN) (VOID *) FreeSpaceNode + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL) & 0xF)) & 0xF); + AllocateHeapParams->RequestedBufferSize = (UINT32) (AllocateHeapParams->RequestedBufferSize + AlignTo16Byte); + if (FreeSpaceNode->BufferSize >= AllocateHeapParams->RequestedBufferSize) { + break; + } + AllocateHeapParams->RequestedBufferSize = (UINT32) (AllocateHeapParams->RequestedBufferSize - AlignTo16Byte); + OffsetOfNode = FreeSpaceNode->OffsetOfNextNode; + FreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfNode); + } + if (OffsetOfNode == AMD_HEAP_INVALID_HEAP_OFFSET) { + // We don't find any free space buffer that matches the requested buffer size. + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_IS_FULL, + AllocateHeapParams->BufferHandle, 0, 0, 0, StdHeader); + return AGESA_BOUNDS_CHK; + } else { + // We find one matched free space buffer. + DeleteFreeSpaceNode (StdHeader, OffsetOfNode); + NewBufferNode = FreeSpaceNode; + // Add new buffer node to the buffer chain + if (HeapManager->FirstActiveBufferOffset == AMD_HEAP_INVALID_HEAP_OFFSET) { + HeapManager->FirstActiveBufferOffset = sizeof (HEAP_MANAGER); + } else { + CurrentBufferNode->OffsetOfNextNode = OffsetOfNode; + } + // New buffer size + RemainSize = FreeSpaceNode->BufferSize - AllocateHeapParams->RequestedBufferSize; + if (RemainSize > sizeof (BUFFER_NODE)) { + NewBufferNode->BufferSize = AllocateHeapParams->RequestedBufferSize; + OffsetOfSplitNode = OffsetOfNode + sizeof (BUFFER_NODE) + NewBufferNode->BufferSize; + SplitFreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfSplitNode); + SplitFreeSpaceNode->BufferSize = RemainSize - sizeof (BUFFER_NODE); + InsertFreeSpaceNode (StdHeader, OffsetOfSplitNode); + } else { + // Remain size is less than BUFFER_NODE, we use whole size instead of requested size. + NewBufferNode->BufferSize = FreeSpaceNode->BufferSize; + } + } + + // Initialize BUFFER_NODE structure of NewBufferNode + NewBufferNode->BufferHandle = AllocateHeapParams->BufferHandle; + if ((AllocateHeapParams->Persist == HEAP_TEMP_MEM) || (AllocateHeapParams->Persist == HEAP_SYSTEM_MEM)) { + NewBufferNode->Persist = AllocateHeapParams->Persist; + } else { + NewBufferNode->Persist = HEAP_LOCAL_CACHE; + } + NewBufferNode->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET; + NewBufferNode->PadSize = AlignTo16Byte; + + // Clear to 0x00 + LibAmdMemFill ((VOID *) ((UINT8 *) NewBufferNode + sizeof (BUFFER_NODE)), 0x00, NewBufferNode->BufferSize, StdHeader); + + // Debug feature + SET_SENTINEL_BEFORE (NewBufferNode, AlignTo16Byte); + SET_SENTINEL_AFTER (NewBufferNode); + + // Update global variables + HeapManager->UsedSize += NewBufferNode->BufferSize + sizeof (BUFFER_NODE); + + // Now fill in the incoming structure + AllocateHeapParams->BufferPtr = (UINT8 *) ((UINT8 *) NewBufferNode + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL + AlignTo16Byte); + AllocateHeapParams->RequestedBufferSize -= (NUM_OF_SENTINEL * SIZE_OF_SENTINEL + AlignTo16Byte); + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Deallocates a previously allocated buffer in the heap + * + * This function will deallocate buffer either by using internal 'AGESA' heapmanager + * or by using externa (IBV) heapmanager. + * + * @param[in] BufferHandle Handle of the buffer to free. + * @param[in] StdHeader Config handle for library and services. + * + * @retval AGESA_SUCCESS No error + * @retval AGESA_BOUNDS_CHK Handle does not exist on the heap + * + */ +AGESA_STATUS +HeapDeallocateBuffer ( + IN UINT32 BufferHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *BaseAddress; + UINT32 NodeSize; + UINT32 OffsetOfFreeSpaceNode; + UINT32 OffsetOfPreviousNode; + UINT32 OffsetOfCurrentNode; + BOOLEAN HeapLocateFlag; + HEAP_MANAGER *HeapManager; + BUFFER_NODE *CurrentNode; + BUFFER_NODE *PreviousNode; + BUFFER_NODE *FreeSpaceNode; + AGESA_BUFFER_PARAMS AgesaBuffer; + + ASSERT (StdHeader != NULL); + + HeapLocateFlag = TRUE; + BaseAddress = (UINT8 *) (UINTN) StdHeader->HeapBasePtr; + HeapManager = (HEAP_MANAGER *) BaseAddress; + + // Check Heap database is valid + if ((BaseAddress == NULL) || (HeapManager->Signature != HEAP_SIGNATURE_VALID)) { + // The base address in StdHeader is incorrect, get base address by itself + BaseAddress = (UINT8 *)(UINT32) HeapGetBaseAddress (StdHeader); + HeapManager = (HEAP_MANAGER *) BaseAddress; + if ((BaseAddress == NULL) || (HeapManager->Signature != HEAP_SIGNATURE_VALID)) { + // Heap is not available, ASSERT here + ASSERT (FALSE); + return AGESA_ERROR; + } + StdHeader->HeapBasePtr = (UINT64)(UINT32) BaseAddress; + } + + OffsetOfPreviousNode = AMD_HEAP_INVALID_HEAP_OFFSET; + OffsetOfCurrentNode = HeapManager->FirstActiveBufferOffset; + CurrentNode = (BUFFER_NODE *) (BaseAddress + OffsetOfCurrentNode); + + // Locate heap + if ((BaseAddress != NULL) && (HeapManager->Signature == HEAP_SIGNATURE_VALID)) { + if (OffsetOfCurrentNode == AMD_HEAP_INVALID_HEAP_OFFSET) { + HeapLocateFlag = FALSE; + } else { + while (CurrentNode->BufferHandle != BufferHandle) { + if (CurrentNode->OffsetOfNextNode == AMD_HEAP_INVALID_HEAP_OFFSET) { + HeapLocateFlag = FALSE; + break; + } else { + OffsetOfPreviousNode = OffsetOfCurrentNode; + OffsetOfCurrentNode = CurrentNode->OffsetOfNextNode; + CurrentNode = (BUFFER_NODE *) (BaseAddress + OffsetOfCurrentNode); + } + } + } + } else { + HeapLocateFlag = FALSE; + } + + if (HeapLocateFlag == TRUE) { + // CurrentNode points to the buffer which wanted to be deallocated. + // Remove deallocated heap from active buffer chain. + if (OffsetOfPreviousNode == AMD_HEAP_INVALID_HEAP_OFFSET) { + HeapManager->FirstActiveBufferOffset = CurrentNode->OffsetOfNextNode; + } else { + PreviousNode = (BUFFER_NODE *) (BaseAddress + OffsetOfPreviousNode); + PreviousNode->OffsetOfNextNode = CurrentNode->OffsetOfNextNode; + } + // Now, CurrentNode become a free space node. + HeapManager->UsedSize -= CurrentNode->BufferSize + sizeof (BUFFER_NODE); + // Loop free space chain to see if any free space node is just before/after CurrentNode, then merge them. + OffsetOfFreeSpaceNode = HeapManager->FirstFreeSpaceOffset; + FreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfFreeSpaceNode); + while (OffsetOfFreeSpaceNode != AMD_HEAP_INVALID_HEAP_OFFSET) { + if ((OffsetOfFreeSpaceNode + sizeof (BUFFER_NODE) + FreeSpaceNode->BufferSize) == OffsetOfCurrentNode) { + DeleteFreeSpaceNode (StdHeader, OffsetOfFreeSpaceNode); + NodeSize = FreeSpaceNode->BufferSize + CurrentNode->BufferSize + sizeof (BUFFER_NODE); + OffsetOfCurrentNode = OffsetOfFreeSpaceNode; + CurrentNode = FreeSpaceNode; + CurrentNode->BufferSize = NodeSize; + } else if (OffsetOfFreeSpaceNode == (OffsetOfCurrentNode + sizeof (BUFFER_NODE) + CurrentNode->BufferSize)) { + DeleteFreeSpaceNode (StdHeader, OffsetOfFreeSpaceNode); + NodeSize = FreeSpaceNode->BufferSize + CurrentNode->BufferSize + sizeof (BUFFER_NODE); + CurrentNode->BufferSize = NodeSize; + } + OffsetOfFreeSpaceNode = FreeSpaceNode->OffsetOfNextNode; + FreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfFreeSpaceNode); + } + InsertFreeSpaceNode (StdHeader, OffsetOfCurrentNode); + return AGESA_SUCCESS; + } else { + // If HeapStatus == HEAP_SYSTEM_MEM, try callout function + if (StdHeader->HeapStatus == HEAP_SYSTEM_MEM) { + AgesaBuffer.StdHeader = *StdHeader; + AgesaBuffer.BufferHandle = BufferHandle; + + AGESA_TESTPOINT (TpIfBeforeDeallocateHeapBuffer, StdHeader); + if (AgesaDeallocateBuffer (0, &AgesaBuffer) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpIfAfterDeallocateHeapBuffer, StdHeader); + + return AGESA_SUCCESS; + } + // If we are still unable to locate the buffer handle, return AGESA_BOUNDS_CHK + if ((BaseAddress != NULL) && (HeapManager->Signature == HEAP_SIGNATURE_VALID)) { + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_BUFFER_HANDLE_IS_NOT_PRESENT, + BufferHandle, 0, 0, 0, StdHeader); + } else { + ASSERT (FALSE); + } + return AGESA_BOUNDS_CHK; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Locates a previously allocated buffer on the heap. + * + * This function searches the heap for a buffer with the desired handle, and + * returns a pointer to the buffer. + * + * @param[in,out] LocateHeap Structure containing the buffer's handle, + * and the return pointer. + * @param[in] StdHeader Config handle for library and services. + * + * @retval AGESA_SUCCESS No error + * @retval AGESA_BOUNDS_CHK Handle does not exist on the heap + * + */ +AGESA_STATUS +HeapLocateBuffer ( + IN OUT LOCATE_HEAP_PTR *LocateHeap, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *BaseAddress; + UINT8 AlignTo16Byte; + UINT32 OffsetOfCurrentNode; + BOOLEAN HeapLocateFlag; + HEAP_MANAGER *HeapManager; + BUFFER_NODE *CurrentNode; + AGESA_BUFFER_PARAMS AgesaBuffer; + + ASSERT (StdHeader != NULL); + + HeapLocateFlag = TRUE; + BaseAddress = (UINT8 *) (UINTN) StdHeader->HeapBasePtr; + HeapManager = (HEAP_MANAGER *) BaseAddress; + + // Check Heap database is valid + if ((BaseAddress == NULL) || (HeapManager->Signature != HEAP_SIGNATURE_VALID)) { + // The base address in StdHeader is incorrect, get base address by itself + BaseAddress = (UINT8 *)(UINT32) HeapGetBaseAddress (StdHeader); + HeapManager = (HEAP_MANAGER *) BaseAddress; + if ((BaseAddress == NULL) || (HeapManager->Signature != HEAP_SIGNATURE_VALID)) { + // Heap is not available, ASSERT here + ASSERT (FALSE); + return AGESA_ERROR; + } + StdHeader->HeapBasePtr = (UINT64)(UINT32) BaseAddress; + } + OffsetOfCurrentNode = HeapManager->FirstActiveBufferOffset; + CurrentNode = (BUFFER_NODE *) (BaseAddress + OffsetOfCurrentNode); + + // Find buffer using internal heap manager + // Locate the heap using handle = LocateHeap-> BufferHandle + // If HeapStatus != HEAP_SYSTEM_ MEM + if ((BaseAddress != NULL) && (HeapManager->Signature == HEAP_SIGNATURE_VALID)) { + if (OffsetOfCurrentNode == AMD_HEAP_INVALID_HEAP_OFFSET) { + HeapLocateFlag = FALSE; + } else { + while (CurrentNode->BufferHandle != LocateHeap->BufferHandle) { + if (CurrentNode->OffsetOfNextNode == AMD_HEAP_INVALID_HEAP_OFFSET) { + HeapLocateFlag = FALSE; + break; + } else { + OffsetOfCurrentNode = CurrentNode->OffsetOfNextNode; + CurrentNode = (BUFFER_NODE *) (BaseAddress + OffsetOfCurrentNode); + } + } + } + } else { + HeapLocateFlag = FALSE; + } + + if (HeapLocateFlag) { + AlignTo16Byte = CurrentNode->PadSize; + LocateHeap->BufferPtr = (UINT8 *) ((UINT8 *) CurrentNode + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL + AlignTo16Byte); + LocateHeap->BufferSize = CurrentNode->BufferSize - NUM_OF_SENTINEL * SIZE_OF_SENTINEL - AlignTo16Byte; + return AGESA_SUCCESS; + } else { + // If HeapStatus == HEAP_SYSTEM_MEM, try callout function + if (StdHeader->HeapStatus == HEAP_SYSTEM_MEM) { + AgesaBuffer.StdHeader = *StdHeader; + AgesaBuffer.BufferHandle = LocateHeap->BufferHandle; + + AGESA_TESTPOINT (TpIfBeforeLocateHeapBuffer, StdHeader); + if (AgesaLocateBuffer (0, &AgesaBuffer) != AGESA_SUCCESS) { + LocateHeap->BufferPtr = NULL; + return AGESA_ERROR; + } + LocateHeap->BufferSize = AgesaBuffer.BufferLength; + AGESA_TESTPOINT (TpIfAfterLocateHeapBuffer, StdHeader); + + LocateHeap->BufferPtr = (UINT8 *) (AgesaBuffer.BufferPointer); + return AGESA_SUCCESS; + } + + // If we are still unable to deallocate the buffer handle, return AGESA_BOUNDS_CHK + LocateHeap->BufferPtr = NULL; + LocateHeap->BufferSize = 0; + if ((BaseAddress != NULL) && (HeapManager->Signature == HEAP_SIGNATURE_VALID)) { + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_BUFFER_HANDLE_IS_NOT_PRESENT, + LocateHeap->BufferHandle, 0, 0, 0, StdHeader); + } else { + ASSERT (FALSE); + } + return AGESA_BOUNDS_CHK; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get the heap base address + * + * This function will try to locate heap from cache, temp memory, main memory. + * The heap signature will be checked for validity on each possible location. + * Firstly, try if heap base is in cache by calling the function HeapGetCurrentBase. + * Secondly, try if heap base is temp memory by UserOptoions.CfgHeapDramAddress. + * Thirdly, try if heap base is in main memory by doing a buffer locate with buffer handle + * AMD_HEAP_IN_MAIN_MEMORY_HANDLE. + * If no valid heap signature is found in each possible location above, a NULL pointer is returned. + * + * @param[in] StdHeader Config handle for library and services. + * + * @return Heap base address of the executing core's heap. + * + */ +UINT64 +HeapGetBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 BaseAddress; + HEAP_MANAGER *HeapManager; + AGESA_BUFFER_PARAMS AgesaBuffer; + + // Firstly, we try to see if heap is in cache + BaseAddress = HeapGetCurrentBase (StdHeader); + HeapManager = (HEAP_MANAGER *) (UINTN) BaseAddress; + + if (HeapManager->Signature != HEAP_SIGNATURE_VALID) { + if ((StdHeader->HeapStatus != HEAP_DO_NOT_EXIST_YET) && + (StdHeader->HeapStatus != HEAP_LOCAL_CACHE)) { + // Secondly, we try to see if heap is in temp memory + BaseAddress = HeapGetBaseAddressInTempMem (StdHeader); + HeapManager = (HEAP_MANAGER *) (UINTN) BaseAddress; + if (HeapManager->Signature != HEAP_SIGNATURE_VALID) { + // Thirdly, we try to see if heap in main memory + // by locating with external buffer manager (IBV) + AgesaBuffer.StdHeader = *StdHeader; + AgesaBuffer.BufferHandle = AMD_HEAP_IN_MAIN_MEMORY_HANDLE; + if (AgesaLocateBuffer (0, &AgesaBuffer) == AGESA_SUCCESS) { + BaseAddress = (UINT64) (UINTN) AgesaBuffer.BufferPointer; + HeapManager = (HEAP_MANAGER *) (UINTN) BaseAddress; + if (HeapManager->Signature != HEAP_SIGNATURE_VALID) { + // No valid heap signature ever found, return a NULL pointer + BaseAddress = (UINT64) (UINTN) NULL; + } + } else { + // No heap buffer is allocated by external manager (IBV), return a NULL pointer + BaseAddress = (UINT64) (UINTN) NULL; + } + } + } else if (StdHeader->HeapStatus == HEAP_LOCAL_CACHE) { + BaseAddress = (UINT64) (UINTN) NULL; + } + } + return BaseAddress; +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * DeleteFreeSpaceNode + * + * Description: + * Delete a free space node from free space chain + * + * Parameters: + * @param[in] StdHeader Config handle for library and services. + * @param[in] OffsetOfDeletedNode Offset of deleted node. + * + * Processing: + * + */ +VOID +STATIC +DeleteFreeSpaceNode ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT32 OffsetOfDeletedNode + ) +{ + UINT8 *BaseAddress; + UINT32 OffsetOfPreviousNode; + UINT32 OffsetOfCurrentNode; + HEAP_MANAGER *HeapManager; + BUFFER_NODE *CurrentFreeSpaceNode; + BUFFER_NODE *PreviousFreeSpaceNode; + + + BaseAddress = (UINT8 *) (UINTN) StdHeader->HeapBasePtr; + HeapManager = (HEAP_MANAGER *) BaseAddress; + + OffsetOfPreviousNode = AMD_HEAP_INVALID_HEAP_OFFSET; + OffsetOfCurrentNode = HeapManager->FirstFreeSpaceOffset; + // + // After AmdInitEnv, there is no free space provided for HeapAllocateBuffer. + // Hence if the FirstFreeSpaceOffset is AMD_HEAP_INVALID_HEAP_OFFSET, then + // no need to do more on delete node. + // + if (OffsetOfCurrentNode != AMD_HEAP_INVALID_HEAP_OFFSET) { + CurrentFreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfCurrentNode); + while ((OffsetOfCurrentNode != AMD_HEAP_INVALID_HEAP_OFFSET) && (OffsetOfCurrentNode != OffsetOfDeletedNode)) { + OffsetOfPreviousNode = OffsetOfCurrentNode; + OffsetOfCurrentNode = CurrentFreeSpaceNode->OffsetOfNextNode; + CurrentFreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfCurrentNode); + } + if (OffsetOfCurrentNode != AMD_HEAP_INVALID_HEAP_OFFSET) { + if (OffsetOfPreviousNode == AMD_HEAP_INVALID_HEAP_OFFSET) { + HeapManager->FirstFreeSpaceOffset = CurrentFreeSpaceNode->OffsetOfNextNode; + } else { + PreviousFreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfPreviousNode); + PreviousFreeSpaceNode->OffsetOfNextNode = CurrentFreeSpaceNode->OffsetOfNextNode; + } + } + } + return; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * InsertFreeSpaceNode + * + * Description: + * Insert a free space node to free space chain, size order + * + * Parameters: + * @param[in] StdHeader Config handle for library and services. + * @param[in] OffsetOfInsertNode Offset of inserted node. + * + * Processing: + * + */ +VOID +STATIC +InsertFreeSpaceNode ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT32 OffsetOfInsertNode + ) +{ + UINT8 *BaseAddress; + UINT32 OffsetOfPreviousNode; + UINT32 OffsetOfCurrentNode; + HEAP_MANAGER *HeapManager; + BUFFER_NODE *CurrentFreeSpaceNode; + BUFFER_NODE *PreviousFreeSpaceNode; + BUFFER_NODE *InsertedFreeSpaceNode; + + BaseAddress = (UINT8 *) (UINTN) StdHeader->HeapBasePtr; + HeapManager = (HEAP_MANAGER *) BaseAddress; + + OffsetOfPreviousNode = AMD_HEAP_INVALID_HEAP_OFFSET; + OffsetOfCurrentNode = HeapManager->FirstFreeSpaceOffset; + CurrentFreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfCurrentNode); + InsertedFreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfInsertNode); + while ((OffsetOfCurrentNode != AMD_HEAP_INVALID_HEAP_OFFSET) && + (CurrentFreeSpaceNode->BufferSize < InsertedFreeSpaceNode->BufferSize)) { + OffsetOfPreviousNode = OffsetOfCurrentNode; + OffsetOfCurrentNode = CurrentFreeSpaceNode->OffsetOfNextNode; + CurrentFreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfCurrentNode); + } + InsertedFreeSpaceNode->OffsetOfNextNode = OffsetOfCurrentNode; + if (OffsetOfPreviousNode == AMD_HEAP_INVALID_HEAP_OFFSET) { + HeapManager->FirstFreeSpaceOffset = OffsetOfInsertNode; + } else { + PreviousFreeSpaceNode = (BUFFER_NODE *) (BaseAddress + OffsetOfPreviousNode); + PreviousFreeSpaceNode->OffsetOfNextNode = OffsetOfInsertNode; + } + return; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the base address of the executing core's heap. + * + * This function uses the executing core's socket/core numbers to determine + * where it's heap should be located. + * + * @param[in] StdHeader Config handle for library and services. + * + * @return A pointer to the executing core's heap. + * + */ +UINT64 +STATIC +HeapGetCurrentBase ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 SystemCoreNumber; + UINT64 ReturnPtr; + AGESA_STATUS IgnoredStatus; + CPU_SPECIFIC_SERVICES *FamilyServices; + + if (IsBsp (StdHeader, &IgnoredStatus)) { + ReturnPtr = AMD_HEAP_START_ADDRESS; + } else { + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + SystemCoreNumber = FamilyServices->GetApCoreNumber (FamilyServices, StdHeader); + ASSERT (SystemCoreNumber != 0); + ASSERT (SystemCoreNumber < 64); + ReturnPtr = ((SystemCoreNumber * AMD_HEAP_SIZE_PER_CORE) + AMD_HEAP_START_ADDRESS); + } + ASSERT (ReturnPtr <= ((AMD_HEAP_REGION_END_ADDRESS + 1) - AMD_HEAP_SIZE_PER_CORE)); + return ReturnPtr; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/heapManager.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/heapManager.h new file mode 100644 index 0000000000..a57c0d2782 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/heapManager.h @@ -0,0 +1,258 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Heap Manager and Heap Allocation APIs, and related functions. + * + * Contains code that initialize, maintain, and allocate the heap space. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _HEAP_MANAGER_H_ +#define _HEAP_MANAGER_H_ + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ +#define AMD_MTRR_VARIABLE_BASE0 0x200 +#define AMD_MTRR_VARIABLE_HEAP_BASE 0x20A +#define AMD_MTRR_VARIABLE_HEAP_MASK (AMD_MTRR_VARIABLE_HEAP_BASE + 1) + +#define AMD_HEAP_START_ADDRESS 0x400000ul +#define AMD_HEAP_REGION_END_ADDRESS 0xBFFFFFul +#define AMD_HEAP_SIZE_PER_CORE 0x010000ul +#define AMD_HEAP_INVALID_HEAP_OFFSET 0xFFFFFFFFul +#define AMD_HEAP_MTRR_MASK ((0xFFFFFFFFFFFFF800ull & (((UINT64)AMD_HEAP_SIZE_PER_CORE ^ (-1)) + 1)) | 0x800) +#define AMD_HEAP_SIZE_DWORD_PER_CORE (AMD_HEAP_SIZE_PER_CORE / 4) + +#define AMD_TEMP_TOM 0x20000000ul // Set TOM to 512 MB (temporary value) +#define AMD_VAR_MTRR_ENABLE_BIT 0x100000ul // bit 20 + +#define AMD_HEAP_RAM_ADDRESS 0xB0000ul + +#define HEAP_SIGNATURE_VALID 0x50414548ul // Signature: 'HEAP' +#define HEAP_SIGNATURE_INVALID 0x00000000ul // Signature cleared + +///Heap Manager Life cycle +#define HEAP_DO_NOT_EXIST_YET 1 +#define HEAP_LOCAL_CACHE 2 +#define HEAP_TEMP_MEM 3 +#define HEAP_SYSTEM_MEM 4 +#define HEAP_DO_NOT_EXIST_ANYMORE 5 +#define HEAP_S3_RESUME 6 +#define HEAP_RUNTIME_SYSTEM_MEM 7 + +///Heap callout +#define HEAP_CALLOUT_BOOTTIME 0 +#define HEAP_CALLOUT_RUNTIME 1 + +#define AMD_MTRR_FIX64k_00000 0x250 +#define AMD_MTRR_FIX16k_80000 0x258 +#define AMD_MTRR_FIX16k_A0000 0x259 +#define AMD_MTRR_FIX4k_C0000 0x268 +#define AMD_MTRR_FIX4k_C8000 0x269 +#define AMD_MTRR_FIX4k_D0000 0x26A +#define AMD_MTRR_FIX4k_D8000 0x26B +#define AMD_MTRR_FIX4k_E0000 0x26C +#define AMD_MTRR_FIX4k_E8000 0x26D +#define AMD_MTRR_FIX4k_F0000 0x26E +#define AMD_MTRR_FIX4k_F8000 0x26F + +#define AMD_MTRR_FIX64K_WB_DRAM 0x1E +#define AMD_MTRR_FIX64K_WT_DRAM 0x1C +#define AMD_MTRR_FIX64K_UC_DRAM 0x18 +#define AMD_MTRR_FIX16K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull +#define AMD_MTRR_FIX16K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull +#define AMD_MTRR_FIX16K_UC_DRAM 0x1818181818181818ull +#define AMD_MTRR_FIX4K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull +#define AMD_MTRR_FIX4K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull +#define AMD_MTRR_FIX4K_UC_DRAM 0x1818181818181818ull + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +/// Allocate Heap Parameters +typedef struct _ALLOCATE_HEAP_PARAMS { + UINT32 RequestedBufferSize; ///< Size of buffer. + UINT32 BufferHandle; ///< An unique ID of buffer. + UINT8 Persist; ///< A flag. If marked, to be stored and passed to AmdInitLate. + UINT8 *BufferPtr; ///< Pointer to buffer. +} ALLOCATE_HEAP_PARAMS; + +/// Locate Heap Parameters +typedef struct _LOCATE_HEAP_PTR { + UINT32 BufferHandle; ///< An unique ID of buffer. + UINT32 BufferSize; ///< Data buffer size. + UINT8 *BufferPtr; ///< Pointer to buffer. +} LOCATE_HEAP_PTR; + +/// Heap Node Header +typedef struct _BUFFER_NODE { + UINT32 BufferHandle; ///< An unique ID of buffer. + UINT32 BufferSize; ///< Size of buffer. + UINT8 Persist; ///< A flag. If marked, to be stored and passed to AmdInitLate. + UINT8 PadSize; ///< Size of pad. + UINT32 OffsetOfNextNode; ///< Offset of next node (relative to the base). +} BUFFER_NODE; + +/// Heap Manager +typedef struct _HEAP_MANAGER { + UINT32 Signature; ///< a signature to indicate if the heap is valid. + UINT32 UsedSize; ///< Used size of heap. + UINT32 FirstActiveBufferOffset; ///< Offset of the first active buffer. + UINT32 FirstFreeSpaceOffset; ///< Offset of the first free space. +} HEAP_MANAGER; + +/// AGESA Buffer Handles (These are reserved) +typedef enum { + AMD_INIT_RESET_HANDLE = 0x000A000, ///< Assign 0x000A000 buffer handle to AmdInitReset routine. + AMD_INIT_EARLY_HANDLE, ///< Assign 0x000A001 buffer handle to AmdInitEarly routine. + AMD_INIT_POST_HANDLE, ///< Assign 0x000A002 buffer handle to AmdInitPost routine. + AMD_INIT_ENV_HANDLE, ///< Assign 0x000A003 buffer handle to AmdInitEnv routine. + AMD_INIT_MID_HANDLE, ///< Assign 0x000A004 buffer handle to AmdInitMid routine. + AMD_INIT_LATE_HANDLE, ///< Assign 0x000A005 buffer handle to AmdInitLate routine. + AMD_INIT_RESUME_HANDLE, ///< Assign 0x000A006 buffer handle to AmdInitResume routine. + AMD_LATE_RUN_AP_TASK_HANDLE, ///< Assign 0x000A007 buffer handle to AmdLateRunApTask routine. + AMD_S3_SAVE_HANDLE, ///< Assign 0x000A008 buffer handle to AmdS3Save routine. + AMD_S3_LATE_RESTORE_HANDLE, ///< Assign 0x000A009 buffer handle to AmdS3LateRestore routine. + AMD_S3_SCRIPT_SAVE_TABLE_HANDLE, ///< Assign 0x000A00A buffer handle to be used for S3 save table + AMD_S3_SCRIPT_TEMP_BUFFER_HANDLE, ///< Assign 0x000A00B buffer handle to be used for S3 save table + AMD_CPU_AP_TASKING_HANDLE, ///< Assign 0x000A00C buffer handle to AP tasking input parameters. + AMD_REC_MEM_SOCKET_HANDLE, ///< Assign 0x000A00D buffer handle to save socket with memory in memory recovery mode. + AMD_MEM_AUTO_HANDLE, ///< Assign 0x000A00E buffer handle to AmdMemAuto routine. + AMD_MEM_SPD_HANDLE, ///< Assign 0x000A00F buffer handle to AmdMemSpd routine. + AMD_MEM_DATA_HANDLE, ///< Assign 0x000A010 buffer handle to MemData + AMD_MEM_TRAIN_BUFFER_HANDLE, ///< Assign 0x000A011 buffer handle to allocate buffer for training + AMD_MEM_S3_DATA_HANDLE, ///< Assign 0x000A012 buffer handle to special case register for S3 + AMD_MEM_S3_NB_HANDLE, ///< Assign 0x000A013 buffer handle to NB block for S3 + AMD_MEM_S3_MR0_DATA_HANDLE, ///< Assign 0x000A014 buffer handle to MR0 data block for S3 + AMD_UMA_INFO_HANDLE, ///< Assign 0x000A015 buffer handle to be used for Uma information + AMD_DMI_MEM_DEV_INFO_HANDLE, ///< Assign 0x000A016 buffer handle to DMI Type16 17 19 20 information + HT_STATE_DATA_HANDLE, ///< Assign 0x000A017 buffer handle to HT State Data + PRESERVE_MAIL_BOX_HANDLE, ///< Assign 0x000A018 buffer handle for Preserve Mailbox Feature. + EVENT_LOG_BUFFER_HANDLE, ///< Assign 0x000A019 buffer handle to Event Log + IDS_CONTROL_HANDLE, ///< Assign 0x000A01A buffer handle to AmdIds routine. + IDS_HT_DATA_HANDLE, ///< Assign 0x000A01B buffer handle to Ht IDS control + IDS_HDT_OUT_BUFFER_HANDLE, ///< Assign 0x000A01C buffer handle to be used for HDTOUT support. + IDS_CHECK_POINT_PERF_HANDLE, ///< Assign 0x000A01D buffer handle to Performance analysis + AMD_PCIE_COMPLEX_DATA_HANDLE, ///< Assign 0x000A01E buffer handle to be used for PCIe support + AMD_MEM_SYS_DATA_HANDLE, ///< Assign 0x000A01F buffer handle to be used for memory data structure + AMD_GNB_SMU_CONFIG_HANDLE, ///< Assign 0x000A020 buffer handle to be used for GNB SMU configuration + AMD_PP_F1_TABLE_HANDLE, ///< Assign 0x000A021 + AMD_GFX_PLATFORM_CONFIG_HANDLE, ///< Assign 0x000A022 buffer handle to be used for Gfx platform configuration + AMD_GNB_TEMP_DATA_HANDLE, ///< Assign 0x000A023 buffer handle for GNB general purpose data block + AMD_MEM_2D_RDQS_HANDLE, ///< Assign 0x000A024 buffer handle for 2D training + AMD_MEM_2D_RD_WR_HANDLE, ///< Assign 0x000A025 buffer handle for 2D Read/Write training + AMD_GNB_IOMMU_SCRATCH_MEM_HANDLE, ///< Assign 0x000A026 buffer handle to be used for GNB IOMMU scratch memory + AMD_MEM_S3_SAVE_HANDLE, ///< Assign 0x000A027 buffer handle for memory data saved right after memory init + AMD_MEM_2D_RDQS_RIM_HANDLE, ///< Assign 0x000A028 buffer handle for 2D training Eye RIM Search + AMD_MEM_2D_RD_WR_RIM_HANDLE, ///< Assign 0x000A029 buffer handle for 2D Read/Write training Eye RIM Search + AMD_TDP_LIMIT_SAVED_PSTATE, ///< Assign 0x000A02A buffer handle for TDP limiting feature to save Pstate + AMD_CPU_NB_PSTATE_FIXUP_HANDLE, ///< Assign 0x000A02B buffer handle for an NB P-state workaround + AMD_MEM_CRAT_INFO_BUFFER_HANDLE, ///< Assign 0x000A02C buffer handle for CRAT Memory affinity component structure + AMD_SKIP_MEM_S3_SAVE, ///< Assign 0x000A02D buffer handle for the flag to skip memory S3 save + AMD_SCS_SMU_RAM_INFO, ///< Assign 0x000A02E buffer handle for keeping the result of SMU SCS service + AMD_SCS_HWP0_FREQ, ///< Assign 0x000A02F buffer handler for keeping frequency of HWP0 + AMD_IS_FEATURE_ENABLED, ///< Assign 0x000A030 buffer handle for keeping the result of IsFeatureEnabled + AMD_MEM_DATAEYE_WORK_AREA_HANDLE, ///< Assign 0x000A031 buffer handle for Composite Data Eye Compression Work Area + AMD_GNB_SAMU_PATCH_HANDLE, ///< Assign 0x000A032 buffer handle for Samu patch buffer + AMD_GNB_SAMU_BOOT_CONTROL_HANDLE, ///< Assign 0x000A033 buffer handle for Samu boot control buffer + AMD_MEM_MISC_HANDLES_START = 0x1000000, ///< Reserve 0x1000000 to 0x1FFFFFF buffer handle + AMD_MEM_MISC_HANDLES_END = 0x1FFFFFF, ///< miscellaneous memory init tasks' buffers. + AMD_HEAP_IN_MAIN_MEMORY_HANDLE = 0x8000000, ///< Assign 0x8000000 to AMD_HEAP_IN_MAIN_MEMORY_HANDLE. + SOCKET_DIE_MAP_HANDLE = 0x534F4B54, ///< 'sokt' + NODE_ID_MAP_HANDLE = 0x4E4F4445, ///< 'node' + HOP_COUNT_TABLE_HANDLE = 0x484F5053, ///< 'hops' + AP_MAIL_BOX_CACHE_HANDLE = 0x414D4258, ///< 'ambx' + AMD_FCH_RESET_DATA_BLOCK_HANDLE = 0x46434852, ///< 'FCHR' Buffer handle for FCH private data block at InitReset + AMD_FCH_DATA_BLOCK_HANDLE = 0x46434845, ///< 'FCHE' Buffer handle for FCH private data block at InitEnv + IDS_TRAP_TABLE_HANDLE = 0x49524547, ///< 'IREG' Handle for IDS register table + IDS_SAVE_IDTR_HANDLE = 0x49445452, ///< 'IDTR' + IDS_BSC_IDT_HANDLE = 0x42534349, ///< 'BSCI' BSC Idt table + IDS_NV_TO_CMOS_HANDLE = 0x534D4349, ///< 'ICMS' Handle for IDS CMOS save + IDS_GRA_HANDLE = 0x41524749, ///< 'IGRA' Handle for IDS GRA save + IDS_EXTEND_HANDLE = 0x54584549, ///< 'IEXT' Handle for IDS extend module + IDS_TEMP_DATA_HANDLE = 0x504D5459, ///< 'ITMP' Handle for IDS temp data +} AGESA_BUFFER_HANDLE; + + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +HeapManagerInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +HeapAllocateBuffer ( + IN OUT ALLOCATE_HEAP_PARAMS *AllocateHeapParams, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +HeapDeallocateBuffer ( + IN UINT32 BufferHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +HeapLocateBuffer ( + IN OUT LOCATE_HEAP_PTR *LocateHeap, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT64 +HeapGetBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +EventLogInitialization ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif // _HEAP_MANAGER_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/mmioMapManager.h b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/mmioMapManager.h new file mode 100644 index 0000000000..542faa6b3c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/mmioMapManager.h @@ -0,0 +1,143 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD MMIO Map Manager APIs, and related functions. + * + * Contains code that manage MMIO base/limit registers + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _MMIO_MAP_MANAGER_H_ +#define _MMIO_MAP_MANAGER_H_ + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (MMIO_MAP_FAMILY_SERVICES); + +/*--------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *--------------------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ +/// MMIO attribute +typedef struct _AMD_MMIO_ATTRIBUTE { + UINT8 MmioReadableRange:1; ///< Indicator whether the range is readable + UINT8 MmioWritableRange:1; ///< Indicator whether the range is writable + UINT8 MmioPostedRange:1; ///< Indicator whether the range is posted + UINT8 MmioSecuredRange:1; ///< Indicator whether the range is locked + UINT8 :3; ///< Reserved + UINT8 OverrideExisting:1; ///< Indicator whether to override the existing MMIO map configurations +} AMD_MMIO_ATTRIBUTE; + +/// MMIO destination +typedef struct _AMD_MMIO_DST { + UINT32 DstNode:3; ///< Destination node ID bits + UINT32 DstLink:2; ///< Destination link ID + UINT32 DstSubLink:1; ///< Destination sublink +} AMD_MMIO_DST; + +/// MMIO range +typedef struct _MMIO_RANGE { + UINT64 Base; ///< Base + UINT64 Limit; ///< Limit + AMD_MMIO_ATTRIBUTE Attribute; ///< Attribute + AMD_MMIO_DST Destination; ///< Destination + UINT8 RangeNum; ///< Range No. + BOOLEAN Modified; ///< if this MMIO base/limit registers need to be updated +} MMIO_RANGE; + +/// AMD_ADD_MMIO_PARAMS +typedef struct _AMD_ADD_MMIO_PARAMS { + AMD_CONFIG_PARAMS StdHeader; ///< Config Handle for library, services. + UINT64 BaseAddress; ///< This is the starting address of the requested MMIO range. + UINT64 Length; ///< This is the length of the range to allocate, in bytes. + PCI_ADDR TargetAddress; ///< This is the PCIe address of the device for which this range is allocated, and it + ///< provides the bus, device, and function of the target device. + AMD_MMIO_ATTRIBUTE Attributes;///< This indicates the attributes of the requested range. +} AMD_ADD_MMIO_PARAMS; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to MMIO map manager. + * + * @param[in] MmioMapServices MMIO map manager services. + * @param[in] AmdAddMmioParams Pointer to a data structure containing the parameter information. + * + * @return Family specific error value. + * + */ +typedef AGESA_STATUS F_MMIO_MAP_ADDING_MAP ( + IN MMIO_MAP_FAMILY_SERVICES *MmioMapServices, + IN AMD_ADD_MMIO_PARAMS AmdAddMmioParams + ); + +/// Reference to a Method. +typedef F_MMIO_MAP_ADDING_MAP *PF_MMIO_MAP_ADDING_MAP; + +/** + * Provide the interface to the MMIO map manager Family Specific Services. + * + * Use the methods or data in this struct to adapt the feature code to a specific cpu family or model (or stepping!). + * Each supported Family must provide an implementation for all methods in this interface, even if the + * implementation is a CommonReturn(). + */ +struct _MMIO_MAP_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_MMIO_MAP_ADDING_MAP addingMmioMap; ///< Method: Family specific call to adding MMIO map. +}; + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +AmdAddMmioMapping ( + IN AMD_ADD_MMIO_PARAMS AmdAddMmioParams + ); + +#endif // _MMIO_MAP_MANAGER_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdFch.h b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdFch.h new file mode 100644 index 0000000000..adef0111dc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdFch.h @@ -0,0 +1,65 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD FCH Component + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _AMD_FCH_H_ +#define _AMD_FCH_H_ + +typedef AGESA_STATUS FCH_INIT (IN VOID *DataPtr); +typedef VOID FCH_TASK_ENTRY (IN VOID *FchCfg); + + +/// FCH API build options +typedef struct { + FCH_INIT *InitReset; ///< InitReset + FCH_INIT *InitResetConstructor; ///< InitResetConstructor + FCH_INIT *InitEnv; ///< InitEnv + FCH_INIT *InitEnvConstructor; ///< InitEnvConstructor + FCH_INIT *InitMid; ///< InitMid + FCH_INIT *InitMidConstructor; ///< InitMidConstructor + FCH_INIT *InitLate; ///< InitLate + FCH_INIT *InitLateConstructor; ///< InitLateConstructor +} BLDOPT_FCH_FUNCTION; + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitEarly.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitEarly.c new file mode 100644 index 0000000000..ebefda7af4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitEarly.c @@ -0,0 +1,323 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuCacheInit.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuEarlyInit.h" +#include "AdvancedApi.h" +#include "cpuServices.h" +#include "CommonInits.h" +#include "GnbInterface.h" +#include "Filecode.h" +#include "heapManager.h" +#include "CreateStruct.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_AMDINITEARLY_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +EXECUTION_CACHE_REGION InitExeCacheMap[] = +{ + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000} +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdEarlyPlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +AllocateExecutionCacheInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN EXECUTION_CACHE_REGION *AmdExeAddrMapPtr + ); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; +/*------------------------------------------------------------------------------------*/ +/** + * Initialize AmdInitEarly stage platform profile and user option input. + * + * @param[in,out] PlatformConfig Platform profile/build option config structure + * @param[in,out] StdHeader AMD standard header config param + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdEarlyPlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CommonPlatformConfigInit (PlatformConfig, StdHeader); + + return AGESA_SUCCESS; +} +/*------------------------------------------------------------------------------------*/ +/** + * Initializer routine that will be invoked by the wrapper to initialize the input + * structure for the AllocateExecutionCache. + * + * @param[in] StdHeader Opaque handle to standard config header + * @param[in] AmdExeAddrMapPtr Our Service interface struct + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AllocateExecutionCacheInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN EXECUTION_CACHE_REGION *AmdExeAddrMapPtr + ) +{ + UINT8 i; + ASSERT (AmdExeAddrMapPtr != NULL); + + for (i = 0; i < MAX_CACHE_REGIONS; ++i) { + AmdExeAddrMapPtr[i].ExeCacheStartAddr = InitExeCacheMap[i].ExeCacheStartAddr; + AmdExeAddrMapPtr[i].ExeCacheSize = InitExeCacheMap[i].ExeCacheSize; + } + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Initializer routine that will be invoked by the wrapper to initialize the input + * structure for the AmdInitEarly. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in,out] EarlyParams The service interface struct to initialize. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +AmdInitEarlyInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_EARLY_PARAMS *EarlyParams + ) +{ + ASSERT (StdHeader != NULL); + ASSERT (EarlyParams != NULL); + + EarlyParams->StdHeader = *StdHeader; + + // We don't check any AGESA_STATUS from the called constructors, since they MUST all SUCCEED. + // + + AllocateExecutionCacheInitializer (&EarlyParams->StdHeader, &EarlyParams->CacheRegion[0]); + + AmdHtInterfaceConstructor (&EarlyParams->StdHeader, &EarlyParams->HtConfig); + + AmdEarlyPlatformConfigInit (&EarlyParams->PlatformConfig, &EarlyParams->StdHeader); + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform initialization services required at the Early Init POST time point. + * + * Execution Cache, HyperTransport, and AP Init advanced services are performed. + * + * @param[in] EarlyParams The interface struct for all early services + * + * @return The most severe AGESA_STATUS returned by any called service. + * + */ +AGESA_STATUS +AmdInitEarly ( + IN OUT AMD_EARLY_PARAMS *EarlyParams + ) +{ + AGESA_STATUS CalledAgesaStatus; + AGESA_STATUS EarlyInitStatus; + WARM_RESET_REQUEST Request; + UINT8 PrevRequestBit; + UINT8 PrevStateBits; + + IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDINITEARLY, &EarlyParams->StdHeader); + + AGESA_TESTPOINT (TpIfAmdInitEarlyEntry, &EarlyParams->StdHeader); + + EarlyInitStatus = AGESA_SUCCESS; + + // Setup ROM execution cache + IDS_HDT_CONSOLE (MAIN_FLOW, "AllocateExecutionCache: Start\n"); + CalledAgesaStatus = AllocateExecutionCache (&EarlyParams->StdHeader, &EarlyParams->CacheRegion[0]); + IDS_HDT_CONSOLE (MAIN_FLOW, "AllocateExecutionCache: End\n"); + if (CalledAgesaStatus > EarlyInitStatus) { + EarlyInitStatus = CalledAgesaStatus; + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + { + extern CHAR8 *BldOptDebugOutput[]; + + UINT8 i; + for (i = 0; BldOptDebugOutput[i] != NULL; i++) { + IDS_HDT_CONSOLE (MAIN_FLOW, "\t%s\n", BldOptDebugOutput[i]); + } + } + ) + + // + // WARNING: AGESA's own IDT is at heap which would be moved from one place to another + // so we MUST restore IDT every time before moving heap. + // + IDS_EXCEPTION_TRAP (IDS_IDT_REPLACE_IDTR_FOR_BSC, NULL, &EarlyParams->StdHeader); + ASSERT (EarlyParams != NULL); + PrevRequestBit = FALSE; + PrevStateBits = WR_STATE_COLD; + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitEarly: Start %x \n\n", PrevStateBits); + // If a previously requested warm reset cannot be triggered in the + // current stage, store the previous state of request and reset the + // request struct to the current post stage + GetWarmResetFlag (&EarlyParams->StdHeader, &Request); + if (Request.RequestBit == TRUE) { + if (Request.StateBits >= Request.PostStage) { + PrevRequestBit = Request.RequestBit; + PrevStateBits = Request.StateBits; + Request.RequestBit = FALSE; + Request.StateBits = Request.PostStage - 1; + SetWarmResetFlag (&EarlyParams->StdHeader, &Request); + } + } + + IDS_OPTION_HOOK (IDS_INIT_EARLY_BEFORE, EarlyParams, &EarlyParams->StdHeader); + + // Full Hypertransport Initialization + // IMPORTANT: All AP cores call Ht Init. HT Init handles full init for the BSC, and map init for APs. + IDS_PERF_TIMESTAMP (TP_BEGINAMDHTINITIALIZE, &EarlyParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdHtInitialize: Start\n"); + CalledAgesaStatus = AmdHtInitialize (&EarlyParams->StdHeader, &EarlyParams->PlatformConfig, &EarlyParams->HtConfig); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdHtInitialize: End\n"); + IDS_PERF_TIMESTAMP (TP_ENDAMDHTINITIALIZE, &EarlyParams->StdHeader); + if (CalledAgesaStatus > EarlyInitStatus) { + EarlyInitStatus = CalledAgesaStatus; + } + + IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATEARLIER, &EarlyParams->StdHeader); + CalledAgesaStatus = GnbInitAtEarlier (EarlyParams); + IDS_PERF_TIMESTAMP (TP_ENDGNBINITATEARLIER, &EarlyParams->StdHeader); + if (CalledAgesaStatus > EarlyInitStatus) { + EarlyInitStatus = CalledAgesaStatus; + } + + // AP launch + IDS_PERF_TIMESTAMP (TP_BEGINAMDCPUEARLY, &EarlyParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuEarly: Start\n"); + CalledAgesaStatus = AmdCpuEarly (&EarlyParams->StdHeader, &EarlyParams->PlatformConfig); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuEarly: End\n"); + IDS_PERF_TIMESTAMP (TP_ENDAMDCPUEARLY, &EarlyParams->StdHeader); + if (CalledAgesaStatus > EarlyInitStatus) { + EarlyInitStatus = CalledAgesaStatus; + } + + // Warm Reset, should be at the end of AmdInitEarly + GetWarmResetFlag (&EarlyParams->StdHeader, &Request); + // If a warm reset is requested in the current post stage, trigger the + // warm reset and ignore the previous request + if (Request.RequestBit == TRUE) { + if (Request.StateBits < Request.PostStage) { + AgesaDoReset (WARM_RESET_WHENEVER, &EarlyParams->StdHeader); + } + } else { + // Otherwise, if there's a previous request, restore it + // so that the subsequent post stage can trigger the warm reset + if (PrevRequestBit == TRUE) { + Request.RequestBit = PrevRequestBit; + Request.StateBits = PrevStateBits; + SetWarmResetFlag (&EarlyParams->StdHeader, &Request); + } + } + + IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATEARLY, &EarlyParams->StdHeader); + CalledAgesaStatus = GnbInitAtEarly (EarlyParams); + IDS_PERF_TIMESTAMP (TP_ENDGNBINITATEARLY, &EarlyParams->StdHeader); + if (CalledAgesaStatus > EarlyInitStatus) { + EarlyInitStatus = CalledAgesaStatus; + } + // Check for Cache As Ram Corruption + IDS_CAR_CORRUPTION_CHECK (&EarlyParams->StdHeader); + + IDS_OPTION_HOOK (IDS_INIT_EARLY_AFTER, EarlyParams, &EarlyParams->StdHeader); + AGESA_TESTPOINT (TpIfAmdInitEarlyExit, &EarlyParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitEarly: End\n\n"); + + // Flush out all debug contents in case warm reset is triggered after this point + IDS_HDT_CONSOLE_FLUSH_BUFFER (&EarlyParams->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDPROCAMDINITEARLY, &EarlyParams->StdHeader); + + return EarlyInitStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitEnv.c new file mode 100644 index 0000000000..83de69b9b9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitEnv.c @@ -0,0 +1,188 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "cpuEnvInit.h" +#include "heapManager.h" +#include "GnbInterface.h" +#include "CommonInits.h" +#include "AmdFch.h" +#include "S3SaveState.h" +#include "Filecode.h" +#include "CreateStruct.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_AMDINITENV_FILECODE + +extern BLDOPT_FCH_FUNCTION BldoptFchFunction; + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/* + *--------------------------------------------------------------------------------------- + * + * Initializer routine that will be invoked by the wrapper + * to initialize the input structure for the AmdInitEnv + * + * @param[in,out] EnvParamsPtr Newly created interface parameters for AmdInitEnv + * + * @retval AGESA_SUCCESS Always succeeds + * + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdInitEnvInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_ENV_PARAMS *EnvParamsPtr + ) +{ + ASSERT (StdHeader != NULL); + ASSERT (EnvParamsPtr != NULL); + + EnvParamsPtr->StdHeader = *StdHeader; + + CommonPlatformConfigInit (&EnvParamsPtr->PlatformConfig, &EnvParamsPtr->StdHeader); + BldoptFchFunction.InitEnvConstructor (EnvParamsPtr); + GnbInitDataStructAtEnvDef (&EnvParamsPtr->GnbEnvConfiguration, EnvParamsPtr); + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for the AMD_INIT_ENV function. + * + * This entry point is responsible for copying the heap contents from the + * temp RAM area to main memory. + * + * @param[in,out] EnvParams Required input parameters for the AMD_INIT_ENV + * entry point. + * + * @return Aggregated status across all internal AMD env calls invoked. + * + */ +AGESA_STATUS +AmdInitEnv ( + IN OUT AMD_ENV_PARAMS *EnvParams + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS AmdInitEnvStatus; + + AGESA_TESTPOINT (TpIfAmdInitEnvEntry, &EnvParams->StdHeader); + + ASSERT (EnvParams != NULL); + AmdInitEnvStatus = AGESA_SUCCESS; + + + //Copy Temp Ram heap content to Main Ram + AgesaStatus = CopyHeapToMainRamAtPost (&(EnvParams->StdHeader)); + if (AgesaStatus > AmdInitEnvStatus) { + AmdInitEnvStatus = AgesaStatus; + } + EnvParams->StdHeader.HeapStatus = HEAP_SYSTEM_MEM; + EnvParams->StdHeader.HeapBasePtr = HeapGetBaseAddress (&EnvParams->StdHeader); + // Any heap allocate/deallocate/locate buffer should be used after heap is rebuilt from here. + // After persistent heaps are transferred and rebuilt, HeapLocateBuffer can start to be used in IDS hook. + + //Heap have been relocated, so Debug Print need be init again to get new address + IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDINITENV, &EnvParams->StdHeader); + IDS_HDT_CONSOLE_INIT (&EnvParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "Heap transfer End\n"); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdInitEnv: Start\n\n"); + IDS_OPTION_HOOK (IDS_PLATFORMCFG_OVERRIDE, &EnvParams->PlatformConfig, &(EnvParams->StdHeader)); + IDS_OPTION_HOOK (IDS_BEFORE_PCI_INIT, EnvParams, &(EnvParams->StdHeader)); + + AgesaStatus = S3ScriptInit (&EnvParams->StdHeader); + if (AgesaStatus > AmdInitEnvStatus) { + AmdInitEnvStatus = AgesaStatus; + } + + IDS_PERF_TIMESTAMP (TP_BEGININITENV, &EnvParams->StdHeader); + AgesaStatus = BldoptFchFunction.InitEnv (EnvParams); + AmdInitEnvStatus = (AgesaStatus > AmdInitEnvStatus) ? AgesaStatus : AmdInitEnvStatus; + IDS_PERF_TIMESTAMP (TP_ENDINITENV, &EnvParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATENV, &EnvParams->StdHeader); + AgesaStatus = GnbInitAtEnv (EnvParams); + if (AgesaStatus > AmdInitEnvStatus) { + AmdInitEnvStatus = AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDGNBINITATENV, &EnvParams->StdHeader); + + AGESA_TESTPOINT (TpIfAmdInitEnvExit, &EnvParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitEnv: End\n"); + IDS_PERF_TIMESTAMP (TP_ENDPROCAMDINITENV, &EnvParams->StdHeader); + IDS_HDT_CONSOLE_FLUSH_BUFFER (&EnvParams->StdHeader); + return AmdInitEnvStatus; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitLate.c new file mode 100644 index 0000000000..92aeb47dab --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitLate.c @@ -0,0 +1,323 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84514 $ @e \$Date: 2012-12-17 10:44:17 -0600 (Mon, 17 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionDmi.h" +#include "OptionSlit.h" +#include "cpuLateInit.h" +#include "cpuFeatures.h" +#include "CommonInits.h" +#include "GnbInterface.h" +#include "OptionPstate.h" +#include "Filecode.h" +#include "heapManager.h" +#include "CreateStruct.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_COMMON_AMDINITLATE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_DMI_CONFIGURATION OptionDmiConfiguration; // global user config record +extern OPTION_SLIT_CONFIGURATION OptionSlitConfiguration; // global user config record +extern OPTION_PSTATE_LATE_CONFIGURATION OptionPstateLateConfiguration; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdLatePlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/*------------------------------------------------------------------------------------*/ +/** + * Initialize AmdInitLate stage platform profile and user option input. + * + * @param[in,out] PlatformConfig Platform profile/build option config structure + * @param[in,out] StdHeader AMD standard header config param + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdLatePlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CommonPlatformConfigInit (PlatformConfig, StdHeader); + + return AGESA_SUCCESS; +} + +/* + *--------------------------------------------------------------------------------------- + * + * AmdInitLateInitializer + * + * Initializer routine that will be invoked by the wrapper + * to initialize the input structure for the AmdInitLate + * + * @param[in, out] IN OUT AMD_LATE_PARAMS *LateParamsPtr + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdInitLateInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_LATE_PARAMS *LateParamsPtr + ) +{ + ASSERT (StdHeader != NULL); + ASSERT (LateParamsPtr != NULL); + + LateParamsPtr->StdHeader = *StdHeader; + + AmdLatePlatformConfigInit (&LateParamsPtr->PlatformConfig, &LateParamsPtr->StdHeader); + GnbInitDataStructAtLateDef (&LateParamsPtr->GnbLateConfiguration, LateParamsPtr); + + LateParamsPtr->AcpiSlit = NULL; + + LateParamsPtr->AcpiSrat = NULL; + + LateParamsPtr->AcpiWheaMce = NULL; + LateParamsPtr->AcpiWheaCmc = NULL; + + LateParamsPtr->AcpiPState = NULL; + + LateParamsPtr->DmiTable = NULL; + + LateParamsPtr->AcpiAlib = NULL; + + LateParamsPtr->IvrsExclusionRangeList = UserOptions.CfgIvrsExclusionRangeList; + + return AGESA_SUCCESS; +} + +/* + *--------------------------------------------------------------------------------------- + * + * AmdInitLateDestructor + * + * Destruct routine that provide a chance if something need to be done + * before the end of AmdInitLate. + * + * @param[in] StdHeader The standard header. + * @param[in] LateParamsPtr AMD init late param. + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdInitLateDestructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_LATE_PARAMS *LateParamsPtr + ) +{ + + ASSERT (LateParamsPtr != NULL); + + (*(OptionDmiConfiguration.DmiReleaseBuffer)) (StdHeader); + (*(OptionSlitConfiguration.SlitReleaseBuffer)) (StdHeader); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for the AMD_INIT_LATE function. + * + * This entry point is responsible for creating any desired ACPI tables, providing + * information for DMI, and to prepare the processors for the operating system + * bootstrap load process. + * + * @param[in,out] LateParams Required input parameters for the AMD_INIT_LATE + * entry point. + * + * @return Aggregated status across all internal AMD late calls invoked. + * + */ +AGESA_STATUS +AmdInitLate ( + IN OUT AMD_LATE_PARAMS *LateParams + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS AmdInitLateStatus; + + IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDINITLATE, &LateParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdInitLate: Start\n\n"); + AGESA_TESTPOINT (TpIfAmdInitLateEntry, &LateParams->StdHeader); + + ASSERT (LateParams != NULL); + AmdInitLateStatus = AGESA_SUCCESS; + + IDS_OPTION_HOOK (IDS_INIT_LATE_BEFORE, LateParams, &LateParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_BEGINCREATSYSTEMTABLE, &LateParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "CreatSystemTable: Start\n"); + // _PSS, XPSS, _PCT, _PSD, _PPC, _CST, _CSD Tables + if ((LateParams->PlatformConfig.UserOptionPState) || (IsFeatureEnabled (IoCstate, &LateParams->PlatformConfig, &LateParams->StdHeader))) { + AgesaStatus = ((*(OptionPstateLateConfiguration.SsdtFeature)) (&LateParams->StdHeader, &LateParams->PlatformConfig, &LateParams->AcpiPState)); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + } + + // CRAT Table Generation + if (LateParams->PlatformConfig.UserOptionCrat) { + AgesaStatus = CreateAcpiCrat (&LateParams->StdHeader, &LateParams->AcpiCrat); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + } + + // CDIT Table Generation + if (LateParams->PlatformConfig.UserOptionCdit) { + AgesaStatus = CreateAcpiCdit (&LateParams->StdHeader, &LateParams->PlatformConfig, &LateParams->AcpiCdit); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + } + + // SRAT Table Generation + if (LateParams->PlatformConfig.UserOptionSrat) { + AgesaStatus = CreateAcpiSrat (&LateParams->StdHeader, &LateParams->AcpiSrat); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + } + + // SLIT Table Generation + if (LateParams->PlatformConfig.UserOptionSlit) { + AgesaStatus = CreateAcpiSlit (&LateParams->StdHeader, &LateParams->PlatformConfig, &LateParams->AcpiSlit); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + } + + // WHEA Table Generation + if (LateParams->PlatformConfig.UserOptionWhea) { + AgesaStatus = CreateAcpiWhea (&LateParams->StdHeader, &LateParams->AcpiWheaMce, &LateParams->AcpiWheaCmc); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + } + + // DMI Table Generation + if (LateParams->PlatformConfig.UserOptionDmi) { + AgesaStatus = CreateDmiRecords (&LateParams->StdHeader, &LateParams->DmiTable); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + } + IDS_HDT_CONSOLE (MAIN_FLOW, "CreatSystemTable: End\n"); + IDS_PERF_TIMESTAMP (TP_ENDCREATSYSTEMTABLE, &LateParams->StdHeader); + + // Cpu Features + IDS_PERF_TIMESTAMP (TP_BEGINDISPATCHCPUFEATURESLATE, &LateParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "DispatchCpuFeatures: LateStart\n"); + AgesaStatus = DispatchCpuFeatures (CPU_FEAT_INIT_LATE_END, &LateParams->PlatformConfig, &LateParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "DispatchCpuFeatures: LateEnd\n"); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDDISPATCHCPUFEATURESLATE, &LateParams->StdHeader); + + // It is the last function run by the AGESA CPU module and prepares the processor + // for the operating system bootstrap load process. + IDS_PERF_TIMESTAMP (TP_BEGINAMDCPULATE, &LateParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuLate: Start\n"); + AgesaStatus = AmdCpuLate (&LateParams->StdHeader, &LateParams->PlatformConfig); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuLate: End\n"); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDAMDCPULATE, &LateParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATLATE, &LateParams->StdHeader); + AgesaStatus = GnbInitAtLate (LateParams); + if (AgesaStatus > AmdInitLateStatus) { + AmdInitLateStatus = AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDGNBINITATLATE, &LateParams->StdHeader); + + IDS_OPTION_HOOK (IDS_INIT_LATE_AFTER, LateParams, &LateParams->StdHeader); + AGESA_TESTPOINT (TpIfAmdInitLateExit, &LateParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitLate: End\n\n"); + AGESA_TESTPOINT (EndAgesaTps, &LateParams->StdHeader); +//End Debug Print Service + IDS_HDT_CONSOLE_EXIT (&LateParams->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDPROCAMDINITLATE, &LateParams->StdHeader); + IDS_PERF_ANALYSE (&LateParams->StdHeader); + + return AmdInitLateStatus; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitMid.c new file mode 100644 index 0000000000..2bd403415c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitMid.c @@ -0,0 +1,178 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "cpuFeatures.h" +#include "CommonInits.h" +#include "GnbInterface.h" +#include "AmdFch.h" +#include "Filecode.h" +#include "heapManager.h" +#include "CreateStruct.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_AMDINITMID_FILECODE + +extern BLDOPT_FCH_FUNCTION BldoptFchFunction; + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/* + *--------------------------------------------------------------------------------------- + * + * Initializer routine that will be invoked by the wrapper + * to initialize the input structure for the AmdInitMid + * + * @param[in,out] MidParamsPtr Newly created interface parameters for AmdInitMid + * + * @retval AGESA_SUCCESS Always succeeds + * + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdInitMidInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_MID_PARAMS *MidParamsPtr + ) +{ + ASSERT (StdHeader != NULL); + ASSERT (MidParamsPtr != NULL); + + MidParamsPtr->StdHeader = *StdHeader; + CommonPlatformConfigInit (&MidParamsPtr->PlatformConfig, &MidParamsPtr->StdHeader); + BldoptFchFunction.InitMidConstructor (MidParamsPtr); + GnbInitDataStructAtMidDef (&MidParamsPtr->GnbMidConfiguration, MidParamsPtr); + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for the AMD_INIT_MID function. + * + * This entry point is responsible for performing any necessary functions needed + * after PCI bus enumeration and just before control is passed to the video option ROM. + * + * @param[in,out] MidParams Required input parameters for the AMD_INIT_MID + * entry point. + * + * @return Aggregated status across all internal AMD mid calls invoked. + * + */ +AGESA_STATUS +AmdInitMid ( + IN OUT AMD_MID_PARAMS *MidParams + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS CalledStatus; + + IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDINITMID, &MidParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdInitMid: Start\n\n"); + AGESA_TESTPOINT (TpIfAmdInitMidEntry, &MidParams->StdHeader); + + AgesaStatus = AGESA_SUCCESS; + + ASSERT (MidParams != NULL); + IDS_OPTION_HOOK (IDS_INIT_MID_BEFORE, MidParams, &MidParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_BEGINDISPATCHCPUFEATURESMID, &MidParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "DispatchCpuFeatures: MidStart\n"); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_INIT_MID_END, &MidParams->PlatformConfig, &MidParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "DispatchCpuFeatures: MidEnd\n"); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDDISPATCHCPUFEATURESMID, &MidParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_BEGININITMID, &MidParams->StdHeader); + CalledStatus = BldoptFchFunction.InitMid (MidParams); + AgesaStatus = (CalledStatus > AgesaStatus) ? CalledStatus : AgesaStatus; + IDS_PERF_TIMESTAMP (TP_ENDINITMID, &MidParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATMID, &MidParams->StdHeader); + CalledStatus = GnbInitAtMid (MidParams); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDGNBINITATMID, &MidParams->StdHeader); + + IDS_OPTION_HOOK (IDS_INIT_MID_AFTER, MidParams, &MidParams->StdHeader); + + AGESA_TESTPOINT (TpIfAmdInitMidExit, &MidParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitMid: End\n\n"); + IDS_HDT_CONSOLE_FLUSH_BUFFER (&MidParams->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDPROCAMDINITMID, &MidParams->StdHeader); + + return AgesaStatus; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitPost.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitPost.c new file mode 100644 index 0000000000..842b1599bb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitPost.c @@ -0,0 +1,349 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "mm.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuPostInit.h" +#include "AdvancedApi.h" +#include "heapManager.h" +#include "CommonInits.h" +#include "cpuServices.h" +#include "GnbInterface.h" +#include "Filecode.h" +#include "CreateStruct.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_AMDINITPOST_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdPostPlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/*------------------------------------------------------------------------------------*/ +/** + * Initialize AmdInitPost stage platform profile and user option input. + * + * @param[in,out] PlatformConfig Platform profile/build option config structure + * @param[in,out] StdHeader AMD standard header config param + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdPostPlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CommonPlatformConfigInit (PlatformConfig, StdHeader); + + return AGESA_SUCCESS; +} + +/* + *--------------------------------------------------------------------------------------- + * + * AmdInitPostInitializer + * + * Initializer routine that will be invoked by the wrapper + * to initialize the input structure for the AmdInitPost + * + * @param[in, out] IN OUT AMD_POST_PARAMS *PostParamsPtr + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdInitPostInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_POST_PARAMS *PostParamsPtr + ) +{ + AGESA_STATUS AgesaStatus; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + ASSERT (StdHeader != NULL); + ASSERT (PostParamsPtr != NULL); + + PostParamsPtr->StdHeader = *StdHeader; + + AllocHeapParams.RequestedBufferSize = sizeof (MEM_DATA_STRUCT); + AllocHeapParams.BufferHandle = AMD_MEM_DATA_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + AgesaStatus = HeapAllocateBuffer (&AllocHeapParams, &PostParamsPtr->StdHeader); + + if (AgesaStatus == AGESA_SUCCESS) { + PostParamsPtr->MemConfig.MemData = (MEM_DATA_STRUCT *) AllocHeapParams.BufferPtr; + PostParamsPtr->MemConfig.MemData->ParameterListPtr = &(PostParamsPtr->MemConfig); + AmdPostPlatformConfigInit (&PostParamsPtr->PlatformConfig, &PostParamsPtr->StdHeader); + AmdMemInitDataStructDef (PostParamsPtr->MemConfig.MemData, &PostParamsPtr->PlatformConfig); + GnbInitDataStructAtPostDef (&PostParamsPtr->GnbPostConfig, PostParamsPtr); + } + return AgesaStatus; +} + +/* + *--------------------------------------------------------------------------------------- + * + * AmdInitPostDestructor + * + * Destruct routine that provide a chance if something need to be done + * before the end of AmdInitPost. + * + * @param[in] StdHeader The standard header. + * @param[in] PostParamsPtr AMD init post param. + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdInitPostDestructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_POST_PARAMS *PostParamsPtr + ) +{ + + ASSERT (PostParamsPtr != NULL); + + PostParamsPtr->StdHeader = *StdHeader; + PostParamsPtr->MemConfig.MemData->StdHeader = *StdHeader; + + // + // AmdMemAuto completed. Here, release heap space which is used for memory init. + // + MemAmdFinalize (PostParamsPtr->MemConfig.MemData); + HeapDeallocateBuffer (AMD_MEM_DATA_HANDLE, StdHeader); + + // + // AmdCpuPost completed. + // + if (PostParamsPtr->MemConfig.SysLimit != 0) { + // WBINVD can only be executed when memory is available + FinalizeAtPost (StdHeader); + } + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for the AMD_INIT_POST function. + * + * This entry point is responsible for initializing all system memory, + * gathering important data out of the pre-memory cache storage into a + * temporary holding buffer in main memory. After that APs will be + * shutdown in preparation for the host environment to take control. + * Note: pre-memory stack will be disabled also. + * + * @param[in,out] PostParams Required input parameters for the AMD_INIT_POST + * entry point. + * + * @return Aggregated status across all internal AMD POST calls invoked. + * + */ +AGESA_STATUS +AmdInitPost ( + IN OUT AMD_POST_PARAMS *PostParams + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS AmdInitPostStatus; + WARM_RESET_REQUEST Request; + UINT8 PrevRequestBit; + UINT8 PrevStateBits; + + IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDINITPOST, &PostParams->StdHeader); + AGESA_TESTPOINT (TpIfAmdInitPostEntry, &PostParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdInitPost: Start\n\n"); + + ASSERT (PostParams != NULL); + AmdInitPostStatus = AGESA_SUCCESS; + PrevRequestBit = FALSE; + PrevStateBits = WR_STATE_COLD; + + IDS_OPTION_HOOK (IDS_INIT_POST_BEFORE, PostParams, &PostParams->StdHeader); + + // If a previously requested warm reset cannot be triggered in the + // current stage, store the previous state of request and reset the + // request struct to the current post stage + GetWarmResetFlag (&PostParams->StdHeader, &Request); + if (Request.RequestBit == TRUE) { + if (Request.StateBits >= Request.PostStage) { + PrevRequestBit = Request.RequestBit; + PrevStateBits = Request.StateBits; + Request.RequestBit = FALSE; + Request.StateBits = Request.PostStage - 1; + SetWarmResetFlag (&PostParams->StdHeader, &Request); + } + } + + IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATPOST, &PostParams->StdHeader); + AgesaStatus = GnbInitAtPost (PostParams); + if (AgesaStatus > AmdInitPostStatus) { + AmdInitPostStatus = AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDGNBINITATPOST, &PostParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_BEGINAMDMEMAUTO, &PostParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdMemAuto: Start\n"); + PostParams->MemConfig.MemData->StdHeader = PostParams->StdHeader; + AgesaStatus = AmdMemAuto (PostParams->MemConfig.MemData); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdMemAuto: End\n"); + if (AgesaStatus > AmdInitPostStatus) { + AmdInitPostStatus = AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDAMDMEMAUTO, &PostParams->StdHeader); + + if (AgesaStatus != AGESA_FATAL) { + // Check BIST status + AgesaStatus = CheckBistStatus (&PostParams->StdHeader); + if (AgesaStatus > AmdInitPostStatus) { + AmdInitPostStatus = AgesaStatus; + } + + // + // P-State data gathered, then, Relinquish APs + // + IDS_PERF_TIMESTAMP (TP_BEGINAMDCPUPOST, &PostParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuPost: Start\n"); + AgesaStatus = AmdCpuPost (&PostParams->StdHeader, &PostParams->PlatformConfig); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuPost: End\n"); + if (AgesaStatus > AmdInitPostStatus) { + AmdInitPostStatus = AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDAMDCPUPOST, &PostParams->StdHeader); + + // Warm Reset + GetWarmResetFlag (&PostParams->StdHeader, &Request); + // If a warm reset is requested in the current post stage, trigger the + // warm reset and ignore the previous request + if (Request.RequestBit == TRUE) { + if (Request.StateBits < Request.PostStage) { + AgesaDoReset (WARM_RESET_WHENEVER, &PostParams->StdHeader); + } + } else { + // Otherwise, if there's a previous request, restore it + // so that the subsequent post stage can trigger the warm reset + if (PrevRequestBit == TRUE) { + Request.RequestBit = PrevRequestBit; + Request.StateBits = PrevStateBits; + SetWarmResetFlag (&PostParams->StdHeader, &Request); + } + } + + IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATPOSTAFTERDRAM, &PostParams->StdHeader); + AgesaStatus = GnbInitAtPostAfterDram (PostParams); + if (AgesaStatus > AmdInitPostStatus) { + AmdInitPostStatus = AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDGNBINITATPOSTAFTERDRAM, &PostParams->StdHeader); + + IDS_OPTION_HOOK (IDS_INIT_POST_AFTER, PostParams, &PostParams->StdHeader); + + AGESA_TESTPOINT (TpIfAmdInitPostExit, &PostParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitPost: End\n\n"); + IDS_HDT_CONSOLE (MAIN_FLOW, "Heap transfer Start ...\n\n"); + + //For Heap will be relocate to new address in next stage, flush out debug print buffer if needed + IDS_HDT_CONSOLE_FLUSH_BUFFER (&PostParams->StdHeader); + + // WARNING: IDT will be moved from local cache to temp memory, so restore IDTR for BSP here + IDS_EXCEPTION_TRAP (IDS_IDT_RESTORE_IDTR_FOR_BSC, NULL, &PostParams->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDPROCAMDINITPOST, &PostParams->StdHeader); + + // Copies BSP heap content to RAM, and it should be at the end of AmdInitPost + AgesaStatus = CopyHeapToTempRamAtPost (&(PostParams->StdHeader)); + if (AgesaStatus > AmdInitPostStatus) { + AmdInitPostStatus = AgesaStatus; + } + PostParams->StdHeader.HeapStatus = HEAP_TEMP_MEM; + } + // Check for Cache As Ram Corruption + IDS_CAR_CORRUPTION_CHECK (&PostParams->StdHeader); + + // At the end of AmdInitPost, set StateBits to POST to allow any warm reset that occurs outside + // of AGESA to be recognized by IsWarmReset() + GetWarmResetFlag (&PostParams->StdHeader, &Request); + Request.StateBits = Request.PostStage; + SetWarmResetFlag (&PostParams->StdHeader, &Request); + + return AmdInitPostStatus; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitReset.c new file mode 100644 index 0000000000..30e194e219 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitReset.c @@ -0,0 +1,257 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuCacheInit.h" +#include "cpuServices.h" +#include "AdvancedApi.h" +#include "GeneralServices.h" +#include "OptionsHt.h" +#include "AmdFch.h" +#include "Filecode.h" +#include "heapManager.h" +#include "CreateStruct.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_AMDINITRESET_FILECODE + +extern BLDOPT_FCH_FUNCTION BldoptFchFunction; + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern CONST OPTION_HT_INIT_RESET HtOptionInitReset; +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdInitResetExecutionCacheAllocateInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN EXECUTION_CACHE_REGION *AmdExeAddrMapPtr + ); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------------------*/ +/** + * Initializer routine that will be invoked by the wrapper to initialize the input + * structure for the AllocateExecutionCache. + * + * Parameters: + * @param[in] StdHeader Opaque handle to standard config header + * @param[in] AmdExeAddrMapPtr Our Service interface struct + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdInitResetExecutionCacheAllocateInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN EXECUTION_CACHE_REGION *AmdExeAddrMapPtr + ) +{ + ASSERT (AmdExeAddrMapPtr != NULL); + + LibAmdMemFill (AmdExeAddrMapPtr, 0, sizeof (EXECUTION_CACHE_REGION) * MAX_CACHE_REGIONS, StdHeader); + + return AGESA_SUCCESS; +} +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for the AMD_INIT_RESET function. + * + * This entry point is responsible for establishing the HT links to the program + * ROM and for performing basic processor initialization. + * + * @param[in,out] ResetParams Required input parameters for the AMD_INIT_RESET + * entry point. + * + * @return Aggregated status across all internal AMD reset calls invoked. + * + */ +AGESA_STATUS +AmdInitReset ( + IN OUT AMD_RESET_PARAMS *ResetParams + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS CalledAgesaStatus; + WARM_RESET_REQUEST Request; + UINT8 PrevRequestBit; + UINT8 PrevStateBits; + + IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDINITRESET, &ResetParams->StdHeader); + AgesaStatus = AGESA_SUCCESS; + + // Setup ROM execution cache + CalledAgesaStatus = AllocateExecutionCache (&ResetParams->StdHeader, &ResetParams->CacheRegion[0]); + if (CalledAgesaStatus > AgesaStatus) { + AgesaStatus = CalledAgesaStatus; + } + + + // Init Debug Print function + IDS_HDT_CONSOLE_INIT (&ResetParams->StdHeader); + + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitReset: Start\n\n"); + + IDS_HDT_CONSOLE (MAIN_FLOW, "\n*** %s ***\n\n", &UserOptions.VersionString); + + AGESA_TESTPOINT (TpIfAmdInitResetEntry, &ResetParams->StdHeader); + ASSERT (ResetParams != NULL); + + PrevRequestBit = FALSE; + PrevStateBits = WR_STATE_COLD; + + IDS_PERF_TIMESTAMP (TP_BEGININITRESET, &ResetParams->StdHeader); + if (IsBsp (&ResetParams->StdHeader, &AgesaStatus)) { + CalledAgesaStatus = BldoptFchFunction.InitReset (ResetParams); + AgesaStatus = (CalledAgesaStatus > AgesaStatus) ? CalledAgesaStatus : AgesaStatus; + } + IDS_PERF_TIMESTAMP (TP_ENDINITRESET, &ResetParams->StdHeader); + + // If a previously requested warm reset cannot be triggered in the + // current stage, store the previous state of request and reset the + // request struct to the current post stage + GetWarmResetFlag (&ResetParams->StdHeader, &Request); + if (Request.RequestBit == TRUE) { + if (Request.StateBits >= Request.PostStage) { + PrevRequestBit = Request.RequestBit; + PrevStateBits = Request.StateBits; + Request.RequestBit = FALSE; + Request.StateBits = Request.PostStage - 1; + SetWarmResetFlag (&ResetParams->StdHeader, &Request); + } + } + + // Initialize the PCI MMIO access mechanism + InitializePciMmio (&ResetParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_BEGINHTINITRESET, &ResetParams->StdHeader); + // Initialize Hyper Transport Registers + if (HtOptionInitReset.HtInitReset != NULL) { + IDS_HDT_CONSOLE (MAIN_FLOW, "HtInitReset: Start\n"); + CalledAgesaStatus = HtOptionInitReset.HtInitReset (&ResetParams->StdHeader, &ResetParams->HtConfig); + IDS_HDT_CONSOLE (MAIN_FLOW, "HtInitReset: End\n"); + if (CalledAgesaStatus > AgesaStatus) { + AgesaStatus = CalledAgesaStatus; + } + } + IDS_PERF_TIMESTAMP (TP_ENDHTINITRESET, &ResetParams->StdHeader); + + // Warm Reset, should be at the end of AmdInitReset + GetWarmResetFlag (&ResetParams->StdHeader, &Request); + // If a warm reset is requested in the current post stage, trigger the + // warm reset and ignore the previous request + if (Request.RequestBit == TRUE) { + if (Request.StateBits < Request.PostStage) { + AgesaDoReset (WARM_RESET_WHENEVER, &ResetParams->StdHeader); + } + } else { + // Otherwise, if there's a previous request, restore it + // so that the subsequent post stage can trigger the warm reset + if (PrevRequestBit == TRUE) { + Request.RequestBit = PrevRequestBit; + Request.StateBits = PrevStateBits; + SetWarmResetFlag (&ResetParams->StdHeader, &Request); + } + } + // Check for Cache As Ram Corruption + IDS_CAR_CORRUPTION_CHECK (&ResetParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitReset: End\n\n"); + + AGESA_TESTPOINT (TpIfAmdInitResetExit, &ResetParams->StdHeader); + + IDS_PERF_TIMESTAMP (TP_ENDPROCAMDINITRESET, &ResetParams->StdHeader); + + return AgesaStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Initialize defaults and options for Amd Init Reset. + * + * @param[in] StdHeader Header + * @param[in] AmdResetParams The Reset Init interface to initialize. + * + * @retval AGESA_SUCCESS Always Succeeds. + */ +AGESA_STATUS +AmdInitResetConstructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_RESET_PARAMS *AmdResetParams + ) +{ + ASSERT (AmdResetParams != NULL); + + AmdResetParams->StdHeader = *StdHeader; + + AmdInitResetExecutionCacheAllocateInitializer (&AmdResetParams->StdHeader, &AmdResetParams->CacheRegion[0]); + // Initialize Hyper Transport input structure + if (HtOptionInitReset.HtResetConstructor != NULL) { + HtOptionInitReset.HtResetConstructor (&AmdResetParams->StdHeader, &AmdResetParams->HtConfig); + } + BldoptFchFunction.InitResetConstructor (AmdResetParams); + + return AGESA_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitResume.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitResume.c new file mode 100644 index 0000000000..77dfdfcf27 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdInitResume.c @@ -0,0 +1,245 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "S3.h" +#include "mfs3.h" +#include "Filecode.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuPostInit.h" +#include "CommonInits.h" +#include "cpuFeatures.h" +#include "heapManager.h" +#include "CreateStruct.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_AMDINITRESUME_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for the AMD_INIT_RESUME function. + * + * This entry point is responsible for performing silicon device and memory + * re-initialization for the resume boot path. + * + * @param[in] ResumeParams Required input parameters for the AMD_INIT_RESUME + * entry point. + * + * @return Aggregated status across all internal AMD resume calls invoked. + * + */ +AGESA_STATUS +AmdInitResume ( + IN AMD_RESUME_PARAMS *ResumeParams + ) +{ + VOID *OrMaskPtr; + AGESA_STATUS ReturnStatus; + AGESA_STATUS AmdInitResumeStatus; + BSC_AP_MSR_SYNC ApMsrSync[4]; + + IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDINITRESUME, &ResumeParams->StdHeader); + AGESA_TESTPOINT (TpIfAmdInitResumeEntry, &ResumeParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdInitResume Start\n"); + + AmdInitResumeStatus = AGESA_SUCCESS; + + ASSERT (ResumeParams != NULL); + + if (ResumeParams->S3DataBlock.NvStorage != NULL) { + IDS_PERF_TIMESTAMP (TP_BEGINAMDMEMS3RESUME, &ResumeParams->StdHeader); + + MemS3ResumeInitNB (&ResumeParams->StdHeader); + + // Restore registers before exiting self refresh + RestorePreESRContext (&OrMaskPtr, + ResumeParams->S3DataBlock.NvStorage, + INIT_RESUME, + &ResumeParams->StdHeader); + // Exit self refresh + ReturnStatus = AmdMemS3Resume (&ResumeParams->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDAMDMEMS3RESUME, &ResumeParams->StdHeader); + if (ReturnStatus > AmdInitResumeStatus) { + AmdInitResumeStatus = ReturnStatus; + } + if (ReturnStatus == AGESA_SUCCESS) { + + // Restore registers after exiting self refresh + RestorePostESRContext (OrMaskPtr, + ResumeParams->S3DataBlock.NvStorage, + INIT_RESUME, + &ResumeParams->StdHeader); + + ApMsrSync[0].RegisterAddress = SYS_CFG; + ApMsrSync[1].RegisterAddress = TOP_MEM; + ApMsrSync[2].RegisterAddress = TOP_MEM2; + ApMsrSync[3].RegisterAddress = 0; + SyncApMsrsToBsc (ApMsrSync, &ResumeParams->StdHeader); + IDS_PERF_TIMESTAMP (TP_BEGINDISPATCHCPUFEATURESS3RESUME, &ResumeParams->StdHeader); + + IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features after S3 AP MTRR sync\n"); + ReturnStatus = DispatchCpuFeatures (CPU_FEAT_AFTER_RESUME_MTRR_SYNC, &ResumeParams->PlatformConfig, &ResumeParams->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDDISPATCHCPUFEATURESS3RESUME, &ResumeParams->StdHeader); + if (ReturnStatus > AmdInitResumeStatus) { + AmdInitResumeStatus = ReturnStatus; + } + } + } + + IDS_OPTION_HOOK (IDS_AFTER_S3_RESUME, NULL, &ResumeParams->StdHeader); + + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdInitResume End\n"); + + // HDT out of All Aps + IDS_HDT_CONSOLE_FLUSH_BUFFER (&ResumeParams->StdHeader); + // Relinquish control of all APs to IBV + RelinquishControlOfAllAPs (&ResumeParams->StdHeader); + + // Restore IDT + IDS_EXCEPTION_TRAP (IDS_IDT_RESTORE_IDTR_FOR_BSC, NULL, &ResumeParams->StdHeader); + AGESA_TESTPOINT (TpIfAmdInitResumeExit, &ResumeParams->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDPROCAMDINITRESUME, &ResumeParams->StdHeader); + IDS_PERF_ANALYSE (&ResumeParams->StdHeader); + + return (AmdInitResumeStatus); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Constructor for the AMD_INIT_RESUME function. + * + * This routine is responsible for setting default values for the + * input parameters needed by the AMD_INIT_RESUME entry point. + * + * @param[in] StdHeader The standard header. + * @param[in,out] ResumeParams Required input parameters for the AMD_INIT_RESUME + * entry point. + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdInitResumeInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_RESUME_PARAMS *ResumeParams + ) +{ + ASSERT (StdHeader != NULL); + ASSERT (ResumeParams != NULL); + + ResumeParams->StdHeader = *StdHeader; + + AmdS3ParamsInitializer (&ResumeParams->S3DataBlock); + CommonPlatformConfigInit (&ResumeParams->PlatformConfig, &ResumeParams->StdHeader); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Destructor for the AMD_INIT_RESUME function. + * + * This routine is responsible for deallocation of heap space allocated during + * AMD_INIT_RESUME entry point. + * + * @param[in] StdHeader The standard header. + * @param[in,out] ResumeParams Required input parameters for the AMD_INIT_RESUME + * entry point. + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +AmdInitResumeDestructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_RESUME_PARAMS *ResumeParams + ) +{ + AGESA_STATUS ReturnStatus; + AGESA_STATUS RetVal; + + ASSERT (ResumeParams != NULL); + + ReturnStatus = AGESA_SUCCESS; + + // Deallocate heap space allocated during memory S3 resume + RetVal = MemS3Deallocate (&ResumeParams->StdHeader); + if (RetVal > ReturnStatus) { + ReturnStatus = RetVal; + } + + return ReturnStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdLateRunApTask.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdLateRunApTask.c new file mode 100644 index 0000000000..b7e125e85b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdLateRunApTask.c @@ -0,0 +1,159 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Options.h" +#include "Filecode.h" +#include "heapManager.h" +#include "CreateStruct.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_COMMON_AMDLATERUNAPTASK_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern CONST DISPATCH_TABLE ApDispatchTable[]; + +/*---------------------------------------------------------------------------------------*/ +/** + * Application Processor perform a function as directed by the BSC. + * + * This is needed for an AP task that must run after AGESA has relinquished control + * of the APs to the IBV. + * + * @param[in] AmdApExeParams The interface struct for any required routine. + * + * @return The most severe AGESA_STATUS returned by any called service. Note + * that this will be the return value passed back to the BSC as the + * return value for the call out. + * + */ +AGESA_STATUS +AmdLateRunApTask ( + IN AP_EXE_PARAMS *AmdApExeParams + ) +{ + AGESA_STATUS CalledAgesaStatus; + AGESA_STATUS ApLateTaskStatus; + DISPATCH_TABLE *Entry; + + AGESA_TESTPOINT (TpIfAmdLateRunApTaskEntry, &AmdApExeParams->StdHeader); + + ASSERT (AmdApExeParams != NULL); + ApLateTaskStatus = AGESA_SUCCESS; + CalledAgesaStatus = AGESA_UNSUPPORTED; + + // Dispatch, if valid + Entry = (DISPATCH_TABLE *) ApDispatchTable; + while (Entry->FunctionId != 0) { + if (AmdApExeParams->FunctionNumber == Entry->FunctionId) { + CalledAgesaStatus = Entry->EntryPoint (AmdApExeParams); + break; + } + Entry++; + } + + if (CalledAgesaStatus > ApLateTaskStatus) { + ApLateTaskStatus = CalledAgesaStatus; + } + + AGESA_TESTPOINT (TpIfAmdLateRunApTaskExit, &AmdApExeParams->StdHeader); + return ApLateTaskStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Constructor for the AMD_LATE_RUN_AP_TASK function. + * + * This routine is responsible for setting default values for the + * input parameters needed by the AMD_S3_SAVE entry point. + * + * @param[in] StdHeader The standard header. + * @param[in,out] AmdApExeParams Required input parameters for the AMD_LATE_RUN_AP_TASK + * entry point. + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdLateRunApTaskInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AP_EXE_PARAMS *AmdApExeParams + ) +{ + ASSERT (StdHeader != NULL); + ASSERT (AmdApExeParams != NULL); + + AmdApExeParams->StdHeader = *StdHeader; + AmdApExeParams->FunctionNumber = 0; + AmdApExeParams->RelatedDataBlock = NULL; + AmdApExeParams->RelatedBlockLength = 0; + return AGESA_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdS3LateRestore.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdS3LateRestore.c new file mode 100644 index 0000000000..5b30e55e20 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdS3LateRestore.c @@ -0,0 +1,217 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "S3.h" +#include "cpuFeatures.h" +#include "S3SaveState.h" +#include "CommonInits.h" +#include "Filecode.h" +#include "heapManager.h" +#include "CreateStruct.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_COMMON_AMDS3LATERESTORE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdS3LateRestorePlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for the AMD_S3LATE_RESTORE function. + * + * This entry point is responsible for restoring saved registers and preparing the + * silicon components for OS restart. + * + * @param[in,out] S3LateParams Required input parameters for the AMD_S3LATE_RESTORE + * entry point. + * + * @return Aggregated status across all internal AMD S3 late restore calls invoked. + * + */ +AGESA_STATUS +AmdS3LateRestore ( + IN OUT AMD_S3LATE_PARAMS *S3LateParams + ) +{ + UINT8 *BufferPointer; + VOID *OrMaskPtr; + VOID *LateContextPtr; + AGESA_STATUS ReturnStatus; + AGESA_STATUS CalledStatus; + + AGESA_TESTPOINT (TpIfAmdS3LateRestoreEntry, &S3LateParams->StdHeader); + + ReturnStatus = AGESA_SUCCESS; + + ASSERT (S3LateParams != NULL); + + BufferPointer = (UINT8 *) S3LateParams->S3DataBlock.VolatileStorage; + S3LateParams->StdHeader.HeapBasePtr = (UINT32) &BufferPointer[((S3_VOLATILE_STORAGE_HEADER *) S3LateParams->S3DataBlock.VolatileStorage)->HeapOffset]; + ASSERT (S3LateParams->StdHeader.HeapBasePtr != 0); + + IDS_HDT_CONSOLE_INIT (&S3LateParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "AmdS3LateRestore: Start\n\n"); + + IDS_OPTION_HOOK (IDS_PLATFORMCFG_OVERRIDE, &S3LateParams->PlatformConfig, &S3LateParams->StdHeader); + IDS_OPTION_HOOK (IDS_BEFORE_S3_RESTORE, S3LateParams, &(S3LateParams->StdHeader)); + + if (((S3_VOLATILE_STORAGE_HEADER *) S3LateParams->S3DataBlock.VolatileStorage)->RegisterDataSize != 0) { + LateContextPtr = &BufferPointer[((S3_VOLATILE_STORAGE_HEADER *) S3LateParams->S3DataBlock.VolatileStorage)->RegisterDataOffset]; + // Restore registers before exiting self refresh + RestorePreESRContext (&OrMaskPtr, + LateContextPtr, + S3_LATE_RESTORE, + &S3LateParams->StdHeader); + // Restore registers after exiting self refresh + RestorePostESRContext (OrMaskPtr, + LateContextPtr, + S3_LATE_RESTORE, + &S3LateParams->StdHeader); + } + + // Dispatch any features needing to run at this time point + IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features at S3 late restore end\n"); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_S3_LATE_RESTORE_END, + &S3LateParams->PlatformConfig, + &S3LateParams->StdHeader); + if (CalledStatus > ReturnStatus) { + ReturnStatus = CalledStatus; + } + + CalledStatus = S3ScriptRestore (&S3LateParams->StdHeader); + if (CalledStatus > ReturnStatus) { + ReturnStatus = CalledStatus; + } + + IDS_OPTION_HOOK (IDS_AFTER_S3_RESTORE, S3LateParams, &S3LateParams->StdHeader); + AGESA_TESTPOINT (TpIfAmdS3LateRestoreExit, &S3LateParams->StdHeader); + IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdS3LateRestore: End\n\n"); + IDS_HDT_CONSOLE_S3_EXIT (&S3LateParams->StdHeader); + return ReturnStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Constructor for the AMD_S3LATE_RESTORE function. + * + * This routine is responsible for setting default values for the + * input parameters needed by the AMD_S3LATE_RESTORE entry point. + * + * @param[in] StdHeader AMD standard header config param. + * @param[in,out] S3LateParams Required input parameters for the + * AMD_S3LATE_RESTORE entry point. + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdS3LateRestoreInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_S3LATE_PARAMS *S3LateParams + ) +{ + ASSERT (StdHeader != NULL); + ASSERT (S3LateParams != NULL); + + S3LateParams->StdHeader = *StdHeader; + + AmdS3ParamsInitializer (&S3LateParams->S3DataBlock); + + AmdS3LateRestorePlatformConfigInit (&S3LateParams->PlatformConfig, &S3LateParams->StdHeader); + + return AGESA_SUCCESS; +} + +/*------------------------------------------------------------------------------------*/ +/** + * Initialize AmdS3LateRestore stage platform profile and user option input. + * + * @param[in,out] PlatformConfig Platform profile/build option config structure + * @param[in,out] StdHeader AMD standard header config param + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdS3LateRestorePlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CommonPlatformConfigInit (PlatformConfig, StdHeader); + + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdS3Save.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdS3Save.c new file mode 100644 index 0000000000..7c5964c925 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/AmdS3Save.c @@ -0,0 +1,424 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Basic Level Public APIs + * + * Contains basic Level Initialization routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Interface + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "S3.h" +#include "mfs3.h" +#include "CommonInits.h" +#include "AmdFch.h" +#include "GnbInterface.h" +#include "Filecode.h" +#include "heapManager.h" +#include "CreateStruct.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_COMMON_AMDS3SAVE_FILECODE + +extern BLDOPT_FCH_FUNCTION BldoptFchFunction; + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +CONST UINT32 ROMDATA S3LateHeapTable[] = +{ + EVENT_LOG_BUFFER_HANDLE, + SOCKET_DIE_MAP_HANDLE, + NODE_ID_MAP_HANDLE, + AP_MAIL_BOX_CACHE_HANDLE, + IDS_CONTROL_HANDLE, + AMD_S3_SCRIPT_SAVE_TABLE_HANDLE, + AMD_PCIE_COMPLEX_DATA_HANDLE +}; + +#define S3LATE_TABLE_SIZE (sizeof (S3LateHeapTable) / sizeof (UINT32)) //(sizeof (S3LateHeapTable) / sizeof (S3LATE_HEAP_ELEMENT)) + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdS3SavePlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------*/ +/** + * Main entry point for the AMD_S3_SAVE function. + * + * This entry point is responsible for saving silicon component registers to the + * SMM save area in preparation of entering system suspend-to-RAM mode. + * + * @param[in,out] AmdS3SaveParams Required input parameters for the AMD_S3_SAVE + * entry point. + * + * @return Aggregated status across all internal AMD S3 save calls invoked. + * + */ +AGESA_STATUS +AmdS3Save ( + IN OUT AMD_S3SAVE_PARAMS *AmdS3SaveParams + ) +{ + UINTN i; + UINT32 EarlyBufferSize; + UINT32 LateBufferSize; + UINT32 LateContextSize; + UINT32 HeapSize; + UINT8 *BufferPointer; + UINT8 HeapStatus; + ALLOCATE_HEAP_PARAMS HeapParams; + LOCATE_HEAP_PTR LocateHeap; + BUFFER_NODE *FreeSpaceNode; + ALLOCATE_HEAP_PARAMS AllocParams; + DEVICE_BLOCK_HEADER *MemoryRelatedDeviceList; + DEVICE_BLOCK_HEADER *NonMemoryRelatedDeviceList; + AGESA_STATUS ReturnStatus; + AGESA_STATUS AgesaStatus; + VOID *HeapPtrs[S3LATE_TABLE_SIZE]; + UINT32 HeapSizes[S3LATE_TABLE_SIZE]; + UINT32 HeapBuffersPresent; + HEAP_MANAGER *HeapPtr; + VOID *MemDataPointer; + + AGESA_TESTPOINT (TpIfAmdS3SaveEntry, &AmdS3SaveParams->StdHeader); + + ASSERT (AmdS3SaveParams != NULL); + + HeapBuffersPresent = 0; + EarlyBufferSize = 0; + LateBufferSize = 0; + LateContextSize = 0; + HeapSize = 0; + NonMemoryRelatedDeviceList = NULL; + MemoryRelatedDeviceList = NULL; + ReturnStatus = AGESA_SUCCESS; + MemDataPointer = NULL; + + IDS_SKIP_HOOK (IDS_BEFORE_S3_SAVE, AmdS3SaveParams, &(AmdS3SaveParams->StdHeader)) { + IDS_PERF_TIMESTAMP (TP_BEGINGNBINITATS3SAVE, &(AmdS3SaveParams->StdHeader)); + AgesaStatus = GnbInitAtS3Save (AmdS3SaveParams); + IDS_PERF_TIMESTAMP (TP_ENDGNBINITATS3SAVE, &(AmdS3SaveParams->StdHeader)); + if (AgesaStatus > ReturnStatus) { + ReturnStatus = AgesaStatus; + } + + LocateHeap.BufferHandle = AMD_SKIP_MEM_S3_SAVE; + if (HeapLocateBuffer (&LocateHeap, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) { + EarlyBufferSize = 0; + } else { + LocateHeap.BufferHandle = AMD_MEM_S3_SAVE_HANDLE; + if (HeapLocateBuffer (&LocateHeap, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) { + // Memory data has been saved and stored in the heap. + // Just copy data from heap. + // First 4 bytes in the heap store the size of the saved memory data. + EarlyBufferSize = *(UINT32 *) LocateHeap.BufferPtr; + MemDataPointer = LocateHeap.BufferPtr + 4; + } else { + // Get memory device list + MemFS3GetDeviceList (&MemoryRelatedDeviceList, &AmdS3SaveParams->StdHeader); + if (MemoryRelatedDeviceList != NULL) { + // Determine size needed + EarlyBufferSize = GetWorstCaseContextSize (MemoryRelatedDeviceList, INIT_RESUME, &AmdS3SaveParams->StdHeader); + } + } + } + + if (UserOptions.CfgS3LateRestore) { + for (i = 0; i < S3LATE_TABLE_SIZE; i++) { + LocateHeap.BufferHandle = S3LateHeapTable[i]; + if (HeapLocateBuffer (&LocateHeap, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) { + HeapBuffersPresent++; + HeapSize += LocateHeap.BufferSize; + HeapPtrs[i] = LocateHeap.BufferPtr; + HeapSizes[i] = LocateHeap.BufferSize; + } else { + HeapPtrs[i] = NULL; + HeapSizes[i] = 0; + } + } + + // Determine heap data size requirements + if (HeapBuffersPresent != 0) { + HeapSize += ((sizeof (HEAP_MANAGER)) + (HeapBuffersPresent * ((sizeof (BUFFER_NODE)) + (NUM_OF_SENTINEL * SIZE_OF_SENTINEL) + 0xF))); // reserve 0xF per buffer node for 16 byte alignment + } + + // Get non memory device list + GetNonMemoryRelatedDeviceList (&NonMemoryRelatedDeviceList, &AmdS3SaveParams->StdHeader); + + if (NonMemoryRelatedDeviceList != NULL) { + // Determine size needed + LateContextSize = GetWorstCaseContextSize (NonMemoryRelatedDeviceList, S3_LATE_RESTORE, &AmdS3SaveParams->StdHeader); + } + LateBufferSize = HeapSize + LateContextSize; + if (LateBufferSize != 0) { + LateBufferSize += sizeof (S3_VOLATILE_STORAGE_HEADER); + } + } + + if ((EarlyBufferSize != 0) || (LateBufferSize != 0)) { + // + // Allocate a buffer + // + AllocParams.RequestedBufferSize = EarlyBufferSize + LateBufferSize; + AllocParams.BufferHandle = AMD_S3_INFO_BUFFER_HANDLE; + AllocParams.Persist = 0; + AGESA_TESTPOINT (TpIfBeforeAllocateS3SaveBuffer, &AmdS3SaveParams->StdHeader); + if (HeapAllocateBuffer (&AllocParams, &AmdS3SaveParams->StdHeader) != AGESA_SUCCESS) { + if (AGESA_ERROR > ReturnStatus) { + ReturnStatus = AGESA_ERROR; + } + } + AGESA_TESTPOINT (TpIfAfterAllocateS3SaveBuffer, &AmdS3SaveParams->StdHeader); + + if (EarlyBufferSize != 0) { + AmdS3SaveParams->S3DataBlock.NvStorage = AllocParams.BufferPtr; + if (MemDataPointer != NULL) { + LibAmdMemCopy (AmdS3SaveParams->S3DataBlock.NvStorage, + MemDataPointer, + EarlyBufferSize, + &AmdS3SaveParams->StdHeader); + } else { + SaveDeviceListContext (MemoryRelatedDeviceList, + AmdS3SaveParams->S3DataBlock.NvStorage, + INIT_RESUME, + &EarlyBufferSize, + &AmdS3SaveParams->StdHeader); + } + } + AmdS3SaveParams->S3DataBlock.NvStorageSize = EarlyBufferSize; + + if (LateBufferSize != 0) { + BufferPointer = AllocParams.BufferPtr; + AmdS3SaveParams->S3DataBlock.VolatileStorage = &(BufferPointer[EarlyBufferSize]); + + ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapOffset = 0; + ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapSize = HeapSize; + ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataOffset = 0; + ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataSize = LateContextSize; + + if (HeapSize != 0) { + // Transfer heap contents + ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapOffset = sizeof (S3_VOLATILE_STORAGE_HEADER); + HeapPtr = (HEAP_MANAGER *) &BufferPointer[EarlyBufferSize + sizeof (S3_VOLATILE_STORAGE_HEADER)]; + HeapPtr->UsedSize = sizeof (HEAP_MANAGER); + HeapPtr->Signature = HEAP_SIGNATURE_VALID; + HeapPtr->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET; + HeapPtr->FirstFreeSpaceOffset = sizeof (HEAP_MANAGER); + FreeSpaceNode = (BUFFER_NODE *) ((UINT8 *) HeapPtr + sizeof (HEAP_MANAGER)); + FreeSpaceNode->BufferSize = HeapSize - sizeof (HEAP_MANAGER) - sizeof (BUFFER_NODE); + FreeSpaceNode->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET; + + HeapStatus = AmdS3SaveParams->StdHeader.HeapStatus; + AmdS3SaveParams->StdHeader.HeapStatus = HEAP_S3_RESUME; + AmdS3SaveParams->StdHeader.HeapBasePtr = (UINT64) (UINTN) HeapPtr; + + for (i = 0; i < S3LATE_TABLE_SIZE; i++) { + if (HeapPtrs[i] != NULL) { + HeapParams.RequestedBufferSize = HeapSizes[i]; // S3LateHeapTable[i].BufferLength; + HeapParams.BufferHandle = S3LateHeapTable[i]; + HeapParams.Persist = HEAP_S3_RESUME; + if (HeapAllocateBuffer (&HeapParams, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) { + LibAmdMemCopy ((VOID *) HeapParams.BufferPtr, HeapPtrs[i], HeapSizes[i], &AmdS3SaveParams->StdHeader); + } + } + } + + AmdS3SaveParams->StdHeader.HeapStatus = HeapStatus; + } + + + if (LateContextSize != 0) { + + ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataOffset = HeapSize + sizeof (S3_VOLATILE_STORAGE_HEADER); + + SaveDeviceListContext (NonMemoryRelatedDeviceList, + &(BufferPointer[EarlyBufferSize + HeapSize + sizeof (S3_VOLATILE_STORAGE_HEADER)]), + S3_LATE_RESTORE, + &LateContextSize, + &AmdS3SaveParams->StdHeader); + } + + AmdS3SaveParams->S3DataBlock.VolatileStorageSize = HeapSize + LateContextSize + sizeof (S3_VOLATILE_STORAGE_HEADER); + } + } + } + + AgesaStatus = BldoptFchFunction.InitLate (AmdS3SaveParams); + if (AgesaStatus > ReturnStatus) { + ReturnStatus = AgesaStatus; + } + IDS_OPTION_HOOK (IDS_AFTER_S3_SAVE, AmdS3SaveParams, &AmdS3SaveParams->StdHeader); + AGESA_TESTPOINT (TpIfAmdS3SaveExit, &AmdS3SaveParams->StdHeader); + return ReturnStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Constructor for the AMD_S3_SAVE function. + * + * This routine is responsible for setting default values for the + * input parameters needed by the AMD_S3_SAVE entry point. + * + * @param[in] StdHeader The standard header. + * @param[in,out] S3SaveParams Required input parameters for the AMD_S3_SAVE + * entry point. + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdS3SaveInitializer ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_S3SAVE_PARAMS *S3SaveParams + ) +{ + ASSERT (StdHeader != NULL); + ASSERT (S3SaveParams != NULL); + + S3SaveParams->StdHeader = *StdHeader; + + AmdS3ParamsInitializer (&S3SaveParams->S3DataBlock); + + AmdS3SavePlatformConfigInit (&S3SaveParams->PlatformConfig, &S3SaveParams->StdHeader); + BldoptFchFunction.InitLateConstructor (S3SaveParams); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Destructor for the AMD_S3_SAVE function. + * + * This routine is responsible for deallocation of heap space allocated during + * AMD_S3_SAVE entry point. + * + * @param[in] StdHeader The standard header. + * @param[in,out] S3SaveParams Required input parameters for the AMD_INIT_RESUME + * entry point. + * + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +AmdS3SaveDestructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_S3SAVE_PARAMS *S3SaveParams + ) +{ + AGESA_STATUS ReturnStatus; + AGESA_STATUS RetVal; + LOCATE_HEAP_PTR LocateHeap; + + ASSERT (S3SaveParams != NULL); + + ReturnStatus = AGESA_SUCCESS; + + // Deallocate heap space allocated during memory S3 save + LocateHeap.BufferHandle = AMD_MEM_S3_SAVE_HANDLE; + if (HeapLocateBuffer (&LocateHeap, StdHeader) == AGESA_SUCCESS) { + RetVal = HeapDeallocateBuffer (AMD_MEM_S3_SAVE_HANDLE, StdHeader); + } else { + RetVal = MemS3Deallocate (&S3SaveParams->StdHeader); + } + if (RetVal > ReturnStatus) { + ReturnStatus = RetVal; + } + + RetVal = HeapDeallocateBuffer (AMD_S3_NB_INFO_BUFFER_HANDLE, StdHeader); + if (RetVal > ReturnStatus) { + ReturnStatus = RetVal; + } + + RetVal = HeapDeallocateBuffer (AMD_S3_INFO_BUFFER_HANDLE, StdHeader); + if (RetVal > ReturnStatus) { + ReturnStatus = RetVal; + } + + return ReturnStatus; +} + +/*------------------------------------------------------------------------------------*/ +/** + * Initialize AmdS3Save stage platform profile and user option input. + * + * @param[in,out] PlatformConfig Platform profile/build option config structure + * @param[in,out] StdHeader AMD standard header config param + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +AmdS3SavePlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + CommonPlatformConfigInit (PlatformConfig, StdHeader); + + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonInits.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonInits.c new file mode 100644 index 0000000000..89471376bb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonInits.c @@ -0,0 +1,143 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Common initialization routines. + * + * Contains common initialization routines across AGESA entries of phases. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Common + * @e \$Revision: 85430 $ @e \$Date: 2013-01-07 20:52:33 -0600 (Mon, 07 Jan 2013) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Filecode.h" +#include "heapManager.h" +#include "CommonInits.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_COMMONINITS_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------------------*/ + +/** + * Common routine to initialize PLATFORM_CONFIGURATION. + * + * @param[in,out] PlatformConfig Platform profile/build option config structure + * @param[in,out] StdHeader AMD standard header config param + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +CommonPlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN i; + + PlatformConfig->PlatformProfile = UserOptions.CfgPerformanceProfile; + PlatformConfig->PlatformDeemphasisList = UserOptions.CfgPlatformDeemphasisList; + PlatformConfig->CoreLevelingMode = (UINT8) UserOptions.CfgCoreLevelingMode; + PlatformConfig->C1eMode = UserOptions.CfgPlatformC1eMode; + PlatformConfig->C1ePlatformData = UserOptions.CfgPlatformC1eOpData; + PlatformConfig->C1ePlatformData1 = UserOptions.CfgPlatformC1eOpData1; + PlatformConfig->C1ePlatformData2 = UserOptions.CfgPlatformC1eOpData2; + PlatformConfig->C1ePlatformData3 = UserOptions.CfgPlatformC1eOpData3; + PlatformConfig->CStateMode = UserOptions.CfgPlatformCStateMode; + PlatformConfig->CStatePlatformData = UserOptions.CfgPlatformCStateOpData; + PlatformConfig->CStateIoBaseAddress = UserOptions.CfgPlatformCStateIoBaseAddress; + PlatformConfig->CpbMode = UserOptions.CfgPlatformCpbMode; + PlatformConfig->UserOptionDmi = UserOptions.OptionDmi; + PlatformConfig->UserOptionPState = UserOptions.OptionAcpiPstates; + PlatformConfig->UserOptionCrat = UserOptions.OptionCrat; + PlatformConfig->UserOptionCdit = UserOptions.OptionCdit; + PlatformConfig->UserOptionSrat = UserOptions.OptionSrat; + PlatformConfig->UserOptionSlit = UserOptions.OptionSlit; + PlatformConfig->UserOptionWhea = UserOptions.OptionWhea; + PlatformConfig->LowPowerPstateForProcHot = UserOptions.CfgLowPowerPstateForProcHot; + PlatformConfig->PowerCeiling = UserOptions.CfgAmdPowerCeiling; + PlatformConfig->HtcTemperatureLimit = UserOptions.CfgHtcTemperatureLimit; + PlatformConfig->LhtcTemperatureLimit = UserOptions.CfgLhtcTemperatureLimit; + PlatformConfig->ForcePstateIndependent = UserOptions.CfgAcpiPstateIndependent; + PlatformConfig->PstatesPsdPolicy = UserOptions.CfgAcpiPstatesPsdPolicy; + PlatformConfig->PStatesInHpcMode = UserOptions.OptionPStatesInHpcMode; + PlatformConfig->NumberOfIoApics = UserOptions.CfgPlatNumIoApics; + for (i = 0; i < MaxVrmType; i++) { + PlatformConfig->VrmProperties[i] = UserOptions.CfgPlatVrmCfg[i]; + } + PlatformConfig->ProcessorScopeInSb = UserOptions.CfgProcessorScopeInSb; + PlatformConfig->ProcessorScopeName0 = UserOptions.CfgProcessorScopeName0; + PlatformConfig->ProcessorScopeName1 = UserOptions.CfgProcessorScopeName1; + PlatformConfig->GnbHdAudio = UserOptions.CfgGnbHdAudio; + PlatformConfig->AbmSupport = UserOptions.CfgAbmSupport; + PlatformConfig->DynamicRefreshRate = UserOptions.CfgDynamicRefreshRate; + PlatformConfig->LcdBackLightControl = UserOptions.CfgLcdBackLightControl; + if ((StdHeader->HeapStatus == HEAP_LOCAL_CACHE) || + (StdHeader->HeapStatus == HEAP_TEMP_MEM) || + (StdHeader->HeapStatus == HEAP_SYSTEM_MEM)) { + IDS_OPTION_HOOK (IDS_PLATFORMCFG_OVERRIDE, PlatformConfig, StdHeader); + } + return AGESA_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonInits.h b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonInits.h new file mode 100644 index 0000000000..d08cbf87ea --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonInits.h @@ -0,0 +1,65 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Common initialization routines. + * + * Contains common initialization routines across AGESA entries of phases. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Common + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _COMMON_INITS_H_ +#define _COMMON_INITS_H_ + +/** + * Common routine to initialize PLATFORM_CONFIGURATION. + * + * @param[in,out] PlatformConfig Platform profile/build option config structure + * @param[in,out] StdHeader AMD standard header config param + * + * @retval AGESA_SUCCESS Always Succeeds. + * + */ +AGESA_STATUS +CommonPlatformConfigInit ( + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _COMMON_INITS_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonReturns.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonReturns.c new file mode 100644 index 0000000000..ec1dadf989 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CommonReturns.c @@ -0,0 +1,262 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Common Return routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Common + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "Ids.h" +#include "Filecode.h" +#include "CommonReturns.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_COMMONRETURNS_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +CommonFchInitStub ( + IN VOID *DataPtr + ); + +VOID +FchTaskDummy ( + IN VOID *DataPtr + ); + +/*----------------------------------------------------------------------------------------*/ +/** +* Return TRUE. +* +* @retval TRUE Default case, no special action +*/ +BOOLEAN +CommonReturnTrue ( VOID ) +{ + return TRUE; +} + + +/*----------------------------------------------------------------------------------------*/ +/** +* Return False. +* +* @retval FALSE Default case, no special action +*/ +BOOLEAN +CommonReturnFalse ( VOID ) +{ + return FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return (UINT8)zero. + * + * + * @retval zero None, or only case zero. + */ +UINT8 +CommonReturnZero8 ( VOID ) +{ + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return (UINT32)zero. + * + * + * @retval zero None, or only case zero. + */ +UINT32 +CommonReturnZero32 ( VOID ) +{ + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return (UINT64)zero. + * + * + * @retval zero None, or only case zero. + */ +UINT64 +CommonReturnZero64 ( VOID ) +{ + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return (UINT8)one. + * + * + * @retval one None, or only case one. + */ +UINT8 +CommonReturnOne8 ( VOID ) +{ + return 1; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return (UINT32)one. + * + * + * @retval one None, or only case one. + */ +UINT32 +CommonReturnOne32 ( VOID ) +{ + return 1; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return (UINT64)one. + * + * + * @retval one None, or only case one. + */ +UINT64 +CommonReturnOne64 ( VOID ) +{ + return 1; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Return NULL + * + * @retval NULL pointer to nothing + */ +VOID * +CommonReturnNULL ( VOID ) +{ + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** +* Return AGESA_SUCCESS. +* +* @retval AGESA_SUCCESS Success. +*/ +AGESA_STATUS +CommonReturnAgesaSuccess ( VOID ) +{ + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** +* Return AGESA_ERROR. +* +* @retval AGESA_ERROR Error. +*/ +AGESA_STATUS +CommonReturnAgesaError ( VOID ) +{ + return AGESA_ERROR; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Do Nothing. + * + */ +VOID +CommonVoid ( VOID ) +{ +} + +/*----------------------------------------------------------------------------------------*/ +/** + * ASSERT if this routine is called. + * + */ +VOID +CommonAssert ( VOID ) +{ + ASSERT (FALSE); +} + + +/*----------------------------------------------------------------------------------------*/ +/** +* Return AGESA_SUCCESS. +* +* @retval AGESA_SUCCESS Success. +*/ +AGESA_STATUS +CommonFchInitStub ( + IN VOID *DataPtr + ) +{ + return AGESA_SUCCESS; +} + + +VOID +FchTaskDummy ( + IN VOID *DataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/CreateStruct.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CreateStruct.c new file mode 100644 index 0000000000..8468d3be35 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CreateStruct.c @@ -0,0 +1,313 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Input Structure Creation + * + * Contains AGESA input structure creation support. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Common + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "GeneralServices.h" +#include "heapManager.h" +#include "CreateStruct.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_CREATESTRUCT_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern CONST FUNCTION_PARAMS_INFO FuncParamsInfo[]; +extern CONST UINTN InitializerCount; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------*/ +/** + * Allocate and initialize Config headers and Service Interface structures. + * + * This function will be called for each AGESA public APIs. + * This function will do the following: + * -# Locate the AGESA API structure parameters initializer function information. + * -# Find the size of the structure that gets passed to each public APIs as + * the entry parameter. Allocate heap space using the size for PreMemHeap, callout for + * memory allocation for PostMemDram, and just set the config and service interface + * pointers for ByHost. + * -# If the allocation is not ByHost, copy the AmdConfigParams into the newly created AmdConfigParams. + * For ByHost, we're using the caller's existing config params. + * -# Call the initializer function, and pass a reference to the Config params and to + * the Service Interface struct. On return the constructor will have filled the + * remaining structure with default values. + * -# Fill the remaining info in the newly created structure on heap in AMD_CONFIG_PARAMS + * area (i.e. Fill *newStructPtr with the pointer to the newly created structure) + * -# Set the appropriate AGESA function number in the StdHeader member of the input + * parameter structure. + * + * @param[in,out] InterfaceParams Pointer to structure containing the function call + * whose parameter structure is to be created, the + * allocation method, and a pointer to the newly + * created structure. + * + * @retval AGESA_SUCCESS The interface struct is allocated and initialized. + * @retval AGESA_UNSUPPORTED The Service is not supported. + * + */ +AGESA_STATUS +AmdCreateStruct ( + IN OUT AMD_INTERFACE_PARAMS *InterfaceParams + ) +{ + UINTN ServiceIndex; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + AMD_CONFIG_PARAMS *NewlyCreatedConfig; + VOID *NewlyCreatedServiceInterface; + AGESA_STATUS AgesaStatus; + AGESA_STATUS TempStatus; + AGESA_STATUS IgnoredSts; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + AgesaStatus = AGESA_SUCCESS; + + ASSERT (InterfaceParams != NULL); + + switch (InterfaceParams->AgesaFunctionName) { + case AMD_INIT_RESET: + if (!IsBsp (&InterfaceParams->StdHeader, &IgnoredSts)) { + // APs must transfer their system core number from the mailbox to + // a local register while it is still valid. + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &InterfaceParams->StdHeader); + FamilySpecificServices->TransferApCoreNumber (FamilySpecificServices, &InterfaceParams->StdHeader); + } + InterfaceParams->StdHeader.HeapStatus = HEAP_DO_NOT_EXIST_YET; + break; + case AMD_INIT_EARLY: + case AMD_INIT_RECOVERY: + case AMD_INIT_RESUME: + case AMD_INIT_POST: + InterfaceParams->StdHeader.HeapStatus = HEAP_LOCAL_CACHE; + break; + case AMD_INIT_ENV: + InterfaceParams->StdHeader.HeapStatus = HEAP_TEMP_MEM; + break; + case AMD_INIT_LATE: + case AMD_INIT_MID: + case AMD_S3_SAVE: + case AMD_LATE_RUN_AP_TASK: + InterfaceParams->StdHeader.HeapStatus = HEAP_SYSTEM_MEM; + break; + case AMD_S3LATE_RESTORE: + InterfaceParams->StdHeader.HeapStatus = HEAP_S3_RESUME; + break; + default: + ASSERT (FALSE); + InterfaceParams->StdHeader.HeapStatus = HEAP_LOCAL_CACHE; + break; + } + + InterfaceParams->StdHeader.HeapBasePtr = HeapGetBaseAddress (&InterfaceParams->StdHeader); + + if (InterfaceParams->AgesaFunctionName == AMD_INIT_RESET) { + AgesaStatus = HeapManagerInit (&InterfaceParams->StdHeader); + } + + // Step 1 + for (ServiceIndex = 0; ServiceIndex < InitializerCount; ServiceIndex++) { + if (FuncParamsInfo[ServiceIndex].AgesaFunctionName == InterfaceParams->AgesaFunctionName) { + break; + } + } + if (ServiceIndex >= InitializerCount) { + // A call was made to AGESA with an invalid function number. This wrapper error may be due to the build target + // not containing the desired entry point. + return AGESA_UNSUPPORTED; + } + + // Step 2 + LibAmdMemFill (&AllocHeapParams, 0, (UINTN) (sizeof (ALLOCATE_HEAP_PARAMS)), &InterfaceParams->StdHeader); + + if (InterfaceParams->AllocationMethod < ByHost) { + // Allocate one buffer to contain the config params and the service struct. + // The service struct begins immediately after the config params. + AllocHeapParams.RequestedBufferSize = FuncParamsInfo[ServiceIndex].CreateStructSize + sizeof (AMD_CONFIG_PARAMS); + AllocHeapParams.BufferHandle = FuncParamsInfo[ServiceIndex].BufferHandle; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + TempStatus = HeapAllocateBuffer (&AllocHeapParams, &(InterfaceParams->StdHeader)); + AgesaStatus = ((AgesaStatus > TempStatus) ? AgesaStatus : TempStatus); + NewlyCreatedConfig = (AMD_CONFIG_PARAMS *)AllocHeapParams.BufferPtr; + NewlyCreatedConfig++; + NewlyCreatedServiceInterface = NewlyCreatedConfig; + NewlyCreatedConfig = (AMD_CONFIG_PARAMS *)AllocHeapParams.BufferPtr; + } else { + // The caller (example, agesa basic interface implementation) already has a buffer to use. + NewlyCreatedConfig = (AMD_CONFIG_PARAMS *)InterfaceParams; + NewlyCreatedServiceInterface = InterfaceParams->NewStructPtr; + ASSERT (InterfaceParams->NewStructSize >= FuncParamsInfo[ServiceIndex].CreateStructSize); + } + ASSERT (NewlyCreatedConfig != NULL); + ASSERT (NewlyCreatedServiceInterface != NULL); + + // Step 3 + if (InterfaceParams->AllocationMethod != ByHost) { + *NewlyCreatedConfig = InterfaceParams->StdHeader; + } + + // Step 4 + TempStatus = FuncParamsInfo[ServiceIndex].AgesaFunction (NewlyCreatedConfig, NewlyCreatedServiceInterface); + AgesaStatus = ((AgesaStatus > TempStatus) ? AgesaStatus : TempStatus); + + // Step 5 + if (InterfaceParams->AllocationMethod != ByHost) { + InterfaceParams->NewStructPtr = (VOID *) NewlyCreatedServiceInterface; + InterfaceParams->NewStructSize = FuncParamsInfo[ServiceIndex].CreateStructSize; + } + + // Step 6 + ((AMD_CONFIG_PARAMS *) InterfaceParams->NewStructPtr)->Func = InterfaceParams->AgesaFunctionName; + return AgesaStatus; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Clears storage space from allocation for a parameter block of an + * AGESA software call entry. + * + * @param[in,out] InterfaceParams Pointer to structure containing the function call + * whose parameter structure is to be deallocated. + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +AmdReleaseStruct ( + IN OUT AMD_INTERFACE_PARAMS *InterfaceParams + ) +{ + UINT8 i; + UINT8 *BufferPtr; + VOID *ServicePtr; + AGESA_STATUS AgesaStatus; + AGESA_STATUS TempStatus; + LOCATE_HEAP_PTR LocHeap; + + AgesaStatus = AGESA_SUCCESS; + + switch (InterfaceParams->AgesaFunctionName) { + case AMD_INIT_RESET: + case AMD_INIT_EARLY: + case AMD_INIT_RECOVERY: + case AMD_INIT_RESUME: + InterfaceParams->StdHeader.HeapStatus = HEAP_LOCAL_CACHE; + break; + case AMD_INIT_POST: + InterfaceParams->StdHeader.HeapStatus = HEAP_TEMP_MEM; + break; + case AMD_INIT_ENV: + case AMD_INIT_LATE: + case AMD_INIT_MID: + case AMD_S3_SAVE: + case AMD_LATE_RUN_AP_TASK: + InterfaceParams->StdHeader.HeapStatus = HEAP_SYSTEM_MEM; + break; + case AMD_S3LATE_RESTORE: + InterfaceParams->StdHeader.HeapStatus = HEAP_S3_RESUME; + break; + default: + ASSERT (FALSE); + InterfaceParams->StdHeader.HeapStatus = HEAP_LOCAL_CACHE; + break; + } + + InterfaceParams->StdHeader.HeapBasePtr = HeapGetBaseAddress (&InterfaceParams->StdHeader); + +// Step 1 + for (i = 0; i < InitializerCount; i++) { + if (FuncParamsInfo[i].AgesaFunctionName == InterfaceParams->AgesaFunctionName) { + break; + } + } + if (i >= InitializerCount) { + return AGESA_BOUNDS_CHK; + } + + // Step 2 + if (InterfaceParams->AllocationMethod < ByHost) { + LocHeap.BufferHandle = FuncParamsInfo[i].BufferHandle; + if (HeapLocateBuffer (&LocHeap, &(InterfaceParams->StdHeader)) == AGESA_SUCCESS) { + BufferPtr = (UINT8 *) LocHeap.BufferPtr; + ServicePtr = &BufferPtr[sizeof (AMD_CONFIG_PARAMS)]; + TempStatus = FuncParamsInfo[i].AgesaDestructor (&(InterfaceParams->StdHeader), ServicePtr); + AgesaStatus = ((AgesaStatus > TempStatus) ? AgesaStatus : TempStatus); + } + } + + // Step 3 + if (InterfaceParams->AllocationMethod < ByHost) { + TempStatus = HeapDeallocateBuffer (FuncParamsInfo[i].BufferHandle, &(InterfaceParams->StdHeader)); + AgesaStatus = ((AgesaStatus > TempStatus) ? AgesaStatus : TempStatus); + } else { + // Unless we define service specific destructors, nothing to do for ByHost. + return AGESA_SUCCESS; + } + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/CreateStruct.h b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CreateStruct.h new file mode 100644 index 0000000000..6b67f5fa38 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/CreateStruct.h @@ -0,0 +1,195 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD AGESA Input Structure Creation + * + * Contains AGESA input creation structures. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Common + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + +#ifndef _CREATE_STRUCT_H_ +#define _CREATE_STRUCT_H_ + +/** + * A constructor method. + * + * Sets inputs to valid, basic level, defaults for the specific service instance. + * Constructors should avoid using the header, since these routines should not + * do operations which may fail or require status back to the user. The constructor + * should always SUCCEED. + * + * @param[in] StdHeader Opaque handle to standard config header + * @param[in] ServiceInterface Service Interface structure to initialize. + * + * @retval AGESA_SUCCESS Constructors are not allowed to fail +*/ +typedef AGESA_STATUS +F_AGESA_FUNCTION ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ServiceInterface + ); + +/// Reference to a Method. +typedef F_AGESA_FUNCTION *PF_AGESA_FUNCTION; + +/** + * A Destructor method. + * + * Sets inputs to valid, basic level, defaults for the specific service instance. + * The constructor should always SUCCEED. + * + * @param[in] StdHeader Opaque handle to standard config header. + * @param[in] ServiceInterface Service Interface structure to initialize. + * + * @retval AGESA_SUCCESS Constructors are not allowed to fail +*/ +typedef AGESA_STATUS +F_AGESA_DESTRUCTOR ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ServiceInterface + ); + +/// Reference to a Method. +typedef F_AGESA_DESTRUCTOR *PF_AGESA_DESTRUCTOR; + +/** + * Provide the information needed to invoke each service constructor. + */ +typedef struct { + IN AGESA_STRUCT_NAME AgesaFunctionName; ///< Identifies the service + IN UINT16 CreateStructSize; ///< The service's input struct size. + /// Do NOT include a config params header! + OUT PF_AGESA_FUNCTION AgesaFunction; ///< The constructor function + OUT PF_AGESA_DESTRUCTOR AgesaDestructor; ///< The destructor function. + IN AGESA_BUFFER_HANDLE BufferHandle; ///< The buffer handle id for the service. +} FUNCTION_PARAMS_INFO; + +/** + * All available services have their constructor info here. + */ +AGESA_STATUS +AmdInitResetConstructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_RESET_PARAMS *AmdResetParams + ); + +AGESA_STATUS +AmdInitRecoveryInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_RECOVERY_PARAMS *AmdRecoveryParamsPtr + ); + +AGESA_STATUS +AmdInitEarlyInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_EARLY_PARAMS *EarlyParams + ); + +AGESA_STATUS +AmdInitPostInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_POST_PARAMS *PostParamsPtr + ); + +AGESA_STATUS +AmdInitPostDestructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_POST_PARAMS *PostParamsPtr + ); + +AGESA_STATUS +AmdInitEnvInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_ENV_PARAMS *EnvParamsPtr + ); + +AGESA_STATUS +AmdInitMidInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_MID_PARAMS *MidParamsPtr + ); + +AGESA_STATUS +AmdInitLateInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_LATE_PARAMS *LateParamsPtr + ); + +AGESA_STATUS +AmdInitLateDestructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_LATE_PARAMS *LateParamsPtr + ); + +AGESA_STATUS +AmdInitResumeInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_RESUME_PARAMS *ResumeParams + ); + +AGESA_STATUS +AmdInitResumeDestructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_RESUME_PARAMS *ResumeParams + ); + +AGESA_STATUS +AmdS3SaveInitializer ( + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_S3SAVE_PARAMS *S3SaveParams + ); + +AGESA_STATUS +AmdS3SaveDestructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_S3SAVE_PARAMS *S3SaveParams + ); + +AGESA_STATUS +AmdS3LateRestoreInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AMD_S3LATE_PARAMS *S3LateParams + ); + +AGESA_STATUS +AmdLateRunApTaskInitializer ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT AP_EXE_PARAMS *AmdApExeParams + ); +#endif // _CREATE_STRUCT_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3RestoreState.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3RestoreState.c new file mode 100644 index 0000000000..9da575cb2b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3RestoreState.c @@ -0,0 +1,441 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * S3 save/restore script + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "Porting.h" +#include "AMD.h" +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "S3SaveState.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_COMMON_S3RESTORESTATE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +extern S3_SCRIPT_CONFIGURATION OptionS3ScriptConfiguration; +extern S3_DISPATCH_FUNCTION_ENTRY S3DispatchFunctionTable[]; +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +AGESA_STATUS +STATIC +S3RestoreStateFromTable ( + IN S3_SAVE_TABLE_HEADER *S3SaveTablePtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] StdHeader Pointer to standard header + */ +AGESA_STATUS +S3ScriptRestore ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return OptionS3ScriptConfiguration.Restore (StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] StdHeader Pointer to standard header + */ +AGESA_STATUS +S3ScriptRestoreStateStub ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] StdHeader Pointer to standard header + */ +AGESA_STATUS +S3ScriptRestoreState ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + S3_SAVE_TABLE_HEADER *S3SaveTablePtr; + Status = S3ScriptGetS3SaveTable (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + IDS_ERROR_TRAP; + return AGESA_FATAL; + } + S3SaveTablePtr->Locked = TRUE; + Status = S3RestoreStateFromTable (S3SaveTablePtr, StdHeader); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] S3SaveTablePtr Pointer to S3 Save Table + * @param[in] StdHeader Pointer to standard header + */ +AGESA_STATUS +STATIC +S3RestoreStateFromTable ( + IN S3_SAVE_TABLE_HEADER *S3SaveTablePtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + VOID *S3SaveTableRecordPtr; + PCI_ADDR PciAddress; + UINTN Index; + S3SaveTableRecordPtr = (UINT8 *) S3SaveTablePtr + sizeof (S3_SAVE_TABLE_HEADER); + IDS_HDT_CONSOLE (S3_TRACE, "Start S3 restore\n", ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address); + while ((UINT8 *) S3SaveTableRecordPtr < ((UINT8 *) S3SaveTablePtr + S3SaveTablePtr->SaveOffset)) { + switch (*(UINT16 *) S3SaveTableRecordPtr) { + case SAVE_STATE_IO_WRITE_OPCODE: + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT16) ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray (StdHeader, (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_WRITE_OP_HEADER), 1, ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + LibAmdIoWrite ( + ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width, + (UINT16) ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_WRITE_OP_HEADER), + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_WRITE_OP_HEADER) + + LibAmdAccessWidth (((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + case SAVE_STATE_IO_READ_WRITE_OPCODE: + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT16) ((S3_READ_WRITE_OP_HEADER*) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER), + 1, + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, " Mask: "); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER) + LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width), + 1, + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + LibAmdIoRMW ( + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width, + (UINT16) ((S3_READ_WRITE_OP_HEADER*) S3SaveTableRecordPtr)->Address, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER), + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER) + LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width), + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_READ_WRITE_OP_HEADER) + + 2 * LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + case SAVE_STATE_MEM_WRITE_OPCODE: + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT16) ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray (StdHeader, (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_WRITE_OP_HEADER), 1, ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + LibAmdMemWrite ( + ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width, + ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_WRITE_OP_HEADER), + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_WRITE_OP_HEADER) + + LibAmdAccessWidth (((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + case SAVE_STATE_MEM_READ_WRITE_OPCODE: + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT16) ((S3_READ_WRITE_OP_HEADER*) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER), + 1, + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, " Mask: "); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER) + LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width), + 1, + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + LibAmdMemRMW ( + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width, + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER), + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER) + LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER*) S3SaveTableRecordPtr)->Width), + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_READ_WRITE_OP_HEADER) + + 2 * LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + case SAVE_STATE_PCI_CONFIG_WRITE_OPCODE: + PciAddress.AddressValue = (UINT32) ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address; + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT16) ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray (StdHeader, (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_WRITE_OP_HEADER), 1, ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + LibAmdPciWrite ( + ((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width, + PciAddress, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_WRITE_OP_HEADER), + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_WRITE_OP_HEADER) + + LibAmdAccessWidth (((S3_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + case SAVE_STATE_PCI_CONFIG_READ_WRITE_OPCODE: + PciAddress.AddressValue = (UINT32) ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Address; + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT16) ((S3_READ_WRITE_OP_HEADER*) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER), + 1, + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, " Mask: "); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER) + LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width), + 1, + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + LibAmdPciRMW ( + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width, + PciAddress, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER), + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_READ_WRITE_OP_HEADER) + LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width), + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_READ_WRITE_OP_HEADER) + + 2 * LibAmdAccessWidth (((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + case SAVE_STATE_STALL_OPCODE: + break; + case SAVE_STATE_INFORMATION_OPCODE: + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: Info: [%s]\n", (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_INFO_OP_HEADER)); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_INFO_OP_HEADER) + + ((S3_INFO_OP_HEADER*) S3SaveTableRecordPtr)->Length; + break; + case SAVE_STATE_DISPATCH_OPCODE: + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Function Id: 0x%02x, Context: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), ((S3_DISPATCH_OP_HEADER*) S3SaveTableRecordPtr)->FunctionId); + S3SaveDebugPrintHexArray ( + StdHeader, + (VOID*)((UINT8*) S3SaveTableRecordPtr + sizeof (S3_DISPATCH_OP_HEADER)), + ((S3_DISPATCH_OP_HEADER*) S3SaveTableRecordPtr)->Length, + AccessWidth8); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + Index = 0; + while (S3DispatchFunctionTable[Index].FunctionId != 0) { + if (S3DispatchFunctionTable[Index].FunctionId == ((S3_DISPATCH_OP_HEADER*) S3SaveTableRecordPtr)->FunctionId) { + (S3DispatchFunctionTable[Index].Function) ( + StdHeader, + ((S3_DISPATCH_OP_HEADER*) S3SaveTableRecordPtr)->Length, + (VOID*)((UINT8*) S3SaveTableRecordPtr + sizeof (S3_DISPATCH_OP_HEADER)) + ); + break; + } + Index++; + } + ASSERT (S3DispatchFunctionTable[Index].FunctionId != 0); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_DISPATCH_OP_HEADER) + + ((S3_DISPATCH_OP_HEADER*) S3SaveTableRecordPtr)->Length; + break; + + case SAVE_STATE_IO_POLL_OPCODE: + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%04x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT16) ((S3_POLL_OP_HEADER*) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER), + 1, + ((S3_READ_WRITE_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, " Mask: "); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER) + LibAmdAccessWidth (((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width), + 1, + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + ) + LibAmdIoPoll ( + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width, + (UINT16) ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Address, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER), + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER) + LibAmdAccessWidth (((S3_POLL_OP_HEADER*) S3SaveTableRecordPtr)->Width), + ((S3_POLL_OP_HEADER*) S3SaveTableRecordPtr)->Delay, + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_POLL_OP_HEADER) + + 2 * LibAmdAccessWidth (((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + case SAVE_STATE_MEM_POLL_OPCODE: + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT32) ((S3_POLL_OP_HEADER*) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER), + 1, + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, " Mask: "); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER) + LibAmdAccessWidth (((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width), + 1, + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + ) + LibAmdMemPoll ( + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width, + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Address, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER), + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER) + LibAmdAccessWidth (((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width), + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Delay, + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_POLL_OP_HEADER) + + 2 * LibAmdAccessWidth (((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + case SAVE_STATE_PCI_CONFIG_POLL_OPCODE: + PciAddress.AddressValue = (UINT32) ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Address; + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Restore: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, *(UINT16 *) S3SaveTableRecordPtr), (UINT32) ((S3_POLL_OP_HEADER*) S3SaveTableRecordPtr)->Address); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER), + 1, + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + IDS_HDT_CONSOLE (S3_TRACE, " Mask: "); + S3SaveDebugPrintHexArray ( + StdHeader, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER) + LibAmdAccessWidth (((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width), + 1, + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width + ); + ) + LibAmdPciPoll ( + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width, + PciAddress, + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER), + (UINT8 *) S3SaveTableRecordPtr + sizeof (S3_POLL_OP_HEADER) + LibAmdAccessWidth (((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width), + ((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Delay, + StdHeader + ); + S3SaveTableRecordPtr = (UINT8 *) S3SaveTableRecordPtr + + sizeof (S3_POLL_OP_HEADER) + + 2 * LibAmdAccessWidth (((S3_POLL_OP_HEADER *) S3SaveTableRecordPtr)->Width); + break; + default: + IDS_HDT_CONSOLE (S3_TRACE, " ERROR!!! Invalid S3 restore opcode\n"); + ASSERT (FALSE); + return AGESA_ERROR; + } + } + IDS_HDT_CONSOLE (S3_TRACE, " End S3 Restore \n"); + return AGESA_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3SaveState.c b/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3SaveState.c new file mode 100644 index 0000000000..c81c877742 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3SaveState.c @@ -0,0 +1,651 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * S3 save/restore script + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "Porting.h" +#include "AMD.h" +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "S3SaveState.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_COMMON_S3SAVESTATE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +extern S3_SCRIPT_CONFIGURATION OptionS3ScriptConfiguration; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +S3SaveStateExtendTableLenth ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT S3_SAVE_TABLE_HEADER **S3SaveTable + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] StdHeader Pointer to standard header + */ +AGESA_STATUS +S3ScriptInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return OptionS3ScriptConfiguration.Init (StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] StdHeader Pointer to standard header + */ +AGESA_STATUS +S3ScriptInitStateStub ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] StdHeader Pointer to standard header + */ +AGESA_STATUS +S3ScriptInitState ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + AllocHeapParams.RequestedBufferSize = S3_TABLE_LENGTH; + AllocHeapParams.BufferHandle = AMD_S3_SCRIPT_SAVE_TABLE_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + Status = HeapAllocateBuffer (&AllocHeapParams, StdHeader); + if (Status == AGESA_SUCCESS) { + ((S3_SAVE_TABLE_HEADER *) AllocHeapParams.BufferPtr)->TableLength = S3_TABLE_LENGTH; + ((S3_SAVE_TABLE_HEADER *) AllocHeapParams.BufferPtr)->SaveOffset = sizeof (S3_SAVE_TABLE_HEADER); + ((S3_SAVE_TABLE_HEADER *) AllocHeapParams.BufferPtr)->Locked = FALSE; + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[in,out] S3SaveTable S3 save table header + */ +AGESA_STATUS +S3SaveStateExtendTableLenth ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT S3_SAVE_TABLE_HEADER **S3SaveTable + ) +{ + AGESA_STATUS Status; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + VOID *TempBuffer; + UINT16 NewTableLength; + UINT16 CurrentTableLength; + //Allocate temporary buffer + NewTableLength = (*S3SaveTable)->TableLength + S3_TABLE_LENGTH_INCREMENT; + AllocHeapParams.RequestedBufferSize = NewTableLength; + AllocHeapParams.BufferHandle = AMD_S3_SCRIPT_TEMP_BUFFER_HANDLE; + AllocHeapParams.Persist = StdHeader->HeapStatus; + Status = HeapAllocateBuffer (&AllocHeapParams, StdHeader); + if (Status != AGESA_SUCCESS) { + return Status; + } + //Save current table length + CurrentTableLength = (*S3SaveTable)->TableLength; + //Update table length + (*S3SaveTable)->TableLength = NewTableLength; + //Copy S3 save toable to temporary location + LibAmdMemCopy (AllocHeapParams.BufferPtr, *S3SaveTable, CurrentTableLength, StdHeader); + //Save pointer to temp buffer + TempBuffer = AllocHeapParams.BufferPtr; + // Free original S3 save buffer + HeapDeallocateBuffer (AMD_S3_SCRIPT_SAVE_TABLE_HANDLE, StdHeader); + + AllocHeapParams.RequestedBufferSize = NewTableLength; + AllocHeapParams.BufferHandle = AMD_S3_SCRIPT_SAVE_TABLE_HANDLE; + AllocHeapParams.Persist = StdHeader->HeapStatus; + Status = HeapAllocateBuffer (&AllocHeapParams, StdHeader); + if (Status != AGESA_SUCCESS) { + return Status; + } + LibAmdMemCopy (AllocHeapParams.BufferPtr, TempBuffer, AllocHeapParams.RequestedBufferSize, StdHeader); + *S3SaveTable = (S3_SAVE_TABLE_HEADER*) AllocHeapParams.BufferPtr; + HeapDeallocateBuffer (AMD_S3_SCRIPT_TEMP_BUFFER_HANDLE, StdHeader); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize S3 Script framework + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[out] S3SaveTable S3 save table header + */ +AGESA_STATUS +S3ScriptGetS3SaveTable ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT S3_SAVE_TABLE_HEADER **S3SaveTable + ) +{ + AGESA_STATUS Status; + LOCATE_HEAP_PTR LocHeapParams; + LocHeapParams.BufferHandle = AMD_S3_SCRIPT_SAVE_TABLE_HANDLE; + Status = HeapLocateBuffer (&LocHeapParams, StdHeader); + if (Status != AGESA_SUCCESS) { + *S3SaveTable = NULL; + return Status; + } + *S3SaveTable = (S3_SAVE_TABLE_HEADER *) LocHeapParams.BufferPtr; + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Save S3 write opcode + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[in] OpCode Operation opcode + * @param[in] Width Width + * @param[in] Address Register address + * @param[in] Count Number of register writes + * @param[in] Buffer Pointer to write buffer + */ +AGESA_STATUS +S3SaveStateSaveWriteOp ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 OpCode, + IN ACCESS_WIDTH Width, + IN UINT64 Address, + IN UINT32 Count, + IN VOID *Buffer + ) +{ + S3_SAVE_TABLE_HEADER *S3SaveTablePtr; + S3_WRITE_OP_HEADER *SaveOffsetPtr; + UINT32 OpCodeLength; + UINT32 WidthLength; + AGESA_STATUS Status; + + Status = S3ScriptGetS3SaveTable (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + if (S3SaveTablePtr->Locked) { + return AGESA_UNSUPPORTED; + } + WidthLength = LibAmdAccessWidth (Width); + OpCodeLength = sizeof (S3_WRITE_OP_HEADER) + WidthLength * Count; + if ((S3SaveTablePtr->SaveOffset + OpCodeLength) > S3SaveTablePtr->TableLength) { + Status = S3SaveStateExtendTableLenth (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + } + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Save: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, OpCode), Address); + S3SaveDebugPrintHexArray (StdHeader, Buffer, Count, Width); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + SaveOffsetPtr = (S3_WRITE_OP_HEADER *) ((UINT8 *) S3SaveTablePtr + S3SaveTablePtr->SaveOffset); + SaveOffsetPtr->OpCode = OpCode; + SaveOffsetPtr->Width = Width; + SaveOffsetPtr->Count = Count; + SaveOffsetPtr->Address = Address; + LibAmdMemCopy ( + (UINT8 *) SaveOffsetPtr + sizeof (S3_WRITE_OP_HEADER), + Buffer, + WidthLength * Count, + StdHeader + ); + S3SaveTablePtr->SaveOffset += OpCodeLength; + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Save S3 write opcode + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[in] OpCode Operation opcode + * @param[in] Width Width + * @param[in] Address Register address + * @param[in] Data Pointer to data + * @param[in] DataMask Pointer data mask + */ +AGESA_STATUS +S3SaveStateSaveReadWriteOp ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 OpCode, + IN ACCESS_WIDTH Width, + IN UINT64 Address, + IN VOID *Data, + IN VOID *DataMask + ) +{ + + S3_SAVE_TABLE_HEADER *S3SaveTablePtr; + S3_READ_WRITE_OP_HEADER *SaveOffsetPtr; + UINT32 OpCodeLength; + UINT32 WidthLength; + AGESA_STATUS Status; + + Status = S3ScriptGetS3SaveTable (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + if (S3SaveTablePtr->Locked) { + return AGESA_UNSUPPORTED; + } + WidthLength = LibAmdAccessWidth (Width); + OpCodeLength = sizeof (S3_READ_WRITE_OP_HEADER) + WidthLength * 2; + if ((S3SaveTablePtr->SaveOffset + OpCodeLength) > S3SaveTablePtr->TableLength) { + Status = S3SaveStateExtendTableLenth (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + } + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Save: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, OpCode), Address); + S3SaveDebugPrintHexArray (StdHeader, Data, 1, Width); + IDS_HDT_CONSOLE (S3_TRACE, " Mask: "); + S3SaveDebugPrintHexArray (StdHeader, DataMask, 1, Width); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + SaveOffsetPtr = (S3_READ_WRITE_OP_HEADER *) ((UINT8 *) S3SaveTablePtr + S3SaveTablePtr->SaveOffset); + SaveOffsetPtr->OpCode = OpCode; + SaveOffsetPtr->Width = Width; + SaveOffsetPtr->Address = Address; + + LibAmdMemCopy ( + (UINT8 *) SaveOffsetPtr + sizeof (S3_READ_WRITE_OP_HEADER), + Data, + WidthLength, + StdHeader + ); + LibAmdMemCopy ( + (UINT8 *) SaveOffsetPtr + sizeof (S3_READ_WRITE_OP_HEADER) + WidthLength, + DataMask, + WidthLength, + StdHeader + ); + S3SaveTablePtr->SaveOffset += OpCodeLength; + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Save S3 poll opcode + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[in] OpCode Operation opcode + * @param[in] Width Width + * @param[in] Address Register address + * @param[in] Data Pointer to data + * @param[in] DataMask Pointer data mask + * @param[in] Delay Time delay for poll + */ +AGESA_STATUS +S3SaveStateSavePollOp ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 OpCode, + IN ACCESS_WIDTH Width, + IN UINT64 Address, + IN VOID *Data, + IN VOID *DataMask, + IN UINT64 Delay + ) +{ + + S3_SAVE_TABLE_HEADER *S3SaveTablePtr; + S3_POLL_OP_HEADER *SaveOffsetPtr; + UINT32 OpCodeLength; + UINT32 WidthLength; + AGESA_STATUS Status; + + Status = S3ScriptGetS3SaveTable (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + if (S3SaveTablePtr->Locked) { + return AGESA_UNSUPPORTED; + } + WidthLength = LibAmdAccessWidth (Width); + OpCodeLength = sizeof (S3_POLL_OP_HEADER) + WidthLength * 2; + if ((S3SaveTablePtr->SaveOffset + OpCodeLength) > S3SaveTablePtr->TableLength) { + Status = S3SaveStateExtendTableLenth (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + } + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Save: %s Address: 0x%08x Data: ", S3SaveDebugOpcodeString (StdHeader, OpCode), Address); + S3SaveDebugPrintHexArray (StdHeader, Data, 1, Width); + IDS_HDT_CONSOLE (S3_TRACE, " Mask: "); + S3SaveDebugPrintHexArray (StdHeader, DataMask, 1, Width); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + SaveOffsetPtr = (S3_POLL_OP_HEADER *) ((UINT8 *) S3SaveTablePtr + S3SaveTablePtr->SaveOffset); + SaveOffsetPtr->OpCode = OpCode; + SaveOffsetPtr->Width = Width; + SaveOffsetPtr->Delay = Delay; + SaveOffsetPtr->Address = Address; + + LibAmdMemCopy ( + (UINT8 *) SaveOffsetPtr + sizeof (S3_POLL_OP_HEADER), + Data, + WidthLength, + StdHeader + ); + LibAmdMemCopy ( + (UINT8 *) SaveOffsetPtr + sizeof (S3_POLL_OP_HEADER) + WidthLength, + DataMask, + WidthLength, + StdHeader + ); + S3SaveTablePtr->SaveOffset += OpCodeLength; + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Save S3 info opcode + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[in] OpCode Operation opcode + * @param[in] InformationLength Info length + * @param[in] Information Pointer to information + */ +AGESA_STATUS +S3SaveStateSaveInfoOp ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 OpCode, + IN UINT32 InformationLength, + IN VOID *Information + ) +{ + + S3_SAVE_TABLE_HEADER *S3SaveTablePtr; + S3_INFO_OP_HEADER *SaveOffsetPtr; + UINT32 OpCodeLength; + + AGESA_STATUS Status; + + Status = S3ScriptGetS3SaveTable (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + if (S3SaveTablePtr->Locked) { + return AGESA_UNSUPPORTED; + } + OpCodeLength = sizeof (S3_INFO_OP_HEADER) + InformationLength; + if ((S3SaveTablePtr->SaveOffset + OpCodeLength) > S3SaveTablePtr->TableLength) { + Status = S3SaveStateExtendTableLenth (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + } + SaveOffsetPtr = (S3_INFO_OP_HEADER *) ((UINT8 *) S3SaveTablePtr + S3SaveTablePtr->SaveOffset); + SaveOffsetPtr->OpCode = OpCode; + SaveOffsetPtr->Length = InformationLength; + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Save: Info: %s \n", Information); + ); + LibAmdMemCopy ( + (UINT8 *) SaveOffsetPtr + sizeof (S3_INFO_OP_HEADER), + Information, + InformationLength, + StdHeader + ); + S3SaveTablePtr->SaveOffset += OpCodeLength; + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Save S3 dispatch opcode + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[in] OpCode Operation opcode + * @param[in] FunctionId Function ID + * @param[in] ContextLength Context length + * @param[in] Context Pointer to Context + */ +AGESA_STATUS +S3SaveStateSaveDispatchOp ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 OpCode, + IN UINT16 FunctionId, + IN UINT16 ContextLength, + IN VOID *Context + ) +{ + + S3_SAVE_TABLE_HEADER *S3SaveTablePtr; + S3_DISPATCH_OP_HEADER *SaveOffsetPtr; + UINT32 OpCodeLength; + AGESA_STATUS Status; + + Status = S3ScriptGetS3SaveTable (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + if (S3SaveTablePtr->Locked) { + return AGESA_UNSUPPORTED; + } + OpCodeLength = sizeof (S3_DISPATCH_OP_HEADER) + ContextLength; + if ((S3SaveTablePtr->SaveOffset + OpCodeLength) > S3SaveTablePtr->TableLength) { + Status = S3SaveStateExtendTableLenth (StdHeader, &S3SaveTablePtr); + if (Status != AGESA_SUCCESS) { + return Status; + } + } + S3_SCRIPT_DEBUG_CODE ( + IDS_HDT_CONSOLE (S3_TRACE, " S3 Save: %s Function Id: 0x%02x, Context: ", S3SaveDebugOpcodeString (StdHeader, OpCode), FunctionId); + S3SaveDebugPrintHexArray (StdHeader, Context, ContextLength, AccessWidth8); + IDS_HDT_CONSOLE (S3_TRACE, "\n"); + ); + SaveOffsetPtr = (S3_DISPATCH_OP_HEADER *) ((UINT8 *) S3SaveTablePtr + S3SaveTablePtr->SaveOffset); + SaveOffsetPtr->OpCode = OpCode; + SaveOffsetPtr->Length = ContextLength; + SaveOffsetPtr->FunctionId = FunctionId; + LibAmdMemCopy ( + (UINT8 *) SaveOffsetPtr + sizeof (S3_DISPATCH_OP_HEADER), + Context, + ContextLength, + StdHeader + ); + + S3SaveTablePtr->SaveOffset += OpCodeLength; + return AGESA_SUCCESS; +} + + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Save S3 debug support + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[in] Op Opcode + */ +CHAR8* +S3SaveDebugOpcodeString ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 Op + ) +{ + switch (Op) { + case SAVE_STATE_IO_WRITE_OPCODE: + return (CHAR8 *)"IO WR"; + case SAVE_STATE_IO_READ_WRITE_OPCODE: + return (CHAR8 *)"IO RD/WR"; + case SAVE_STATE_IO_POLL_OPCODE: + return (CHAR8 *)"IO POLL"; + case SAVE_STATE_MEM_WRITE_OPCODE: + return (CHAR8 *)"MEM WR"; + case SAVE_STATE_MEM_READ_WRITE_OPCODE: + return (CHAR8 *)"MEM RD/WR"; + case SAVE_STATE_MEM_POLL_OPCODE: + return (CHAR8 *)"MEM POLL"; + case SAVE_STATE_PCI_CONFIG_WRITE_OPCODE: + return (CHAR8 *)"PCI WR"; + case SAVE_STATE_PCI_CONFIG_READ_WRITE_OPCODE: + return (CHAR8 *)"PCI RD/WR"; + case SAVE_STATE_PCI_CONFIG_POLL_OPCODE: + return (CHAR8 *)"PCI POLL"; + case SAVE_STATE_STALL_OPCODE: + return (CHAR8 *)"STALL"; + case SAVE_STATE_DISPATCH_OPCODE: + return (CHAR8 *)"DISPATCH"; + default: + IDS_ERROR_TRAP; + } + return (CHAR8 *)"!!! Unrecognize opcode !!!"; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Save S3 debug support + * + * + * + * @param[in] StdHeader Pointer to standard header + * @param[in] Array Array + * @param[in] Count Count of element in array + * @param[in] Width Array Element width + */ +VOID +S3SaveDebugPrintHexArray ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *Array, + IN UINT32 Count, + IN ACCESS_WIDTH Width + ) +{ + UINTN Index; + + for (Index = 0; Index < Count; Index++) { + switch (Width) { + case AccessWidth8: + case AccessS3SaveWidth8: + IDS_HDT_CONSOLE (S3_TRACE, "0x%02x", *((UINT8*)Array + Index)); + break; + case AccessWidth16: + case AccessS3SaveWidth16: + IDS_HDT_CONSOLE (S3_TRACE, "0x%04x", *((UINT16*)Array + Index)); + break; + case AccessWidth32: + case AccessS3SaveWidth32: + IDS_HDT_CONSOLE (S3_TRACE, "0x%08x", *((UINT32*)Array + Index)); + break; + case AccessWidth64: + case AccessS3SaveWidth64: + IDS_HDT_CONSOLE (S3_TRACE, "0x%08x%08x", ((UINT32*) ((UINT64*)Array + Index))[1], ((UINT32*) ((UINT64*)Array + Index))[0]); + break; + default: + IDS_ERROR_TRAP; + } + if (Index < (Count - 1)) { + IDS_HDT_CONSOLE (S3_TRACE, ", "); + } + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3SaveState.h b/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3SaveState.h new file mode 100644 index 0000000000..1801ef95fb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Common/S3SaveState.h @@ -0,0 +1,365 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various PCI service routines. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _S3SAVESTATE_H_ +#define _S3SAVESTATE_H_ + +#pragma pack (push, 1) + +#ifndef S3_SCRIPT_DEBUG_CODE + #define S3_SCRIPT_DEBUG_CODE(Code) Code +#endif + +/// Dispatch function ID repository +typedef enum { + NbSmuIndirectWriteS3Script_ID = 1, ///< GNB SMU service request function ID. + NbSmuServiceRequestS3Script_ID, ///< GNB PCIe late restore function ID. + PcieLateRestoreS3Script_ID, ///< GNB SMU indirect write. + GnbSmuServiceRequestV4S3Script_ID, ///< SMU service request + GnbLibStallS3Script_ID, ///< Stall request + PcieLateRestoreTNS3Script_ID, ///< GNB PCIe late restore TN + PcieLateRestoreXXS3Script_ID_RSV1, + PcieLateRestoreXXS3Script_ID_RSV2, + PcieLateRestoreKBS3Script_ID, ///< GNB PCIe late restore KB + PcieLateRestoreXXS3Script_ID_RSV3, + GfxRequestSclkTNS3Script_ID, ///< SCLk setting + GnbSmuServiceRequestV7S3Script_ID ///< SMU service request +} S3_DISPATCH_FUNCTION_ID; + +#define SAVE_STATE_IO_WRITE_OPCODE 0x00 +#define SAVE_STATE_IO_READ_WRITE_OPCODE 0x01 +#define SAVE_STATE_MEM_WRITE_OPCODE 0x02 +#define SAVE_STATE_MEM_READ_WRITE_OPCODE 0x03 +#define SAVE_STATE_PCI_CONFIG_WRITE_OPCODE 0x04 +#define SAVE_STATE_PCI_CONFIG_READ_WRITE_OPCODE 0x05 +#define SAVE_STATE_STALL_OPCODE 0x07 +#define SAVE_STATE_INFORMATION_OPCODE 0x0A +#define SAVE_STATE_IO_POLL_OPCODE 0x0D +#define SAVE_STATE_MEM_POLL_OPCODE 0x0E +#define SAVE_STATE_PCI_CONFIG_POLL_OPCODE 0x0F +#define SAVE_STATE_DISPATCH_OPCODE 0x20 +#define SAVE_STATE_BREAKPOINT_OPCODE 0x21 + + +#define S3_TABLE_LENGTH 8 * 1024 +#define S3_TABLE_LENGTH_INCREMENT 1 * 1024 + +/// S3 Save Table +typedef struct { + UINT16 TableLength; ///< Table Length + UINT32 SaveOffset; ///< Save Location + BOOLEAN Locked; ///< Locked +} S3_SAVE_TABLE_HEADER; + +/// S3 write operation header +typedef struct { + UINT16 OpCode; ///< Opcode + ACCESS_WIDTH Width; ///< Data width (byte, word, dword) + UINT64 Address; ///< Register address + UINT32 Count; ///< Write count +} S3_WRITE_OP_HEADER; + +/// S3 Read and Write Operation header +typedef struct { + UINT16 OpCode; ///< Opcode + ACCESS_WIDTH Width; ///< Data width (byte, word, dword) + UINT64 Address; ///< Register Address +} S3_READ_WRITE_OP_HEADER; + +/// S3 Poll operation header +typedef struct { + UINT16 OpCode; ///< Opcode + ACCESS_WIDTH Width; ///< Data width (byte, word, dword) + UINT64 Address; ///< Register address + UINT64 Delay; ///< Time delay +} S3_POLL_OP_HEADER; + +/// Information operation header +typedef struct { + UINT16 OpCode; ///< Opcode + UINT32 Length; ///< Length of info +} S3_INFO_OP_HEADER; + +/// Dispatch operation header +typedef struct { + UINT16 OpCode; ///< Opcode + UINT16 FunctionId; ///< Function ID + UINT16 Length; ///< Length in bytes of the context +} S3_DISPATCH_OP_HEADER; + + +typedef VOID S3_DISPATCH_FUNCTION ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID *Context + ); + +/// Dispatch function table entry +typedef struct { + UINT16 FunctionId; ///StdHeader; + + if ( LocalCfgPtr->Azalia.AzaliaEnable == 1 ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEB, AccessWidth8, (UINT32)~BIT0, 0); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEB, AccessWidth8, (UINT32)~BIT0, BIT0); + RwPci ((AZALIA_BUS_DEV_FUN << 16) + 0x4C, AccessWidth8, (UINT32)~BIT0, BIT0, StdHeader); + + if ( LocalCfgPtr->Azalia.AzaliaMsiEnable) { + RwPci ((AZALIA_BUS_DEV_FUN << 16) + FCH_AZ_REG44, AccessWidth32, (UINT32)~BIT8, BIT8, StdHeader); + } + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaLate.c new file mode 100644 index 0000000000..fa7c5bd337 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaLate.c @@ -0,0 +1,59 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config FCH HD Audio Controller + * + * Init Azalia Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_AZALIA_AZALIALATE_FILECODE + +/** + * FchInitLateAzalia - Prepare Azalia controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateAzalia ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaMid.c new file mode 100644 index 0000000000..2472893f96 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaMid.c @@ -0,0 +1,509 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config FCH HD Audio Controller + * + * Init Azalia Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_AZALIA_AZALIAMID_FILECODE +// +// Declaration of local functions +// +VOID +ConfigureAzaliaPinCmd ( + IN FCH_DATA_BLOCK *FchDataPtr, + IN UINT32 BAR0, + IN UINT8 ChannelNum + ); + +VOID +ConfigureAzaliaSetConfigD4Dword ( + IN CODEC_ENTRY *TempAzaliaCodecEntryPtr, + IN UINT32 ChannelNumDword, + IN UINT32 BAR0, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * FchInitMidAzalia - Config Azalia controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidAzalia ( + IN VOID *FchDataPtr + ) +{ + UINT8 Index; + BOOLEAN EnableAzalia; + UINT32 PinRouting; + UINT8 ChannelNum; + UINT8 AzaliaTempVariableByte; + UINT16 AzaliaTempVariableWord; + UINT32 BAR0; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + EnableAzalia = FALSE; + ChannelNum = 0; + AzaliaTempVariableByte = 0; + AzaliaTempVariableWord = 0; + BAR0 = 0; + + if ( LocalCfgPtr->Azalia.AzaliaEnable == 1 ) { + return; + } else { + RwPci ((AZALIA_BUS_DEV_FUN << 16) + FCH_AZ_REG04, AccessWidth8, (UINT32)~BIT1, BIT1, StdHeader); + + if ( LocalCfgPtr->Azalia.AzaliaSsid != 0 ) { + RwPci ((AZALIA_BUS_DEV_FUN << 16) + FCH_AZ_REG2C, AccessWidth32, 0x00, LocalCfgPtr->Azalia.AzaliaSsid, StdHeader); + } + + ReadPci ((AZALIA_BUS_DEV_FUN << 16) + FCH_AZ_REG10, AccessWidth32, &BAR0, StdHeader); + + if ( BAR0 != 0 ) { + if ( BAR0 != 0xFFFFFFFF ) { + BAR0 &= ~(0x03FFF); + EnableAzalia = TRUE; + } + } + } + + if ( EnableAzalia ) { + // + // Get SDIN Configuration + // + if ( LocalCfgPtr->Azalia.AzaliaConfig.AzaliaSdin0 == 2 ) { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0xA7, AccessWidth8, 0, 0x3E); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + 0xA7, AccessWidth8, 0, 0x00); + } else { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0xA7, AccessWidth8, 0, 0x0); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + 0xA7, AccessWidth8, 0, 0x01); + } + + if ( LocalCfgPtr->Azalia.AzaliaConfig.AzaliaSdin1 == 2 ) { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0xA8, AccessWidth8, 0, 0x3E); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + 0xA8, AccessWidth8, 0, 0x00); + } else { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0xA8, AccessWidth8, 0, 0x0); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + 0xA8, AccessWidth8, 0, 0x01); + } + + if ( LocalCfgPtr->Azalia.AzaliaConfig.AzaliaSdin2 == 2 ) { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0xA9, AccessWidth8, 0, 0x3E); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + 0xA9, AccessWidth8, 0, 0x00); + } else { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0xA9, AccessWidth8, 0, 0x0); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + 0xA9, AccessWidth8, 0, 0x01); + } + + if ( LocalCfgPtr->Azalia.AzaliaConfig.AzaliaSdin3 == 2 ) { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0xAA, AccessWidth8, 0, 0x3E); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + 0xAA, AccessWidth8, 0, 0x00); + } else { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0xAA, AccessWidth8, 0, 0x0); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + 0xAA, AccessWidth8, 0, 0x01); + } + + Index = 11; + do { + ReadMem ( BAR0 + FCH_AZ_BAR_REG08, AccessWidth8, &AzaliaTempVariableByte); + AzaliaTempVariableByte |= BIT0; + WriteMem (BAR0 + FCH_AZ_BAR_REG08, AccessWidth8, &AzaliaTempVariableByte); + FchStall (1000, StdHeader); + ReadMem (BAR0 + FCH_AZ_BAR_REG08, AccessWidth8, &AzaliaTempVariableByte); + Index--; + } while ((! (AzaliaTempVariableByte & BIT0)) && (Index > 0) ); + + if ( Index == 0 ) { + return; + } + + FchStall (1000, StdHeader); + ReadMem ( BAR0 + FCH_AZ_BAR_REG0E, AccessWidth16, &AzaliaTempVariableWord); + if ( AzaliaTempVariableWord & 0x0F ) { + + // + //at least one azalia codec found + // + //PinRouting = LocalCfgPtr->Azalia.AZALIA_CONFIG.AzaliaSdinPin; + //new structure need make up PinRouting + //need adjust later!!! + // + PinRouting = 0; + PinRouting = (UINT32 )LocalCfgPtr->Azalia.AzaliaConfig.AzaliaSdin3; + PinRouting <<= 8; + PinRouting |= (UINT32 )LocalCfgPtr->Azalia.AzaliaConfig.AzaliaSdin2; + PinRouting <<= 8; + PinRouting |= (UINT32 )LocalCfgPtr->Azalia.AzaliaConfig.AzaliaSdin1; + PinRouting <<= 8; + PinRouting |= (UINT32 )LocalCfgPtr->Azalia.AzaliaConfig.AzaliaSdin0; + + do { + if ( ( ! (PinRouting & BIT0) ) && (PinRouting & BIT1) ) { + ConfigureAzaliaPinCmd (LocalCfgPtr, BAR0, ChannelNum); + } + PinRouting >>= 8; + ChannelNum++; + } while ( ChannelNum != 4 ); + } else { + // + //No Azalia codec found + // + if ( LocalCfgPtr->Azalia.AzaliaEnable != 2 ) { + EnableAzalia = FALSE; + } + } + } + + if ( EnableAzalia ) { + if ( LocalCfgPtr->Azalia.AzaliaSnoop == 1 ) { + RwPci ((AZALIA_BUS_DEV_FUN << 16) + 0x42, AccessWidth8, 0xFF, BIT1 + BIT0, StdHeader); + } + RwPci ((AZALIA_BUS_DEV_FUN << 16) + FCH_AZ_REG44 + 1, AccessWidth8, 0xFB, BIT2, StdHeader); + } else { + // + //disable Azalia controller + // + RwPci ((AZALIA_BUS_DEV_FUN << 16) + FCH_AZ_REG04, AccessWidth16, 0, 0, StdHeader); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEB, AccessWidth8, (UINT32)~BIT0, 0); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEB, AccessWidth8, (UINT32)~BIT0, 0); + } +} + +/** + * Pin Config for ALC880, ALC882 and ALC883. + * + * + * + */ +CODEC_ENTRY AzaliaCodecAlc882Table[] = +{ + {0x14, 0x01014010}, + {0x15, 0x01011012}, + {0x16, 0x01016011}, + {0x17, 0x01012014}, + {0x18, 0x01A19030}, + {0x19, 0x411111F0}, + {0x1a, 0x01813080}, + {0x1b, 0x411111F0}, + {0x1C, 0x411111F0}, + {0x1d, 0x411111F0}, + {0x1e, 0x01441150}, + {0x1f, 0x01C46160}, + {0xff, 0xffffffff} +}; + +/** + * Pin Config for ALC0262. + * + * + * + */ +CODEC_ENTRY AzaliaCodecAlc262Table[] = +{ + {0x14, 0x01014010}, + {0x15, 0x411111F0}, + {0x16, 0x411111F0}, + {0x18, 0x01A19830}, + {0x19, 0x02A19C40}, + {0x1a, 0x01813031}, + {0x1b, 0x02014C20}, + {0x1c, 0x411111F0}, + {0x1d, 0x411111F0}, + {0x1e, 0x0144111E}, + {0x1f, 0x01C46150}, + {0xff, 0xffffffff} +}; + +/** + * Pin Config for ALC0269. + * + * + * + */ +CODEC_ENTRY AzaliaCodecAlc269Table[] = +{ + {0x12, 0x99A308F0}, + {0x14, 0x99130010}, + {0x15, 0x0121101F}, + {0x16, 0x99036120}, + {0x18, 0x01A19850}, + {0x19, 0x99A309F0}, + {0x1a, 0x01813051}, + {0x1b, 0x0181405F}, + {0x1d, 0x40134601}, + {0x1e, 0x01442130}, + {0x11, 0x99430140}, + {0x20, 0x0030FFFF}, + {0xff, 0xffffffff} +}; + +/** + * Pin Config for ALC0861. + * + * + * + */ +CODEC_ENTRY AzaliaCodecAlc861Table[] = +{ + {0x01, 0x8086C601}, + {0x0B, 0x01014110}, + {0x0C, 0x01813140}, + {0x0D, 0x01A19941}, + {0x0E, 0x411111F0}, + {0x0F, 0x02214420}, + {0x10, 0x02A1994E}, + {0x11, 0x99330142}, + {0x12, 0x01451130}, + {0x1F, 0x411111F0}, + {0x20, 0x411111F0}, + {0x23, 0x411111F0}, + {0xff, 0xffffffff} +}; + +/** + * Pin Config for ALC0889. + * + * + * + */ +CODEC_ENTRY AzaliaCodecAlc889Table[] = +{ + {0x11, 0x411111F0}, + {0x14, 0x01014010}, + {0x15, 0x01011012}, + {0x16, 0x01016011}, + {0x17, 0x01013014}, + {0x18, 0x01A19030}, + {0x19, 0x411111F0}, + {0x1a, 0x411111F0}, + {0x1b, 0x411111F0}, + {0x1C, 0x411111F0}, + {0x1d, 0x411111F0}, + {0x1e, 0x01442150}, + {0x1f, 0x01C42160}, + {0xff, 0xffffffff} +}; + +/** + * Pin Config for ADI1984. + * + * + * + */ +CODEC_ENTRY AzaliaCodecAd1984Table[] = +{ + {0x11, 0x0221401F}, + {0x12, 0x90170110}, + {0x13, 0x511301F0}, + {0x14, 0x02A15020}, + {0x15, 0x50A301F0}, + {0x16, 0x593301F0}, + {0x17, 0x55A601F0}, + {0x18, 0x55A601F0}, + {0x1A, 0x91F311F0}, + {0x1B, 0x014511A0}, + {0x1C, 0x599301F0}, + {0xff, 0xffffffff} +}; + +/** + * FrontPanel Config table list + * + * + * + */ +CODEC_ENTRY FrontPanelAzaliaCodecTableList[] = +{ + {0x19, 0x02A19040}, + {0x1b, 0x02214020}, + {0xff, 0xffffffff} +}; + +/** + * Current HD Audio support codec list + * + * + * + */ +CODEC_TBL_LIST AzaliaCodecTableList[] = +{ + {0x010ec0880, &AzaliaCodecAlc882Table[0]}, + {0x010ec0882, &AzaliaCodecAlc882Table[0]}, + {0x010ec0883, &AzaliaCodecAlc882Table[0]}, + {0x010ec0885, &AzaliaCodecAlc882Table[0]}, + {0x010ec0889, &AzaliaCodecAlc889Table[0]}, + {0x010ec0262, &AzaliaCodecAlc262Table[0]}, + {0x010ec0269, &AzaliaCodecAlc269Table[0]}, + {0x010ec0861, &AzaliaCodecAlc861Table[0]}, + {0x011d41984, &AzaliaCodecAd1984Table[0]}, + { (UINT32) 0x0FFFFFFFF, (CODEC_ENTRY*) (UINTN)0x0FFFFFFFF} +}; + +/** + * ConfigureAzaliaPinCmd - Configuration HD Audio PIN Command + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * @param[in] BAR0 HD Audio BAR0 base address. + * @param[in] ChannelNum Channel Number. + * + */ +VOID +ConfigureAzaliaPinCmd ( + IN FCH_DATA_BLOCK *FchDataPtr, + IN UINT32 BAR0, + IN UINT8 ChannelNum + ) +{ + UINT32 AzaliaTempVariable; + UINT32 ChannelNumDword; + CODEC_TBL_LIST *TempAzaliaOemCodecTablePtr; + CODEC_ENTRY *TempAzaliaCodecEntryPtr; + + if ( (FchDataPtr->Azalia.AzaliaPinCfg) != 1 ) { + return; + } + + ChannelNumDword = ChannelNum << 28; + AzaliaTempVariable = 0xF0000; + AzaliaTempVariable |= ChannelNumDword; + + WriteMem (BAR0 + FCH_AZ_BAR_REG60, AccessWidth32, &AzaliaTempVariable); + FchStall (600, FchDataPtr->StdHeader); + ReadMem (BAR0 + FCH_AZ_BAR_REG64, AccessWidth32, &AzaliaTempVariable); + + if ( ((FchDataPtr->Azalia.AzaliaOemCodecTablePtr) == NULL) || ((FchDataPtr->Azalia.AzaliaOemCodecTablePtr) == ((CODEC_TBL_LIST*) (UINTN)0xFFFFFFFF))) { + TempAzaliaOemCodecTablePtr = (CODEC_TBL_LIST*) (&AzaliaCodecTableList[0]); + } else { + TempAzaliaOemCodecTablePtr = (CODEC_TBL_LIST*) FchDataPtr->Azalia.AzaliaOemCodecTablePtr; + } + + while ( TempAzaliaOemCodecTablePtr->CodecId != 0xFFFFFFFF ) { + if ( TempAzaliaOemCodecTablePtr->CodecId == AzaliaTempVariable ) { + break; + } else { + ++TempAzaliaOemCodecTablePtr; + } + } + + if ( TempAzaliaOemCodecTablePtr->CodecId != 0xFFFFFFFF ) { + TempAzaliaCodecEntryPtr = (CODEC_ENTRY*) TempAzaliaOemCodecTablePtr->CodecTablePtr; + if ( ((FchDataPtr->Azalia.AzaliaOemCodecTablePtr) == NULL) || ((FchDataPtr->Azalia.AzaliaOemCodecTablePtr) == ((CODEC_TBL_LIST*) (UINTN)0xFFFFFFFF)) ) { + TempAzaliaCodecEntryPtr = (CODEC_ENTRY*) (TempAzaliaCodecEntryPtr); + } + + ConfigureAzaliaSetConfigD4Dword (TempAzaliaCodecEntryPtr, ChannelNumDword, BAR0, FchDataPtr->StdHeader); + + if ( FchDataPtr->Azalia.AzaliaFrontPanel != 1 ) { + if ( (FchDataPtr->Azalia.AzaliaFrontPanel == 2) || (FchDataPtr->Azalia.FrontPanelDetected == 1) ) { + if ( ((FchDataPtr->Azalia.AzaliaOemFpCodecTablePtr) == NULL) || ((FchDataPtr->Azalia.AzaliaOemFpCodecTablePtr) == (VOID*) (UINTN)0xFFFFFFFF) ) { + TempAzaliaCodecEntryPtr = (CODEC_ENTRY*) (&FrontPanelAzaliaCodecTableList[0]); + } else { + TempAzaliaCodecEntryPtr = (CODEC_ENTRY*) FchDataPtr->Azalia.AzaliaOemFpCodecTablePtr; + } + + ConfigureAzaliaSetConfigD4Dword (TempAzaliaCodecEntryPtr, ChannelNumDword, BAR0, FchDataPtr->StdHeader); + } + } + } +} + +/** + * ConfigureAzaliaSetConfigD4Dword - Configuration HD Audio Codec table + * + * + * @param[in] TempAzaliaCodecEntryPtr HD Audio Codec table structure pointer. + * @param[in] ChannelNumDword HD Audio Channel Number. + * @param[in] BAR0 HD Audio BAR0 base address. + * @param[in] StdHeader + * + */ +VOID +ConfigureAzaliaSetConfigD4Dword ( + IN CODEC_ENTRY *TempAzaliaCodecEntryPtr, + IN UINT32 ChannelNumDword, + IN UINT32 BAR0, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 TempByte1; + UINT8 TempByte2; + UINT8 Index; + UINT32 TempDword1; + UINT32 TempDword2; + + TempDword1 = 0; + TempDword2 = 0; + + while ( (TempAzaliaCodecEntryPtr->Nid) != 0xFF ) { + TempByte1 = 0x20; + if ( (TempAzaliaCodecEntryPtr->Nid) == 0x1 ) { + TempByte1 = 0x24; + } + + TempDword1 = TempAzaliaCodecEntryPtr->Nid; + TempDword1 &= 0xff; + TempDword1 <<= 20; + TempDword1 |= ChannelNumDword; + TempDword1 |= (0x700 << 8); + + for ( Index = 4; Index > 0; Index-- ) { + do { + ReadMem (BAR0 + FCH_AZ_BAR_REG68, AccessWidth32, &TempDword2); + } while ( (TempDword2 & BIT0) != 0 ); + + TempByte2 = (UINT8) (( (TempAzaliaCodecEntryPtr->Byte40) >> ((4 - Index) * 8 ) ) & 0xff); + TempDword1 = (TempDword1 & 0xFFFF0000) + ((TempByte1 - Index) << 8) + TempByte2; + WriteMem (BAR0 + FCH_AZ_BAR_REG60, AccessWidth32, &TempDword1); + FchStall (60, StdHeader); + } + + ++TempAzaliaCodecEntryPtr; + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaReset.c new file mode 100644 index 0000000000..0966e9fb88 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Azalia/AzaliaReset.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config FCH HD Audio Controller + * + * Init Azalia Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_AZALIA_AZALIARESET_FILECODE + +/** + * FchInitResetAzalia - Config Azalia controller during Power-On + * + * + * + * @param[in] FchDataPtr + * + */ +VOID +FchInitResetF1 ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.c new file mode 100644 index 0000000000..905025f24d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.c @@ -0,0 +1,242 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH ACPI lib + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_COMMON_ACPILIB_FILECODE +// +// +// Routine Description: +// +// Locate ACPI table +// +// Arguments: +// +// Signature - table signature +// +//Returns: +// +// pointer to ACPI table +// +// +VOID* +AcpiLocateTable ( + IN UINT32 Signature + ) +{ + UINT32 Index; + UINT32 *RsdPtr; + UINT32 *Rsdt; + UINTN TableOffset; + DESCRIPTION_HEADER *CurrentTable; + + RsdPtr = (UINT32*) (UINTN) FCHOEM_ACPI_TABLE_RANGE_LOW; + Rsdt = NULL; + do { + if ( *RsdPtr == Int32FromChar('R','S','D',' ') && *(RsdPtr + 1) == Int32FromChar('P','T','R',' ') ) { /* ' DSR' & ' RTP' */ + Rsdt = (UINT32*) (UINTN) ((RSDP_HEADER*)RsdPtr)->RsdtAddress; + break; + } + RsdPtr += 4; + } while ( RsdPtr <= (UINT32*) (UINTN) FCHOEM_ACPI_TABLE_RANGE_HIGH ); + + if ( Rsdt != NULL && AcpiGetTableCheckSum (Rsdt) == 0 ) { + for ( Index = 0; Index < (((DESCRIPTION_HEADER*)Rsdt)->Length - sizeof (DESCRIPTION_HEADER)) / 4; Index++ ) { + TableOffset = *(UINTN*) ((UINT8*)Rsdt + sizeof (DESCRIPTION_HEADER) + Index * 4); + CurrentTable = (DESCRIPTION_HEADER*)TableOffset; + if ( CurrentTable->Signature == Signature ) { + return CurrentTable; + } + } + } + return NULL; +} + +// +// +// Routine Description: +// +// Update table CheckSum +// +// Arguments: +// +// TablePtr - table pointer +// +// Returns: +// +// none +// +// +VOID +AcpiSetTableCheckSum ( + IN VOID *TablePtr + ) +{ + UINT8 CheckSum; + + CheckSum = 0; + ((DESCRIPTION_HEADER*)TablePtr)->CheckSum = 0; + CheckSum = AcpiGetTableCheckSum (TablePtr); + ((DESCRIPTION_HEADER*)TablePtr)->CheckSum = (UINT8) (FCHOEM_ACPI_BYTE_CHECHSUM - CheckSum); +} + +// +// +// Routine Description: +// +// Get table CheckSum - Get ACPI table checksum +// +// Arguments: +// +// TablePtr - table pointer +// +// Returns: +// +// none +// +// +UINT8 +AcpiGetTableCheckSum ( + IN VOID *TablePtr + ) +{ + return GetByteSum (TablePtr, ((DESCRIPTION_HEADER*)TablePtr)->Length); +} + + +// +// +// Routine Description: +// +// GetByteSum - Get BYTE checksum value +// +// Arguments: +// +// DataPtr - table pointer +// Length - table length +// +// Returns: +// +// CheckSum - CheckSum value +// +// +UINT8 +GetByteSum ( + IN VOID *DataPtr, + IN UINT32 Length + ) +{ + UINT32 Index; + UINT8 CheckSum; + + CheckSum = 0; + for ( Index = 0; Index < Length; Index++ ) { + CheckSum = CheckSum + (*((UINT8*)DataPtr + Index)); + } + return CheckSum; +} + +// +// +// Routine Description: +// +// GetFchAcpiMmioBase - Get FCH HwAcpi MMIO Base Address +// +// Arguments: +// +// AcpiMmioBase - HwAcpi MMIO Base Address +// StdHeader - Amd Stand Header +// +// Returns: +// +// AcpiMmioBase - HwAcpi MMIO Base Address +// +// +VOID +GetFchAcpiMmioBase ( + OUT UINT32 *AcpiMmioBase, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 AcpiMmioBaseAddressDword; + + ReadPmio (FCH_PMIOA_REG24 + 2, AccessWidth16, &AcpiMmioBaseAddressDword, StdHeader); + *AcpiMmioBase = AcpiMmioBaseAddressDword << 16; +} + +// +// +// Routine Description: +// +// GetFchAcpiPmBase - Get FCH HwAcpi PM Base Address +// +// Arguments: +// +// AcpiPmBase - HwAcpi PM Base Address +// StdHeader - Amd Stand Header +// +// Returns: +// +// AcpiPmBase - HwAcpi PM Base Address +// +// +VOID +GetFchAcpiPmBase ( + OUT UINT16 *AcpiPmBase, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + ReadPmio (FCH_PMIOA_REG60, AccessWidth16, AcpiPmBase, StdHeader); +} + + +UINT8 +ReadFchSleepType ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 Value16; + ReadPmio (FCH_PMIOA_REG62, AccessWidth16, &Value16, StdHeader); + LibAmdIoRead (AccessWidth16, Value16, &Value16, StdHeader); + return (UINT8) ((Value16 >> 10) & 7); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.h new file mode 100644 index 0000000000..5c7f375dd3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/AcpiLib.h @@ -0,0 +1,91 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH ACPI lib + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#ifndef _FCH_ACPILIB_H_ +#define _FCH_ACPILIB_H_ +/// +/// RSDP - ACPI 2.0 table RSDP +/// +typedef struct _RSDP_HEADER { + UINT64 Signature; ///< RSDP signature "RSD PTR" + UINT8 CheckSum; ///< checksum of the first 20 bytes + UINT8 OEMID[6]; ///< OEM ID + UINT8 Revision; ///< 0 for APCI 1.0, 2 for ACPI 2.0 + UINT32 RsdtAddress; ///< physical address of RSDT + UINT32 Length; ///< total length of RSDP (including extended part) + UINT64 XsdtAddress; ///< physical address of XSDT + UINT8 ExtendedCheckSum; ///< chechsum of whole table + UINT8 Reserved[3]; ///< Reserved +} RSDP_HEADER; + +/// +/// DESCRIPTION_HEADER - ACPI common table header +/// +typedef struct _DESCRIPTION_HEADER { + UINT32 Signature; ///< ACPI signature (4 ASCII characters) + UINT32 Length; ///< Length of table, in bytes, including header + UINT8 Revision; ///< ACPI Specification minor version # + UINT8 CheckSum; ///< To make sum of entire table == 0 + UINT8 OemId[6]; ///< OEM identification + UINT8 OemTableId[8]; ///< OEM table identification + UINT32 OemRevision; ///< OEM revision number + UINT32 CreatorId; ///< ASL compiler vendor ID + UINT32 CreatorRevision; ///< ASL compiler revision number +} DESCRIPTION_HEADER; + +/// +/// _AcpiRegWrite - ACPI MMIO register R/W structure +/// +typedef struct _ACPI_REG_WRITE { + UINT8 MmioBase; /// MmioBase: Index of Fch block (For instance GPIO_BASE:0x01 SMI_BASE:0x02) + UINT8 MmioReg; /// MmioReg : Register index + UINT8 DataAndMask; /// DataANDMask : AND Register Data + UINT8 DataOrMask; /// DataOrMask : Or Register Data +} ACPI_REG_WRITE; + +VOID* AcpiLocateTable (IN UINT32 Signature); +VOID AcpiSetTableCheckSum (IN VOID *TablePtr); +UINT8 AcpiGetTableCheckSum (IN VOID *TablePtr); +UINT8 GetByteSum (IN VOID *DataPtr, IN UINT32 Length); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchBiosRamUsage.h b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchBiosRamUsage.h new file mode 100644 index 0000000000..60e40d60a7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchBiosRamUsage.h @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH BIOS Ram usage + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#ifndef _FCH_BIOS_RAM_USAGE_H_ +#define _FCH_BIOS_RAM_USAGE_H_ + +#define RESTORE_MEMORY_CONTROLLER_START 0 +#define XHCI_REGISTER_BAR00 0xD0 +#define XHCI_REGISTER_BAR01 0xD1 +#define XHCI_REGISTER_BAR02 0xD2 +#define XHCI_REGISTER_BAR03 0xD3 +#define XHCI_REGISTER_04H 0xD4 +#define XHCI_REGISTER_0CH 0xD5 +#define XHCI_REGISTER_3CH 0xD6 +#define XHCI1_REGISTER_BAR00 0xE0 +#define XHCI1_REGISTER_BAR01 0xE1 +#define XHCI1_REGISTER_BAR02 0xE2 +#define XHCI1_REGISTER_BAR03 0xE3 +#define XHCI1_REGISTER_04H 0xE4 +#define XHCI1_REGISTER_0CH 0xE5 +#define XHCI1_REGISTER_3CH 0xE6 +#define RTC_WORKAROUND_DATA_START 0xF0 +#define BOOT_TIME_FLAG_SEC 0xF8 +#define BOOT_TIME_FLAG_INT19 0xFC + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchCommon.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchCommon.c new file mode 100644 index 0000000000..c8f948da6e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchCommon.c @@ -0,0 +1,47 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH common + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "heapManager.h" +#define FILECODE PROC_FCH_COMMON_FCHCOMMON_FILECODE + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchCommonCfg.h b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchCommonCfg.h new file mode 100644 index 0000000000..7376a965df --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchCommonCfg.h @@ -0,0 +1,1219 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Function Support Definition + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#ifndef _FCH_COMMON_CFG_H_ +#define _FCH_COMMON_CFG_H_ + +#pragma pack (push, 1) + +//----------------------------------------------------------------------------- +// FCH DEFINITIONS AND MACROS +//----------------------------------------------------------------------------- + +// +// FCH Component Data Structure Definitions +// + +/// PCI_ADDRESS - PCI access structure +#define PCI_ADDRESS(bus, dev, func, reg) \ + (UINT32) ( (((UINT32)bus) << 24) + (((UINT32)dev) << 19) + (((UINT32)func) << 16) + ((UINT32)reg) ) + +#define CPUID_FMF 0x80000001ul // Family Model Features information +/// +/// - Byte Register R/W structure +/// +typedef struct _REG8_MASK { + UINT8 RegIndex; /// RegIndex - Reserved + UINT8 AndMask; /// AndMask - Reserved + UINT8 OrMask; /// OrMask - Reserved +} REG8_MASK; + + +/// +/// PCIE Reset Block +/// +typedef enum { + NbBlock, ///< Reset for NB PCIE + FchBlock ///< Reset for FCH GPP +} RESET_BLOCK; + +/// +/// PCIE Reset Operation +/// +typedef enum { + DeassertReset, ///< DeassertRese - Deassert reset + AssertReset ///< AssertReset - Assert reset +} RESET_OP; + + +/// +/// SD structure +/// +typedef struct { + SD_MODE SdConfig; ///< SD Mode configuration + /// @li 00 - Disabled + /// @li 00 - AMDA + /// @li 01 - DMA + /// @li 10 - PIO + /// + UINT8 SdSpeed; ///< SD Speed + /// @li 0 - Low speed + /// @li 1 - High speed + /// + UINT8 SdBitWidth; ///< SD Bit Width + /// @li 0 - 32BIT clear 23 + /// @li 1 - 64BIT, set 23,default + /// + UINT32 SdSsid; ///< SD Subsystem ID + SD_CLOCK_CONTROL SdClockControl; ///< SD Clock Control + BOOLEAN SdClockMultiplier; ///< SD Clock Multiplier enable/disable + UINT8 SdReTuningMode; ///< SD Re-tuning modes select + /// @li 0 - mode 1 + /// @li 1 - mode 2 + /// @li 2 - mode 3 + UINT8 SdHostControllerVersion; ///< SD controller Version + /// @li 1 - SD 2.0 + /// @li 2 - SD 3.0 + UINT8 SdrCapabilities; ///< SDR Capability mode select + /// @li 00 - SDR25/15 + /// @li 01 - SDR50 + /// @li 11 - SDR104 +} FCH_SD; + +/// +/// CODEC_ENTRY - Fch HD Audio OEM Codec structure +/// +typedef struct _CODEC_ENTRY { + UINT8 Nid; /// Nid - Reserved + UINT32 Byte40; /// Byte40 - Reserved +} CODEC_ENTRY; + +/// +/// CODEC_TBL_LIST - Fch HD Audio Codec table list +/// +typedef struct _CODEC_TBL_LIST { + UINT32 CodecId; /// CodecID - Codec ID + CODEC_ENTRY* CodecTablePtr; /// CodecTablePtr - Codec table pointer +} CODEC_TBL_LIST; + +/// +/// AZALIA_PIN - HID Azalia or GPIO define structure. +/// +typedef struct _AZALIA_PIN { + UINT8 AzaliaSdin0; ///< AzaliaSdin0 + /// @par + /// @li 00 - GPIO PIN + /// @li 10 - As a Azalia SDIN pin + + UINT8 AzaliaSdin1; ///< AzaliaSdin1 + /// @par + /// SDIN1 is define at BIT2 & BIT3 + /// @li 00 - GPIO PIN + /// @li 10 - As a Azalia SDIN pin + + UINT8 AzaliaSdin2; ///< AzaliaSdin2 + /// @par + /// SDIN2 is define at BIT4 & BIT5 + /// @li 00 - GPIO PIN + /// @li 10 - As a Azalia SDIN pin + + UINT8 AzaliaSdin3; ///< AzaliaSdin3 + /// @par + /// SDIN3 is define at BIT6 & BIT7 + /// @li 00 - GPIO PIN + /// @li 10 - As a Azalia SDIN pin +} AZALIA_PIN; + +/// +/// Azalia structure +/// +typedef struct { + UINT8 AzaliaEnable; ///< AzaliaEnable - Azalia function configuration + BOOLEAN AzaliaMsiEnable; ///< AzaliaMsiEnable - Azalia MSI capability + UINT32 AzaliaSsid; ///< AzaliaSsid - Azalia Subsystem ID + UINT8 AzaliaPinCfg; ///< AzaliaPinCfg - Azalia Controller SDIN pin Configuration + /// @par + /// @li 0 - disable + /// @li 1 - enable + + UINT8 AzaliaFrontPanel; ///< AzaliaFrontPanel - Azalia Controller Front Panel Configuration + /// @par + /// Support Front Panel configuration + /// @li 0 - Auto + /// @li 1 - disable + /// @li 2 - enable + + UINT8 FrontPanelDetected; ///< FrontPanelDetected - Force Azalia Controller Front Panel Configuration + /// @par + /// Force Front Panel configuration + /// @li 0 - Not Detected + /// @li 1 - Detected + + UINT8 AzaliaSnoop; ///< AzaliaSnoop - Azalia Controller Snoop feature Configuration + /// @par + /// Azalia Controller Snoop feature Configuration + /// @li 0 - disable + /// @li 1 - enable + + UINT8 AzaliaDummy; /// AzaliaDummy - Reserved */ + + AZALIA_PIN AzaliaConfig; /// AzaliaConfig - Azaliz Pin Configuration + +/// +/// AZOEMTBL - Azalia Controller OEM Codec Table Pointer +/// + CODEC_TBL_LIST *AzaliaOemCodecTablePtr; /// AzaliaOemCodecTablePtr - Oem Azalia Codec Table Pointer + +/// +/// AZOEMFPTBL - Azalia Controller Front Panel OEM Table Pointer +/// + VOID *AzaliaOemFpCodecTablePtr; /// AzaliaOemFpCodecTablePtr - Oem Front Panel Codec Table Pointer +} FCH_AZALIA; + +/// +/// _SPI_DEVICE_PROFILE Spi Device Profile structure +/// +typedef struct _SPI_DEVICE_PROFILE { + UINT32 JEDEC_ID; /// JEDEC ID + UINT32 RomSize; /// ROM Size + UINT32 SectorSize; /// Sector Size + UINT16 MaxNormalSpeed; /// Max Normal Speed + UINT16 MaxFastSpeed; /// Max Fast Speed + UINT16 MaxDualSpeed; /// Max Dual Speed + UINT16 MaxQuadSpeed; /// Max Quad Speed + UINT8 QeReadRegister; /// QE Read Register + UINT8 QeWriteRegister; /// QE Write Register + UINT8 QeOperateSize; /// QE Operate Size 1byte/2bytes + UINT16 QeLocation; // QE Location in the register +} SPI_DEVICE_PROFILE; + +/// +/// _SPI_CONTROLLER_PROFILE Spi Device Profile structure +/// +typedef struct _SPI_CONTROLLER_PROFILE { +// UINT32 SPI_CONTROLLER_ID; /// SPI Controller ID + UINT16 FifoSize; /// FIFO Size + UINT16 MaxNormalSpeed; /// Max Normal Speed + UINT16 MaxFastSpeed; /// Max Fast Speed + UINT16 MaxDualSpeed; /// Max Dual Speed + UINT16 MaxQuadSpeed; /// Max Quad Speed +} SPI_CONTROLLER_PROFILE; + +/// +/// SPI structure +/// +typedef struct { + BOOLEAN LpcMsiEnable; ///< LPC MSI capability + UINT32 LpcSsid; ///< LPC Subsystem ID + UINT32 RomBaseAddress; ///< SpiRomBaseAddress + /// @par + /// SPI ROM BASE Address + /// + UINT8 SpiSpeed; ///< SpiSpeed - Spi Frequency + /// @par + /// SPI Speed [1.0] - the clock speed for non-fast read command + /// @li 00 - 66Mhz + /// @li 01 - 33Mhz + /// @li 10 - 22Mhz + /// @li 11 - 16.5Mhz + /// + UINT8 SpiFastSpeed; ///< FastSpeed - Spi Fast Speed feature + /// SPIFastSpeed [1.0] - the clock speed for Fast Speed Feature + /// @li 00 - 66Mhz + /// @li 01 - 33Mhz + /// @li 10 - 22Mhz + /// @li 11 - 16.5Mhz + /// + UINT8 WriteSpeed; ///< WriteSpeed - Spi Write Speed + /// @par + /// WriteSpeed [1.0] - the clock speed for Spi write command + /// @li 00 - 66Mhz + /// @li 01 - 33Mhz + /// @li 10 - 22Mhz + /// @li 11 - 16.5Mhz + /// + UINT8 SpiMode; ///< SpiMode - Spi Mode Setting + /// @par + /// @li 101 - Qual-io 1-4-4 + /// @li 100 - Dual-io 1-2-2 + /// @li 011 - Qual-io 1-1-4 + /// @li 010 - Dual-io 1-1-2 + /// @li 111 - FastRead + /// @li 110 - Normal + /// + UINT8 AutoMode; ///< AutoMode - Spi Auto Mode + /// @par + /// SPI Auto Mode + /// @li 0 - Disabled + /// @li 1 - Enabled + /// + UINT8 SpiBurstWrite; ///< SpiBurstWrite - Spi Burst Write Mode + /// @par + /// SPI Burst Write + /// @li 0 - Disabled + /// @li 1 - Enabled + BOOLEAN LpcClk0; ///< Lclk0En - LPCCLK0 + /// @par + /// LPC Clock 0 mode + /// @li 0 - forced to stop + /// @li 1 - functioning with CLKRUN protocol + BOOLEAN LpcClk1; ///< Lclk1En - LPCCLK1 + /// @par + /// LPC Clock 1 mode + /// @li 0 - forced to stop + /// @li 1 - functioning with CLKRUN protocol +// UINT32 SPI100_RX_Timing_Config_Register_38; ///< SPI100_RX_Timing_Config_Register_38 +// UINT16 SPI100_RX_Timing_Config_Register_3C; ///< SPI100_RX_Timing_Config_Register_3C +// UINT8 SpiProtectEn0_1d_34; /// + UINT8 SPI100_Enable; /// + SPI_DEVICE_PROFILE SpiDeviceProfile; /// Spi Device Profile +} FCH_SPI; + + +/// +/// IDE structure +/// +typedef struct { + BOOLEAN IdeEnable; ///< IDE function switch + BOOLEAN IdeMsiEnable; ///< IDE MSI capability + UINT32 IdeSsid; ///< IDE controller Subsystem ID +} FCH_IDE; + +/// +/// IR Structure +/// +typedef struct { + IR_CONFIG IrConfig; ///< IrConfig + UINT8 IrPinControl; ///< IrPinControl +} FCH_IR; + + +/// +/// PCI Bridge Structure +/// +typedef struct { + BOOLEAN PcibMsiEnable; ///< PCI-PCI Bridge MSI capability + UINT32 PcibSsid; ///< PCI-PCI Bridge Subsystem ID + UINT8 PciClks; ///< 33MHz PCICLK0/1/2/3 Enable, bits [0:3] used + /// @li 0 - disable + /// @li 1 - enable + /// + UINT16 PcibClkStopOverride; ///< PCIB_CLK_Stop Override + BOOLEAN PcibClockRun; ///< Enable the auto clkrun functionality + /// @li 0 - disable + /// @li 1 - enable + /// +} FCH_PCIB; + + +/// +/// - SATA Phy setting structure +/// +typedef struct _SATA_PHY_SETTING { + UINT16 PhyCoreControlWord; /// PhyCoreControlWord - Reserved + UINT32 PhyFineTuneDword; /// PhyFineTuneDword - Reserved +} SATA_PHY_SETTING; + +/// +/// SATA main setting structure +/// +typedef struct _SATA_ST { + UINT8 SataModeReg; ///< SataModeReg - Sata Controller Mode + BOOLEAN SataEnable; ///< SataEnable - Sata Controller Function + /// @par + /// Sata Controller + /// @li 0 - disable + /// @li 1 - enable + /// + UINT8 Sata6AhciCap; ///< Sata6AhciCap - Reserved */ + BOOLEAN SataSetMaxGen2; ///< SataSetMaxGen2 - Set Sata Max Gen2 mode + /// @par + /// Sata Controller Set to Max Gen2 mode + /// @li 0 - disable + /// @li 1 - enable + /// + BOOLEAN IdeEnable; ///< IdeEnable - Ide Controller Mode + /// @par + /// Sata IDE Controller set to Combined Mode + /// @li 0 - disable + /// @li 1 - enable + /// + UINT8 SataClkMode; /// SataClkMode - Reserved +} SATA_ST; + +/// +/// SATA_PORT_ST - SATA PORT structure +/// +typedef struct _SATA_PORT_ST { + UINT8 SataPortReg; ///< SATA Port bit map - bits[0:7] for ports 0 ~ 7 + /// @li 0 - disable + /// @li 1 - enable + /// + BOOLEAN Port0; ///< PORT0 - 0:disable, 1:enable + BOOLEAN Port1; ///< PORT1 - 0:disable, 1:enable + BOOLEAN Port2; ///< PORT2 - 0:disable, 1:enable + BOOLEAN Port3; ///< PORT3 - 0:disable, 1:enable + BOOLEAN Port4; ///< PORT4 - 0:disable, 1:enable + BOOLEAN Port5; ///< PORT5 - 0:disable, 1:enable + BOOLEAN Port6; ///< PORT6 - 0:disable, 1:enable + BOOLEAN Port7; ///< PORT7 - 0:disable, 1:enable +} SATA_PORT_ST; + +/// +///< _SATA_PORT_MD - Force Each PORT to GEN1/GEN2 mode +/// +typedef struct _SATA_PORT_MD { + UINT16 SataPortMode; ///< SATA Port GEN1/GEN2 mode bit map - bits [0:15] for ports 0 ~ 7 + UINT8 Port0; ///< PORT0 - set BIT0 to GEN1, BIT1 - PORT0 set to GEN2 + UINT8 Port1; ///< PORT1 - set BIT2 to GEN1, BIT3 - PORT1 set to GEN2 + UINT8 Port2; ///< PORT2 - set BIT4 to GEN1, BIT5 - PORT2 set to GEN2 + UINT8 Port3; ///< PORT3 - set BIT6 to GEN1, BIT7 - PORT3 set to GEN2 + UINT8 Port4; ///< PORT4 - set BIT8 to GEN1, BIT9 - PORT4 set to GEN2 + UINT8 Port5; ///< PORT5 - set BIT10 to GEN1, BIT11 - PORT5 set to GEN2 + UINT8 Port6; ///< PORT6 - set BIT12 to GEN1, BIT13 - PORT6 set to GEN2 + UINT8 Port7; ///< PORT7 - set BIT14 to GEN1, BIT15 - PORT7 set to GEN2 +} SATA_PORT_MD; +/// +/// SATA structure +/// +typedef struct { + BOOLEAN SataMsiEnable; ///< SATA MSI capability + UINT32 SataIdeSsid; ///< SATA IDE mode SSID + UINT32 SataRaidSsid; ///< SATA RAID mode SSID + UINT32 SataRaid5Ssid; ///< SATA RAID 5 mode SSID + UINT32 SataAhciSsid; ///< SATA AHCI mode SSID + + SATA_ST SataMode; /// SataMode - Reserved + SATA_CLASS SataClass; ///< SataClass - SATA Controller mode [2:0] + UINT8 SataIdeMode; ///< SataIdeMode - Sata IDE Controller mode + /// @par + /// @li 0 - Legacy IDE mode + /// @li 1 - Native IDE mode + /// + UINT8 SataDisUnusedIdePChannel; ///< SataDisUnusedIdePChannel-Disable Unused IDE Primary Channel + /// @par + /// @li 0 - Channel Enable + /// @li 1 - Channel Disable + /// + UINT8 SataDisUnusedIdeSChannel; ///< SataDisUnusedIdeSChannel - Disable Unused IDE Secondary Channel + /// @par + /// @li 0 - Channel Enable + /// @li 1 - Channel Disable + /// + UINT8 IdeDisUnusedIdePChannel; ///< IdeDisUnusedIdePChannel-Disable Unused IDE Primary Channel + /// @par + /// @li 0 - Channel Enable + /// @li 1 - Channel Disable + /// + UINT8 IdeDisUnusedIdeSChannel; ///< IdeDisUnusedIdeSChannel-Disable Unused IDE Secondary Channel + /// @par + /// @li 0 - Channel Enable + /// @li 1 - Channel Disable + /// + UINT8 SataOptionReserved; /// SataOptionReserved - Reserved + + SATA_PORT_ST SataEspPort; ///< SataEspPort - SATA port is external accessible on a signal only connector (eSATA:) + + SATA_PORT_ST SataPortPower; ///< SataPortPower - Port Power configuration + + SATA_PORT_MD SataPortMd; ///< SataPortMd - Port Mode + + UINT8 SataAggrLinkPmCap; /// SataAggrLinkPmCap - 0:OFF 1:ON + UINT8 SataPortMultCap; /// SataPortMultCap - 0:OFF 1:ON + UINT8 SataClkAutoOff; /// SataClkAutoOff - AutoClockOff 0:Disabled, 1:Enabled + UINT8 SataPscCap; /// SataPscCap 1:Enable PSC, 0:Disable PSC capability + UINT8 BiosOsHandOff; /// BiosOsHandOff - Reserved + UINT8 SataFisBasedSwitching; /// SataFisBasedSwitching - Reserved + UINT8 SataCccSupport; /// SataCccSupport - Reserved + UINT8 SataSscCap; /// SataSscCap - 1:Enable, 0:Disable SSC capability + UINT8 SataMsiCapability; /// SataMsiCapability 0:Hidden 1:Visible + UINT8 SataForceRaid; /// SataForceRaid 0:No function 1:Force RAID + UINT8 SataInternal100Spread; /// SataInternal100Spread - Reserved + UINT8 SataDebugDummy; /// SataDebugDummy - Reserved + UINT8 SataTargetSupport8Device; /// SataTargetSupport8Device - Reserved + UINT8 SataDisableGenericMode; /// SataDisableGenericMode - Reserved + BOOLEAN SataAhciEnclosureManagement; /// SataAhciEnclosureManagement - Reserved + UINT8 SataSgpio0; /// SataSgpio0 - Reserved + UINT8 SataSgpio1; /// SataSgpio1 - Reserved + UINT8 SataPhyPllShutDown; /// SataPhyPllShutDown - Reserved + BOOLEAN SataHotRemovalEnh; /// SataHotRemovalEnh - Reserved + + SATA_PORT_ST SataHotRemovalEnhPort; ///< SataHotRemovalEnhPort - Hot Remove + + BOOLEAN SataOobDetectionEnh; /// SataOobDetectionEnh - TRUE + BOOLEAN SataPowerSavingEnh; /// SataPowerSavingEnh - TRUE + UINT8 SataMemoryPowerSaving; /// SataMemoryPowerSaving - 0-3 Default [3] + BOOLEAN SataRasSupport; /// SataRasSupport - Support RAS function TRUE: Enable FALSE: Disable + BOOLEAN SataAhciDisPrefetchFunction; /// SataAhciDisPrefetchFunction - Disable AHCI Prefetch Function Support + BOOLEAN SataDevSlpPort0; /// SataDevSlpPort0 - Reserved + BOOLEAN SataDevSlpPort1; /// SataDevSlpPort1 - Reserved + UINT32 TempMmio; /// TempMmio - Reserved +} FCH_SATA; + + +// +// IMC Message Register Software Interface +// +#define CPU_MISC_BUS_DEV_FUN ((0x18 << 3) + 3) + +#define MSG_SYS_TO_IMC 0x80 +#define Fun_80 0x80 +#define Fun_81 0x81 +#define Fun_82 0x82 +#define Fun_83 0x83 +#define Fun_84 0x84 +#define Fun_85 0x85 +#define Fun_86 0x86 +#define Fun_87 0x87 +#define Fun_88 0x88 +#define Fun_89 0x89 +#define Fun_90 0x90 +#define MSG_IMC_TO_SYS 0x81 +#define MSG_REG0 0x82 +#define MSG_REG1 0x83 +#define MSG_REG2 0x84 +#define MSG_REG3 0x85 +#define MSG_REG4 0x86 +#define MSG_REG5 0x87 +#define MSG_REG6 0x88 +#define MSG_REG7 0x89 +#define MSG_REG8 0x8A +#define MSG_REG9 0x8B +#define MSG_REGA 0x8C +#define MSG_REGB 0x8D +#define MSG_REGC 0x8E +#define MSG_REGD 0x8F + +#define DISABLED 0 +#define ENABLED 1 + + + +/// +/// EC structure +/// +typedef struct _FCH_EC { + UINT8 MsgFun81Zone0MsgReg0; ///00 - by default strapping + /// @li 01 - enable + /// @li 10 - disable + /// +} FCH_IMC; + + +/// +/// Hpet structure +/// +typedef struct { + BOOLEAN HpetEnable; ///< HPET function switch + + BOOLEAN HpetMsiDis; ///< HpetMsiDis - South Bridge HPET MSI Configuration + /// @par + /// @li 1 - disable + /// @li 0 - enable + + UINT32 HpetBase; ///< HpetBase + /// @par + /// HPET Base address +} FCH_HPET; + + +/// +/// GCPU related parameters +/// +typedef struct { + UINT8 AcDcMsg; ///< Send a message to CPU to indicate the power mode (AC vs battery) + /// @li 1 - disable + /// @li 0 - enable + + UINT8 TimerTickTrack; ///< Send a message to CPU to indicate the latest periodic timer interval + /// @li 1 - disable + /// @li 0 - enable + + UINT8 ClockInterruptTag; ///< Mark the periodic timer interrupt + /// @li 1 - disable + /// @li 0 - enable + + UINT8 OhciTrafficHanding; ///< Cause CPU to break out from C state when USB OHCI has pending traffic + /// @li 1 - disable + /// @li 0 - enable + + UINT8 EhciTrafficHanding; ///< Cause CPU to break out from C state when USB EHCI has pending traffic + /// @li 1 - disable + /// @li 0 - enable + + UINT8 GcpuMsgCMultiCore; ///< Track of CPU C state by monitoring each core's C state message + /// @li 1 - disable + /// @li 0 - enable + + UINT8 GcpuMsgCStage; ///< Enable the FCH C state coordination logic + /// @li 1 - disable + /// @li 0 - enable +} FCH_GCPU; + + +/// +/// Timer +/// +typedef struct { + BOOLEAN Enable; ///< Whether to register timer SMI in POST + BOOLEAN StartNow; ///< Whether to start the SMI immediately during registration + UINT16 CycleDuration; ///< [14:0] - Actual cycle duration = CycleDuration + 1 +} TIMER_SMI; + + +/// +/// MISC structure +/// +typedef struct { + BOOLEAN NativePcieSupport; /// PCIe NativePcieSupport - Debug function. 1:Enabled, 0:Disabled + BOOLEAN S3Resume; /// S3Resume - Flag of ACPI S3 Resume. + BOOLEAN RebootRequired; /// RebootRequired - Flag of Reboot system is required. + UINT8 FchVariant; /// FchVariant - FCH Variant value. + UINT8 Cg2Pll; ///< CG2 PLL - 0:disable, 1:enable + TIMER_SMI LongTimer; ///< Long Timer SMI + TIMER_SMI ShortTimer; ///< Short Timer SMI + UINT32 FchCpuId; ///< Saving CpuId for FCH Module. +} FCH_MISC; + + +/// +/// SMBus structure +/// +typedef struct { + UINT32 SmbusSsid; ///< SMBUS controller Subsystem ID +} FCH_SMBUS; + + +/// +/// Acpi structure +/// +typedef struct { + UINT16 Smbus0BaseAddress; ///< Smbus0BaseAddress + /// @par + /// Smbus BASE Address + /// + UINT16 Smbus1BaseAddress; ///< Smbus1BaseAddress + /// @par + /// Smbus1 (ASF) BASE Address + /// + UINT16 SioPmeBaseAddress; ///< SioPmeBaseAddress + /// @par + /// SIO PME BASE Address + /// + UINT32 WatchDogTimerBase; ///< WatchDogTimerBase + /// @par + /// Watch Dog Timer Address + /// + UINT16 AcpiPm1EvtBlkAddr; ///< AcpiPm1EvtBlkAddr + /// @par + /// ACPI PM1 event block Address + /// + UINT16 AcpiPm1CntBlkAddr; ///< AcpiPm1CntBlkAddr + /// @par + /// ACPI PM1 Control block Address + /// + UINT16 AcpiPmTmrBlkAddr; ///< AcpiPmTmrBlkAddr + /// @par + /// ACPI PM timer block Address + /// + UINT16 CpuControlBlkAddr; ///< CpuControlBlkAddr + /// @par + /// ACPI CPU control block Address + /// + UINT16 AcpiGpe0BlkAddr; ///< AcpiGpe0BlkAddr + /// @par + /// ACPI GPE0 block Address + /// + UINT16 SmiCmdPortAddr; ///< SmiCmdPortAddr + /// @par + /// SMI command port Address + /// + UINT16 AcpiPmaCntBlkAddr; ///< AcpiPmaCntBlkAddr + /// @par + /// ACPI PMA Control block Address + /// + BOOLEAN AnyHt200MhzLink; ///< AnyHt200MhzLink + /// @par + /// HT Link Speed on 200MHz option for each CPU specific LDTSTP# (Force enable) + /// + BOOLEAN SpreadSpectrum; ///< SpreadSpectrum + /// @par + /// Spread Spectrum function + /// @li 0 - disable + /// @li 1 - enable + /// + POWER_FAIL PwrFailShadow; ///< PwrFailShadow = PM_Reg: 5Bh [3:0] + /// @par + /// @li 00 - Always off + /// @li 01 - Always on + /// @li 11 - Use previous + /// + UINT8 StressResetMode; ///< StressResetMode 01-10 + /// @li 00 - Disabed + /// @li 01 - Io Write 0x64 with 0xfe + /// @li 10 - Io Write 0xcf9 with 0x06 + /// @li 11 - Io Write 0xcf9 with 0x0e + /// + BOOLEAN MtC1eEnable; /// MtC1eEnable - Enable MtC1e + VOID* OemProgrammingTablePtr; /// Pointer of ACPI OEM table + UINT8 SpreadSpectrumOptions; /// SpreadSpectrumOptions - Spread Spectrum Option +} FCH_ACPI; + + +/// +/// HWM temp parameter structure +/// +typedef struct _FCH_HWM_TEMP_PAR { + UINT16 At; ///< At + UINT16 Ct; ///< Ct + UINT8 Mode; ///< Mode BIT0:HiRatio BIT1:HiCurrent +} FCH_HWM_TEMP_PAR; + +/// +/// HWM Current structure +/// +typedef struct _FCH_HWM_CUR { + UINT16 FanSpeed[5]; ///< FanSpeed - fan Speed + UINT16 Temperature[5]; ///< Temperature - temperature + UINT16 Voltage[8]; ///< Voltage - voltage +} FCH_HWM_CUR; + +/// +/// HWM fan control structure +/// +typedef struct _FCH_HWM_FAN_CTR { + UINT8 InputControlReg00; /// Fan Input Control register, PM2 offset [0:4]0 + UINT8 ControlReg01; /// Fan control register, PM2 offset [0:4]1 + UINT8 FreqReg02; /// Fan frequency register, PM2 offset [0:4]2 + UINT8 LowDutyReg03; /// Low Duty register, PM2 offset [0:4]3 + UINT8 MedDutyReg04; /// Med Duty register, PM2 offset [0:4]4 + UINT8 MultiplierReg05; /// Multiplier register, PM2 offset [0:4]5 + UINT16 LowTempReg06; /// Low Temp register, PM2 offset [0:4]6 + UINT16 MedTempReg08; /// Med Temp register, PM2 offset [0:4]8 + UINT16 HighTempReg0A; /// High Temp register, PM2 offset [0:4]A + UINT8 LinearRangeReg0C; /// Linear Range register, PM2 offset [0:4]C + UINT8 LinearHoldCountReg0D; /// Linear Hold Count register, PM2 offset [0:4]D +} FCH_HWM_FAN_CTR; + +/// +/// Hwm structure +/// +typedef struct _FCH_HWM { + UINT8 HwMonitorEnable; ///< HwMonitorEnable + UINT32 HwmControl; ///< hwmControl + /// @par + /// HWM control configuration + /// @li 0 - HWM is Enabled + /// @li 1 - IMC is Enabled + /// + UINT8 FanSampleFreqDiv; ///< Sampling rate of Fan Speed + /// @li 00 - Base(22.5KHz) + /// @li 01 - Base(22.5KHz)/2 + /// @li 10 - Base(22.5KHz)/4 + /// @li 11 - Base(22.5KHz)/8 + /// + UINT8 HwmFchtsiAutoPoll; ///< TSI Auto Polling + /// @li 0 - disable + /// @li 1 - enable + /// + UINT8 HwmFchtsiAutoPollStarted; ///< HwmSbtsiAutoPollStarted + UINT8 FanLinearEnhanceEn; ///< FanLinearEnhanceEn + UINT8 FanLinearHoldFix; ///< FanLinearHoldFix + UINT8 FanLinearRangeOutLimit; ///< FanLinearRangeOutLimit + UINT16 HwmCalibrationFactor; /// Calibration Factor + FCH_HWM_CUR HwmCurrent; /// HWM Current structure + FCH_HWM_CUR HwmCurrentRaw; /// HWM Current Raw structure + FCH_HWM_TEMP_PAR HwmTempPar[5]; /// HWM Temp parameter structure + FCH_HWM_FAN_CTR HwmFanControl[5]; /// HWM Fan Control structure + FCH_HWM_FAN_CTR HwmFanControlCooked[5]; /// HWM Fan Control structure +} FCH_HWM; + + +/// +/// Gec structure +/// +typedef struct { + BOOLEAN Enable; ///< GecEnable - GEC function switch +} FCH_F1; + + +/// +/// _ABTblEntry - AB link register table R/W structure +/// +typedef struct _AB_TBL_ENTRY { + UINT8 RegType; /// RegType : AB Register Type (ABCFG, AXCFG and so on) + UINT32 RegIndex; /// RegIndex : AB Register Index + UINT32 RegMask; /// RegMask : AB Register Mask + UINT32 RegData; /// RegData : AB Register Data +} AB_TBL_ENTRY; + +/// +/// AB structure +/// +typedef struct { + BOOLEAN AbMsiEnable; ///< ABlink MSI capability + UINT8 ALinkClkGateOff; /// Alink Clock Gate-Off function - 0:disable, 1:enable *KR + UINT8 BLinkClkGateOff; /// Blink Clock Gate-Off function - 0:disable, 1:enable *KR + UINT8 AbClockGating; /// AB Clock Gating - 0:disable, 1:enable *KR + UINT8 GppClockGating; /// GPP Clock Gating - 0:disable, 1:enable + UINT8 UmiL1TimerOverride; /// UMI L1 inactivity timer overwrite value + UINT8 UmiLinkWidth; /// UMI Link Width + UINT8 UmiDynamicSpeedChange; /// UMI Dynamic Speed Change - 0:disable, 1:enable + UINT8 PcieRefClockOverClocking; /// PCIe Ref Clock OverClocking value + UINT8 UmiGppTxDriverStrength; /// UMI GPP TX Driver Strength + BOOLEAN NbSbGen2; /// UMI link Gen2 - 0:Gen1, 1:Gen2 + UINT8 PcieOrderRule; /// PCIe Order Rule - 0:disable, 1:enable *KR AB Posted Pass Non-Posted + UINT8 SlowSpeedAbLinkClock; /// Slow Speed AB Link Clock - 0:disable, 1:enable *KR + BOOLEAN ResetCpuOnSyncFlood; /// Reset Cpu On Sync Flood - 0:disable, 1:enable *KR + BOOLEAN AbDmaMemoryWrtie3264B; /// AB DMA Memory Write 32/64 BYTE Support *KR only + BOOLEAN AbMemoryPowerSaving; /// AB Memory Power Saving *KR only + BOOLEAN SbgDmaMemoryWrtie3264ByteCount; /// SBG DMA Memory Write 32/64 BYTE Count Support *KR only + BOOLEAN SbgMemoryPowerSaving; /// SBG Memory Power Saving *KR only +} FCH_AB; + + +/** + * PCIE_CAP_ID - PCIe Cap ID + * + */ +#define PCIE_CAP_ID 0x10 + +/// +/// FCH_GPP_PORT_CONFIG - Fch GPP port config structure +/// +typedef struct { + BOOLEAN PortPresent; ///< Port connection + /// @par + /// @li 0 - Port doesn't have slot. No need to train the link + /// @li 1 - Port connection defined and needs to be trained + /// + BOOLEAN PortDetected; ///< Link training status + /// @par + /// @li 0 - EP not detected + /// @li 1 - EP detected + /// + BOOLEAN PortIsGen2; ///< Port link speed configuration + /// @par + /// @li 00 - Auto + /// @li 01 - Forced GEN1 + /// @li 10 - Forced GEN2 + /// @li 11 - Reserved + /// + BOOLEAN PortHotPlug; ///< Support hot plug? + /// @par + /// @li 0 - No support + /// @li 1 - support + /// + UINT8 PortMisc; /// PortMisc - Reserved +} FCH_GPP_PORT_CONFIG; + +/// +/// GPP structure +/// +typedef struct { + FCH_GPP_PORT_CONFIG PortCfg[4]; /// GPP port configuration structure + GPP_LINKMODE GppLinkConfig; ///< GppLinkConfig - PCIE_GPP_Enable[3:0] + /// @li 0000 - Port ABCD -> 4:0:0:0 + /// @li 0010 - Port ABCD -> 2:2:0:0 + /// @li 0011 - Port ABCD -> 2:1:1:0 + /// @li 0100 - Port ABCD -> 1:1:1:1 + /// + BOOLEAN GppFunctionEnable; ///< GPP Function - 0:disable, 1:enable + BOOLEAN GppToggleReset; ///< Toggle GPP core reset + UINT8 GppHotPlugGeventNum; ///< Hotplug GEVENT # - valid value 0-31 + UINT8 GppFoundGfxDev; ///< Gpp Found Gfx Device + /// @li 0 - Not found + /// @li 1 - Found + /// + BOOLEAN GppGen2; ///< GPP Gen2 - 0:disable, 1:enable + UINT8 GppGen2Strap; ///< GPP Gen2 Strap - 0:disable, 1:enable, FCH itself uses this + BOOLEAN GppMemWrImprove; ///< GPP Memory Write Improve - 0:disable, 1:enable + BOOLEAN GppUnhidePorts; ///< GPP Unhide Ports - 0:disable, 1:enable + UINT8 GppPortAspm; ///< GppPortAspm - ASPM state for all GPP ports + /// @li 01 - Disabled + /// @li 01 - L0s + /// @li 10 - L1 + /// @li 11 - L0s + L1 + /// + BOOLEAN GppLaneReversal; ///< GPP Lane Reversal - 0:disable, 1:enable + BOOLEAN GppPhyPllPowerDown; ///< GPP PHY PLL Power Down - 0:disable, 1:enable + BOOLEAN GppDynamicPowerSaving; ///< GPP Dynamic Power Saving - 0:disable, 1:enable + BOOLEAN PcieAer; ///< PcieAer - Advanced Error Report: 0/1-disable/enable + BOOLEAN PcieRas; ///< PCIe RAS - 0:disable, 1:enable + BOOLEAN PcieCompliance; ///< PCIe Compliance - 0:disable, 1:enable + BOOLEAN PcieSoftwareDownGrade; ///< PCIe Software Down Grade + BOOLEAN UmiPhyPllPowerDown; ///< UMI PHY PLL Power Down - 0:disable, 1:enable + BOOLEAN SerialDebugBusEnable; ///< Serial Debug Bus Enable + UINT8 GppHardwareDownGrade; ///< GppHardwareDownGrade - Gpp HW Down Grade function 0:Disable, 1-4: portA-D + UINT8 GppL1ImmediateAck; ///< GppL1ImmediateAck - Gpp L1 Immediate ACK 0: enable, 1: disable + BOOLEAN NewGppAlgorithm; ///< NewGppAlgorithm - New GPP procedure + UINT8 HotPlugPortsStatus; ///< HotPlugPortsStatus - Save Hot-Plug Ports Status + UINT8 FailPortsStatus; ///< FailPortsStatus - Save Failure Ports Status + UINT8 GppPortMinPollingTime; ///< GppPortMinPollingTime - Min. Polling time for Gpp Port Training + BOOLEAN IsCapsuleMode; ///< IsCapsuleMode - Support Capsule Mode in FCH +} FCH_GPP; + + +/// +/// FCH USB sturcture +/// +typedef struct { + BOOLEAN Ohci1Enable; ///< OHCI1 controller enable + BOOLEAN Ohci2Enable; ///< OHCI2 controller enable + BOOLEAN Ohci3Enable; ///< OHCI3 controller enable + BOOLEAN Ohci4Enable; ///< OHCI4 controller enable + BOOLEAN Ehci1Enable; ///< EHCI1 controller enable + BOOLEAN Ehci2Enable; ///< EHCI2 controller enable + BOOLEAN Ehci3Enable; ///< EHCI3 controller enable + BOOLEAN Xhci0Enable; ///< XHCI0 controller enable + BOOLEAN Xhci1Enable; ///< XHCI1 controller enable + BOOLEAN UsbMsiEnable; ///< USB MSI capability + UINT32 OhciSsid; ///< OHCI SSID + UINT32 Ohci4Ssid; ///< OHCI 4 SSID + UINT32 EhciSsid; ///< EHCI SSID + UINT32 XhciSsid; ///< XHCI SSID + BOOLEAN UsbPhyPowerDown; ///< USB PHY Power Down - 0:disable, 1:enable + UINT32 UserDefineXhciRomAddr; ///< XHCI ROM address define by platform BIOS + UINT8 Ehci1Phy[5]; ///< EHCI1 USB PHY Driving Strength value table + UINT8 Ehci2Phy[5]; ///< EHCI2 USB PHY Driving Strength value table + UINT8 Ehci3Phy[4]; ///< EHCI3 USB PHY Driving Strength value table + UINT8 Xhci20Phy[4]; ///< XHCI USB 2.0 PHY Driving Strength value table +} FCH_USB; + + +/// Private: FCH_DATA_BLOCK_RESET +typedef struct _FCH_RESET_DATA_BLOCK { + AMD_CONFIG_PARAMS *StdHeader; ///< Header structure + FCH_RESET_INTERFACE FchReset; ///< Reset interface + + UINT8 FastSpeed; ///< SPI FastSpeed: 1-66MHz, 2-33MHz, 3-22MHz, 4-16.5MHz, 5-100Mhz + UINT8 WriteSpeed; ///< SPI Write Speed: 1-66MHz, 2-33MHz, 3-22MHz, 4-16.5MHz, 5-100Mhz + UINT8 Mode; ///< SPI Mode + /// @li 101 - Qual-io 1-4-4 + /// @li 100 - Dual-io 1-2-2 + /// @li 011 - Qual-io 1-1-4 + /// @li 010 - Dual-io 1-1-2 + /// @li 111 - FastRead + /// @li 110 - Normal + /// + UINT8 AutoMode; ///< SPI Auto Mode - 0:disable, 1:enable + UINT8 BurstWrite; ///< SPI Burst Write - 0:disable, 1:enable + BOOLEAN Sata6AhciCap; ///< SATA 6 AHCI Capability - TRUE:enable, FALSE:disable + UINT8 Cg2Pll; ///< CG2 PLL - 0:disable, 1:enable + BOOLEAN EcKbd; ///< EC KBD - 0:disable, 1:enable + BOOLEAN LegacyFree; ///< Legacy Free - 0:disable, 1:enable + BOOLEAN SataSetMaxGen2; ///< SATA enable maximum GEN2 + UINT8 SataClkMode; ///< SATA reference clock selector and divider + UINT8 SataModeReg; ///< Output: SATAConfig PMIO:0xDA + BOOLEAN SataInternal100Spread; ///< SATA internal 100MHz spread ON/OFF + UINT8 SpiSpeed; ///< SPI NormSpeed: 1-66MHz, 2-33MHz, 3-22MHz, 4-16.5MHz, 5-100Mhz +// UINT32 SPI100_RX_Timing_Config_Register_38; ///< SPI100_RX_Timing_Config_Register_38 +// UINT16 SPI100_RX_Timing_Config_Register_3C; ///< SPI100_RX_Timing_Config_Register_3C +// UINT8 SpiProtectEn0_1d_34; /// + UINT8 SPI100_Enable; /// + BOOLEAN EcChannel0; ///< Enable EC channel 0 + FCH_GPP Gpp; ///< GPP subsystem + FCH_SPI Spi; ///< SPI subsystem + BOOLEAN QeEnabled; /// Quad Mode Enabled +// VOID* OemSpiDeviceTable; /// Pointer of OEM Spi Device table + VOID* OemResetProgrammingTablePtr; /// Pointer of ACPI OEM table +} FCH_RESET_DATA_BLOCK; + + +/// Private: FCH_DATA_BLOCK +typedef struct _FCH_DATA_BLOCK { + AMD_CONFIG_PARAMS *StdHeader; ///< Header structure + + FCH_ACPI HwAcpi; ///< ACPI structure + FCH_AB Ab; ///< AB structure + FCH_GPP Gpp; ///< GPP structure + FCH_USB Usb; ///< USB structure + FCH_SATA Sata; ///< SATA structure + FCH_SMBUS Smbus; ///< SMBus structure + FCH_IDE Ide; ///< IDE structure + FCH_AZALIA Azalia; + FCH_SPI Spi; ///< SPI structure + FCH_PCIB Pcib; ///< PCIB structure + FCH_F1 F1; ///< GEC structure + FCH_SD Sd; ///< SD structure + FCH_HWM Hwm; ///< Hardware Moniter structure + FCH_IR Ir; ///< IR structure + FCH_HPET Hpet; ///< HPET structure + FCH_GCPU Gcpu; ///< GCPU structure + FCH_IMC Imc; ///< IMC structure + FCH_MISC Misc; ///< MISC structure +} FCH_DATA_BLOCK; + +#pragma pack (pop) + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchDef.h b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchDef.h new file mode 100644 index 0000000000..1d717e47c2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchDef.h @@ -0,0 +1,438 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH routine definition + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#ifndef _FCH_DEF_H_ +#define _FCH_DEF_H_ + + +UINT32 ReadAlink (IN UINT32 Index, IN AMD_CONFIG_PARAMS *StdHeader); +VOID WriteAlink (IN UINT32 Index, IN UINT32 Data, IN AMD_CONFIG_PARAMS *StdHeader); +VOID RwAlink (IN UINT32 Index, IN UINT32 AndMask, IN UINT32 OrMask, IN AMD_CONFIG_PARAMS *StdHeader); +VOID ReadMem (IN UINT32 Address, IN UINT8 OpFlag, IN VOID *ValuePtr); +VOID WriteMem (IN UINT32 Address, IN UINT8 OpFlag, IN VOID *ValuePtr); +VOID RwMem (IN UINT32 Address, IN UINT8 OpFlag, IN UINT32 Mask, IN UINT32 Data); +VOID ReadPci (IN UINT32 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID WritePci (IN UINT32 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID RwPci (IN UINT32 Address, IN UINT8 OpFlag, IN UINT32 Mask, IN UINT32 Data, IN AMD_CONFIG_PARAMS *StdHeader); +VOID ProgramPciByteTable (IN REG8_MASK* pPciByteTable, IN UINT16 dwTableSize, IN AMD_CONFIG_PARAMS *StdHeader); +VOID ProgramFchAcpiMmioTbl (IN ACPI_REG_WRITE *pAcpiTbl, IN AMD_CONFIG_PARAMS *StdHeader); +VOID ProgramFchSciMapTbl (IN SCI_MAP_CONTROL *pSciMapTbl, IN FCH_RESET_DATA_BLOCK *FchResetDataBlock); +VOID ProgramFchGpioTbl (IN GPIO_CONTROL *pGpioTbl, IN FCH_RESET_DATA_BLOCK *FchResetDataBlock); +VOID ProgramFchSataPhyTbl (IN SATA_PHY_CONTROL *pSataPhyTbl, IN FCH_RESET_DATA_BLOCK *FchResetDataBlock); +VOID GetChipSysMode (IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +BOOLEAN IsImcEnabled (IN AMD_CONFIG_PARAMS *StdHeader); +VOID ReadPmio (IN UINT8 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID WritePmio (IN UINT8 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID RwPmio (IN UINT8 Address, IN UINT8 OpFlag, IN UINT32 AndMask, IN UINT32 OrMask, IN AMD_CONFIG_PARAMS *StdHeader); +VOID ReadPmio2 (IN UINT8 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID WritePmio2 (IN UINT8 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID RwPmio2 (IN UINT8 Address, IN UINT8 OpFlag, IN UINT32 AndMask, IN UINT32 OrMask, IN AMD_CONFIG_PARAMS *StdHeader); +VOID ReadBiosram (IN UINT8 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID WriteBiosram (IN UINT8 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID GetFchAcpiMmioBase (OUT UINT32 *AcpiMmioBase, IN AMD_CONFIG_PARAMS *StdHeader); +VOID GetFchAcpiPmBase (OUT UINT16 *AcpiPmBase, IN AMD_CONFIG_PARAMS *StdHeader); +UINT8 ReadFchSleepType (IN AMD_CONFIG_PARAMS *StdHeader); + +/// +/// Fch Ab Routines +/// +/// Pei Phase +/// +VOID FchInitResetAb (IN VOID* FchDataPtr); +VOID FchProgramAbPowerOnReset (IN VOID* FchDataPtr); +/// +/// Dxe Phase +/// +VOID FchInitEnvAb (IN VOID* FchDataPtr); +VOID FchInitEnvAbSpecial (IN VOID* FchDataPtr); +VOID FchInitMidAb (IN VOID* FchDataPtr); +VOID FchInitLateAb (IN VOID* FchDataPtr); +/// +/// Other Public Routines +/// +VOID FchInitEnvAbLinkInit (IN VOID* FchDataPtr); +BOOLEAN IsUmiOneLaneGen1Mode (IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchAbLateProgram (IN VOID* FchDataPtr); + +/// +/// Fch Pcie Routines +/// +/// Pei Phase +/// +VOID FchInitResetPcie (IN VOID* FchDataPtr); +/// +/// Dxe Phase +/// +VOID FchInitEnvPcie (IN VOID* FchDataPtr); +VOID FchInitMidPcie (IN VOID* FchDataPtr); +VOID FchInitLatePcie (IN VOID* FchDataPtr); +VOID ProgramPcieNativeMode (IN VOID* FchDataPtr); + +/// +/// Fch Gpp Routines +/// +/// Pei Phase +/// +VOID FchInitResetGpp (IN VOID* FchDataPtr); +VOID ProgramFchGppInitReset (IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchResetPcie (IN RESET_BLOCK ResetBlock, IN RESET_OP ResetOp, IN AMD_CONFIG_PARAMS *StdHeader); + +/// +/// Dxe Phase +/// +VOID FchInitEnvGpp (IN VOID* FchDataPtr); +VOID FchInitMidGpp (IN VOID* FchDataPtr); +VOID FchInitLateGpp (IN VOID* FchDataPtr); + +/// +/// Common Gpp Routines +/// +VOID ProgramGppTogglePcieReset (IN BOOLEAN DoToggling, IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchGppForceGen1 (IN FCH_GPP *FchGpp, IN CONST UINT8 ActivePorts, IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchGppForceGen2 (IN FCH_GPP *FchGpp, IN CONST UINT8 ActivePorts, IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchGppDynamicPowerSaving (IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader); +UINT8 GppPortPollingLtssm (IN FCH_GPP *FchGpp, IN UINT8 ActivePorts, IN BOOLEAN IsGen2, IN AMD_CONFIG_PARAMS *StdHeader); +VOID GppGen2Workaround (IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader); +UINT8 FchFindPciCap (IN UINT32 PciAddress, IN UINT8 TargetCapId, IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchGppPortInit (IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchGppPortInitPhaseII (IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchGppPortInitS3Phase (IN FCH_GPP *FchGpp, IN AMD_CONFIG_PARAMS *StdHeader); +UINT32 GppGetFchTempBus (IN AMD_CONFIG_PARAMS *StdHeader); + +/// +/// Fch Azalia Routines +/// +/// Pei Phase +/// +VOID FchInitResetF1 (IN VOID *FchDataPtr); +/// +/// Dxe Phase +/// +VOID FchInitEnvAzalia (IN VOID *FchDataPtr); +VOID FchInitMidAzalia (IN VOID *FchDataPtr); +VOID FchInitLateAzalia (IN VOID *FchDataPtr); + + +/// Other Public Routines +/// +VOID FchInitGecController (IN VOID* FchDataPtr); +VOID FchSwInitGecBootRom (IN VOID* FchDataPtr); + +/// +/// Fch HwAcpi Routines +/// +/// Pei Phase +/// +VOID FchInitResetHwAcpiP (IN VOID *FchDataPtr); +VOID FchInitResetHwAcpi (IN VOID *FchDataPtr); +VOID ProgramFchHwAcpiResetP (IN VOID *FchDataPtr); +/// +/// Dxe Phase +/// +VOID FchInitEnvHwAcpiP (IN VOID *FchDataPtr); +VOID FchInitEnvHwAcpi (IN VOID *FchDataPtr); +VOID ProgramEnvPFchAcpiMmio (IN VOID *FchDataPtr); +VOID ProgramFchEnvHwAcpiPciReg (IN VOID *FchDataPtr); +VOID ProgramSpecificFchInitEnvAcpiMmio (IN VOID *FchDataPtr); +VOID ProgramFchEnvSpreadSpectrum (IN VOID *FchDataPtr); +VOID FchInitMidHwAcpi (IN VOID *FchDataPtr); +VOID FchInitLateHwAcpi (IN VOID *FchDataPtr); + +/// +/// Other Public Routines +/// +VOID HpetInit (IN VOID *FchDataPtr); +VOID C3PopupSetting (IN VOID *FchDataPtr); +VOID MtC1eEnable (IN VOID *FchDataPtr); +VOID GcpuRelatedSetting (IN VOID *FchDataPtr); +VOID StressResetModeLate (IN VOID *FchDataPtr); + +/// +/// Fch Hwm Routines +/// +/// Pei Phase +/// +/// +/// Dxe Phase +/// +/// +/// Other Public Routines +/// +VOID HwmInitRegister (IN VOID* FchDataPtr); +VOID FchECfancontrolservice (IN VOID* FchDataPtr); + + +/// +/// Fch Ide Routines +/// +VOID FchInitEnvIde (IN VOID* FchDataPtr); +VOID FchInitMidIde (IN VOID* FchDataPtr); +VOID FchInitLateIde (IN VOID* FchDataPtr); + + +/// +/// Fch Imc Routines +/// +/// Pei Phase +/// +VOID FchInitResetImc (IN VOID *FchDataPtr); +/// +/// Dxe Phase +/// +VOID FchInitEnvImc (IN VOID *FchDataPtr); +VOID FchInitMidImc (IN VOID *FchDataPtr); +VOID FchInitLateImc (IN VOID *FchDataPtr); +VOID FchInitEnvEc (IN VOID *FchDataPtr); +VOID FchInitMidEc (IN VOID *FchDataPtr); +VOID FchInitLateEc (IN VOID *FchDataPtr); +/// +/// Other Public Routines +/// +VOID EnterEcConfig (IN AMD_CONFIG_PARAMS *StdHeader); +VOID ExitEcConfig (IN AMD_CONFIG_PARAMS *StdHeader); +VOID ReadEc8 (IN UINT8 Address, IN UINT8* Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID WriteEc8 (IN UINT8 Address, IN UINT8* Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID RwEc8 (IN UINT8 Address, IN UINT8 AndMask, IN UINT8 OrMask, IN AMD_CONFIG_PARAMS *StdHeader); +VOID WriteECmsg (IN UINT8 Address, IN UINT8 OpFlag, IN VOID* Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID ReadECmsg (IN UINT8 Address, IN UINT8 OpFlag, OUT VOID* Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID WaitForEcLDN9MailboxCmdAck (IN AMD_CONFIG_PARAMS *StdHeader); + +VOID ImcSleep (IN VOID *FchDataPtr); +VOID ImcEnableSurebootTimer (IN VOID *FchDataPtr); +VOID ImcDisarmSurebootTimer (IN VOID *FchDataPtr); +VOID ImcDisableSurebootTimer (IN VOID *FchDataPtr); +VOID ImcWakeup (IN VOID *FchDataPtr); +VOID ImcIdle (IN VOID *FchDataPtr); +BOOLEAN ValidateImcFirmware (IN VOID *FchDataPtr); +VOID SoftwareToggleImcStrapping (IN VOID *FchDataPtr); + + +/// +/// Fch Ir Routines +/// +/// Dxe Phase +/// + +/// +/// Fch Pcib Routines +/// +/// Pei Phase +/// +VOID FchInitResetPcib (IN VOID* FchDataPtr); +VOID FchInitResetPcibPort80Enable (IN VOID* FchDataPtr); + + + +/// +/// Fch SATA Routines +/// +/// Pei Phase +/// +VOID FchInitResetSata (IN VOID *FchDataPtr); +VOID FchInitResetSataProgram (IN VOID *FchDataPtr); +/// +/// Dxe Phase +/// +VOID FchInitMidSata (IN VOID *FchDataPtr); +VOID FchInitEnvSata (IN VOID *FchDataPtr); +VOID FchInitEnvProgramSataPciRegs (IN VOID *FchDataPtr); +VOID FchInitMidProgramSataRegs (IN VOID *FchDataPtr); +VOID FchInitLateProgramSataRegs (IN VOID *FchDataPtr); + +VOID FchInitLateSata (IN VOID *FchDataPtr); +VOID FchInitEnvSataIde (IN VOID *FchDataPtr); +VOID FchInitMidSataIde (IN VOID *FchDataPtr); +VOID FchInitLateSataIde (IN VOID *FchDataPtr); +VOID FchInitEnvSataAhci (IN VOID *FchDataPtr); +VOID FchInitMidSataAhci (IN VOID *FchDataPtr); +VOID FchInitLateSataAhci (IN VOID *FchDataPtr); +VOID FchInitEnvSataRaid (IN VOID *FchDataPtr); +VOID FchInitMidSataRaid (IN VOID *FchDataPtr); +VOID FchInitLateSataRaid (IN VOID *FchDataPtr); +VOID FchInitEnvSataIde2Ahci (IN VOID *FchDataPtr); +VOID FchInitMidSataIde2Ahci (IN VOID *FchDataPtr); +VOID FchInitLateSataIde2Ahci (IN VOID *FchDataPtr); + +VOID SataAhciSetDeviceNumMsi (IN VOID *FchDataPtr); +VOID SataRaidSetDeviceNumMsi (IN VOID *FchDataPtr); +VOID SataIde2AhciSetDeviceNumMsi (IN VOID *FchDataPtr); +VOID SataSetIrqIntResource (IN VOID *FchDataPtr, IN AMD_CONFIG_PARAMS *StdHeader); +VOID SataBar5setting (IN VOID *FchDataPtr, IN UINT32 *Bar5Ptr); +VOID SataEnableWriteAccess (IN AMD_CONFIG_PARAMS *StdHeader); +VOID SataDisableWriteAccess (IN AMD_CONFIG_PARAMS *StdHeader); +VOID SataSetDeviceNumMsi (IN VOID *FchDataPtr); +VOID FchSataSetDeviceNumMsi (IN VOID *FchDataPtr); +VOID ShutdownUnconnectedSataPortClock (IN VOID *FchDataPtr, IN UINT32 Bar5); +VOID FchShutdownUnconnectedSataPortClock (IN VOID *FchDataPtr, IN UINT32 Bar5); +VOID SataDriveDetection (IN VOID *FchDataPtr, IN UINT32 *Bar5Ptr); +VOID FchSataDriveDetection (IN VOID *FchDataPtr, IN UINT32 *Bar5Ptr); +VOID FchSataGpioInitial (IN VOID *FchDataPtr); +VOID SataBar5RegSet (IN VOID *FchDataPtr); +VOID SataSetPortGenMode (IN VOID *FchDataPtr); +VOID FchSataSetPortGenMode (IN VOID *FchDataPtr); +VOID FchProgramSataPhy (IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchSataDriveFpga (IN VOID *FchDataPtr); + +/// +/// FCH USB Controller Public Function +/// +/// Pei Phase +/// +VOID FchInitResetUsb (IN VOID *FchDataPtr); +VOID FchInitResetOhci (IN VOID *FchDataPtr); +VOID FchInitResetEhci (IN VOID *FchDataPtr); +VOID FchInitResetXhci (IN VOID *FchDataPtr); +VOID FchInitResetXhciProgram (IN VOID *FchDataPtr); +/// +/// Dxe Phase +/// +VOID FchInitEnvUsb (IN VOID *FchDataPtr); +VOID FchInitMidUsb (IN VOID *FchDataPtr); +VOID FchInitLateUsb (IN VOID *FchDataPtr); +VOID FchInitEnvUsbOhci (IN VOID *FchDataPtr); +VOID FchInitMidUsbOhci (IN VOID *FchDataPtr); +VOID FchInitLateUsbOhci (IN VOID *FchDataPtr); +VOID FchInitEnvUsbEhci (IN VOID *FchDataPtr); +VOID FchInitMidUsbEhci (IN VOID *FchDataPtr); +VOID FchInitLateUsbEhci (IN VOID *FchDataPtr); +VOID FchInitEnvUsbXhci (IN VOID *FchDataPtr); +VOID FchInitMidUsbXhci (IN VOID *FchDataPtr); +VOID FchInitLateUsbXhci (IN VOID *FchDataPtr); +VOID FchInitMidUsbOhci1 (IN VOID *FchDataPtr); +VOID FchInitMidUsbOhci2 (IN VOID *FchDataPtr); +VOID FchInitMidUsbOhci3 (IN VOID *FchDataPtr); +VOID FchInitMidUsbOhci4 (IN VOID *FchDataPtr); +VOID FchInitMidUsbEhci1 (IN FCH_DATA_BLOCK *FchDataPtr); +VOID FchInitMidUsbEhci2 (IN FCH_DATA_BLOCK *FchDataPtr); +VOID FchInitMidUsbEhci3 (IN FCH_DATA_BLOCK *FchDataPtr); +/// +/// Other Public Routines +/// +VOID FchSetUsbEnableReg (IN FCH_DATA_BLOCK *FchDataPtr); +VOID FchOhciInitAfterPciInit (IN UINT32 Value, IN FCH_DATA_BLOCK* FchDataPtr); +VOID FchEhciInitAfterPciInit (IN UINT32 Value, IN FCH_DATA_BLOCK* FchDataPtr); +VOID FchXhciInitBeforePciInit (IN FCH_DATA_BLOCK* FchDataPtr); +VOID FchXhciInitIndirectReg (IN FCH_DATA_BLOCK* FchDataPtr); +VOID FchInitLateUsbXhciProgram (IN VOID *FchDataPtr); +VOID FchXhciUsbPhyCalibrated (IN FCH_DATA_BLOCK* FchDataPtr); + + +/// +/// Fch Sd Routines +/// +VOID FchInitEnvSd (IN VOID *FchDataPtr); +VOID FchInitMidSd (IN VOID *FchDataPtr); +VOID FchInitLateSd (IN VOID *FchDataPtr); + +/// +/// Other Public Routines +/// + +VOID FchInitEnvSdProgram (IN VOID *FchDataPtr); + +/// +/// Fch Spi Routines +/// +/// Pei Phase +/// +VOID FchInitResetSpi (IN VOID *FchDataPtr); +VOID FchInitResetLpc (IN VOID *FchDataPtr); +VOID FchInitResetLpcProgram (IN VOID *FchDataPtr); +/// +/// Dxe Phase +/// +VOID FchInitEnvSpi (IN VOID *FchDataPtr); +VOID FchInitMidSpi (IN VOID *FchDataPtr); +VOID FchInitLateSpi (IN VOID *FchDataPtr); +VOID FchInitEnvLpc (IN VOID *FchDataPtr); +VOID FchInitMidLpc (IN VOID *FchDataPtr); +VOID FchInitLateLpc (IN VOID *FchDataPtr); +VOID FchInitEnvLpcProgram (IN VOID *FchDataPtr); +/// +/// Other Public Routines +/// +VOID FchSpiUnlock (IN VOID *FchDataPtr); +VOID FchSpiLock (IN VOID *FchDataPtr); + +/*--------------------------- Documentation Pages ---------------------------*/ +VOID FchStall (IN UINT32 uSec, IN AMD_CONFIG_PARAMS *StdHeader); +VOID CimFchStall (IN UINT32 uSec, IN AMD_CONFIG_PARAMS *StdHeader); +VOID FchPciReset (IN AMD_CONFIG_PARAMS *StdHeader); +VOID OutPort80 (IN UINT32 pcode, IN AMD_CONFIG_PARAMS *StdHeader); +VOID TurnOffCG2 (OUT VOID); +VOID BackUpCG2 (OUT VOID); +VOID FchCopyMem (IN VOID* pDest, IN VOID* pSource, IN UINTN Length); +VOID* GetRomSigPtr (IN UINTN* RomSigPtr, IN AMD_CONFIG_PARAMS *StdHeader); +VOID RwXhciIndReg (IN UINT32 Index, IN UINT32 AndMask, IN UINT32 OrMask, IN AMD_CONFIG_PARAMS *StdHeader); +VOID RwXhci0IndReg (IN UINT32 Index, IN UINT32 AndMask, IN UINT32 OrMask, IN AMD_CONFIG_PARAMS *StdHeader); +VOID RwXhci1IndReg (IN UINT32 Index, IN UINT32 AndMask, IN UINT32 OrMask, IN AMD_CONFIG_PARAMS *StdHeader); +VOID ReadXhci0Phy (IN UINT32 Port, IN UINT32 Address, IN UINT32 *Value, IN AMD_CONFIG_PARAMS *StdHeader); +VOID AcLossControl (IN UINT8 AcLossControlValue); +VOID FchVgaInit (OUT VOID); +VOID RecordFchConfigPtr (IN UINT32 FchConfigPtr); +VOID ValidateFchVariant (IN VOID *FchDataPtr); +VOID RecordSmiStatus (IN AMD_CONFIG_PARAMS *StdHeader); +BOOLEAN IsGCPU (IN VOID *FchDataPtr); +BOOLEAN IsExternalClockMode (IN VOID *FchDataPtr); +VOID SbSleepTrapControl (IN BOOLEAN SleepTrap); + +AGESA_STATUS +FchSpiTransfer ( + IN UINT8 PrefixCode, + IN UINT8 Opcode, + IN OUT UINT8 *DataPtr, + IN UINT8 *AddressPtr, + IN UINT8 Length, + IN BOOLEAN WriteFlag, + IN BOOLEAN AddressFlag, + IN BOOLEAN DataFlag, + IN BOOLEAN FinishedFlag + ); + +BOOLEAN +FchPlatformSpiQe ( + IN VOID *FchDataPtr + ); + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchLib.c new file mode 100644 index 0000000000..091552a4bc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchLib.c @@ -0,0 +1,598 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH IO access common routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_COMMON_FCHLIB_FILECODE + +/**< FchStall - Reserved */ +VOID +FchStall ( + IN UINT32 uSec, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 timerAddr; + UINT32 startTime; + UINT32 elapsedTime; + + LibAmdMemRead (AccessWidth16, (UINT64) (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG64), &timerAddr, StdHeader); + if ( timerAddr == 0 ) { + uSec = uSec / 2; + while ( uSec != 0 ) { + LibAmdIoRead (AccessWidth8, FCHOEM_IO_DELAY_PORT, (UINT8 *) (&startTime), StdHeader); + uSec--; + } + } else { + LibAmdIoRead (AccessWidth32, timerAddr, &startTime, StdHeader); + for ( ;; ) { + LibAmdIoRead (AccessWidth32, timerAddr, &elapsedTime, StdHeader); + if ( elapsedTime < startTime ) { + elapsedTime = elapsedTime + FCH_MAX_TIMER - startTime; + } else { + elapsedTime = elapsedTime - startTime; + } + if ( (elapsedTime * FCHOEM_ELAPSED_TIME_UNIT / FCHOEM_ELAPSED_TIME_DIVIDER) > uSec ) { + break; + } + } + } +} + +/**< cimFchStall - Reserved */ +VOID +CimFchStall ( + IN UINT32 uSec, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 timerAddr; + UINT32 startTime; + UINT32 elapsedTime; + + LibAmdMemRead (AccessWidth16, (UINT64) (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG64), &timerAddr, StdHeader); + if ( timerAddr == 0 ) { + uSec = uSec / 2; + while ( uSec != 0 ) { + LibAmdIoRead (AccessWidth8, FCHOEM_IO_DELAY_PORT, (UINT8*)&elapsedTime, StdHeader); + uSec--; + } + } else { + LibAmdIoRead (AccessWidth32, timerAddr, &startTime, StdHeader); + for ( ;; ) { + LibAmdIoRead (AccessWidth32, timerAddr, &elapsedTime, StdHeader); + if ( elapsedTime < startTime ) { + elapsedTime = elapsedTime + FCH_MAX_TIMER - startTime; + } else { + elapsedTime = elapsedTime - startTime; + } + if ( (elapsedTime * FCHOEM_ELAPSED_TIME_UNIT / FCHOEM_ELAPSED_TIME_DIVIDER) > uSec ) { + break; + } + } + } +} + +/**< FchReset - Reserved */ +VOID +FchPciReset ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PciRstValue; + + PciRstValue = 0x06; + LibAmdIoWrite (AccessWidth8, FCH_PCIRST_BASE_IO, &PciRstValue, StdHeader); +} + +/**< outPort80 - Reserved */ +VOID +OutPort80 ( + IN UINT32 pcode, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LibAmdIoWrite (AccessWidth8, FCHOEM_OUTPUT_DEBUG_PORT, &pcode, StdHeader); + return; +} + +/**< FchCopyMem - Reserved */ +VOID +FchCopyMem ( + IN VOID* pDest, + IN VOID* pSource, + IN UINTN Length + ) +{ + UINTN i; + UINT8 *Ptr; + UINT8 *Source; + Ptr = (UINT8*)pDest; + Source = (UINT8*)pSource; + for (i = 0; i < Length; i++) { + *Ptr = *Source; + Source++; + Ptr++; + } +} + +/** GetRomSigPtr - Reserved **/ +VOID* +GetRomSigPtr ( + IN UINTN *RomSigPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 RomPtr; + UINT32 RomSig; + UINT16 MswAddr; + + *RomSigPtr = 0; + MswAddr = 0xFFF0; + do { + RomPtr = (MswAddr << 16) + FCH_ROMSIG_BASE_IO; + LibAmdMemRead (AccessWidth32, (UINT64) RomPtr, &RomSig, StdHeader); + if (RomSig == FCH_ROMSIG_SIGNATURE) { + *RomSigPtr = RomPtr; + break; + } + MswAddr <<= 1; + } while (MswAddr != 0xFE00); + return RomSigPtr; +} + +/** RwXhciIndReg - Reserved **/ +VOID +RwXhciIndReg ( + IN UINT32 Index, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 RevReg; + PCI_ADDR PciAddress; + + PciAddress.AddressValue = (USB_XHCI_BUS_DEV_FUN << 12) + 0x48; + LibAmdPciWrite (AccessWidth32, PciAddress, &Index, StdHeader); + PciAddress.AddressValue = (USB_XHCI_BUS_DEV_FUN << 12) + 0x4C; + RevReg = ~AndMask; + LibAmdPciRMW (AccessWidth32, PciAddress, &OrMask, &RevReg, StdHeader); + + PciAddress.AddressValue = (USB_XHCI1_BUS_DEV_FUN << 12) + 0x48; + LibAmdPciWrite (AccessWidth32, PciAddress, &Index, StdHeader); + PciAddress.AddressValue = (USB_XHCI1_BUS_DEV_FUN << 12) + 0x4C; + RevReg = ~AndMask; + LibAmdPciRMW (AccessWidth32, PciAddress, &OrMask, &RevReg, StdHeader); +} + +/** RwXhci0IndReg - Reserved **/ +VOID +RwXhci0IndReg ( + IN UINT32 Index, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 RevReg; + PCI_ADDR PciAddress; + + PciAddress.AddressValue = (USB_XHCI_BUS_DEV_FUN << 12) + 0x48; + LibAmdPciWrite (AccessWidth32, PciAddress, &Index, StdHeader); + PciAddress.AddressValue = (USB_XHCI_BUS_DEV_FUN << 12) + 0x4C; + RevReg = ~AndMask; + LibAmdPciRMW (AccessWidth32, PciAddress, &OrMask, &RevReg, StdHeader); +} + + +/** ReadXhci0Phy - Reserved **/ +VOID +ReadXhci0Phy ( + IN UINT32 Port, + IN UINT32 Address, + IN UINT32 *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 RegIndex; + UINT32 RegValue; + PCI_ADDR PciAddress; + + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + Address, StdHeader); + + RegIndex = FCH_XHCI_IND60_REG04; + PciAddress.AddressValue = (USB_XHCI_BUS_DEV_FUN << 12) + 0x48; + LibAmdPciWrite (AccessWidth32, PciAddress, &RegIndex, StdHeader); + PciAddress.AddressValue = (USB_XHCI_BUS_DEV_FUN << 12) + 0x4C; + LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader); + + (*Value) = ( RegValue >> (Port * 8)) & 0x000000FF; +} + + +/** AcLossControl - Reserved **/ +VOID +AcLossControl ( + IN UINT8 AcLossControlValue + ) +{ + AcLossControlValue &= 0x03; + AcLossControlValue |= BIT2; + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG5B, AccessWidth8, 0xF0, AcLossControlValue); +} + +/** RecordFchConfigPtr - Reserved **/ +VOID +RecordFchConfigPtr ( + IN UINT32 FchConfigPtr + ) +{ + RwMem (ACPI_MMIO_BASE + CMOS_RAM_BASE + 0x08, AccessWidth8, 0, (UINT8) ((FchConfigPtr >> 0) & 0xFF) ); + RwMem (ACPI_MMIO_BASE + CMOS_RAM_BASE + 0x09, AccessWidth8, 0, (UINT8) ((FchConfigPtr >> 8) & 0xFF) ); + RwMem (ACPI_MMIO_BASE + CMOS_RAM_BASE + 0x0A, AccessWidth8, 0, (UINT8) ((FchConfigPtr >> 16) & 0xFF) ); + RwMem (ACPI_MMIO_BASE + CMOS_RAM_BASE + 0x0B, AccessWidth8, 0, (UINT8) ((FchConfigPtr >> 24) & 0xFF) ); +} + +/** ReadAlink - Reserved **/ +UINT32 +ReadAlink ( + IN UINT32 Index, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Data; + LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &Index, StdHeader); + LibAmdIoRead (AccessWidth32, ALINK_ACCESS_DATA, &Data, StdHeader); + //Clear Index + Index = 0; + LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &Index, StdHeader); + return Data; +} + +/** WriteAlink - Reserved **/ +VOID +WriteAlink ( + IN UINT32 Index, + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &Index, StdHeader); + LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_DATA, &Data, StdHeader); + //Clear Index + Index = 0; + LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &Index, StdHeader); +} + +/** RwAlink - Reserved **/ +VOID +RwAlink ( + IN UINT32 Index, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 AccessType; + + AccessType = Index & 0xE0000000; + if (AccessType == (0 << 29)) { + WriteAlink ((0x30 | AccessType), Index & 0x1FFFFFFF, StdHeader); + Index = 0x34 | AccessType; + } else if (AccessType == (2 << 29)) { + WriteAlink ((0x38 | AccessType), Index & 0x1FFFFFFF, StdHeader); + Index = 0x3C | AccessType; + } + WriteAlink (Index, (ReadAlink (Index, StdHeader) & AndMask) | OrMask, StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PMIO + * + * + * + * @param[in] Address - PMIO Offset value + * @param[in] OpFlag - Access sizes + * @param[in] Value - Read Data Buffer + * @param[in] StdHeader + * + */ +VOID +ReadPmio ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + + OpFlag = OpFlag & 0x7f; + OpFlag = 1 << (OpFlag - 1); + for (i = 0; i < OpFlag; i++) { + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD6, &Address, StdHeader); + Address++; + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGCD7, (UINT8 *)Value + i, StdHeader); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PMIO + * + * + * + * @param[in] Address - PMIO Offset value + * @param[in] OpFlag - Access sizes + * @param[in] Value - Write Data Buffer + * @param[in] StdHeader + * + */ +VOID +WritePmio ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + + OpFlag = OpFlag & 0x7f; + OpFlag = 1 << (OpFlag - 1); + for (i = 0; i < OpFlag; i++) { + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD6, &Address, StdHeader); + Address++; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD7, (UINT8 *)Value + i, StdHeader); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * RwPmio - Read/Write PMIO + * + * + * + * @param[in] Address - PMIO Offset value + * @param[in] OpFlag - Access sizes + * @param[in] AndMask - Data And Mask 32 bits + * @param[in] OrMask - Data OR Mask 32 bits + * @param[in] StdHeader + * + */ +VOID +RwPmio ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Result; + + ReadPmio (Address, OpFlag, &Result, StdHeader); + Result = (Result & AndMask) | OrMask; + WritePmio (Address, OpFlag, &Result, StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PMIO2 + * + * + * + * @param[in] Address - PMIO2 Offset value + * @param[in] OpFlag - Access sizes + * @param[in] Value - Read Data Buffer + * @param[in] StdHeader + * + */ +VOID +ReadPmio2 ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + + OpFlag = OpFlag & 0x7f; + OpFlag = 1 << (OpFlag - 1); + for ( i = 0; i < OpFlag; i++ ) { + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD0, &Address, StdHeader); + Address++; + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGCD1, (UINT8 *) Value + i, StdHeader); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PMIO 2 + * + * + * + * @param[in] Address - PMIO2 Offset value + * @param[in] OpFlag - Access sizes + * @param[in] Value - Write Data Buffer + * @param[in] StdHeader + * + */ +VOID +WritePmio2 ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + + OpFlag = OpFlag & 0x7f; + OpFlag = 1 << (OpFlag - 1); + + for ( i = 0; i < OpFlag; i++ ) { + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD0, &Address, StdHeader); + Address++; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD1, (UINT8 *) Value + i, StdHeader); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * RwPmio2 - Read/Write PMIO2 + * + * + * + * @param[in] Address - PMIO2 Offset value + * @param[in] OpFlag - Access sizes + * @param[in] AndMask - Data And Mask 32 bits + * @param[in] OrMask - Data OR Mask 32 bits + * @param[in] StdHeader + * + */ +VOID +RwPmio2 ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Result; + + ReadPmio2 (Address, OpFlag, &Result, StdHeader); + Result = (Result & AndMask) | OrMask; + WritePmio2 (Address, OpFlag, &Result, StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read BIOSRAM + * + * + * + * @param[in] Address - BIOSRAM Offset value + * @param[in] OpFlag - Access sizes + * @param[in] Value - Read Data Buffer + * @param[in] StdHeader + * + */ +VOID +ReadBiosram ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + + OpFlag = OpFlag & 0x7f; + OpFlag = 1 << (OpFlag - 1); + for (i = 0; i < OpFlag; i++) { + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD4, &Address, StdHeader); + Address++; + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGCD5, (UINT8 *)Value + i, StdHeader); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write BIOSRAM + * + * + * + * @param[in] Address - BIOSRAM Offset value + * @param[in] OpFlag - Access sizes + * @param[in] Value - Write Data Buffer + * @param[in] StdHeader + * + */ +VOID +WriteBiosram ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + + OpFlag = OpFlag & 0x7f; + OpFlag = 1 << (OpFlag - 1); + for (i = 0; i < OpFlag; i++) { + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD4, &Address, StdHeader); + Address++; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGCD5, (UINT8 *)Value + i, StdHeader); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Record SMI Status + * + * + * @param[in] StdHeader + * + */ +VOID +RecordSmiStatus ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN Index; + UINT8 SwSmiValue; + + ACPIMMIO8 (0xfed80320) |= 0x01; + for ( Index = 0; Index < 20; Index++ ) { + ACPIMMIO8 (0xfed10020 + Index) = ACPIMMIO8 (0xfed80280 + Index); + } + LibAmdIoRead (AccessWidth8, 0xB0, &SwSmiValue, StdHeader); + ACPIMMIO8 (0xfed10040) = SwSmiValue; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchPeLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchPeLib.c new file mode 100644 index 0000000000..09055570c1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/FchPeLib.c @@ -0,0 +1,260 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH IO access common routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ + +#include "FchPlatform.h" +#define FILECODE PROC_FCH_COMMON_FCHPELIB_FILECODE + +/*----------------------------------------------------------------------------------------*/ +/** + * ProgramPciByteTable - Program PCI register by table (8 bits data) + * + * + * + * @param[in] pPciByteTable - Table data pointer + * @param[in] dwTableSize - Table length + * @param[in] StdHeader + * + */ +VOID +ProgramPciByteTable ( + IN REG8_MASK *pPciByteTable, + IN UINT16 dwTableSize, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 dbBusNo; + UINT8 dbDevFnNo; + UINT8 Or8; + UINT8 Mask8; + PCI_ADDR PciAddress; + + dbBusNo = pPciByteTable->RegIndex; + dbDevFnNo = pPciByteTable->AndMask; + pPciByteTable++; + + for ( i = 1; i < dwTableSize; i++ ) { + if ( (pPciByteTable->RegIndex == 0xFF) && (pPciByteTable->AndMask == 0xFF) && (pPciByteTable->OrMask == 0xFF) ) { + pPciByteTable++; + dbBusNo = pPciByteTable->RegIndex; + dbDevFnNo = pPciByteTable->AndMask; + pPciByteTable++; + i++; + } else { + PciAddress.AddressValue = (dbBusNo << 20) + (dbDevFnNo << 12) + pPciByteTable->RegIndex; + Or8 = pPciByteTable->OrMask; + Mask8 = ~pPciByteTable->AndMask; + LibAmdPciRMW (AccessWidth8, PciAddress, &Or8, &Mask8, StdHeader); + pPciByteTable++; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * ProgramFchAcpiMmioTbl - Program FCH ACPI MMIO register by table (8 bits data) + * + * + * + * @param[in] pAcpiTbl - Table data pointer + * @param[in] StdHeader + * + */ +VOID +ProgramFchAcpiMmioTbl ( + IN ACPI_REG_WRITE *pAcpiTbl, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 Or8; + UINT8 Mask8; + UINT32 ddtempVar; + + if (pAcpiTbl != NULL) { + if ((pAcpiTbl->MmioReg == 0) && (pAcpiTbl->MmioBase == 0) && (pAcpiTbl->DataAndMask == 0xB0) && (pAcpiTbl->DataOrMask == 0xAC)) { + // Signature Checking + pAcpiTbl++; + for ( i = 1; pAcpiTbl->MmioBase < 0x1D; i++ ) { + ddtempVar = ACPI_MMIO_BASE | (pAcpiTbl->MmioBase) << 8 | pAcpiTbl->MmioReg; + Or8 = pAcpiTbl->DataOrMask; + Mask8 = ~pAcpiTbl->DataAndMask; + LibAmdMemRMW (AccessWidth8, (UINT64) ddtempVar, &Or8, &Mask8, StdHeader); + pAcpiTbl++; + } + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * ProgramFchGpioTbl - Program FCH Gpio table (8 bits data) + * + * + * + * @param[in] pGpioTbl - Table data pointer + * @param[in] FchResetDataBlock + * + */ +VOID +ProgramFchGpioTbl ( + IN GPIO_CONTROL *pGpioTbl, + IN FCH_RESET_DATA_BLOCK *FchResetDataBlock + ) +{ + AMD_CONFIG_PARAMS *StdHeader; + + UINT32 ddtempVar; + StdHeader = FchResetDataBlock->StdHeader; + + if (pGpioTbl != NULL) { + while (pGpioTbl->GpioPin != 0xFF) { + ddtempVar = ACPI_MMIO_BASE | IOMUX_BASE | pGpioTbl->GpioPin; + LibAmdMemWrite (AccessWidth8, (UINT64) ddtempVar, &pGpioTbl->PinFunction, StdHeader); + ddtempVar = ACPI_MMIO_BASE | GPIO_BASE | pGpioTbl->GpioPin; + LibAmdMemWrite (AccessWidth8, (UINT64) ddtempVar, &pGpioTbl->CfgByte, StdHeader); + pGpioTbl++; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * ProgramSataPhyTbl - Program FCH Sata Phy table (8 bits data) + * + * + * + * @param[in] pSataPhyTbl - Table data pointer + * @param[in] FchResetDataBlock + * + */ +VOID +ProgramFchSataPhyTbl ( + IN SATA_PHY_CONTROL *pSataPhyTbl, + IN FCH_RESET_DATA_BLOCK *FchResetDataBlock + ) +{ + AMD_CONFIG_PARAMS *StdHeader; + + //UINT32 ddtempVar; + StdHeader = FchResetDataBlock->StdHeader; + + if (pSataPhyTbl != NULL) { + while (pSataPhyTbl->PhyData != 0xFFFFFFFF) { + //to be implemented + pSataPhyTbl++; + } + } +} + +/** + * GetChipSysMode - Get Chip status + * + * + * @param[in] Value - Return Chip strap status + * StrapStatus [15.0] - Hudson-2 chip Strap Status + * @li 0001 - Not USED FWH + * @li 0002 - Not USED LPC ROM + * @li 0004 - EC enabled + * @li 0008 - Reserved + * @li 0010 - Internal Clock mode + * @param[in] StdHeader + * + */ +VOID +GetChipSysMode ( + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LibAmdMemRead (AccessWidth8, (UINT64) (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG80), Value, StdHeader); +} + +/** + * IsImcEnabled - Is IMC Enabled + * @retval TRUE for IMC Enabled; FALSE for IMC Disabled + */ +BOOLEAN +IsImcEnabled ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 dbSysConfig; + GetChipSysMode (&dbSysConfig, StdHeader); + if (dbSysConfig & ChipSysEcEnable) { + return TRUE; + } else { + return FALSE; + } +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * SbSleepTrapControl - SB Sleep Trap Control + * + * + * + * @param[in] SleepTrap - Whether sleep trap is enabled + * + */ +VOID +SbSleepTrapControl ( + IN BOOLEAN SleepTrap + ) +{ + if (SleepTrap) { + ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB0) &= ~(BIT2 + BIT3); + ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB0) |= BIT2; + + ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGBE) &= ~ (BIT5); + ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + 0xB) &= ~ (BIT0 + BIT1); + ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + 0xB) |= BIT1; + } else { + ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGBE) |= BIT5; + ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + 0xB) &= ~ (BIT0 + BIT1); + ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + 0xB) |= BIT0; + + ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB0) &= ~(BIT2 + BIT3); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/MemLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/MemLib.c new file mode 100644 index 0000000000..08bd0f9457 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/MemLib.c @@ -0,0 +1,145 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH memory access lib + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Ids.h" +#define FILECODE PROC_FCH_COMMON_MEMLIB_FILECODE + + +/** + * ReadMem - Read FCH BAR Memory + * + * @param[in] Address - Memory BAR address + * @param[in] OpFlag - Access width + * @param[in] *ValuePtr - In/Out value pointer + * + */ +VOID +ReadMem ( + IN UINT32 Address, + IN UINT8 OpFlag, + IN VOID *ValuePtr + ) +{ + OpFlag = OpFlag & 0x7f; + + switch ( OpFlag ) { + case AccessWidth8: + *((UINT8*)ValuePtr) = *((UINT8*) ((UINTN)Address)); + break; + + case AccessWidth16: + *((UINT16*)ValuePtr) = *((UINT16*) ((UINTN)Address)); + break; + + case AccessWidth32: + *((UINT32*)ValuePtr) = *((UINT32*) ((UINTN)Address)); + break; + + default: + ASSERT (FALSE); + break; + } +} + +/** + * WriteMem - Write FCH BAR Memory + * + * @param[in] Address - Memory BAR address + * @param[in] OpFlag - Access width + * @param[in] *ValuePtr - In/Out Value pointer + * + */ +VOID +WriteMem ( + IN UINT32 Address, + IN UINT8 OpFlag, + IN VOID *ValuePtr + ) +{ + OpFlag = OpFlag & 0x7f; + + switch ( OpFlag ) { + case AccessWidth8 : + *((UINT8*) ((UINTN)Address)) = *((UINT8*)ValuePtr); + break; + + case AccessWidth16: + *((UINT16*) ((UINTN)Address)) = *((UINT16*)ValuePtr); + break; + + case AccessWidth32: + *((UINT32*) ((UINTN)Address)) = *((UINT32*)ValuePtr); + break; + + default: + ASSERT (FALSE); + break; + } +} + +/** + * RwMem - Read & Write FCH BAR Memory + * + * @param[in] Address - Memory BAR address + * @param[in] OpFlag - Access width + * @param[in] Mask - Mask Value of data + * @param[in] Data - Write data + * + */ +VOID +RwMem ( + IN UINT32 Address, + IN UINT8 OpFlag, + IN UINT32 Mask, + IN UINT32 Data + ) +{ + UINT32 Result; + + ReadMem (Address, OpFlag, &Result); + Result = (Result & Mask) | Data; + WriteMem (Address, OpFlag, &Result); + ReadMem (Address, OpFlag, &Result); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/PciLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/PciLib.c new file mode 100644 index 0000000000..6ef1bd0643 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Common/PciLib.c @@ -0,0 +1,94 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH PCI access lib + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_COMMON_PCILIB_FILECODE + +VOID +ReadPci ( + IN UINT32 Address, + IN UINT8 OpFlag, + IN VOID* Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + + PciAddress.AddressValue = ((Address >> 4) & ~0xFFF) + (Address & 0xFFF); + LibAmdPciRead ((ACCESS_WIDTH) OpFlag, PciAddress, Value, StdHeader); +} + + +VOID +WritePci ( + IN UINT32 Address, + IN UINT8 OpFlag, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + + PciAddress.AddressValue = ((Address >> 4) & ~0xFFF) + (Address & 0xFFF); + LibAmdPciWrite ((ACCESS_WIDTH) OpFlag, PciAddress, Value, StdHeader); +} + + +VOID +RwPci ( + IN UINT32 Address, + IN UINT8 OpFlag, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + UINT32 rMask; + + PciAddress.AddressValue = ((Address >> 4) & ~0xFFF) + (Address & 0xFFF); + rMask = ~Mask; + LibAmdPciRMW ((ACCESS_WIDTH) OpFlag, PciAddress, &Data, &rMask, StdHeader); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Fch.h b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Fch.h new file mode 100644 index 0000000000..a67439a68a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Fch.h @@ -0,0 +1,1624 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH registers definition + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87830 $ @e \$Date: 2013-02-11 12:48:20 -0600 (Mon, 11 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#define FCH_REVISION "0.0.5.0" +#define FCH_ID "FCH_A05" +#define FCH_VERSION 0x0000 + +/** + * @page fchinitguide FCH implement phase in AGESA + * + * FCH provides below access to supported FCH service functions + * and data. + * - @subpage fchreset "FCH_INIT_RESET" + * - @subpage fchenv "FCH_INIT_ENV" + * - @subpage fchmid "FCH_INIT_MID" + * - @subpage fchlate "FCH_INIT_LATE" + * - @subpage fchs3early "FCH_INIT_S3_EARLY_RESTORE" + * - @subpage fchs3late "FCH_INIT_S3_LATE_RESTORE" + * - @subpage fchsmm "FCH_SMM_SERVICE" + * - @subpage fchsmmacpion "FCH_SMM_ACPION" + */ + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page fchreset FCH_INIT_RESET + * @section FCH_INIT_RESET Interface Call + * @par + * Initialize structure referenced by FCH_RESET_DATA_BLOCK to default recommended value. + * @subsection FCH_INIT_RESET_CallIn Call Prototype + * @par + * AGESA_STATUS FchInitReset (IN AMD_RESET_PARAMS *ResetParams); + * @subsection FCH_INIT_RESET_CallOut Prepare for Callout + * @par + * Not Applicable (Not necessary for the current implementation) + * @subsection FCH_INIT_RESET_Config Prepare for Configuration Data. + * @par + * + * + * + * + * + + * + * + * + * + * + * + * + * + * + *
BUILD_OPT_CFG::CfgSmbus0BaseAddress Required
BUILD_OPT_CFG::CfgSmbus1BaseAddress Required
BUILD_OPT_CFG::CfgSioPmeBaseAddress Required
BUILD_OPT_CFG::CfgWatchDogTimerBase Required
BUILD_OPT_CFG::CfgSpiRomBaseAddress Required
BUILD_OPT_CFG::CfgAcpiPm1EvtBlkAddr Required
BUILD_OPT_CFG::CfgAcpiPm1CntBlkAddr Required
BUILD_OPT_CFG::CfgAcpiPmTmrBlkAddr Required
BUILD_OPT_CFG::CfgCpuControlBlkAddr Required
BUILD_OPT_CFG::CfgAcpiGpe0BlkAddr Required
BUILD_OPT_CFG::CfgSmiCmdPortAddr Required
FCH_RESET_INTERFACE::SataEnable Optional
FCH_RESET_INTERFACE::IdeEnable Optional
+ * + */ + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page fchenv FCH_INIT_ENV + * @section FCH_INIT_ENV Interface Call + * @par + * Initialize structure referenced by FCH_DATA_BLOCK to default recommended value. + * @subsection FCH_INIT_ENV_CallIn Call Prototype + * @par + * AGESA_STATUS FchInitEnv (IN AMD_ENV_PARAMS *EnvParams); + * @subsection FCH_INIT_ENV_CallOut Prepare for Callout + * @par + * Not Applicable (Not necessary for the current implementation) + * @subsection FCH_INIT_ENV_Config Prepare for Configuration Data. + * @par + * + * + * + * + * + * + * + * + * + * + * + * + *
FCH_INTERFACE::SdConfig Optional
FCH_INTERFACE::AzaliaController Optional
FCH_INTERFACE::IrConfig Optional
FCH_INTERFACE::SataClass Optional
FCH_INTERFACE::SataEnable Optional
FCH_INTERFACE::SataIdeMode Optional
FCH_INTERFACE::Ohci1Enable Optional
FCH_INTERFACE::Ohci2Enable Optional
FCH_INTERFACE::Ohci3Enable Optional
FCH_INTERFACE::Ohci4Enable Optional
FCH_INTERFACE::XhciSwitch Optional
+ * + */ + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page fchmid FCH_INIT_MID + * @section FCH_INIT_MID Interface Call + * @par + * Initialize structure referenced by FCH_DATA_BLOCK to default recommended value. + * @subsection FCH_INIT_MID_CallIn Call Prototype + * @par + * AGESA_STATUS FchInitMid (IN AMD_MID_PARAMS *MidParams); + * @subsection FCH_INIT_MID_CallOut Prepare for Callout + * @par + * Not Applicable (Not necessary for the current implementation) + * @subsection FCH_INIT_MID_Config Prepare for Configuration Data. + * @par + * + * + * + * + * + * + *
FCH_INTERFACE::AzaliaController Optional
FCH_INTERFACE::SataClass Optional
FCH_INTERFACE::SataEnable Optional
FCH_INTERFACE::IdeEnable Optional
FCH_INTERFACE::XhciSwitch Optional
+ * + */ + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page fchlate FCH_INIT_LATE + * @section FCH_INIT_LATE Interface Call + * @par + * Initialize structure referenced by FCH_DATA_BLOCK to default recommended value. + * @subsection FCH_INIT_LATE_CallIn Call Prototype + * @par + * AGESA_STATUS FchInitLate (IN AMD_S3SAVE_PARAMS *LateParams); + * @subsection FCH_INIT_LATE_CallOut Prepare for Callout + * @par + * Not Applicable (Not necessary for the current implementation) + * @subsection FCH_INIT_LATE_Config Prepare for Configuration Data. + * @par + * + * + * + * + * + *
FCH_INTERFACE::SataClass Optional
FCH_INTERFACE::SataEnable Optional
FCH_INTERFACE::XhciSwitch Optional
BUILD_OPT_CFG::CfgSpiRomBaseAddress Required
+ * + */ + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page fchs3early FCH_INIT_S3_EARLY_RESTORE + * @section FCH_INIT_S3_EARLY_RESTORE Interface Call + * @par + * Initialize structure referenced by FCH_DATA_BLOCK to default recommended value. + * @subsection FCH_INIT_S3_EARLY_RESTORE_CallIn Call Prototype + * @par + * VOID FchInitS3EarlyRestore (IN FCH_DATA_BLOCK *FchDataPtr); + * @subsection FCH_INIT_S3_EARLY_RESTORE_CallOut Prepare for Callout + * @par + * Not Applicable (Not necessary for the current implementation) + * @subsection FCH_INIT_S3_EARLY_RESTORE_Config Prepare for Configuration Data. + * @par + * + * + * + * + * + * + * + * + * + * + * + * + *
FCH_INTERFACE::SdConfig Optional
FCH_INTERFACE::AzaliaController Optional
FCH_INTERFACE::IrConfig Optional
FCH_INTERFACE::SataClass Optional
FCH_INTERFACE::SataEnable Optional
FCH_INTERFACE::SataIdeMode Optional
FCH_INTERFACE::Ohci1Enable Optional
FCH_INTERFACE::Ohci2Enable Optional
FCH_INTERFACE::Ohci3Enable Optional
FCH_INTERFACE::Ohci4Enable Optional
FCH_INTERFACE::XhciSwitch Optional
+ * + */ + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page fchs3late FCH_INIT_S3_LATE_RESTORE + * @section FCH_INIT_S3_LATE_RESTORE Interface Call + * @par + * Initialize structure referenced by FCH_DATA_BLOCK to default recommended value. + * @subsection FCH_INIT_S3_LATE_RESTORE_CallIn Call Prototype + * @par + * VOID FchInitS3LateRestore (IN FCH_DATA_BLOCK *FchDataPtr); + * @subsection FCH_INIT_S3_LATE_RESTORE_CallOut Prepare for Callout + * @par + * Not Applicable (Not necessary for the current implementation) + * @subsection FCH_INIT_S3_LATE_RESTORE_Config Prepare for Configuration Data. + * @par + * + * + * + * + * + * + * + *
FCH_INTERFACE::AzaliaController Optional
FCH_INTERFACE::SataClass Optional
FCH_INTERFACE::SataEnable Optional
FCH_INTERFACE::IdeEnable Optional
FCH_INTERFACE::XhciSwitch Optional
BUILD_OPT_CFG::CfgSpiRomBaseAddress Required
+ * + */ + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page fchsmm FCH_SMM_SERVICE + * @section FCH_SMM_SERVICE Interface Call + * Initialize structure referenced by FCHCFG to default recommended value. + * @subsection FCH_SMM_SERVICE_CallIn Call Prototype + * @par + * FchSmmService ((FCHCFG*)pConfig) (Followed PH Interface) + * @subsection FCH_SMM_SERVICE_CallID Service ID + * @par + * + * + *
FCH_SMM_SERVICE --> 0x00010060
+ * @subsection FCH_SMM_SERVICE_CallOut Prepare for Callout + * @par + * Not Applicable (Not necessary for the current implementation) + * @subsection FCH_SMM_SERVICE_Config Prepare for Configuration Data. + * @par + * Not necessary on current implementation + * + */ +#define FCH_SMM_SERVICE 0x00010060ul +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page fchsmmacpion FCH_SMM_ACPION + * @section FCH_SMM_ACPION Interface Call + * Initialize structure referenced by FCHCFG to default recommended value. + * @subsection FCH_SMM_ACPION_CallIn Call Prototype + * @par + * FchSmmAcpiOn ((FCHCFG*)pConfig) (Followed PH Interface) + * @subsection FCH_SMM_ACPION_CallID Service ID + * @par + * + * + *
FCH_SMM_ACPION --> 0x00010061
+ * @subsection FCH_SMM_ACPION_CallOut Prepare for Callout + * @par + * Not Applicable (Not necessary for the current implementation) + * @subsection FCH_SMM_ACPION_Config Prepare for Configuration Data. + * @par + * Not necessary on current implementation + * + */ +#define FCH_SMM_ACPION 0x00010061ul + +#ifndef OEM_CALLBACK_BASE + #define OEM_CALLBACK_BASE 0x00010100ul +#endif + +//0x00 - 0x0F callback functions are reserved for bootblock +#define SATA_PHY_PROGRAMMING OEM_CALLBACK_BASE + 0x10 +#define PULL_UP_PULL_DOWN_SETTINGS OEM_CALLBACK_BASE + 0x20 +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page CB_SBGPP_RESET_ASSERT_Page CB_SBGPP_RESET_ASSERT + * @section CB_SBGPP_RESET_ASSERT Interface Call + * Initialize structure referenced by FCHCFG to default recommended value. + * @subsection CB_SBGPP_RESET_ASSERT_CallID Service ID + * @par + * + * + *
CB_SBGPP_RESET_ASSERT --> 0x00010130
+ * @subsection CB_SBGPP_RESET_ASSERT_Config Prepare for Configuration Data. + * @par + * Not necessary on current implementation + * + */ +#define CB_SBGPP_RESET_ASSERT OEM_CALLBACK_BASE + 0x30 +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page CB_SBGPP_RESET_DEASSERT_Page CB_SBGPP_RESET_DEASSERT + * @section CB_SBGPP_RESET_DEASSERT Interface Call + * Initialize structure referenced by FCHCFG to default recommended value. + * @subsection CB_SBGPP_RESET_DEASSERT _CallID Service ID + * @par + * + * + *
CB_SBGPP_RESET_DEASSERT --> 0x00010131
+ * @subsection CB_SBGPP_RESET_DEASSERT _Config Prepare for Configuration Data. + * @par + * Not necessary on current implementation + * + */ +#define CB_SBGPP_RESET_DEASSERT OEM_CALLBACK_BASE + 0x31 + +#define CFG_ADDR_PORT 0xCF8 +#define CFG_DATA_PORT 0xCFC + +#define ALINK_ACCESS_INDEX 0x0CD8 +#define ALINK_ACCESS_DATA ALINK_ACCESS_INDEX + 4 + +/*------------------------------------------------------------------ +; I/O Base Address - Should be set by host BIOS +;------------------------------------------------------------------ */ +#define DELAY_PORT 0x0E0 + +#define FCH_8259_CONTROL_REG_MASTER 0x20 +#define FCH_8259_MASK_REG_MASTER 0x21 + +/*------------------------------------------------------------------ +; DEBUG_PORT = 8-bit I/O Port Address for POST Code Display +;------------------------------------------------------------------ */ +// ASIC VendorID and DeviceIDs +#define AMD_FCH_VID 0x1022 +#define FCH_DEVICE_ID 0x780B +#define FCH_SATA_VID AMD_FCH_VID // Dev 17 Func 0 +#define FCH_SATA_DID 0x7800 +#define FCH_SATA_AHCI_DID 0x7801 +#define FCH_SATA_RAID_DID 0x7802 +#define FCH_SATA_RAID5_DID 0x7803 +#define FCH_SATA_AMDAHCI_DID 0x7804 +#define FCH_SATA_RAID_DOTHILL_DID 0x7805 +#define FCH_SATA_RAID5_DOTHILL_DID 0x780A +#define FCH_USB_OHCI_VID AMD_FCH_VID // Dev 18 Func 0, +#define FCH_USB_OHCI_DID 0x7807 +#define FCH_USB_EHCI_VID AMD_FCH_VID // Dev 18 Func 2, +#define FCH_USB_EHCI_DID 0x7808 +#define FCH_USB_XHCI_VID AMD_FCH_VID // Dev 10 Func 0 +#define FCH_USB_XHCI_DID 0x7812 +#define FCH_SMBUS_VID AMD_FCH_VID // Dev 20 Func 0 +#define FCH_SMBUS_DID 0x780B +#define FCH_IDE_VID AMD_FCH_VID // Dev 20 Func 1 +#define FCH_IDE_DID 0x780C +#define FCH_AZALIA_VID AMD_FCH_VID // Dev 20 Func 2 +#define FCH_AZALIA_DID 0x780D +#define FCH_LPC_VID AMD_FCH_VID // Dev 20 Func 3 +#define FCH_LPC_DID 0x780E +#define FCH_PCIB_VID AMD_FCH_VID // Dev 20 Func 4 +#define FCH_PCIB_DID 0x780F +#define FCH_USB_OHCIF_VID AMD_FCH_VID // dev 20 Func 5 +#define FCH_USB_OHCIF_DID 0x7809 +#define FCH_NIC_VID 0x14E4 // Dev 20 Func 6 +#define FCH_NIC_DID 0x1699 +#define FCH_SD_VID AMD_FCH_VID // Dev 20 Func 7 +#define FCH_SD_DID 0x7806 + + +#define FCH_YANGTZE 0x39 +//Misc +#define R_FCH_ACPI_PM1_STATUS 0x00 +#define R_FCH_ACPI_PM1_ENABLE 0x02 +#define R_FCH_ACPI_PM_CONTROL 0x04 +#define R_FCH_ACPI_EVENT_STATUS 0x20 +#define R_FCH_ACPI_EVENT_ENABLE 0x24 +#define R_FCH_PM_ACPI_PMA_CNT_BLK_LO 0x2C + +// ACPI Sleep Type +#define ACPI_SLPTYP_S0 0 +#define ACPI_SLPTYP_S1 1 +#define ACPI_SLPTYP_S3 3 +#define ACPI_SLPTYP_S4 4 +#define ACPI_SLPTYP_S5 5 + +//#define SATA_BUS_DEV_FUN_FPGA 0x228 +#define SATA_BUS_DEV_FUN ((0x11 << 3) + 0) +#define FCH_SATA1_BUS 0 +#define FCH_SATA1_DEV 17 +#define FCH_SATA1_FUNC 0 + +#define FC_BUS_DEV_FUN ((0x11 << 3) + 1) +#define FCH_XHCI_BUS 0 +#define FCH_XHCI_DEV 16 +#define FCH_XHCI_FUNC 0 +#define USB_XHCI_BUS_DEV_FUN ((FCH_XHCI_DEV << 3) + FCH_XHCI_FUNC) +#define FCH_XHCI1_BUS 0 +#define FCH_XHCI1_DEV 16 +#define FCH_XHCI1_FUNC 1 +#define USB_XHCI1_BUS_DEV_FUN ((FCH_XHCI1_DEV << 3) + FCH_XHCI1_FUNC) +#define USB1_OHCI_BUS_DEV_FUN ((0x12 << 3) + 0) // PORT 0-4 +#define FCH_OHCI1_BUS 0 +#define FCH_OHCI1_DEV 18 +#define FCH_OHCI1_FUNC 0 +#define USB2_OHCI_BUS_DEV_FUN ((0x13 << 3) + 0) // PORT 5-9 +#define FCH_OHCI2_BUS 0 +#define FCH_OHCI2_DEV 19 +#define FCH_OHCI2_FUNC 0 +#define USB3_OHCI_BUS_DEV_FUN ((0x16 << 3) + 0) // PORT 10-13 +#define FCH_OHCI3_BUS 0 +#define FCH_OHCI3_DEV 22 +#define FCH_OHCI3_FUNC 0 +#define USB1_EHCI_BUS_DEV_FUN ((0x12 << 3) + 2) // PORT 0-4 +#define FCH_EHCI1_BUS 0 +#define FCH_EHCI1_DEV 18 +#define FCH_EHCI1_FUNC 2 +#define USB2_EHCI_BUS_DEV_FUN ((0x13 << 3) + 2) // PORT 5-9 +#define FCH_EHCI2_BUS 0 +#define FCH_EHCI2_DEV 19 +#define FCH_EHCI2_FUNC 2 +#define USB3_EHCI_BUS_DEV_FUN ((0x16 << 3) + 2) // PORT 10-13 +#define FCH_EHCI3_BUS 0 +#define FCH_EHCI3_DEV 22 +#define FCH_EHCI3_FUNC 2 +#define SMBUS_BUS_DEV_FUN ((0x14 << 3) + 0) +#define FCH_ISA_BUS 0 +#define FCH_ISA_DEV 20 +#define FCH_ISA_FUNC 0 +#define IDE_BUS_DEV_FUN ((0x14 << 3) + 1) +#define FCH_IDE_BUS 0 +#define FCH_IDE_DEV 20 +#define FCH_IDE_FUNC 1 +#define AZALIA_BUS_DEV_FUN ((0x14 << 3) + 2) +#define FCH_AZALIA_BUS 0 +#define FCH_AZALIA_DEV 20 +#define FCH_AZALIA_FUNC 2 +#define LPC_BUS_DEV_FUN ((0x14 << 3) + 3) +#define FCH_LPC_BUS 0 +#define FCH_LPC_DEV 20 +#define FCH_LPC_FUNC 3 +#define FCH_PCI_BUS 0 +#define FCH_PCI_DEV 20 +#define FCH_PCI_FUNC 4 +#define USB4_OHCI_BUS_DEV_FUN ((0x14 << 3) + 5) // PORT FL0 - FL1 +#define FCH_OHCI4_BUS 0 +#define FCH_OHCI4_DEV 20 +#define FCH_OHCI4_FUNC 5 +//Gigabyte Ethernet Controller +#define GEC_BUS_DEV_FUN ((0x14 << 3) + 6) +#define FCH_GBEC_BUS 0 +#define FCH_GBEC_DEV 20 +#define FCH_GBEC_FUNC 6 + +#define SD_BUS_DEV_FUN ((0x14 << 3) + 7) // SD Controller +#define SD_PCI_BUS 0 +#define SD_PCI_DEV 20 +#define SD_PCI_FUNC 7 + + +#define ACPI_MMIO_BASE 0xFED80000ul +#define FCH_CFG_BASE 0x000 // DWORD +#define GPIO_BASE 0x100 // BYTE +#define SMI_BASE 0x200 // DWORD +#define PMIO_BASE 0x300 // DWORD +#define PMIO2_BASE 0x400 // BYTE +#define BIOS_RAM_BASE 0x500 // BYTE +#define CMOS_RAM_BASE 0x600 // BYTE +#define CMOS_BASE 0x700 // BYTE +#define ASF_BASE 0x900 // DWORD +#define SMBUS_BASE 0xA00 // DWORD +#define WATCHDOG_BASE 0xB00 // +#define HPET_BASE 0xC00 // DWORD +#define IOMUX_BASE 0xD00 // BYTE +#define MISC_BASE 0xE00 +#define SERIAL_DEBUG_BASE 0x1000 +#define GFX_DAC_BASE 0x1400 +//#define CEC_BASE 0x1800 +#define XHCI_BASE 0x1C00 + + +// Chip type definition +#define CHIPTYPE_HUDSON2 (1 << 0) + +// +// ROM SIG type definition +// +#define NUM_OF_ROMSIG_FILED 0x04 +#define XHCI_FILED_NUM 0x03 +#define ROMSIG_CFG_MASK 0x07 +#define XHCI_BOOT_RAM_OFFSET 0x8000 +#define INSTRUCTION_RAM_SIG 0x55AA +#define ROMSIG_SIG 0x55AA55AAul + +// RegSpace field (AB_INDEX[31:29] +#define ABCFG 6 // ABCFG + +#define GPP_DEV_NUM 21 // +#define MAX_GPP_PORTS 4 + +// +// ABCFG Registers +// +#define FCH_ABCFG_REG54 0x54 // MISCCTL_54 +#define FCH_ABCFG_REG58 0x58 // BL RAB CONTROL + + +#define FCH_ABCFG_REG80 0x80 // BL DMA PREFETCH CONTROL +#define FCH_ABCFG_REG90 0x90 // BIF CONTROL 0 +#define FCH_ABCFG_REG94 0x94 // MSI CONTROL +#define FCH_ABCFG_REG10054 0x10054ul // AL_ARB_CTL +#define FCH_ABCFG_REG10090 0x10090ul // BIF CONTROL 0 + + + +// +// AXINDC Registers +// + +#define FCH_AB_REG04 0x04 +#define FCH_AB_REG40 0x40 + +//Sata Port Configuration +#define SIX_PORTS 0 +#define FOUR_PORTS 1 + + + + +// USB ports +#define NUM_USB1_PORTS 5 +#define NUM_USB2_PORTS 5 +#define NUM_USB3_PORTS 4 +#define NUM_USB4_PORTS 2 +#define NUM_XHC0_PORTS 2 +#define NUM_XHC1_PORTS 2 + + +// +// USB OHCI Device 0x7807 +// Device 18 (0x12)/Device 19 (0x13)/Device 22 (0x16) Func 0 +// Device 20 (0x14) Func 5 (FL) 0x7809 +// +#define FCH_OHCI_REG00 0x00 // Device/Vendor ID - R (0x43971002ul) +#define FCH_OHCI_REG04 0x04 // Command - RW +#define FCH_OHCI_REG06 0x06 // Status - R +#define FCH_OHCI_REG08 0x08 // Revision ID/Class Code - R +#define FCH_OHCI_REG0C 0x0C // Miscellaneous - RW +#define FCH_OHCI_REG10 0x10 // Bar_OCI - RW +#define FCH_OHCI_REG2C 0x2C // Subsystem Vendor ID/ Subsystem ID - RW +#define FCH_OHCI_REG34 0x34 // Capability Pointer - R +#define FCH_OHCI_REG3C 0x3C // Interrupt Line - RW +#define FCH_OHCI_REG3D 0x3D // Interrupt Line - RW +#define FCH_OHCI_REG40 0x40 // Config Timers - RW +#define FCH_OHCI_REG42 0x42 // Port Disable Control - RW (800) +#define FCH_OHCI_REG48 0x48 // Port Force Reset - RW (800) +#define FCH_OHCI_REG58 0x58 // Over Current Control - RW +#define FCH_OHCI_REG68 0x68 // Over Current PME Enable - RW +#define FCH_OHCI_REG74 0x74 // Target Timeout Control - RW +#define FCH_OHCI_REG80 0x80 // +#define FCH_OHCI_REGD0 0x0D0 // MSI Control - RW +#define FCH_OHCI_REGD4 0x0D4 // MSI Address - RW +#define FCH_OHCI_REGD8 0x0D8 // MSI Data - RW +#define FCH_OHCI_REGE4 0x0E4 // HT MSI Support +#define FCH_OHCI_REGF0 0x0F0 // Function Level Reset Capability +#define FCH_OHCI_REGF4 0x0F4 // Function Level Reset Control + +#define FCH_OHCI_BAR_REG00 0x00 // cRevision - R +#define FCH_OHCI_BAR_REG04 0x04 // cControl +#define FCH_OHCI_BAR_REG08 0x08 // cCommandStatus +#define FCH_OHCI_BAR_REG0C 0x0C // cInterruptStatus RW +#define FCH_OHCI_BAR_REG10 0x10 // cInterruptEnable +#define FCH_OHCI_BAR_REG14 0x14 // cInterruptDisable +#define FCH_OHCI_BAR_REG18 0x18 // HcCCA +#define FCH_OHCI_BAR_REG1C 0x1C // cPeriodCurrentED +#define FCH_OHCI_BAR_REG20 0x20 // HcControleadED +#define FCH_OHCI_BAR_REG24 0x24 // cControlCurrentED RW +#define FCH_OHCI_BAR_REG28 0x28 // HcBulkeadED +#define FCH_OHCI_BAR_REG2C 0x2C // cBulkCurrentED- RW +#define FCH_OHCI_BAR_REG30 0x30 // HcDoneead +#define FCH_OHCI_BAR_REG34 0x34 // cFmInterval +#define FCH_OHCI_BAR_REG38 0x38 // cFmRemaining +#define FCH_OHCI_BAR_REG3C 0x3C // cFmNumber +#define FCH_OHCI_BAR_REG40 0x40 // cPeriodicStart +#define FCH_OHCI_BAR_REG44 0x44 // HcLSThresold +#define FCH_OHCI_BAR_REG48 0x48 // HcRDescriptorA +#define FCH_OHCI_BAR_REG4C 0x4C // HcRDescriptorB +#define FCH_OHCI_BAR_REG50 0x50 // HcRStatus +#define FCH_OHCI_BAR_REG54 0x54 // HcRhPortStatus (800) +#define FCH_OHCI_BAR_REG58 0x58 // HcRhPortStatus NPD (800) +#define FCH_OHCI_BAR_REGF0 0xF0 // OHCI Loop Back feature Support (800) + +// +// USB EHCI Device 0x7808 +// Device 18 (0x12)/Device 19 (0x13)/Device 22 (0x16) Func 2 +// +#define FCH_EHCI_REG00 0x00 // DEVICE/VENDOR ID - R +#define FCH_EHCI_REG04 0x04 // Command - RW +#define FCH_EHCI_REG06 0x06 // Status - R +#define FCH_EHCI_REG08 0x08 // Revision ID/Class Code - R +#define FCH_EHCI_REG0C 0x0C // Miscellaneous - RW +#define FCH_EHCI_REG10 0x10 // BAR - RW +#define FCH_EHCI_REG2C 0x2C // Subsystem ID/Subsystem Vendor ID - RW +#define FCH_EHCI_REG34 0x34 // Capability Pointer - R +#define FCH_EHCI_REG3C 0x3C // Interrupt Line - RW +#define FCH_EHCI_REG3D 0x3D // Interrupt Line - RW +#define FCH_EHCI_REG54 0x54 // EHCI Misc Control - RW +#define FCH_EHCI_REG60 0x60 // SBRN - R +#define FCH_EHCI_REG61 0x61 // FLADJ - RW +#define FCH_EHCI_REGC0 0x0C0 // PME control - RW (800) +#define FCH_EHCI_REGC4 0x0C4 // PME Data /Status - RW (800) +#define FCH_EHCI_REGD0 0x0D0 // MSI Control - RW +#define FCH_EHCI_REGD4 0x0D4 // MSI Address - RW +#define FCH_EHCI_REGD8 0x0D8 // MSI Data - RW +#define FCH_EHCI_REGF0 0x0F0 // Function Level Reset Capability - R (800) +#define FCH_EHCI_REGF4 0x0F4 // Function Level Reset Capability - R (800) + +#define FCH_EHCI_BAR_REG00 0x00 // CAPLENGT - R +#define FCH_EHCI_BAR_REG02 0x002 +#define FCH_EHCI_BAR_REG04 0x004 +#define FCH_EHCI_BAR_REG08 0x008 + +#define FCH_EHCI_BAR_REG20 0x020 +#define FCH_EHCI_BAR_REG24 0x024 +#define FCH_EHCI_BAR_REG28 0x028 +#define FCH_EHCI_BAR_REG2C 0x02C +#define FCH_EHCI_BAR_REG30 0x030 +#define FCH_EHCI_BAR_REG34 0x034 +#define FCH_EHCI_BAR_REG38 0x038 +#define FCH_EHCI_BAR_REG60 0x060 +#define FCH_EHCI_BAR_REG64 0x064 +#define FCH_EHCI_BAR_REGA4 0x0A4 +#define FCH_EHCI_BAR_REGA8 0x0A8 +#define FCH_EHCI_BAR_REGAC 0x0AC +#define FCH_EHCI_BAR_REGB4 0x0B4 +#define FCH_EHCI_BAR_REGB8 0x0B8 +#define FCH_EHCI_BAR_REGBC 0x0BC +#define FCH_EHCI_BAR_REGC0 0x0C0 +#define FCH_EHCI_BAR_REGC4 0x0C4 +#define FCH_EHCI_BAR_REGC8 0x0C8 +#define FCH_EHCI_BAR_REGD0 0x0D0 +#define FCH_EHCI_BAR_REGD4 0x0D4 + +// +// USB XHCI Device 0x7812/0x7814 +// Device 16 (0x10) Func 0 +// +#define FCH_XHCI_REG00 0x00 // DEVICE/VENDOR ID - R +#define FCH_XHCI_REG04 0x04 // Command - RW +#define FCH_XHCI_REG10 0x10 // Bar0 +#define FCH_XHCI_REG2C 0x2C // Sub System ID +#define FCH_XHCI_REG40 0x40 // Index0 +#define FCH_XHCI_REG44 0x44 // Data0 +#define FCH_XHCI_REG48 0x48 // Index1 +#define FCH_XHCI_REG4C 0x4C // Data0 +#define FCH_XHCI_REG54 0x54 // PME Control/Status + +// +// FCH CFG device 0x780B +// Device 20 (0x14) Func 0 +// +#define FCH_CFG_REG00 0x000 // VendorID - R +#define FCH_CFG_REG02 0x002 // DeviceID - R +#define FCH_CFG_REG04 0x004 // Command- RW +#define FCH_CFG_REG05 0x005 // Command- RW +#define FCH_CFG_REG06 0x006 // STATUS- RW +#define FCH_CFG_REG08 0x008 // Revision ID/Class Code- R +#define FCH_CFG_REG0A 0x00A // +#define FCH_CFG_REG0B 0x00B // +#define FCH_CFG_REG0C 0x00C // Cache Line Size- R +#define FCH_CFG_REG0D 0x00D // Latency Timer- R +#define FCH_CFG_REG0E 0x00E // Header Type- R +#define FCH_CFG_REG0F 0x00F // BIST- R +#define FCH_CFG_REG10 0x010 // Base Address 0- R +#define FCH_CFG_REG11 0x011 //; +#define FCH_CFG_REG12 0x012 //; +#define FCH_CFG_REG13 0x013 //; +#define FCH_CFG_REG14 0x014 // Base Address 1- R +#define FCH_CFG_REG18 0x018 // Base Address 2- R +#define FCH_CFG_REG1C 0x01C // Base Address 3- R +#define FCH_CFG_REG20 0x020 // Base Address 4- R +#define FCH_CFG_REG24 0x024 // Base Address 5- R +#define FCH_CFG_REG28 0x028 // Cardbus CIS Pointer- R +#define FCH_CFG_REG2C 0x02C // Subsystem Vendor ID- W +#define FCH_CFG_REG2E 0x02E // Subsystem ID- W +#define FCH_CFG_REG30 0x030 // Expansion ROM Base Address - R +#define FCH_CFG_REG34 0x034 // Capability Pointer - R (800) default changed as 0x00 +#define FCH_CFG_REG3C 0x03C // Interrupt Line - R +#define FCH_CFG_REG3D 0x03D // Interrupt Pin - R +#define FCH_CFG_REG3E 0x03E // Min_Gnt - R +#define FCH_CFG_REG3F 0x03F // Max_Lat - R +#define FCH_CFG_REG90 0x090 // Smbus Base Address - R +#define FCH_CFG_REG9C 0x09C // SBResourceMMIO_BASE + +// +// FCH AZALIA device 0x780D +// Device 20 (0x14) Func 2 +// + +#define FCH_AZ_REG00 0x00 // Vendor ID - R +#define FCH_AZ_REG02 0x02 // Device ID - R/W +#define FCH_AZ_REG04 0x04 // PCI Command +#define FCH_AZ_REG06 0x06 // PCI Status - R/W +#define FCH_AZ_REG08 0x08 // Revision ID +#define FCH_AZ_REG09 0x09 // Programming Interface +#define FCH_AZ_REG0A 0x0A // Sub Class Code +#define FCH_AZ_REG0B 0x0B // Base Class Code +#define FCH_AZ_REG0C 0x0C // Cache Line Size - R/W +#define FCH_AZ_REG0D 0x0D // Latency Timer +#define FCH_AZ_REG0E 0x0E // Header Type +#define FCH_AZ_REG0F 0x0F // BIST +#define FCH_AZ_REG10 0x10 // Lower Base Address Register +#define FCH_AZ_REG14 0x14 // Upper Base Address Register +#define FCH_AZ_REG2C 0x2C // Subsystem Vendor ID +#define FCH_AZ_REG34 0x34 // Capabilities Pointer +#define FCH_AZ_REG3C 0x3C // Interrupt Line +#define FCH_AZ_REG3D 0x3D // Interrupt Pin +#define FCH_AZ_REG3E 0x3E // Minimum Grant +#define FCH_AZ_REG3F 0x3F // Maximum Latency +#define FCH_AZ_REG40 0x40 // Misc Control 1 +#define FCH_AZ_REG44 0x44 // Interrupt Pin Control Register +#define FCH_AZ_REG50 0x50 // Power Management Capability ID +#define FCH_AZ_REG54 0x54 // Power Management Control/Status +#define FCH_AZ_REG60 0x60 // MSI Capability ID +#define FCH_AZ_REG64 0x64 // MSI Message Lower Address +#define FCH_AZ_REG68 0x68 // MSI Message Upper Address +#define FCH_AZ_REG6C 0x6C // MSI Message Data + +#define FCH_AZ_BAR_REG00 0x00 // Global Capabilities - R +#define FCH_AZ_BAR_REG02 0x02 // Minor Version - R +#define FCH_AZ_BAR_REG03 0x03 // Major Version - R +#define FCH_AZ_BAR_REG04 0x04 // Output Payload Capability - R +#define FCH_AZ_BAR_REG06 0x06 // Input Payload Capability - R +#define FCH_AZ_BAR_REG08 0x08 // Global Control - R/W +#define FCH_AZ_BAR_REG0C 0x0C // Wake Enable - R/W +#define FCH_AZ_BAR_REG0E 0x0E // State Change Status - R/W +#define FCH_AZ_BAR_REG10 0x10 // Global Status - R/W +#define FCH_AZ_BAR_REG18 0x18 // Output Stream Payload Capability - R +#define FCH_AZ_BAR_REG1A 0x1A // Input Stream Payload Capability - R +#define FCH_AZ_BAR_REG20 0x20 // Interrupt Control - R/W +#define FCH_AZ_BAR_REG24 0x24 // Interrupt Status - R/W +#define FCH_AZ_BAR_REG30 0x30 // Wall Clock Counter - R +#define FCH_AZ_BAR_REG38 0x38 // Stream Synchronization - R/W +#define FCH_AZ_BAR_REG40 0x40 // CORB Lower Base Address - R/W +#define FCH_AZ_BAR_REG44 0x44 // CORB Upper Base Address - RW +#define FCH_AZ_BAR_REG48 0x48 // CORB Write Pointer - R/W +#define FCH_AZ_BAR_REG4A 0x4A // CORB Read Pointer - R/W +#define FCH_AZ_BAR_REG4C 0x4C // CORB Control - R/W +#define FCH_AZ_BAR_REG4D 0x4D // CORB Status - R/W +#define FCH_AZ_BAR_REG4E 0x4E // CORB Size - R/W +#define FCH_AZ_BAR_REG50 0x50 // RIRB Lower Base Address - RW +#define FCH_AZ_BAR_REG54 0x54 // RIRB Upper Address - RW +#define FCH_AZ_BAR_REG58 0x58 // RIRB Write Pointer - RW +#define FCH_AZ_BAR_REG5A 0x5A // RIRB Response Interrupt Count - R/W +#define FCH_AZ_BAR_REG5C 0x5C // RIRB Control - R/W +#define FCH_AZ_BAR_REG5D 0x5D // RIRB Status - R/W +#define FCH_AZ_BAR_REG5E 0x5E // RIRB Size - R/W +#define FCH_AZ_BAR_REG60 0x60 // Immediate Command Output Interface - R/W +#define FCH_AZ_BAR_REG64 0x64 // Immediate Command Input Interface - R/W +#define FCH_AZ_BAR_REG68 0x68 // Immediate Command Input Interface - R/W +#define FCH_AZ_BAR_REG70 0x70 // DMA Position Lower Base Address - R/W +#define FCH_AZ_BAR_REG74 0x74 // DMA Position Upper Base Address - R/W +#define FCH_AZ_BAR_REG2030 0x2030 // Wall Clock Counter Alias - R + +// +// FCH LPC Device 0x780E +// Device 20 (0x14) Func 3 +// +#define FCH_LPC_REG00 0x00 // VID- R +#define FCH_LPC_REG02 0x02 // DID- R +#define FCH_LPC_REG04 0x04 // CMD- RW +#define FCH_LPC_REG06 0x06 // STATUS- RW +#define FCH_LPC_REG08 0x08 // Revision ID/Class Code - R +#define FCH_LPC_REG0C 0x0C // Cache Line Size - R +#define FCH_LPC_REG0D 0x0D // Latency Timer - R +#define FCH_LPC_REG0E 0x0E // Header Type - R +#define FCH_LPC_REG0F 0x0F // BIST- R +#define FCH_LPC_REG10 0x10 // Base Address Reg 0- RW* +#define FCH_LPC_REG2C 0x2C // Subsystem ID & Subsystem Vendor ID - Wo/Ro +#define FCH_LPC_REG34 0x34 // Capabilities Pointer - Ro +#define FCH_LPC_REG40 0x40 // PCI Control - RW +#define FCH_LPC_REG44 0x44 // IO Port Decode Enable Register 1- RW +#define FCH_LPC_REG45 0x45 // IO Port Decode Enable Register 2- RW +#define FCH_LPC_REG46 0x46 // IO Port Decode Enable Register 3- RW +#define FCH_LPC_REG47 0x47 // IO Port Decode Enable Register 4- RW +#define FCH_LPC_REG48 0x48 // IO/Mem Port Decode Enable Register 5- RW +#define FCH_LPC_REG4C 0x4C // Memory Range Register - RW +#define FCH_LPC_REG50 0x50 // Rom Protect 0 - RW +#define FCH_LPC_REG54 0x54 // Rom Protect 1 - RW +#define FCH_LPC_REG58 0x58 // Rom Protect 2 - RW +#define FCH_LPC_REG5C 0x5C // Rom Protect 3 - RW +#define FCH_LPC_REG60 0x60 // PCI Memory Start Address of LPC Target Cycles - +#define FCH_LPC_REG62 0x62 // PCI Memory End Address of LPC Target Cycles - +#define FCH_LPC_REG64 0x64 // PCI IO base Address of Wide Generic Port - RW +#define FCH_LPC_REG68 0x68 // LPC ROM Address Range 1 (Start Address) - RW +#define FCH_LPC_REG6C 0x6C // LPC ROM Address Range 2 (Start Address)- RW +#define FCH_LPC_REG74 0x74 // Alternative Wide IO Range Enable- W/R +#define FCH_LPC_REG7C 0x7C // TPM (trusted plant form module) reg- W/R +#define FCH_LPC_REGA0 0x0A0 // SPI base address +#define FCH_LPC_REGA4 0x0A4 +#define FCH_LPC_REGB8 0x0B8 +#define FCH_LPC_REGBA 0x0BA +#define FCH_LPC_REGBB 0x0BB +#define FCH_LPC_REGC8 0x0C8 +#define FCH_LPC_REGCC 0x0CC // AutoRomCfg +#define FCH_LPC_REGD0 0x0D0 + +// +// FCH GEC 0x14E4 0x1699 +// Device 20 (0x14) Func 6 +// + +// +// FCH SD +// Device 20 (0x14) Func 7 +// +#define SD_PCI_REG10 0x10 +#define SD_PCI_REG2C 0x2C +#define SD_PCI_REGA4 0xA4 +#define SD_PCI_REGA8 0xA8 +#define SD_PCI_REGB0 0xB0 +#define SD_PCI_REGBC 0xBC +#define SD_PCI_REGD0 0xD0 +#define SD_PCI_REGF0 0xF0 +#define SD_PCI_REGF4 0xF4 +#define SD_PCI_REGF8 0xF8 +#define SD_PCI_REGFC 0xFC +#define FCH_SD_BAR_REG28 0x28 +#define SD_CARD_PRESENT BIT0 +#define FCH_SD_BAR_REG2C 0x2C +#define FCH_SD_FREQUENCY_SLT BIT2 +#define FCH_SD_BAR_REG3C 0x3C +#define FCH_SD_1_8V BIT3 + +// +// FCH MMIO Base (SMI) +// offset : 0x200 +// +#define FCH_SMI_REG00 0x00 // EventStatus +#define FCH_SMI_REG04 0x04 // EventEnable +#define FCH_SMI_REG08 0x08 // SciTrig +#define FCH_SMI_REG0C 0x0C // SciLevl +#define FCH_SMI_REG10 0x10 // SmiSciStatus +#define FCH_SMI_REG14 0x14 // SmiSciEn +#define FCH_SMI_REG18 0x18 // ForceSciEn +#define FCH_SMI_REG1C 0x1C // SciRwData +#define FCH_SMI_REG3C 0x3C // DataErrorStatus +#define FCH_SMI_REG20 0x20 // SciS0En +#define FCH_SMI_Gevent0 0x40 // SciMap0 +#define FCH_SMI_Gevent1 0x41 // SciMap1 +#define FCH_SMI_Gevent2 0x42 // SciMap2 +#define FCH_SMI_Gevent3 0x43 // SciMap3 +#define FCH_SMI_Gevent4 0x44 // SciMap4 +#define FCH_SMI_Gevent5 0x45 // SciMap5 +#define FCH_SMI_Gevent6 0x46 // SciMap6 +#define FCH_SMI_Gevent7 0x47 // SciMap7 +#define FCH_SMI_Gevent8 0x48 // SciMap8 +#define FCH_SMI_Gevent9 0x49 // SciMap9 +#define FCH_SMI_Gevent10 0x4A // SciMap10 +#define FCH_SMI_Gevent11 0x4B // SciMap11 +#define FCH_SMI_Gevent12 0x4C // SciMap12 +#define FCH_SMI_Gevent13 0x4D // SciMap13 +#define FCH_SMI_Gevent14 0x4E // SciMap14 +#define FCH_SMI_Gevent15 0x4F // SciMap15 +#define FCH_SMI_Gevent16 0x50 // SciMap16 +#define FCH_SMI_Gevent17 0x51 // SciMap17 +#define FCH_SMI_Gevent18 0x52 // SciMap18 +#define FCH_SMI_Gevent19 0x53 // SciMap19 +#define FCH_SMI_Gevent20 0x54 // SciMap20 +#define FCH_SMI_Gevent21 0x55 // SciMap21 +#define FCH_SMI_Gevent22 0x56 // SciMap22 +#define FCH_SMI_Gevent23 0x57 // SciMap23 +#define FCH_SMI_Usbwakup0 0x58 // SciMap24 +#define FCH_SMI_Usbwakup1 0x59 // SciMap25 +#define FCH_SMI_Usbwakup2 0x5A // SciMap26 +#define FCH_SMI_Usbwakup3 0x5B // SciMap27 +#define FCH_SMI_SBGppPme0 0x5C // SciMap28 +#define FCH_SMI_SBGppPme1 0x5D // SciMap29 +#define FCH_SMI_SBGppPme2 0x5E // SciMap30 +#define FCH_SMI_SBGppPme3 0x5F // SciMap31 +#define FCH_SMI_SBGppHp0 0x60 // SciMap32 +#define FCH_SMI_SBGppHp1 0x61 // SciMap33 +#define FCH_SMI_SBGppHp2 0x62 // SciMap34 +#define FCH_SMI_SBGppHp3 0x63 // SciMap35 +#define FCH_SMI_AzaliaPme 0x64 // SciMap36 +#define FCH_SMI_SataGevent0 0x65 // SciMap37 +#define FCH_SMI_SataGevent1 0x66 // SciMap38 +#define FCH_SMI_GecPme 0x67 // SciMap39 +#define FCH_SMI_IMCGevent0 0x68 // SciMap40 +#define FCH_SMI_IMCGevent1 0x69 // SciMap41 +#define FCH_SMI_CIRPme 0x6A // SciMap42 +#define FCH_SMI_WakePinGevent 0x6B // SciMap43 +#define FCH_SMI_FanThGevent 0x6C // SciMap44 //FanThermalGevent +#define FCH_SMI_ASFMasterIntr 0x6D // SciMap45 +#define FCH_SMI_ASFSlaveIntr 0x6E // SciMap46 +#define FCH_SMI_SMBUS0 0x6F // SciMap47 +#define FCH_SMI_TWARN 0x70 // SciMap48 +#define FCH_SMI_TMI 0x71 // SciMap49 // TrafficMonitorIntr +#define FCH_SMI_iLLB 0x72 // SciMap50 +#define FCH_SMI_PowerButton 0x73 // SciMap51 +#define FCH_SMI_ProcHot 0x74 // SciMap52 +#define FCH_SMI_APUHwAssertion 0x75 // SciMap53 +#define FCH_SMI_APUSciAssertion 0x76 // SciMap54 +#define FCH_SMI_RAS 0x77 // SciMap55 +#define FCH_SMI_xHC0Pme 0x78 // SciMap56 +#define FCH_SMI_xHC1Pme 0x79 // SciMap57 + +// Empty from 0x72-0x7F +//#Define FCH_SMI_REG7C 0x7F // SciMap63 *** + +#define FCH_SMI_REG80 0x80 // SmiStatus0 +#define FCH_SMI_REG84 0x84 // SmiStatus1 +#define FCH_SMI_REG88 0x88 // SmiStatus2 +#define FCH_SMI_REG8C 0x8C // SmiStatus3 +#define FCH_SMI_REG90 0x90 // SmiStatus4 +#define FCH_SMI_REG94 0x94 // SmiPointer +#define FCH_SMI_REG96 0x96 // SmiTimer +#define FCH_SMI_REG98 0x98 // SmiTrig +#define FCH_SMI_REG9C 0x9C // SmiTrig +#define FCH_SMI_REGA0 0xA0 +#define FCH_SMI_REGA1 0xA1 +#define FCH_SMI_REGA2 0xA2 +#define FCH_SMI_REGA3 0xA3 +#define FCH_SMI_REGA4 0xA4 +#define FCH_SMI_REGA5 0xA5 +#define FCH_SMI_REGA6 0xA6 +#define FCH_SMI_REGA7 0xA7 +#define FCH_SMI_REGA8 0xA8 +#define FCH_SMI_REGA9 0xA9 +#define FCH_SMI_REGAA 0xAA +#define FCH_SMI_REGAB 0xAB +#define FCH_SMI_REGAC 0xAC +#define FCH_SMI_REGAD 0xAD +#define FCH_SMI_REGAE 0xAE +#define FCH_SMI_REGAF 0xAF +#define FCH_SMI_REGB0 0xB0 +#define FCH_SMI_REGB1 0xB1 +#define FCH_SMI_REGB2 0xB2 +#define FCH_SMI_REGB3 0xB3 +#define FCH_SMI_REGB4 0xB4 +#define FCH_SMI_REGB5 0xB5 +#define FCH_SMI_REGB6 0xB6 +#define FCH_SMI_REGB7 0xB7 +#define FCH_SMI_REGB8 0xB8 +#define FCH_SMI_REGB9 0xB9 +#define FCH_SMI_REGBA 0xBA +#define FCH_SMI_REGBB 0xBB +#define FCH_SMI_REGBC 0xBC +#define FCH_SMI_REGBD 0xBD +#define FCH_SMI_REGBE 0xBE +#define FCH_SMI_REGBF 0xBF +#define FCH_SMI_REGC0 0xC0 +#define FCH_SMI_REGC1 0xC1 +#define FCH_SMI_REGC2 0xC2 +#define FCH_SMI_REGC3 0xC3 +#define FCH_SMI_REGC4 0xC4 +#define FCH_SMI_REGC5 0xC5 +#define FCH_SMI_REGC6 0xC6 +#define FCH_SMI_REGC7 0xC7 +#define FCH_SMI_REGC8 0xC8 +#define FCH_SMI_REGCA 0xCA // IoTrapping1 +#define FCH_SMI_REGCC 0xCC // IoTrapping2 +#define FCH_SMI_REGCE 0xCE // IoTrapping3 +#define FCH_SMI_TRAPPING_WRITE 0x01 +#define FCH_SMI_REGD0 0xD0 // MemTrapping0 +#define FCH_SMI_REGD4 0xD4 // MemRdOvrData0 +#define FCH_SMI_REGD8 0xD8 // MemTrapping1 +#define FCH_SMI_REGDC 0xDC // MemRdOvrData1 +#define FCH_SMI_REGE0 0xE0 // MemTrapping2 +#define FCH_SMI_REGE4 0xE4 // MemRdOvrData2 +#define FCH_SMI_REGE8 0xE8 // MemTrapping3 +#define FCH_SMI_REGEC 0xEC // MemRdOvrData3 +#define FCH_SMI_REGF0 0xF0 // CfgTrapping0 +#define FCH_SMI_REGF4 0xF4 // CfgTrapping1 +#define FCH_SMI_REGF8 0xF8 // CfgTrapping2 +#define FCH_SMI_REGFC 0xFC // CfgTrapping3 + +// +// FCH MMIO Base (PMIO) +// offset : 0x300 +// +#define FCH_PMIOA_REG00 0x00 +#define FCH_PMIOA_REG04 0x04 +#define FCH_PMIOA_REG08 0x08 +#define FCH_PMIOA_REG0C 0x0C +#define FCH_PMIOA_REG10 0x10 +#define FCH_PMIOA_REG14 0x14 +#define FCH_PMIOA_REG20 0x20 +#define FCH_PMIOA_REG24 0x24 +#define FCH_PMIOA_REG28 0x28 +#define FCH_PMIOA_REG2C 0x2C +#define FCH_PMIOA_REG2E 0x2E +#define FCH_PMIOA_REG34 0x34 +#define FCH_PMIOA_REG3C 0x3C +#define FCH_PMIOA_REG44 0x44 +#define FCH_PMIOA_REG48 0x48 +#define FCH_PMIOA_REG4C 0x4C +#define FCH_PMIOA_REG50 0x50 +#define FCH_PMIOA_REG54 0x54 +#define FCH_PMIOA_REG56 0x56 +#define FCH_PMIOA_REG58 0x58 +#define FCH_PMIOA_REG59 0x59 +#define FCH_PMIOA_REG5B 0x5B +#define FCH_PMIOA_REG5C 0x5C +#define FCH_PMIOA_REG5E 0x5E +#define FCH_PMIOA_REG5F 0x5F +#define FCH_PMIOA_REG60 0x60 +#define FCH_PMIOA_REG62 0x62 +#define FCH_PMIOA_REG64 0x64 +#define FCH_PMIOA_REG66 0x66 +#define FCH_PMIOA_REG68 0x68 +#define FCH_PMIOA_REG6A 0x6A +#define FCH_PMIOA_REG6C 0x6C +#define FCH_PMIOA_REG6E 0x6E +#define FCH_PMIOA_REG74 0x74 +#define FCH_PMIOA_REG78 0x78 +#define FCH_PMIOA_REG7A 0x7A +#define FCH_PMIOA_REG7C 0x7C +#define FCH_PMIOA_REG7E 0x7E +#define FCH_PMIOA_REG7F 0x7F +#define FCH_PMIOA_REG84 0x84 +#define FCH_PMIOA_REG88 0x88 +#define FCH_PMIOA_REG8C 0x8C +#define FCH_PMIOA_REG8E 0x8E +#define FCH_PMIOA_REG94 0x94 +#define FCH_PMIOA_REG98 0x98 +#define FCH_PMIOA_REG9C 0x9C +#define FCH_PMIOA_REG9D 0x9D +#define FCH_PMIOA_REGA0 0xA0 +#define FCH_PMIOA_REGA4 0xA4 +#define FCH_PMIOA_REGA8 0xA8 +#define FCH_PMIOA_REGAA 0xAA +#define FCH_PMIOA_REGAC 0xAC +#define FCH_PMIOA_REGAE 0xAE +#define FCH_PMIOA_REGB0 0xB0 +#define FCH_PMIOA_REGB4 0xB4 +#define FCH_PMIOA_REGB8 0xB8 +#define FCH_PMIOA_REGB9 0xB9 +#define FCH_PMIOA_REGBA 0xBA +#define FCH_PMIOA_REGBB 0xBB +#define FCH_PMIOA_REGBC 0xBC +#define FCH_PMIOA_REGBE 0xBE +#define FCH_PMIOA_REGC0 0xC0 +#define FCH_PMIOA_REGC2 0xC2 +#define FCH_PMIOA_REGC4 0xC4 +#define FCH_PMIOA_REGC5 0xC5 +#define FCH_PMIOA_REGC8 0xC8 +#define FCH_PMIOA_REGCC 0xCC +#define FCH_PMIOA_REGD0 0xD0 +#define FCH_PMIOA_REGD2 0xD2 +#define FCH_PMIOA_REGD3 0xD3 +#define FCH_PMIOA_REGD6 0xD6 +#define FCH_PMIOA_REGD7 0xD7 +#define FCH_PMIOA_REGE0 0xE0 +#define FCH_PMIOA_REGE8 0xE8 +#define FCH_PMIOA_REGEB 0xEB +#define FCH_PMIOA_REGEC 0xEC +#define FCH_PMIOA_REGED 0xED +#define FCH_PMIOA_REGEE 0xEE +#define FCH_PMIOA_REGEF 0xEF +#define FCH_PMIOA_REGF0 0xF0 +#define FCH_PMIOA_REGF2 0xF2 +#define FCH_PMIOA_REGF4 0xF4 +#define FCH_PMIOA_REGF8 0xF8 + +// +// FCH MMIO Base (PMIO2) +// offset : 0x400 +// +#define FCH_PMIO2_REG00 0x00 +#define FCH_PMIO2_REG01 0x01 +#define FCH_PMIO2_REG02 0x02 +#define FCH_PMIO2_REG03 0x03 +#define FCH_PMIO2_REG04 0x04 + + +#define FCH_PMIO2_REG63 0x63 +#define FCH_PMIO2_REG69 0x69 + +#define FCH_PMIO2_REG92 0x92 + + + +// +// FCH MMIO Base (GPIO/IoMux) +// offset : 0x100/0xD00 +// +/* +GPIO from 0 ~ 67, (GEVENT 0-23) 128 ~ 150, 160 ~ 226. +*/ +#define FCH_GPIO_REG00 0x00 +#define FCH_GPIO_REG06 0x06 +#define FCH_GPIO_REG09 0x09 +#define FCH_GPIO_REG10 0x0A +#define FCH_GPIO_REG17 0x11 +#define FCH_GPIO_REG21 0x15 +#define FCH_GPIO_REG28 0x1C +#define FCH_GPIO_REG32 0x20 +#define FCH_GPIO_REG33 0x21 +#define FCH_GPIO_REG34 0x22 +#define FCH_GPIO_REG35 0x23 +#define FCH_GPIO_REG36 0x24 +#define FCH_GPIO_REG37 0x25 +#define FCH_GPIO_REG38 0x26 +#define FCH_GPIO_REG39 0x27 +#define FCH_GPIO_REG40 0x28 +#define FCH_GPIO_REG41 0x29 +#define FCH_GPIO_REG42 0x2A +#define FCH_GPIO_REG43 0x2B +#define FCH_GPIO_REG44 0x2C +#define FCH_GPIO_REG45 0x2D +#define FCH_GPIO_REG46 0x2E +#define FCH_GPIO_REG47 0x2F +#define FCH_GPIO_REG48 0x30 +#define FCH_GPIO_REG49 0x31 +#define FCH_GPIO_REG50 0x32 +#define FCH_GPIO_REG51 0x33 +#define FCH_GPIO_REG52 0x34 +#define FCH_GPIO_REG53 0x35 +#define FCH_GPIO_REG54 0x36 +#define FCH_GPIO_REG55 0x37 +#define FCH_GPIO_REG56 0x38 +#define FCH_GPIO_REG57 0x39 +#define FCH_GPIO_REG58 0x3A +#define FCH_GPIO_REG59 0x3B +#define FCH_GPIO_REG60 0x3C +#define FCH_GPIO_REG61 0x3D +#define FCH_GPIO_REG62 0x3E +#define FCH_GPIO_REG63 0x3F +#define FCH_GPIO_REG64 0x40 +#define FCH_GPIO_REG65 0x41 +#define FCH_GPIO_REG66 0x42 +#define FCH_GPIO_REG67 0x43 +#define FCH_GPIO_REG68 0x44 +#define FCH_GPIO_REG69 0x45 +#define FCH_GPIO_REG70 0x46 +#define FCH_GPIO_REG71 0x47 +#define FCH_GPIO_REG72 0x48 +#define FCH_GPIO_REG73 0x49 +#define FCH_GPIO_REG74 0x4A +#define FCH_GPIO_REG75 0x4B +#define FCH_GPIO_REG76 0x4C +#define FCH_GPIO_REG77 0x4D +#define FCH_GPIO_REG78 0x4E +#define FCH_GPIO_REG79 0x4F +#define FCH_GPIO_REG80 0x50 + +// S5-DOMAIN GPIO + +// +// FCH MMIO Base (SMBUS) +// offset : 0xA00 +// +#define FCH_SMBUS_REG12 0x12 // I2CbusConfig + +// +// FCH MMIO Base (MISC) +// offset : 0xE00 +// +#define FCH_MISC_REG00 0x00 // ClkCntrl0 +/* +FCH_MISC_REG00 EQU 000h + ClkCntrl0 EQU 0FFFFFFFFh +*/ +#define FCH_MISC_REG04 0x04 // ClkCntrl1 +/* +FCH_MISC_REG04 EQU 004h + ClkCntrl1 EQU 0FFFFFFFFh +*/ +#define FCH_MISC_REG08 0x08 // ClkCntrl2 +/* +FCH_MISC_REG08 EQU 008h + ClkCntrl2 EQU 0FFFFFFFFh +*/ +#define FCH_MISC_REG0C 0x0C // ClkCntrl3 +/* +FCH_MISC_REG0C EQU 00Ch + ClkCntrl3 EQU 0FFFFFFFFh +*/ +#define FCH_MISC_REG10 0x10 // ClkCntrl4 +/* +FCH_MISC_REG10 EQU 010h + ClkCntrl4 EQU 0FFFFFFFFh +*/ +#define FCH_MISC_REG14 0x14 // ClkCntrl5 +/* +FCH_MISC_REG14 EQU 014h + ClkCntrl5 EQU 0FFFFFFFFh +*/ +#define FCH_MISC_REG18 0x18 // ClkCntrl6 +/* +FCH_MISC_REG18 EQU 018h + ClkCntrl6 EQU 0FFFFFFFFh +*/ +#define FCH_MISC_REG1C 0x1C +#define FCH_MISC_REG30 0x30 // OscFreqCounter +/* +FCH_MISC_REG30 EQU 030h + OscCounter EQU 0FFFFFFFFh ; The 32bit register shows the number of OSC clock per second. +*/ +#define FCH_MISC_REG34 0x34 // HpetClkPeriod +/* +FCH_MISC_REG34 EQU 034h + HpetClkPeriod EQU 0FFFFFFFFh ; default - 0x429B17Eh (14.31818M). +*/ +#define FCH_MISC_REG28 0x28 // ClkDrvSth2 +#define FCH_MISC_REG2C 0x2C +#define FCH_MISC_REG40 0x40 // MiscCntrl for clock only +#define FCH_MISC_REG50 0x50 // +#define FCH_MISC_REG6C 0x6C +/* +FCH_MISC_REG40 EQU 040h +*/ + +#define FCH_MISC_REG80 0x80 + +#define ChipSysNotUseFWHRom 0x0001 // EcPwm3 pad +#define ChipSysNotUseLpcRom 0x0002 // Inverted version from EcPwm2 pad (default - 1) + // Note: Both EcPwm3 and EcPwm2 straps pins are used to select boot ROM type. +#define ChipSysEcEnable 0x0004 // Enable Embedded Controller (EC) +#define ChipSysBootFailTmrEn 0x0008 // Enable Watchdog function +#define ChipSysIntClkGen 0x0010 // Select 25Mhz crystal clock or 100Mhz PCI-E clock ** + +/* +FCH_MISC_REG84 EQU 084h + Override FWHDisableStrap EQU BIT0 ; Override FWHDiableStrap value from external pin. + Override UseLpcRomStrap EQU BIT1 ; Override UseLpcRomStrap value from external pin. + Override EcEnableStrap EQU BIT2 ; Override EcEnableStrap value from external pin. + Override BootFailTmrEnStrap EQU BIT3 ; Override BootFailTmrEnStrap value from external pin. + Override DefaultModeStrap EQU BIT5 ; Override DefaultModeStrap value from external pin. + Override I2CRomStrap EQU BIT7 ; Override I2CRomStrap value from external pin. + Override ILAAutorunEnBStrap EQU BIT8 ; Override ILAAutorunEnBStrap value from external pin. + Override FcPllBypStrap EQU BIT9 ; Override FcPllBypStrap value from external pin. + Override PciPllBypStrap EQU BIT10 ; Override PciPllBypStrap value from external pin. + Override ShortResetStrap EQU BIT11 ; Override ShortResetStrap value from external pin. + Override FastBif2ClkStrap EQU BIT13 ; Override FastBif2ClkStrap value from external pin + PciRomBootStrap EQU BIT15 ; Override PCI Rom Boot Strap value from external pin + BlinkSlowModestrap EQU BIT16 ; Override Blink Slow mode (100Mhz) from external pin + ClkGenStrap EQU BIT17 ; Override CLKGEN from external pin. + BIF_GEN2_COMPL_Strap EQU BIT18 ; Override BIF_ GEN2_COMPLIANCE strap from external pin. + StrapOverrideEn EQU BIT31 ; Enable override strapping feature. +*/ +#define FCH_MISC_REGC0 0xC0 // CPU_Pstate0 +/* +FCH_MISC_REGC0 EQU 0C0h + Core0_PState EQU BIT0+BIT1+BIT2 ; 000: P0 001: P1 010: P2 011: P3 100: P4 101: P5 110: P6 111: P7 + Core1_PState EQU BIT4+BIT5+BIT6 + Core2_PState EQU BIT8+BIT9+BIT10 + Core3_PState EQU BIT12+BIT13+BIT14 + Core4_PState EQU BIT16++BIT17+BIT18 + Core5_PState EQU BIT20+BIT21+BIT22 + Core6_PState EQU BIT24+BIT25+BIT26 + Core7_PState EQU BIT28+BIT29+BIT30 +*/ +#define FCH_MISC_REGC4 0xC4 // CPU_Pstate1 +/* +FCH_MISC_REGC4 EQU 0C4h + Core8_PState EQU BIT0+BIT1+BIT2 ; 000: P0 001: P1 010: P2 011: P3 100: P4 101: P5 110: P6 111: P7 + Core9_PState EQU BIT4+BIT5+BIT6 + Core10_PState EQU BIT8+BIT9+BIT10 + Core11_PState EQU BIT12+BIT13+BIT14 + Core12_PState EQU BIT16++BIT17+BIT18 + Core13_PState EQU BIT20+BIT21+BIT22 + Core14_PState EQU BIT24+BIT25+BIT26 + Core15_PState EQU BIT28+BIT29+BIT30 +*/ +#define FCH_MISC_REGD0 0xD0 // CPU_Cstate0 +/* +FCH_MISC_REGD0 EQU 0D0h + Core0_CState EQU BIT0+BIT1+BIT2 ; 000: C0 001: C1 010: C2 011: C3 100: C4 101: C5 110: C6 111: C7 + Core1_CState EQU BIT4+BIT5+BIT6 + Core2_CState EQU BIT8+BIT9+BIT10 + Core3_CState EQU BIT12+BIT13+BIT14 + Core4_CState EQU BIT16++BIT17+BIT18 + Core5_CState EQU BIT20+BIT21+BIT22 + Core6_CState EQU BIT24+BIT25+BIT26 + Core7_CState EQU BIT28+BIT29+BIT30 +*/ +#define FCH_MISC_REGD4 0xD4 // CPU_Cstate1 +/* +FCH_MISC_REGD4 EQU 0D4h + Core8_CState EQU BIT0+BIT1+BIT2 ; 000: C0 001: C1 010: C2 011: C3 100: C4 101: C5 110: C6 111: C7 + Core9_CState EQU BIT4+BIT5+BIT6 + Core10_CState EQU BIT8+BIT9+BIT10 + Core11_CState EQU BIT12+BIT13+BIT14 + Core12_CState EQU BIT16++BIT17+BIT18 + Core13_CState EQU BIT20+BIT21+BIT22 + Core14_CState EQU BIT24+BIT25+BIT26 + Core15_CState EQU BIT28+BIT29+BIT30 +*/ +#define FCH_MISC_REGF0 0xF0 // SataPortSts +/* +FCH_MISC_REGF0 EQU 0F0h + Port0Sts EQU BIT0 ; The selected status of Port 0. + Port1Sts EQU BIT1 ; The selected status of Port 1 + Port2Sts EQU BIT2 ; The selected status of Port 2. + Port3Sts EQU BIT3 ; The selected status of Port 3 + Port4Sts EQU BIT4 ; The selected status of Port 4. + Port5Sts EQU BIT5 ; The selected status of Port 5 + SataPortSel EQU BIT24+BIT25 ; 00 - Select "led" for Port 0 to 5 + ; 01 - Select "delete" for Port 0 to 5 + ; 10 - Select "err" for Port 0 to 5 + ; 11 - Select "led" for Port 0 to 5 +*/ + +// +// FCH MMIO Base (SERIAL_DEBUG_BASE) +// offset : 0x1000 +// + +#define FCH_RTC_REG00 0x00 // Seconds - RW +#define FCH_RTC_REG01 0x01 // Seconds Alarm - RW +#define FCH_RTC_REG02 0x02 // Minutes - RW +#define FCH_RTC_REG03 0x03 // Minutes Alarm - RW +#define FCH_RTC_REG04 0x04 // ours - RW +#define FCH_RTC_REG05 0x05 // ours Alarm- RW +#define FCH_RTC_REG06 0x06 // Day of Week - RW +#define FCH_RTC_REG07 0x07 // Date of Mont - RW +#define FCH_RTC_REG08 0x08 // Mont - RW +#define FCH_RTC_REG09 0x09 // Year - RW +#define FCH_RTC_REG0A 0x0A // Register A - RW +#define FCH_RTC_REG0B 0x0B // Register B - RW +#define FCH_RTC_REG0C 0x0C // Register C - R +#define FCH_RTC_REG0D 0x0D // DateAlarm - RW +#define FCH_RTC_REG32 0x32 // AltCentury - RW +#define FCH_RTC_REG48 0x48 // Century - RW +#define FCH_RTC_REG50 0x50 // Extended RAM Address Port - RW +#define FCH_RTC_REG53 0x53 // Extended RAM Data Port - RW +#define FCH_RTC_REG7E 0x7E // RTC Time Clear - RW +#define FCH_RTC_REG7F 0x7F // RTC RAM Enable - RW + + +#define FCH_IOMAP_REG00 0x000 // Dma_C 0 +#define FCH_IOMAP_REG02 0x002 // Dma_C 1 +#define FCH_IOMAP_REG04 0x004 // Dma_C 2 +#define FCH_IOMAP_REG06 0x006 // Dma_C 3 +#define FCH_IOMAP_REG08 0x008 // Dma_Status +#define FCH_IOMAP_REG09 0x009 // Dma_WriteRest +#define FCH_IOMAP_REG0A 0x00A // Dma_WriteMask +#define FCH_IOMAP_REG0B 0x00B // Dma_WriteMode +#define FCH_IOMAP_REG0C 0x00C // Dma_Clear +#define FCH_IOMAP_REG0D 0x00D // Dma_MasterClr +#define FCH_IOMAP_REG0E 0x00E // Dma_ClrMask +#define FCH_IOMAP_REG0F 0x00F // Dma_AllMask +#define FCH_IOMAP_REG20 0x020 // IntrCntrlReg1 +#define FCH_IOMAP_REG21 0x021 // IntrCntrlReg2 +#define FCH_IOMAP_REG40 0x040 // TimerC0 +#define FCH_IOMAP_REG41 0x041 // TimerC1 +#define FCH_IOMAP_REG42 0x042 // TimerC2 +#define FCH_IOMAP_REG43 0x043 // Tmr1CntrlWord +#define FCH_IOMAP_REG61 0x061 // Nmi_Status +#define FCH_IOMAP_REG70 0x070 // Nmi_Enable +#define FCH_IOMAP_REG71 0x071 // RtcDataPort +#define FCH_IOMAP_REG72 0x072 // AlternatRtcAddrPort +#define FCH_IOMAP_REG73 0x073 // AlternatRtcDataPort +#define FCH_IOMAP_REG80 0x080 // Dma_Page_Reserved0 +#define FCH_IOMAP_REG81 0x081 // Dma_PageC2 +#define FCH_IOMAP_REG82 0x082 // Dma_PageC3 +#define FCH_IOMAP_REG83 0x083 // Dma_PageC1 +#define FCH_IOMAP_REG84 0x084 // Dma_Page_Reserved1 +#define FCH_IOMAP_REG85 0x085 // Dma_Page_Reserved2 +#define FCH_IOMAP_REG86 0x086 // Dma_Page_Reserved3 +#define FCH_IOMAP_REG87 0x087 // Dma_PageC0 +#define FCH_IOMAP_REG88 0x088 // Dma_Page_Reserved4 +#define FCH_IOMAP_REG89 0x089 // Dma_PageC6 +#define FCH_IOMAP_REG8A 0x08A // Dma_PageC7 +#define FCH_IOMAP_REG8B 0x08B // Dma_PageC5 +#define FCH_IOMAP_REG8C 0x08C // Dma_Page_Reserved5 +#define FCH_IOMAP_REG8D 0x08D // Dma_Page_Reserved6 +#define FCH_IOMAP_REG8E 0x08E // Dma_Page_Reserved7 +#define FCH_IOMAP_REG8F 0x08F // Dma_Refres +#define FCH_IOMAP_REG92 0x092 // FastInit +#define FCH_IOMAP_REGA0 0x0A0 // IntrCntrl2Reg1 +#define FCH_IOMAP_REGA1 0x0A1 // IntrCntrl2Reg2 +#define FCH_IOMAP_REGC0 0x0C0 // Dma2_C4Addr +#define FCH_IOMAP_REGC2 0x0C2 // Dma2_C4Cnt +#define FCH_IOMAP_REGC4 0x0C4 // Dma2_C5Addr +#define FCH_IOMAP_REGC6 0x0C6 // Dma2_C5Cnt +#define FCH_IOMAP_REGC8 0x0C8 // Dma2_C6Addr +#define FCH_IOMAP_REGCA 0x0CA // Dma2_C6Cnt +#define FCH_IOMAP_REGCC 0x0CC // Dma2_C7Addr +#define FCH_IOMAP_REGCE 0x0CE // Dma2_C7Cnt +#define FCH_IOMAP_REGD0 0x0D0 // Dma_Status +#define FCH_IOMAP_REGD2 0x0D2 // Dma_WriteRest +#define FCH_IOMAP_REGD4 0x0D4 // Dma_WriteMask +#define FCH_IOMAP_REGD6 0x0D6 // Dma_WriteMode +#define FCH_IOMAP_REGD8 0x0D8 // Dma_Clear +#define FCH_IOMAP_REGDA 0x0DA // Dma_Clear +#define FCH_IOMAP_REGDC 0x0DC // Dma_ClrMask +#define FCH_IOMAP_REGDE 0x0DE // Dma_ClrMask +#define FCH_IOMAP_REGF0 0x0F0 // NCP_Error +#define FCH_IOMAP_REGC00 0x0C00 // Pci_Intr_Index +#define FCH_IOMAP_REGC01 0x0C01 // Pci_Intr_Data +#define FCH_IOMAP_REGC14 0x0C14 // Pci_Error +#define FCH_IOMAP_REGCD0 0x0CD0 // PMio2_Index +#define FCH_IOMAP_REGCD1 0x0CD1 // PMio2_Data +#define FCH_IOMAP_REGCD4 0x0CD4 // BIOSRAM_Index +#define FCH_IOMAP_REGCD5 0x0CD5 // BIOSRAM_Data +#define FCH_IOMAP_REGCD6 0x0CD6 // PM_Index +#define FCH_IOMAP_REGCD7 0x0CD7 // PM_Data +#define FCH_IOMAP_REGCF9 0x0CF9 // CF9Rst reg + +#define FCH_IRQ_INTA 0x00 // INTA# +#define FCH_IRQ_INTB 0x01 // INTB# +#define FCH_IRQ_INTC 0x02 // INTC# +#define FCH_IRQ_INTD 0x03 // INTD# +#define FCH_IRQ_INTE 0x04 // INTE# +#define FCH_IRQ_INTF 0x05 // INTF# +#define FCH_IRQ_INTG 0x06 // INTG# +#define FCH_IRQ_INTH 0x07 // INTH# +#define FCH_IRQ_SCI 0x10 // SCI +#define FCH_IRQ_SMBUS0 0x11 // SMBUS0 +#define FCH_IRQ_ASF 0x12 // ASF +#define FCH_IRQ_HDAUDIO 0x13 // HD Audio +#define FCH_IRQ_FC 0x14 // FC +#define FCH_IRQ_GEC 0x15 // GEC +#define FCH_IRQ_SD 0x17 // SD +#define FCH_IRQ_IMCINT0 0x20 // IMC INT0 +#define FCH_IRQ_IMCINT1 0x21 // IMC INT1 +#define FCH_IRQ_IMCINT2 0x22 // IMC INT2 +#define FCH_IRQ_IMCINT3 0x23 // IMC INT3 +#define FCH_IRQ_IMCINT4 0x24 // IMC INT4 +#define FCH_IRQ_IMCINT5 0x25 // IMC INT5 +#define FCH_IRQ_USB18INTA 0x30 // Dev 18 (USB) INTA# +#define FCH_IRQ_USB18INTB 0x31 // Dev 18 (USB) INTB# +#define FCH_IRQ_USB19INTA 0x32 // Dev 19 (USB) INTA# +#define FCH_IRQ_USB19INTB 0x33 // Dev 19 (USB) INTB# +#define FCH_IRQ_USB22INTA 0x34 // Dev 22 (USB) INTA# +#define FCH_IRQ_USB22INTB 0x35 // Dev 22 (USB) INTB# +#define FCH_IRQ_USB20INTC 0x36 // Dev 20 (USB) INTC# +#define FCH_IRQ_IDE 0x40 // IDE pci interrupt +#define FCH_IRQ_SATA 0x41 // SATA pci interrupt +#define FCH_IRQ_GPPINT0 0x50 // Gpp Int0 +#define FCH_IRQ_GPPINT1 0x51 // Gpp Int1 +#define FCH_IRQ_GPPINT2 0x52 // Gpp Int2 +#define FCH_IRQ_GPPINT3 0x53 // Gpp Int3 +#define FCH_IRQ_IOAPIC 0x80 // Select IRQ routing to IoApic mode +#define FCH_IRQ_PIC 0x00 // Select IRQ routing to PIC mode + +#define FCH_SPI_MMIO_REG00 0x00 //SPI_ +#define FCH_SPI_OPCODE 0x000000FFl // +#define FCH_SPI_TX_COUNT 0x00000F00l // +#define FCH_SPI_RX_COUNT 0x0000F000l // +#define FCH_SPI_EXEC_OPCODE 0x00010000l // +#define FCH_SPI_FIFO_PTR_CRL 0x00100000l // +#define FCH_SPI_FIFO_PTR_INC 0x00200000l // +#define FCH_SPI_BUSY 0x80000000l // +#define FCH_SPI_MMIO_REG0C 0x0C //SPI_Cntrl1 Register +#define FCH_SPI_PARAMETER 0x000000FFl // +#define FCH_SPI_FIFO_PTR 0x00000700l // +#define FCH_SPI_BYTE_PROGRAM 0xFF000000l // +#define FCH_SPI_MMIO_REG1C 0x1C // +#define FCH_SPI_RETRY_TIMES 0x3 // + +#define FCH_SPI_MMIO_REG1D 0x1D // +#define FCH_SPI_MMIO_REG1E 0x1E // +#define FCH_SPI_MMIO_REG1F 0x1F // + +#define FCH_SPI_MMIO_REG1F_X05_TX_BYTE_COUNT 0x05 // +#define FCH_SPI_MMIO_REG1F_X06_RX_BYTE_COUNT 0x06 // + +#define FCH_SPI_MMIO_REG20 0x20 // +#define FCH_SPI_MMIO_REG22 0x22 // + +#define FCH_SPI_MMIO_REG45_CMDCODE 0x45 // +#define FCH_SPI_MMIO_REG47_CMDTRIGGER 0x47 // +#define FCH_SPI_MMIO_REG48_TXBYTECOUNT 0x48 // +#define FCH_SPI_MMIO_REG4B_RXBYTECOUNT 0x4B // +#define FCH_SPI_MMIO_REG4C_SPISTATUS 0x4C // +#define FCH_SPI_MMIO_REG80_FIFO 0x80 // + +#define FCH_SPI_MODE_FAST 0x7 // +#define FCH_SPI_MODE_NORMAL 0x6 // +#define FCH_SPI_MODE_QUAL_144 0x5 // +#define FCH_SPI_MODE_QUAL_122 0x4 // +#define FCH_SPI_MODE_QUAL_114 0x3 // +#define FCH_SPI_MODE_QUAL_112 0x2 // + +#define FCH_SPI_DEVICE_MODE_DIS 0x7 // +#define FCH_SPI_DEVICE_MODE_144 0x4 // +#define FCH_SPI_DEVICE_MODE_114 0x3 // +#define FCH_SPI_DEVICE_MODE_122 0x2 // +#define FCH_SPI_DEVICE_MODE_112 0x1 // +#define FCH_SPI_DEVICE_MODE_FAST 0x0 // + +#define FCH_SPI_SPEED_16M 0x4 // +#define FCH_SPI_SPEED_22M 0x3 // +#define FCH_SPI_SPEED_33M 0x2 // +#define FCH_SPI_SPEED_66M 0x1 // +#define FCH_SPI_SPEED_100M 0x5 // + +#define AMD_NB_REG78 0x78 +#define AMD_NB_SCRATCH AMD_NB_REG78 +#define MailBoxPort 0x3E + +#define MAX_LT_POLLINGS 0x4000 +#define SMI_TIMER_ENABLE BIT15 + + +#define ACPIMMIO32(x) (*(volatile UINT32*)(UINTN)(x)) +#define ACPIMMIO16(x) (*(volatile UINT16*)(UINTN)(x)) +#define ACPIMMIO8(x) (*(volatile UINT8*)(UINTN)(x)) + +#define U3PLL_LOCK BIT7 +#define U3PLL_RESET BIT8 +#define U3PHY_RESET BIT9 +#define U3CORE_RESET BIT10 +#define XHC0_FUNC_RESET BIT11 +#define XHC1_FUNC_RESET BIT12 + +#define XHCI_ACPI_MMIO_AMD_REG00 0x00 +#define XHCI_ACPI_MMIO_AMD_REG04 0x04 +#define XHCI_ACPI_MMIO_AMD_REG08 0x08 +#define XHCI_ACPI_MMIO_AMD_REG10 0x10 +#define XHCI_ACPI_MMIO_AMD_REG14 0x14 +#define XHCI_ACPI_MMIO_AMD_REG20 0x20 +#define XHCI_ACPI_MMIO_AMD_REG24 0x24 +#define XHCI_ACPI_MMIO_AMD_REG30 0x30 +#define XHCI_ACPI_MMIO_AMD_REG40 0x40 +#define XHCI_ACPI_MMIO_AMD_REG48 0x48 // USB3.0_Ind_REG Index +#define XHCI_ACPI_MMIO_AMD_REG4C 0x4C // USB2.0_Ind_REG Data +#define XHCI_ACPI_MMIO_AMD_REG8C 0x8C +#define XHCI_ACPI_MMIO_AMD_REG90 0x90 // adaptation timer settings +#define XHCI_ACPI_MMIO_AMD_REGA0 0xA0 // BAR 0 +#define XHCI_ACPI_MMIO_AMD_REGA4 0xA4 // BAR 1 +#define XHCI_ACPI_MMIO_AMD_REGA8 0xA8 // BAR 2 +#define XHCI_ACPI_MMIO_AMD_REGB0 0xB0 // SPI_Valid_Base. +#define XHCI_ACPI_MMIO_AMD_REGC0 0xC0 // Firmware starting offset for coping +#define XHCI_ACPI_MMIO_AMD_REGB4 0xB4 +#define XHCI_ACPI_MMIO_AMD_REGD0 0xD0 + +#define FCH_XHCI_REG48 0x48 // XHCI IND_REG Index registers +#define FCH_XHCI_REG4C 0x4C // XHCI IND_REG Data registers + +#define FCH_XHCI_IND60_BASE 0x40000000ul // + +#define FCH_XHCI_IND60_REG00 FCH_XHCI_IND60_BASE + 0x00 // +#define FCH_XHCI_IND60_REG04 FCH_XHCI_IND60_BASE + 0x04 // +#define FCH_XHCI_IND60_REG08 FCH_XHCI_IND60_BASE + 0x08 // +#define FCH_XHCI_IND60_REG0C FCH_XHCI_IND60_BASE + 0x0C // +#define FCH_XHCI_IND60_REG18 FCH_XHCI_IND60_BASE + 0x18 // +#define FCH_XHCI_IND60_REG48 FCH_XHCI_IND60_BASE + 0x48 // +#define FCH_XHCI_IND60_REG50 FCH_XHCI_IND60_BASE + 0x50 // +#define FCH_XHCI_IND60_REG54 FCH_XHCI_IND60_BASE + 0x54 // + +#define FCH_XHCI_IND_REG00 0x00 +#define FCH_XHCI_IND_REG04 0x04 +#define FCH_XHCI_IND_REG48 0x48 +#define FCH_XHCI_IND_REG54 0x54 +#define FCH_XHCI_IND_REG88 0x88 +#define FCH_XHCI_IND_REG94 0x94 +#define FCH_XHCI_IND_REG98 0x98 +#define FCH_XHCI_IND_REGC8 0xC8 +#define FCH_XHCI_IND_REGD4 0xD4 +#define FCH_XHCI_IND_REGD8 0xD8 +#define FCH_XHCI_IND_REG100 0x100 +#define FCH_XHCI_IND_REG120 0x120 +#define FCH_XHCI_IND_REG128 0x128 +#define MAX_XHCI_PORTS 0x04 + +//SMBUS +#define FCH_SMB_IOREG00 0x00 // SMBusStatus +#define FCH_SMB_IOREG01 0x01 // SMBusSlaveStatus +#define FCH_SMB_IOREG02 0x02 // SMBusControl +#define FCH_SMB_IOREG03 0x03 // SMBusHostCmd +#define FCH_SMB_IOREG04 0x04 // SMBusAddress +#define FCH_SMB_IOREG05 0x05 // SMBusData0 +#define FCH_SMB_IOREG06 0x06 // SMBusData1 +#define FCH_SMB_IOREG07 0x07 // SMBusBlockData +#define FCH_SMB_IOREG08 0x08 // SMBusSlaveControl +#define FCH_SMB_IOREG14 0x14 // SMBusAutoPoll +#define FCH_SMB_IOREG16 0x16 // SMBusPausePoll +#define FCH_SMB_IOREG17 0x17 // SMBusHostCmd2 + +#define FCH_SMB_CMD_QUICK 0x00 << 2 // Quick Read or Write +#define FCH_SMB_CMD_BYTE 0x01 << 2 // Byte Read or Write +#define FCH_SMB_CMD_BYTE_DATA 0x02 << 2 // Byte Data Read or Write +#define FCH_SMB_CMD_WORD_DATA 0x03 << 2 // Word Data Read or Write +#define FCH_SMB_CMD_BLOCK 0x05 << 2 // Block Read or Write + +#define FCH_SMB_ALL_HOST_STATUS 0x1f // HostBusy+SMBInterrupt+DeviceErr+BusCollision+Failed +#define FCH_SMB_CMD_BYTE_DATA_START 0x48 // Byte Data Read or Write +#define FCH_SMB_CMD_START BIT6 +#define FCH_SMB_READ_ENABLE BIT0 +#define FCH_SMB_AUTO_POLL_EN BIT0 +#define FCH_SMB_POLL2BYTE BIT7 + + +#define FCH_EC_ENTER_CONFIG 0X5A +#define FCH_EC_EXIT_CONFIG 0XA5 +#define FCH_EC_REG07 0X07 +#define FCH_EC_REG30 0X30 +#define FCH_EC_REG60 0X60 +#define FCH_EC_REG61 0X61 + +#define FCH_IMC_ROMSIG 0x55aa55aaul + +#define SPI_HEAD_LENGTH 0x0E +#define SPI_BAR0_VLD 0x01 +#define SPI_BASE0 (0x00 << 7) +#define SPI_BAR1_VLD (0x01 << 8) +#define SPI_BASE1 (SPI_HEAD_LENGTH << 10) +#define SPI_BAR2_VLD (0x01 << 16) +#define SPI_BASE2(x) ((SPI_HEAD_LENGTH + ACPIMMIO16(x)) << 18) + +#define FW_TO_SIGADDR_OFFSET 0x0C +#define BCD_ADDR_OFFSET 0x02 +#define BCD_SIZE_OFFSET 0x04 +#define FW_ADDR_OFFSET 0x06 +#define FW_SIZE_OFFSET 0x08 +#define ACD_ADDR_OFFSET 0x0A +#define ACD_SIZE_OFFSET 0x0C +#define XHC_BOOT_RAM_SIZE 0x8000 + +#define PKT_DATA_REG ACPI_MMIO_BASE + GFX_DAC_BASE + 0x00 +#define PKT_LEN_REG ACPI_MMIO_BASE + GFX_DAC_BASE + 0x14 +#define PKT_CTRL_REG ACPI_MMIO_BASE + GFX_DAC_BASE + 0x15 +#define EFUS_DAC_ADJUSTMENT_CONTROL 0x850A8ul +#define BGADJ 0x1F +#define DACADJ 0x1B +#define EFUS_DAC_ADJUSTMENT_CONTROL_DATA (BGADJ + (DACADJ << 8) + BIT16 ) + +#define KABINI_OSC_OUT_CLOCK_SEL_48MHz 0x02 +#define KABINI_OSC_OUT_CLOCK_SEL_25MHz 0x01 + +#ifndef FCH_DEADLOOP + #define FCH_DEADLOOP() { volatile UINTN __i; __i = 1; while (__i); } +#endif + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/FchPlatform.h b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/FchPlatform.h new file mode 100644 index 0000000000..ebf7599425 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/FchPlatform.h @@ -0,0 +1,117 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH platform definition + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#ifndef _FCH_PLATFORM_H_ +#define _FCH_PLATFORM_H_ + +#define MAX_SATA_PORTS 8 + +#include "AGESA.h" + +#ifndef FCHOEM_ACPI_RESTORE_SWSMI + #define FCHOEM_BEFORE_PCI_RESTORE_SWSMI 0xD3 + #define FCHOEM_AFTER_PCI_RESTORE_SWSMI 0xD4 + #define FCHOEM_ENABLE_ACPI_SWSMI 0xA0 + #define FCHOEM_DISABLE_ACPI_SWSMI 0xA1 + #define FCHOEM_START_TIMER_SMI 0xBC + #define FCHOEM_STOP_TIMER_SMI 0xBD +#endif + +#ifndef FCHOEM_SPI_UNLOCK_SWSMI + #define FCHOEM_SPI_UNLOCK_SWSMI 0xAA +#endif +#ifndef FCHOEM_SPI_LOCK_SWSMI + #define FCHOEM_SPI_LOCK_SWSMI 0xAB +#endif + +#ifndef FCHOEM_ACPI_TABLE_RANGE_LOW + #define FCHOEM_ACPI_TABLE_RANGE_LOW 0xE0000ul +#endif + +#ifndef FCHOEM_ACPI_TABLE_RANGE_HIGH + #define FCHOEM_ACPI_TABLE_RANGE_HIGH 0xFFFF0ul +#endif + +#ifndef FCHOEM_ACPI_BYTE_CHECHSUM + #define FCHOEM_ACPI_BYTE_CHECHSUM 0x100 +#endif + +#ifndef FCHOEM_IO_DELAY_PORT + #define FCHOEM_IO_DELAY_PORT 0x80 +#endif + +#ifndef FCHOEM_OUTPUT_DEBUG_PORT + #define FCHOEM_OUTPUT_DEBUG_PORT 0x80 +#endif + +#define FCH_PCIRST_BASE_IO 0xCF9 +#define FCH_PCI_RESET_COMMAND06 0x06 +#define FCH_PCI_RESET_COMMAND0E 0x0E +#define FCH_KBDRST_BASE_IO 0x64 +#define FCH_KBC_RESET_COMMAND 0xFE +#define FCH_ROMSIG_BASE_IO 0x20000l +#define FCH_ROMSIG_SIGNATURE 0x55AA55AAul +#define FCH_MAX_TIMER 0xFFFFFFFFul +#define FCH_HPET_REG_MASK 0xFFFFF800ul +#define FCH_FAKE_USB_BAR_ADDRESS 0x58830000ul + + +#ifndef FCHOEM_ELAPSED_TIME_UNIT + #define FCHOEM_ELAPSED_TIME_UNIT 28 +#endif + +#ifndef FCHOEM_ELAPSED_TIME_DIVIDER + #define FCHOEM_ELAPSED_TIME_DIVIDER 100 +#endif + +#include "Fch.h" +#include "amdlib.h" +#include "FchCommonCfg.h" +#include "AcpiLib.h" +#include "FchDef.h" +#include "FchBiosRamUsage.h" +#include "AmdFch.h" + +extern BUILD_OPT_CFG UserOptions; + +#endif // _FCH_PLATFORM_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiEnvService.c new file mode 100644 index 0000000000..a035a722c3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiEnvService.c @@ -0,0 +1,485 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch HwAcpi controller + * + * Init HwAcpi Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87262 $ @e \$Date: 2013-01-31 09:13:43 -0600 (Thu, 31 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "amdlib.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWACPI_FAMILY_YANGTZE_YANGTZEHWACPIENVSERVICE_FILECODE + +#define AMD_CPUID_APICID_LPC_BID 0x00000001ul // Local APIC ID, Logical Processor Count, Brand ID + +ACPI_REG_WRITE FchYangtzeInitEnvSpecificHwAcpiMmioTable[] = +{ + {00, 00, 0xB0, 0xAC}, + {PMIO_BASE >> 8, FCH_PMIOA_REG28, (UINT8)~(BIT0 + BIT2), BIT0}, // Set ASF SMBUS master function enabled here (temporary) +#ifdef ACPI_SLEEP_TRAP + {SMI_BASE >> 8, FCH_SMI_REGB0, (UINT8)~(BIT2 + BIT3), BIT2}, // Set SLP_TYPE as SMI event + {PMIO_BASE >> 8, FCH_PMIOA_REGBE, (UINT8)~BIT5, 0x00}, // Disabled SLP function for S1/S3/S4/S5 + {PMIO_BASE >> 8, 0x08 + 3, (UINT8)~(BIT0 + BIT1), BIT1}, // Set S state transition disabled (BIT0) force ACPI to + // send SMI message when writing to SLP_TYP Acpi register. (BIT1) + {SMI_BASE >> 8, FCH_SMI_REG98 + 3, (UINT8)~BIT7, 0x00}, // Enabled Global Smi ( BIT7 clear as 0 to enable ) +#endif + {PMIO_BASE >> 8, 0x80 + 1, (UINT8)~(BIT3 + BIT4), BIT3 + BIT4}, + {0xFF, 0xFF, 0xFF, 0xFF}, +}; + + +/** + * FchInitEnvHwAcpiMmioTable - Fch ACPI MMIO initial + * during POST. + * + */ +ACPI_REG_WRITE FchYangtzeInitEnvHwAcpiMmioTable[] = +{ + {00, 00, 0xB0, 0xAC}, /// Signature + + // + // HPET workaround + // + {PMIO_BASE >> 8, FCH_PMIOA_REG54 + 2, 0x7F, BIT7}, + {PMIO_BASE >> 8, FCH_PMIOA_REG54 + 2, 0x7F, 0x00}, + {PMIO_BASE >> 8, FCH_PMIOA_REGC4, (UINT8)~BIT2, BIT2}, + {PMIO_BASE >> 8, FCH_PMIOA_REGC0, 0, 0x3D}, + {PMIO_BASE >> 8, FCH_PMIOA_REGC0 + 1, 0x0, 0x04}, + {PMIO_BASE >> 8, FCH_PMIOA_REGC2, 0x20, 0x58}, + {PMIO_BASE >> 8, FCH_PMIOA_REGC2 + 1, 0, 0x40}, + {PMIO_BASE >> 8, FCH_PMIOA_REGC2, (UINT8)~(BIT4), BIT4}, + {PMIO_BASE >> 8, FCH_PMIOA_REGCC, 0xF8, 0x07}, + {PMIO_BASE >> 8, FCH_PMIOA_REG74, 0x00, BIT0 + BIT1 + BIT2 + BIT4}, + {PMIO_BASE >> 8, 0x74 + 3, (UINT8)~BIT5, 0}, + {PMIO_BASE >> 8, FCH_PMIOA_REGBA, (UINT8)~BIT3, BIT3}, + {PMIO_BASE >> 8, FCH_PMIOA_REGBA + 1, (UINT8)~BIT6, BIT6}, + {PMIO_BASE >> 8, FCH_PMIOA_REGBC, (UINT8)~BIT1, BIT1}, + {PMIO_BASE >> 8, FCH_PMIOA_REGED, (UINT8)~(BIT0 + BIT1), 0}, + {PMIO_BASE >> 8, 0xDC, 0x7C, BIT1}, + + {SMI_BASE >> 8, FCH_SMI_Gevent1, 0, 1}, + {SMI_BASE >> 8, FCH_SMI_Gevent3, 0, 3}, + {SMI_BASE >> 8, FCH_SMI_Gevent4, 0, 4}, + {SMI_BASE >> 8, FCH_SMI_Gevent5, 0, 5}, + {SMI_BASE >> 8, FCH_SMI_Gevent6, 0, 6}, + {SMI_BASE >> 8, FCH_SMI_Gevent23, 0, 23}, + {SMI_BASE >> 8, FCH_SMI_xHC0Pme, 0, 11}, + {SMI_BASE >> 8, FCH_SMI_xHC1Pme, 0, 11}, + {SMI_BASE >> 8, FCH_SMI_Usbwakup0, 0, 11}, + {SMI_BASE >> 8, FCH_SMI_Usbwakup1, 0, 11}, + {SMI_BASE >> 8, FCH_SMI_Usbwakup2, 0, 11}, + {SMI_BASE >> 8, FCH_SMI_Usbwakup3, 0, 11}, + {SMI_BASE >> 8, FCH_SMI_IMCGevent0, 0, 12}, + {SMI_BASE >> 8, FCH_SMI_FanThGevent, 0, 13}, + {SMI_BASE >> 8, FCH_SMI_SBGppPme0, 0, 15}, + {SMI_BASE >> 8, FCH_SMI_SBGppPme1, 0, 16}, + {SMI_BASE >> 8, FCH_SMI_SBGppPme2, 0, 17}, + {SMI_BASE >> 8, FCH_SMI_SBGppPme3, 0, 18}, + {SMI_BASE >> 8, FCH_SMI_GecPme, 0, 19}, + {SMI_BASE >> 8, FCH_SMI_CIRPme, 0, 28}, + {SMI_BASE >> 8, FCH_SMI_Gevent8, 0, 24}, +// {SMI_BASE >> 8, FCH_SMI_AzaliaPme, 0, 27}, + {SMI_BASE >> 8, FCH_SMI_SataGevent0, 0, 30}, + {SMI_BASE >> 8, FCH_SMI_SataGevent1, 0, 31}, + {SMI_BASE >> 8, FCH_SMI_REG08, 0xE7, 0}, + {SMI_BASE >> 8, FCH_SMI_REG0C + 2, (UINT8)~BIT3, BIT3}, + {SMI_BASE >> 8, FCH_SMI_TWARN, 0, 9}, + {0xFF, 0xFF, 0xFF, 0xFF}, +}; + +/** + * FchYangtzeInitEnvHwAcpiPciTable - PCI device registers initial + * during early POST. + * + */ +REG8_MASK FchYangtzeInitEnvHwAcpiPciTable[] = +{ + // + // SMBUS Device (Bus 0, Dev 20, Func 0) + // + {0x00, SMBUS_BUS_DEV_FUN, 0}, + {FCH_CFG_REG10, 0X00, (FCH_VERSION & 0xFF)}, ///Program the version information + {FCH_CFG_REG11, 0X00, (FCH_VERSION >> 8)}, + {0xFF, 0xFF, 0xFF}, +}; + + +/** + * ProgramEnvPFchAcpiMmio - Config HwAcpi MMIO registers + * Acpi S3 resume won't execute this procedure (POST only) + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ProgramEnvPFchAcpiMmio ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + ProgramFchAcpiMmioTbl ((ACPI_REG_WRITE*) (&FchYangtzeInitEnvHwAcpiMmioTable[0]), StdHeader); +} + +/** + * ProgramFchEnvHwAcpiPciReg - Config HwAcpi PCI controller + * before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ProgramFchEnvHwAcpiPciReg ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + //Early post initialization of pci config space + // + ProgramPciByteTable ((REG8_MASK*) (&FchYangtzeInitEnvHwAcpiPciTable[0]), sizeof (FchYangtzeInitEnvHwAcpiPciTable) / sizeof (REG8_MASK), StdHeader); + + if ( LocalCfgPtr->Smbus.SmbusSsid != 0 ) { + RwPci ((SMBUS_BUS_DEV_FUN << 16) + FCH_CFG_REG2C, AccessWidth32, 0x00, LocalCfgPtr->Smbus.SmbusSsid, StdHeader); + } + ProgramPcieNativeMode (FchDataPtr); +} + +/** + * FchVgaInit - Config VGA CODEC + * + * @param[in] VOID empty + * + */ +VOID +FchVgaInit ( + OUT VOID + ) +{ +} + +/** + * ProgramSpecificFchInitEnvAcpiMmio - Config HwAcpi MMIO before + * PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ProgramSpecificFchInitEnvAcpiMmio ( + IN VOID *FchDataPtr + ) +{ + CPUID_DATA CpuId; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + ProgramFchAcpiMmioTbl ((ACPI_REG_WRITE*) (&FchYangtzeInitEnvSpecificHwAcpiMmioTable[0]), StdHeader); + + LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuId, StdHeader); + + if ((LocalCfgPtr->HwAcpi.AnyHt200MhzLink) || ((CpuId.EAX_Reg & 0x00ff00f0) == 0x100080) || ((CpuId.EAX_Reg & 0x00ff00f0) == 0x100090) || ((CpuId.EAX_Reg & 0x00ff00f0) == 0x1000A0)) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG94, AccessWidth8, 0, 0x0A); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0x80 + 3, AccessWidth8, 0xFE, 0x28); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG94, AccessWidth8, 0, 0x01); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0x80 + 3, AccessWidth8, 0xFE, 0x20); + } + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG6C + 2, AccessWidth8, 0x5F, 0xA0); + // + // Ac Loss Control + // + AcLossControl ((UINT8) LocalCfgPtr->HwAcpi.PwrFailShadow); + // + // FCH VGA Init + // + FchVgaInit (); + + // + // Set ACPIMMIO by OEM Input table + // + ProgramFchAcpiMmioTbl ((ACPI_REG_WRITE *) (LocalCfgPtr->HwAcpi.OemProgrammingTablePtr), StdHeader); +} + +/** + * ValidateFchVariant - Validate FCH Variant + * + * + * + * @param[in] FchDataPtr + * + */ +VOID +ValidateFchVariant ( + IN VOID *FchDataPtr + ) +{ + CPUID_DATA CpuId; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + LibAmdCpuidRead (CPUID_FMF, &CpuId, StdHeader); + LocalCfgPtr->Misc.FchCpuId = ( UINT32 ) (CpuId.EAX_Reg & 0xFFFFFFFF); +} + +/** + * IsExternalClockMode - Is External Clock Mode? + * + * + * @retval TRUE or FALSE + * + */ +BOOLEAN +IsExternalClockMode ( + IN VOID *FchDataPtr + ) +{ + UINT8 MISC80; + ReadMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG80 + 2, AccessWidth8, &MISC80); + return ( (BOOLEAN) ((MISC80 & BIT1) == 0) ); +} + + +/** + * ProgramFchEnvSpreadSpectrum - Config SpreadSpectrum before + * PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ProgramFchEnvSpreadSpectrum ( + IN VOID *FchDataPtr + ) +{ + UINT8 PortStatus; + UINT8 FchSpreadSpectrum; + + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + FchSpreadSpectrum = LocalCfgPtr->HwAcpi.SpreadSpectrum; + + if ( FchSpreadSpectrum ) { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG08, AccessWidth8, 0xFE, 0x00); + if ( LocalCfgPtr->HwAcpi.SpreadSpectrumOptions == 0 ) { + /// -0.362% + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG18 + 1, AccessWidth8, 0xF0, 0x01); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14 + 2, AccessWidth16, 0, 0xCF5C); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14, AccessWidth16, 0, 0x0137); + } + if ( LocalCfgPtr->HwAcpi.SpreadSpectrumOptions == 1 ) { + /// -0.375% + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG18 + 1, AccessWidth8, 0xF0, 0x01); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14 + 2, AccessWidth16, 0, 0xE000); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14, AccessWidth16, 0, 0x0142); + } + if ( LocalCfgPtr->HwAcpi.SpreadSpectrumOptions == 2 ) { + /// -0.4% + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG18 + 1, AccessWidth8, 0xF0, 0x02); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14 + 2, AccessWidth16, 0, 0); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14, AccessWidth16, 0, 0x0158); + } + if ( LocalCfgPtr->HwAcpi.SpreadSpectrumOptions == 3 ) { + /// -0.425% + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG18 + 1, AccessWidth8, 0xF0, 0x02); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14 + 2, AccessWidth16, 0, 0x1FFF); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14, AccessWidth16, 0, 0x016D); + } + if ( LocalCfgPtr->HwAcpi.SpreadSpectrumOptions == 4 ) { + /// -0.45% + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG18 + 1, AccessWidth8, 0xF0, 0x02); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14 + 2, AccessWidth16, 0, 0x4000); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14, AccessWidth16, 0, 0x0183); + } + if ( LocalCfgPtr->HwAcpi.SpreadSpectrumOptions == 5 ) { + /// -0.475% + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG18 + 1, AccessWidth8, 0xF0, 0x02); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14 + 2, AccessWidth16, 0, 0x6000); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG14, AccessWidth16, 0, 0x0198); + } + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG08, AccessWidth8, 0xFE, BIT0); + } else { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG08, AccessWidth8, 0xFE, 0x00); + } + + // + // PLL 100Mhz Reference Clock Buffer setting for internal clock generator mode (BIT5) + // OSC Clock setting for internal clock generator mode (BIT6) + // + GetChipSysMode (&PortStatus, StdHeader); + if ( ((PortStatus & ChipSysIntClkGen) == ChipSysIntClkGen) ) { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG04 + 1, AccessWidth8, (UINT32)~(BIT5 + BIT6), BIT5 + BIT6); + } +} + +/** + * TurnOffCG2 + * + * + * @retval VOID + * + */ +VOID +TurnOffCG2 ( + OUT VOID + ) +{ +} + +/** + * BackUpCG2 + * + * + * @retval VOID + * + */ +VOID +BackUpCG2 ( + OUT VOID + ) +{ +} + +/** + * HpetInit - Program Fch HPET function + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +HpetInit ( + IN VOID *FchDataPtr + ) +{ + DESCRIPTION_HEADER *HpetTable; + UINT8 FchHpetTimer; + UINT8 FchHpetMsiDis; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + FchHpetTimer = (UINT8) LocalCfgPtr->Hpet.HpetEnable; + FchHpetMsiDis = (UINT8) LocalCfgPtr->Hpet.HpetMsiDis; + + HpetTable = NULL; + if ( FchHpetTimer == TRUE ) { + // + //Program the HPET BAR address + // + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG50, AccessWidth32, FCH_HPET_REG_MASK, LocalCfgPtr->Hpet.HpetBase); + + // + //Enabling decoding of HPET MMIO + //Enable HPET MSI support + //Enable High Precision Event Timer (also called Multimedia Timer) interrupt + // + if ( FchHpetMsiDis == FALSE ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG50, AccessWidth32, FCH_HPET_REG_MASK, BIT0 + BIT1 + BIT2 + BIT3 + BIT4); +#ifdef FCH_TIMER_TICK_INTERVAL_WA + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG50, AccessWidth32, FCH_HPET_REG_MASK, BIT0 + BIT1); +#endif + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG50, AccessWidth32, FCH_HPET_REG_MASK, BIT0 + BIT1); + } + + } else { + if ( ! (LocalCfgPtr->Misc.S3Resume) ) { + HpetTable = (DESCRIPTION_HEADER*) AcpiLocateTable (Int32FromChar('H','P','E','T'));//'TEPH' + } + if ( HpetTable != NULL ) { + HpetTable->Signature = Int32FromChar('T','E','P','H');//'HPET' + } + } +} + +/** + * ProgramPcieNativeMode - Config Pcie Native Mode + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ProgramPcieNativeMode ( + IN VOID *FchDataPtr + ) +{ + UINT8 FchNativepciesupport; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + FchNativepciesupport = (UINT8) LocalCfgPtr->Misc.NativePcieSupport; + + // + // PCIE Native setting + // + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGBA + 1, AccessWidth8, (UINT32)~BIT6, 0); + if ( FchNativepciesupport == 1) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0x74 + 3, AccessWidth8, (UINT32)~(BIT3 + BIT1 + BIT0), BIT3 + BIT0); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0x74 + 3, AccessWidth8, (UINT32)~(BIT3 + BIT1 + BIT0), BIT3); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiLateService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiLateService.c new file mode 100644 index 0000000000..2913e6f6fc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiLateService.c @@ -0,0 +1,152 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch HwAcpi controller + * + * Init HwAcpi Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWACPI_FAMILY_YANGTZE_YANGTZEHWACPILATESERVICE_FILECODE + +#define AMD_CPUID_APICID_LPC_BID 0x00000001ul // Local APIC ID, Logical Processor Count, Brand ID + + +/** + * GcpuRelatedSetting - Program Gcpu C related function + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +GcpuRelatedSetting ( + IN VOID *FchDataPtr + ) +{ + UINT8 FchAcDcMsg; + UINT8 FchTimerTickTrack; + UINT8 FchClockInterruptTag; + UINT8 FchOhciTrafficHanding; + UINT8 FchEhciTrafficHanding; + UINT8 FchGcpuMsgCMultiCore; + UINT8 FchGcpuMsgCStage; + UINT32 Value; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + FchAcDcMsg = (UINT8) LocalCfgPtr->Gcpu.AcDcMsg; + FchTimerTickTrack = (UINT8) LocalCfgPtr->Gcpu.TimerTickTrack; + FchClockInterruptTag = (UINT8) LocalCfgPtr->Gcpu.ClockInterruptTag; + FchOhciTrafficHanding = (UINT8) LocalCfgPtr->Gcpu.OhciTrafficHanding; + FchEhciTrafficHanding = (UINT8) LocalCfgPtr->Gcpu.EhciTrafficHanding; + FchGcpuMsgCMultiCore = (UINT8) LocalCfgPtr->Gcpu.GcpuMsgCMultiCore; + FchGcpuMsgCStage = (UINT8) LocalCfgPtr->Gcpu.GcpuMsgCStage; + + ReadMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGA0, AccessWidth32, &Value); + Value = Value & 0xC07F00A0; + + if ( FchAcDcMsg ) { + Value = Value | BIT0; + } + + if ( FchTimerTickTrack ) { + Value = Value | BIT1; + } + + if ( FchClockInterruptTag ) { + Value = Value | BIT10; + } + + if ( FchOhciTrafficHanding ) { + Value = Value | BIT13; + } + + if ( FchEhciTrafficHanding ) { + Value = Value | BIT15; + } + + if ( FchGcpuMsgCMultiCore ) { + Value = Value | BIT23; + } + + if ( FchGcpuMsgCMultiCore ) { + Value = (Value | (BIT6 + BIT4 + BIT3 + BIT2)); + } + + WriteMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGA0, AccessWidth32, &Value); +} + +/** + * StressResetModeLate - Stress Reset Mode + * + * + * + * @param[in] FchDataPtr + * + */ +VOID +StressResetModeLate ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + switch ( LocalCfgPtr->HwAcpi.StressResetMode ) { + case 0: + return; + default: + ASSERT (FALSE); + return; + } + while (LocalCfgPtr->HwAcpi.StressResetMode) { + } +} + + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiMidService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiMidService.c new file mode 100644 index 0000000000..394e77d051 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeHwAcpiMidService.c @@ -0,0 +1,48 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch HwAcpi controller + * + * Init HwAcpi Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "amdlib.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWACPI_FAMILY_YANGTZE_YANGTZEHWACPIMIDSERVICE_FILECODE diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeSSService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeSSService.c new file mode 100644 index 0000000000..3db2cbeae1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/Family/Yangtze/YangtzeSSService.c @@ -0,0 +1,124 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch HwAcpi controller + * + * Init Spread Spectrum features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 86067 $ @e \$Date: 2013-01-15 19:48:08 -0600 (Tue, 15 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "amdlib.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWACPI_FAMILY_YANGTZE_YANGTZESSSERVICE_FILECODE + +/** + * FchInitResetAcpiMmioTable - Fch ACPI MMIO initial + * during the power on stage. + * + * + * + * + */ +ACPI_REG_WRITE FchInitResetAcpiMmioTable[] = +{ + {00, 00, 0xB0, 0xAC}, + // + // Supported Yuba RPR / KR BKDG spread-spectrum setting. + // + {MISC_BASE >> 8, FCH_MISC_REG40 + 1, 0x0F, 0x40}, + {MISC_BASE >> 8, FCH_MISC_REG40, 0xEF, 0x00}, + {PMIO_BASE >> 8, 0x5D, 0xFC, BIT1}, + {PMIO_BASE >> 8, FCH_PMIOA_REGD2, 0xCF, 0x00}, + {SMBUS_BASE >> 8, FCH_SMBUS_REG12, 0x00, BIT0}, + {PMIO_BASE >> 8, FCH_PMIOA_REG44 + 3, 0x67, 0}, + {PMIO_BASE >> 8, FCH_PMIOA_REG48, 0xFF, BIT0}, + {PMIO_BASE >> 8, FCH_PMIOA_REG00, 0xFF, 0x0E}, + {PMIO_BASE >> 8, FCH_PMIOA_REG00 + 2, 0xFF, 0x40}, + {PMIO_BASE >> 8, FCH_PMIOA_REG00 + 3, 0xFF, 0x08}, + {PMIO_BASE >> 8, FCH_PMIOA_REG34, 0xEF, BIT0 + BIT1}, + {PMIO_BASE >> 8, FCH_PMIOA_REGEC, 0xF9, BIT1 + BIT2}, + {PMIO_BASE >> 8, FCH_PMIOA_REG08, 0xFE, BIT2 + BIT4}, + {PMIO_BASE >> 8, FCH_PMIOA_REG08 + 1, 0xFF, BIT0}, + {PMIO_BASE >> 8, FCH_PMIOA_REG54, 0x00, BIT4 + BIT6 + BIT7}, + {PMIO_BASE >> 8, 0x74, 0xF6, BIT0 + BIT3}, + {PMIO_BASE >> 8, FCH_PMIOA_REGF0, (UINT8)~BIT2, 0x00}, + + {PMIO_BASE >> 8, FCH_PMIOA_REGF8, 0x00, 0x6C}, + {PMIO_BASE >> 8, FCH_PMIOA_REGF8 + 1, 0x00, 0x07}, + {PMIO_BASE >> 8, FCH_PMIOA_REGF8 + 2, 0x00, 0x00}, + {PMIO_BASE >> 8, FCH_PMIOA_REGC4, 0xee, 0x04}, + {PMIO_BASE >> 8, FCH_PMIOA_REGC0 + 2, 0xBF, 0x40}, + {PMIO_BASE >> 8, FCH_PMIOA_REGBE, 0xDF, BIT5}, + {PMIO_BASE >> 8, FCH_PMIOA_REGBB, 0xFF, BIT2}, + {PMIO_BASE >> 8, FCH_PMIOA_REGD0, 0xFF, 0}, + {PMIO_BASE >> 8, FCH_PMIOA_REGD7, 0xFD, 0}, + {MISC_BASE >> 8, FCH_MISC_REG6C + 2, 0x7F, BIT7}, + {MISC_BASE >> 8, FCH_MISC_REG6C + 3, 0xF7, BIT3}, // MISC 0x6C BIT27 + {MISC_BASE >> 8, FCH_MISC_REG1C + 0x03, 0xDF, 0x00}, + {MISC_BASE >> 8, FCH_MISC_REG1C + 0x02, 0x9F, 0x60}, + {MISC_BASE >> 8, FCH_MISC_REG1C + 0x03, 0xFA, 0x05}, + {0xFF, 0xFF, 0xFF, 0xFF}, +}; + +/** + * ProgramFchHwAcpiResetP - Config SpreadSpectrum before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ProgramFchHwAcpiResetP ( + IN VOID *FchDataPtr + ) +{ + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + StdHeader = &((AMD_RESET_PARAMS *)FchDataPtr)->StdHeader; + + RwPmio (FCH_PMIOA_REGD3, AccessWidth8, (UINT32)~BIT4, 0, StdHeader); + RwPmio (FCH_PMIOA_REGD3, AccessWidth8, (UINT32)~BIT4, BIT4, StdHeader); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGC8 + 3, AccessWidth8, 0x7F, BIT7, StdHeader); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiEnv.c new file mode 100644 index 0000000000..c8c878f800 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiEnv.c @@ -0,0 +1,102 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch HwAcpi controller + * + * Init HwAcpi Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "amdlib.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWACPI_HWACPIENV_FILECODE + +/** + * FchInitEnvHwAcpiP - Config HwAcpi controller preliminary + * (Special) + * Acpi S3 resume won't execute this procedure (POST only) + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvHwAcpiP ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + RecordFchConfigPtr ( (UINT32) ((UINTN) (LocalCfgPtr))); + + ValidateFchVariant (LocalCfgPtr); + + ProgramEnvPFchAcpiMmio (FchDataPtr); + + ProgramFchEnvSpreadSpectrum (FchDataPtr); +} + +/** + * FchInitEnvHwAcpi - Config HwAcpi controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvHwAcpi ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + ProgramFchEnvHwAcpiPciReg (FchDataPtr); + // + // FCH Specific Function programming + // + ProgramSpecificFchInitEnvAcpiMmio (FchDataPtr); + HpetInit (LocalCfgPtr); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiLate.c new file mode 100644 index 0000000000..db46136bc0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiLate.c @@ -0,0 +1,167 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch HwAcpi controller + * + * Init HwAcpi Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "amdlib.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWACPI_HWACPILATE_FILECODE + +#define AMD_CPUID_APICID_LPC_BID 0x00000001ul // Local APIC ID, Logical Processor Count, Brand ID + + + +/// +/// PCI_IRQ_REG_BLOCK- FCH PCI IRQ registers block +/// +typedef struct _PCI_IRQ_REG_BLOCK { + UINT8 PciIrqIndex; // PciIrqIndex - selects which PCI interrupt to map + UINT8 PciIrqData; // PciIrqData - Interrupt # +} PCI_IRQ_REG_BLOCK; + +STATIC PCI_IRQ_REG_BLOCK FchInternalDeviceIrqForApicMode[] = { + { (FCH_IRQ_INTA | FCH_IRQ_IOAPIC), 0x10}, + { (FCH_IRQ_INTB | FCH_IRQ_IOAPIC), 0x11}, + { (FCH_IRQ_INTC | FCH_IRQ_IOAPIC), 0x12}, + { (FCH_IRQ_INTD | FCH_IRQ_IOAPIC), 0x13}, + { (FCH_IRQ_INTE | FCH_IRQ_IOAPIC), 0x14}, + { (FCH_IRQ_INTF | FCH_IRQ_IOAPIC), 0x15}, + { (FCH_IRQ_INTG | FCH_IRQ_IOAPIC), 0x16}, + { (FCH_IRQ_INTH | FCH_IRQ_IOAPIC), 0x17}, + { (FCH_IRQ_HDAUDIO | FCH_IRQ_IOAPIC), 0x10}, + { (FCH_IRQ_GEC | FCH_IRQ_IOAPIC), 0x10}, + { (FCH_IRQ_SD | FCH_IRQ_IOAPIC), 0x10}, + { (FCH_IRQ_GPPINT0 | FCH_IRQ_IOAPIC), 0x10}, + { (FCH_IRQ_IDE | FCH_IRQ_IOAPIC), 0x11}, + { (FCH_IRQ_USB18INTB | FCH_IRQ_IOAPIC), 0x11}, + { (FCH_IRQ_USB19INTB | FCH_IRQ_IOAPIC), 0x11}, + { (FCH_IRQ_USB22INTB | FCH_IRQ_IOAPIC), 0x11}, + { (FCH_IRQ_GPPINT1 + FCH_IRQ_IOAPIC), 0x11}, + { (FCH_IRQ_USB18INTA | FCH_IRQ_IOAPIC), 0x12}, + { (FCH_IRQ_USB19INTA | FCH_IRQ_IOAPIC), 0x12}, + { (FCH_IRQ_USB22INTA | FCH_IRQ_IOAPIC), 0x12}, + { (FCH_IRQ_USB20INTC | FCH_IRQ_IOAPIC), 0x12}, + { (FCH_IRQ_GPPINT2 | FCH_IRQ_IOAPIC), 0x12}, + { (FCH_IRQ_SATA | FCH_IRQ_IOAPIC), 0x13}, + { (FCH_IRQ_GPPINT3 | FCH_IRQ_IOAPIC), 0x13}, + }; + +#define NUM_OF_DEVICE_FOR_APICIRQ sizeof (FchInternalDeviceIrqForApicMode) / sizeof (PCI_IRQ_REG_BLOCK) + +/** + * FchInitLateHwAcpi - Prepare HwAcpi controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateHwAcpi ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + UINT8 i; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + if ( IsGCPU (LocalCfgPtr) ) { + GcpuRelatedSetting (LocalCfgPtr); + } else { + } + + // Mt C1E Enable + + + StressResetModeLate (LocalCfgPtr); + SbSleepTrapControl (FALSE); + for (i = 0; i < NUM_OF_DEVICE_FOR_APICIRQ; i++) { + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &FchInternalDeviceIrqForApicMode[i].PciIrqIndex, StdHeader); + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &FchInternalDeviceIrqForApicMode[i].PciIrqData, StdHeader); + } +} + +/** + * IsGCPU - Is Gcpu Cpu? + * + * + * @retval TRUE or FALSE + * + */ +BOOLEAN +IsGCPU ( + IN VOID *FchDataPtr + ) +{ + UINT8 ExtendedFamily; + UINT8 ExtendedModel; + UINT8 BaseFamily; + UINT8 BaseModel; + UINT8 Stepping; + UINT8 Family; + UINT8 Model; + CPUID_DATA CpuId; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + LibAmdCpuidRead (AMD_CPUID_APICID_LPC_BID, &CpuId, StdHeader); + + ExtendedFamily = (UINT8) ((CpuId.EAX_Reg >> 20) & 0xff); + ExtendedModel = (UINT8) ((CpuId.EAX_Reg >> 16) & 0xf); + BaseFamily = (UINT8) ((CpuId.EAX_Reg >> 8) & 0xf); + BaseModel = (UINT8) ((CpuId.EAX_Reg >> 4) & 0xf); + Stepping = (UINT8) ((CpuId.EAX_Reg >> 0) & 0xf); + Family = BaseFamily + ExtendedFamily; + Model = (ExtendedModel << 4) + BaseModel; + + if ( Family == 0x16 ) { + return TRUE; + } else { + return FALSE; + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiMid.c new file mode 100644 index 0000000000..2f7656cf43 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiMid.c @@ -0,0 +1,64 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch HwAcpi controller + * + * Init HwAcpi Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "amdlib.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWACPI_HWACPIMID_FILECODE + +/** + * FchInitMidHwAcpi - Config HwAcpi controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidHwAcpi ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiReset.c new file mode 100644 index 0000000000..5a3833e252 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/HwAcpi/HwAcpiReset.c @@ -0,0 +1,213 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch HwAcpi controller + * + * Init HwAcpi Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87999 $ @e \$Date: 2013-02-14 10:48:03 -0600 (Thu, 14 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWACPI_HWACPIRESET_FILECODE + +extern ACPI_REG_WRITE FchInitResetAcpiMmioTable[]; + +/** + * FchInitResetHwAcpiP - Config HwAcpi controller ( Preliminary + * ) during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetHwAcpiP ( + IN VOID *FchDataPtr + ) +{ + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + + StdHeader = &((AMD_RESET_PARAMS *)FchDataPtr)->StdHeader; + + // + // Enabled (Mmio_mem_enable) + // + RwPmio (FCH_PMIOA_REG24, AccessWidth8, 0xFF, BIT0, StdHeader); + + ProgramFchHwAcpiResetP (FchDataPtr); + RwPmio (0xD2, AccessWidth8, (UINT32)~BIT6, 0, StdHeader); +} + +/** + * FchInitResetHwAcpi - Config HwAcpi controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetHwAcpi ( + IN VOID *FchDataPtr + ) +{ + UINT16 SmbusBase; + UINT8 Value; + UINT16 AsfPort; + UINT32 GeventEnableBits; + UINT32 GeventValue; + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + // Set Build option into SB + // + WritePci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG64, AccessWidth16, &(UserOptions.FchBldCfg->CfgSioPmeBaseAddress), StdHeader); + + // + // Enabled SMBUS0/SMBUS1 (ASF) Base Address + // + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG2C, AccessWidth16, 06, (UserOptions.FchBldCfg->CfgSmbus0BaseAddress) + BIT0); ///protect BIT[2:1] + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG28, AccessWidth16, 06, (UserOptions.FchBldCfg->CfgSmbus1BaseAddress) + BIT0); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG60, AccessWidth16, 00, (UserOptions.FchBldCfg->CfgAcpiPm1EvtBlkAddr)); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG62, AccessWidth16, 00, (UserOptions.FchBldCfg->CfgAcpiPm1CntBlkAddr)); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG64, AccessWidth16, 00, (UserOptions.FchBldCfg->CfgAcpiPmTmrBlkAddr)); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG66, AccessWidth16, 00, (UserOptions.FchBldCfg->CfgCpuControlBlkAddr)); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG68, AccessWidth16, 00, (UserOptions.FchBldCfg->CfgAcpiGpe0BlkAddr)); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG6A, AccessWidth16, 00, (UserOptions.FchBldCfg->CfgSmiCmdPortAddr)); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG6E, AccessWidth16, 00, (UserOptions.FchBldCfg->CfgSmiCmdPortAddr) + 8); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG48, AccessWidth32, 00, (UserOptions.FchBldCfg->CfgWatchDogTimerBase)); + + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG2E, AccessWidth8, (UINT32)~(BIT1 + BIT2), 0); ///clear BIT[2:1] + SmbusBase = (UINT16) (UserOptions.FchBldCfg->CfgSmbus0BaseAddress); + Value = 0x00; + LibAmdIoWrite (AccessWidth8, SmbusBase + 0x14, &Value, StdHeader); + + ProgramFchAcpiMmioTbl ((ACPI_REG_WRITE*) (&FchInitResetAcpiMmioTable[0]), StdHeader); + + + if (UserOptions.FchBldCfg->CfgFchGpioControl != NULL) { + ProgramFchGpioTbl ((UserOptions.FchBldCfg->CfgFchGpioControl), LocalCfgPtr); + } + + if (UserOptions.FchBldCfg->CfgFchSataPhyControl != NULL) { + ProgramFchSataPhyTbl ((UserOptions.FchBldCfg->CfgFchSataPhyControl), LocalCfgPtr); + } + + // + // Prevent RTC error + // + Value = 0x0A; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG70, &Value, StdHeader); + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REG71, &Value, StdHeader); + Value &= 0xEF; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG71, &Value, StdHeader); + + Value = 0x08; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &Value, StdHeader); + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGC01, &Value, StdHeader); + if ( !LocalCfgPtr->EcKbd ) { + // + // Route SIO IRQ1/IRQ12 to USB IRQ1/IRQ12 input + // + Value = Value | 0x0A; + } + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &Value, StdHeader); + + Value = 0x09; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &Value, StdHeader); + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGC01, &Value, StdHeader); + if ( !LocalCfgPtr->EcKbd ) { + // + // Route SIO IRQ1/IRQ12 to USB IRQ1/IRQ12 input + // + Value = Value & 0xF9; + } + + if ( LocalCfgPtr->LegacyFree ) { + // + // Disable IRQ1/IRQ12 filter enable for Legacy free with USB KBC emulation. + // + Value = Value & 0x9F; + } + // + // Enabled IRQ input + // + Value = Value | BIT4; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &Value, StdHeader); + + AsfPort = ((UINT16) UserOptions.FchBldCfg->CfgSmbus1BaseAddress & 0xFFF0); + if ( AsfPort != 0 ) { + UINT8 dbValue; + dbValue = 0x70; + LibAmdIoWrite (AccessWidth8, AsfPort + 0x0E, &dbValue, StdHeader); + dbValue = 0x2F; + LibAmdIoWrite (AccessWidth8, AsfPort + 0x0A, &dbValue, StdHeader); + } + // + // PciExpWakeStatus workaround + // + ReadMem (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG04, AccessWidth32, &GeventEnableBits); + ReadMem (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG00, AccessWidth32, &GeventValue); + if ( (GeventValue & GeventEnableBits) != 0 ) { + Value = 0x40; + LibAmdIoWrite (AccessWidth8, AsfPort, &Value, StdHeader); + } + ReadMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG60, AccessWidth16, &AsfPort); + AsfPort++; + LibAmdIoRead (AccessWidth8, AsfPort, &Value, StdHeader); + if ((Value & (BIT2 + BIT0)) != 0) { + Value = 0x40; + LibAmdIoWrite (AccessWidth8, AsfPort, &Value, StdHeader); + } + // + // Set ACPIMMIO by OEM Input table + // + if ( LocalCfgPtr->OemResetProgrammingTablePtr != NULL ) { + ProgramFchAcpiMmioTbl ((ACPI_REG_WRITE *) (LocalCfgPtr->OemResetProgrammingTablePtr), StdHeader); + } +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/Family/Yangtze/YangtzeHwmEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/Family/Yangtze/YangtzeHwmEnvService.c new file mode 100644 index 0000000000..ea4ee73923 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/Family/Yangtze/YangtzeHwmEnvService.c @@ -0,0 +1,87 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config FCH Hwm controller + * + * Init Hwm Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWM_FAMILY_YANGTZE_YANGTZEHWMENVSERVICE_FILECODE + + +/** + * HwmInitRegister - Init Hardware Monitor Register. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +HwmInitRegister ( + IN VOID *FchDataPtr + ) +{ + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xB2, AccessWidth8, 0, 0x55); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xB3, AccessWidth8, 0, 0x55); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x91, AccessWidth8, 0, 0x55); + + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x00, AccessWidth8, 0, 0x06); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x10, AccessWidth8, 0, 0x06); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x20, AccessWidth8, 0, 0x06); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x30, AccessWidth8, 0, 0x06); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x40, AccessWidth8, 0, 0x06); + + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x66, AccessWidth8, 0, 0x01); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x6B, AccessWidth8, 0, 0x01); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x70, AccessWidth8, 0, 0x01); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x75, AccessWidth8, 0, 0x01); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x7A, AccessWidth8, 0, 0x01); + + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xE6, AccessWidth8, 0xff, 0x02); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xF8, AccessWidth8, 0, 0x05); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xF9, AccessWidth8, 0, 0x06); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xFF, AccessWidth8, 0, 0x42); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xE9, AccessWidth8, 0, 0xFF); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xEB, AccessWidth8, 0, 0x1F); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xEF, AccessWidth8, 0, 0x04); + RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xFB, AccessWidth8, 0, 0x00); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xB6, AccessWidth8, 0x0F, 0x00); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/Family/Yangtze/YangtzeHwmLateService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/Family/Yangtze/YangtzeHwmLateService.c new file mode 100644 index 0000000000..f26dfc9be7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/Family/Yangtze/YangtzeHwmLateService.c @@ -0,0 +1,189 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config FCH Hwm controller + * + * Init Hwm Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWM_FAMILY_YANGTZE_YANGTZEHWMLATESERVICE_FILECODE + +/** + * Table for Function Number + * + * + * + * + */ +STATIC UINT8 FunctionNumber[] = +{ + Fun_81, + Fun_83, + Fun_85, + Fun_89, +}; + +/** + * Table for Max Thermal Zone + * + * + * + * + */ +UINT8 MaxZone[] = +{ + 4, + 4, + 4, + 4, +}; + + +/** + * Table for Max Register + * + * + * + * + */ +UINT8 MaxRegister[] = +{ + MSG_REG9, + MSG_REGB, + MSG_REG9, + MSG_REGA, +}; + +/*------------------------------------------------------------------------------- +;Procedure: IsZoneFuncEnable +; +;Description: This routine will check every zone support function with BitMap from user define +; +; +;Exit: None +; +;Modified: None +; +;----------------------------------------------------------------------------- +*/ +STATIC BOOLEAN +IsZoneFuncEnable ( + IN UINT16 Flag, + IN UINT8 func, + IN UINT8 Zone + ) +{ + return (BOOLEAN) (((Flag >> (func *4)) & 0xF) & ((UINT8 )1 << Zone)); +} + +/*------------------------------------------------------------------------------- +;Procedure: FchECfancontrolservice +; +;Description: This routine service EC fan policy +; +; +;Exit: None +; +;Modified: None +; +;----------------------------------------------------------------------------- +*/ +VOID +FchECfancontrolservice ( + IN VOID *FchDataPtr + ) +{ + UINT8 ZoneNum; + UINT8 FunNum; + UINT8 RegNum; + UINT8 *CurPoint; + UINT8 FunIndex; + BOOLEAN IsSendEcMsg; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + if (!IsImcEnabled (StdHeader)) { + return; //IMC is not enabled + } + + CurPoint = &LocalCfgPtr->Imc.EcStruct.MsgFun81Zone0MsgReg0 + MaxZone[0] * (MaxRegister[0] - MSG_REG0 + 1); + + for ( FunIndex = 1; FunIndex <= 3; FunIndex++ ) { + FunNum = FunctionNumber[FunIndex]; + for ( ZoneNum = 0; ZoneNum < MaxZone[FunIndex]; ZoneNum++ ) { + IsSendEcMsg = IsZoneFuncEnable (LocalCfgPtr->Imc.EcStruct.IMCFUNSupportBitMap, FunIndex, ZoneNum); + if (IsSendEcMsg) { + for ( RegNum = MSG_REG0; RegNum <= MaxRegister[FunIndex]; RegNum++ ) { + WriteECmsg (RegNum, AccessWidth8, CurPoint, StdHeader); + CurPoint += 1; + } + WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &FunNum, StdHeader); // function number + WaitForEcLDN9MailboxCmdAck (StdHeader); + } else { + CurPoint += (MaxRegister[FunIndex] - MSG_REG0 + 1); + } + } + } + + CurPoint = &LocalCfgPtr->Imc.EcStruct.MsgFun81Zone0MsgReg0; + for ( FunIndex = 0; FunIndex <= 0; FunIndex++ ) { + FunNum = FunctionNumber[FunIndex]; + for ( ZoneNum = 0; ZoneNum < MaxZone[FunIndex]; ZoneNum++ ) { + IsSendEcMsg = IsZoneFuncEnable (LocalCfgPtr->Imc.EcStruct.IMCFUNSupportBitMap, FunIndex, ZoneNum); + if (IsSendEcMsg) { + for ( RegNum = MSG_REG0; RegNum <= MaxRegister[FunIndex]; RegNum++ ) { + if (RegNum == MSG_REG2) { + *CurPoint &= 0xFE; + } + WriteECmsg (RegNum, AccessWidth8, CurPoint, StdHeader); + CurPoint += 1; + } + WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &FunNum, StdHeader); // function number + WaitForEcLDN9MailboxCmdAck (StdHeader); + } else { + CurPoint += (MaxRegister[FunIndex] - MSG_REG0 + 1); + } + } + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/HwmLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/HwmLate.c new file mode 100644 index 0000000000..0adfd48b8a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Hwm/HwmLate.c @@ -0,0 +1,74 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config FCH Hwm controller + * + * Init Hwm Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87213 $ @e \$Date: 2013-01-30 15:37:54 -0600 (Wed, 30 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_HWM_HWMLATE_FILECODE + + +/** + * FchInitLateHwm - Prepare Hwm controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateHwm ( + IN VOID *FchDataPtr + ); + +VOID +FchInitLateHwm ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + HwmInitRegister (LocalCfgPtr); + ImcWakeup (LocalCfgPtr); + FchECfancontrolservice (LocalCfgPtr); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeEnv.c new file mode 100644 index 0000000000..16d9effeb7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeEnv.c @@ -0,0 +1,63 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch IDE controller + * + * Init IDE Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_IDE_IDEENV_FILECODE + +/** + * FchInitEnvIde - Config Ide controller before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvIde ( + IN VOID *FchDataPtr + ) +{ +} + + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeLate.c new file mode 100644 index 0000000000..2e2099de53 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeLate.c @@ -0,0 +1,59 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch IDE controller + * + * Init IDE Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_IDE_IDELATE_FILECODE +/** + * FchInitLateIde - Prepare IDE controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateIde ( + IN VOID *FchDataPtr + ) +{ +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeMid.c new file mode 100644 index 0000000000..cc4e088051 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Ide/IdeMid.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch IDE controller + * + * Init IDE Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_IDE_IDEMID_FILECODE + +/** + * FchInitMidIde - Config IDE controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidIde ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/Family/Yangtze/YangtzeImcService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/Family/Yangtze/YangtzeImcService.c new file mode 100644 index 0000000000..c176d1e5e1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/Family/Yangtze/YangtzeImcService.c @@ -0,0 +1,97 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Imc controller + * + * Init Imc Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87213 $ @e \$Date: 2013-01-30 15:37:54 -0600 (Wed, 30 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_IMC_FAMILY_YANGTZE_YANGTZEIMCSERVICE_FILECODE + +// +// Declaration of local functions +// + + +/** + * SoftwareToggleImcStrapping - Software Toggle IMC Firmware Strapping. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +SoftwareToggleImcStrapping ( + IN VOID *FchDataPtr + ) +{ + UINT8 ValueByte; + AMD_CONFIG_PARAMS *StdHeader; + FCH_DATA_BLOCK *LocalCfgPtr; + + StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader; + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + if ( LocalCfgPtr->Imc.ImcEnableOverWrite == 1 ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGD6 + 1, AccessWidth8, 0x7F, BIT7); + + ValueByte = 0x0; + while (ValueByte == 0) { + FchStall (10000, StdHeader); + ReadPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG40, AccessWidth8, &ValueByte, StdHeader); + ValueByte &= 0x80; + }; + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGC4, AccessWidth8, 0xF7, 0x08); + + EnterEcConfig (StdHeader); + RwEc8 (FCH_EC_REG07, 0x00, 0x09, StdHeader); ///switch to device 9 (Mailbox) + RwEc8 (FCH_EC_REG60, 0x00, (MailBoxPort >> 8), StdHeader); ///set MSB of Mailbox port + RwEc8 (FCH_EC_REG61, 0x00, (MailBoxPort & 0xFF), StdHeader); ///set LSB of Mailbox port + RwEc8 (FCH_EC_REG30, 0x00, 0x01, StdHeader); ///;Enable Mailbox Registers Interface, bit0=1 + + RwMem (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB3, AccessWidth8, (UINT32)~BIT6, BIT6); + ExitEcConfig (StdHeader); + + ImcSleep (FchDataPtr); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGD6 + 1, AccessWidth8, 0x7F, 0); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcEnv.c new file mode 100644 index 0000000000..e18790003d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcEnv.c @@ -0,0 +1,185 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Embedded Controller + * + * Init Ec Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_IMC_FCHECENV_FILECODE + + +/** + * FchInitEnvEc - Config Ec controller before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvEc ( + IN VOID *FchDataPtr + ) +{ +} + +/*----------------------------------------------------------------------------------------*/ +/** + * EnterEcConfig - Force EC into Config mode + * + * + * + * + */ +VOID +EnterEcConfig ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 EcIndexPortDword; + UINT8 FchEcData8; + + ReadPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGA4, AccessWidth16, &EcIndexPortDword, StdHeader); + EcIndexPortDword &= ~(BIT0); + FchEcData8 = FCH_EC_ENTER_CONFIG; + LibAmdIoWrite (AccessWidth8, EcIndexPortDword, &FchEcData8, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * ExitEcConfig - Force EC exit Config mode + * + * + * + * + */ +VOID +ExitEcConfig ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 EcIndexPortDword; + UINT8 FchEcData8; + + ReadPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGA4, AccessWidth16, &EcIndexPortDword, StdHeader); + EcIndexPortDword &= ~(BIT0); + FchEcData8 = FCH_EC_EXIT_CONFIG; + LibAmdIoWrite (AccessWidth8, EcIndexPortDword, &FchEcData8, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * ReadEc8 - Read EC register data + * + * + * + * @param[in] Address - EC Register Offset Value + * @param[in] Value - Read Data Buffer + * @param[in] StdHeader + * + */ +VOID +ReadEc8 ( + IN UINT8 Address, + IN UINT8 *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 EcIndexPortDword; + + ReadPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGA4, AccessWidth16, &EcIndexPortDword, StdHeader); + EcIndexPortDword &= ~(BIT0); + LibAmdIoWrite (AccessWidth8, EcIndexPortDword, &Address, StdHeader); + LibAmdIoRead (AccessWidth8, EcIndexPortDword + 1, Value, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * RwEc8 - Read/Write EC register + * + * + * + * @param[in] Address - EC Register Offset Value + * @param[in] AndMask - Data And Mask 8 bits + * @param[in] OrMask - Data OR Mask 8 bits + * @param[in] StdHeader + * + */ +VOID +RwEc8 ( + IN UINT8 Address, + IN UINT8 AndMask, + IN UINT8 OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Result; + + ReadEc8 (Address, &Result, StdHeader); + Result = (Result & AndMask) | OrMask; + WriteEc8 (Address, &Result, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * WriteEc8 - Write date into EC register + * + * + * + * @param[in] Address - EC Register Offset Value + * @param[in] Value - Write Data Buffer + * @param[in] StdHeader + * + */ +VOID +WriteEc8 ( + IN UINT8 Address, + IN UINT8 *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 EcIndexPortDword; + + ReadPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGA4, AccessWidth16, &EcIndexPortDword, StdHeader); + EcIndexPortDword &= ~(BIT0); + LibAmdIoWrite (AccessWidth8, EcIndexPortDword, &Address, StdHeader); + LibAmdIoWrite (AccessWidth8, EcIndexPortDword + 1, Value, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcLate.c new file mode 100644 index 0000000000..8bdb4c2be3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcLate.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Embedded Controller + * + * Init Ec Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_IMC_FCHECLATE_FILECODE + +/** + * FchInitLateEc - Prepare Ec controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateEc ( + IN VOID *FchDataPtr + ) +{ +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcMid.c new file mode 100644 index 0000000000..c1a7ecdbaa --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/FchEcMid.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Embedded Controller + * + * Init Ec Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_IMC_FCHECMID_FILECODE + +/** + * FchInitMidIde - Config Ec controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidEc ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcEnv.c new file mode 100644 index 0000000000..73d12c04ec --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcEnv.c @@ -0,0 +1,140 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Imc controller + * + * Init Imc Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87213 $ @e \$Date: 2013-01-30 15:37:54 -0600 (Wed, 30 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_IMC_IMCENV_FILECODE + + +// +// Declaration of local functions +// + + +/** + * FchInitEnvImc - Config Imc controller before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvImc ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + SoftwareToggleImcStrapping (LocalCfgPtr); + FchInitEnvEc (LocalCfgPtr); +} + +/** + * ValidateImcFirmware - Validate IMC Firmware. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + * @retval TRUE Pass + * @retval FALSE Failed + */ +BOOLEAN +ValidateImcFirmware ( + IN VOID *FchDataPtr + ) +{ + UINT32 ImcSig; + UINT32 ImcSigAddr; + UINT32 ImcAddr; + UINT32 CurAddr; + UINT32 ImcBinSig0; + UINT32 ImcBinSig1; + UINT16 ImcBinSig2; + UINT8 IMCChecksumeByte; + UINT8 IMCByte; + + ImcAddr = 0; + + // + // Software IMC enable + // + ImcSigAddr = 0x80000; /// start from 512k to 64M + ImcSig = 0x0; + + while ( ( ImcSig != FCH_IMC_ROMSIG ) && ( ImcSigAddr <= 0x4000000 ) ) { + CurAddr = 0xffffffff - ImcSigAddr + 0x20001; + ReadMem (CurAddr, AccessWidth32, &ImcSig); + ReadMem ((CurAddr + 4), AccessWidth32, &ImcAddr); + ImcSigAddr <<= 1; + } + + IMCChecksumeByte = 0xff; + + if ( ImcSig == FCH_IMC_ROMSIG ) { + // + // "_AMD_IMC_C" at offset 0x2000 of the binary + // + ReadMem ((ImcAddr + 0x2000), AccessWidth32, &ImcBinSig0); + ReadMem ((ImcAddr + 0x2004), AccessWidth32, &ImcBinSig1); + ReadMem ((ImcAddr + 0x2008), AccessWidth16, &ImcBinSig2); + + if ((ImcBinSig0 == 0x444D415F) && (ImcBinSig1 == 0x434D495F) && (ImcBinSig2 == 0x435F) ) { + IMCChecksumeByte = 0; + + for ( CurAddr = ImcAddr; CurAddr < ImcAddr + 0x10000; CurAddr++ ) { + ReadMem (CurAddr, AccessWidth8, &IMCByte); + IMCChecksumeByte = IMCChecksumeByte + IMCByte; + } + } + } + + if ( IMCChecksumeByte ) { + return FALSE; + } else { + return TRUE; + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcLate.c new file mode 100644 index 0000000000..340da0f026 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcLate.c @@ -0,0 +1,81 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Imc controller + * + * Init Imc Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_IMC_IMCLATE_FILECODE + +/** + * FchInitLateImc - Prepare Imc controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateImc ( + IN VOID *FchDataPtr + ) +{ + FchInitLateEc (FchDataPtr); +} + +/** + * ImcDisarmSurebootTimer - IMC Disarm Sureboot Timer. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ImcDisarmSurebootTimer ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + ImcDisableSurebootTimer (LocalCfgPtr); + LocalCfgPtr->Imc.ImcSureBootTimer = 0; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcLib.c new file mode 100644 index 0000000000..44fe2cd99d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcLib.c @@ -0,0 +1,314 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH IMC lib + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87213 $ @e \$Date: 2013-01-30 15:37:54 -0600 (Wed, 30 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_IMC_IMCLIB_FILECODE + +/** + * WriteECmsg + * + * + * + * @param[in] Address - Address + * @param[in] OpFlag - Access width + * @param[in] *Value - Out Value pointer + * @param[in] StdHeader + * + */ +VOID +WriteECmsg ( + IN UINT8 Address, + IN UINT8 OpFlag, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Index; + + OpFlag = OpFlag & 0x7f; + if (OpFlag == 0x02) { + OpFlag = 0x03; + } + + for (Index = 0; Index <= OpFlag; Index++) { + /// EC_LDN9_MAILBOX_BASE_ADDRESS + LibAmdIoWrite (AccessWidth8, MailBoxPort, &Address, StdHeader); + Address++; + /// EC_LDN9_MAILBOX_BASE_ADDRESS + LibAmdIoWrite (AccessWidth8, MailBoxPort + 1, (UINT8 *)Value + Index, StdHeader); + } +} + +/** + * ReadECmsg + * + * + * + * @param[in] Address - Address + * @param[in] OpFlag - Access width + * @param[out] *Value - Out Value pointer + * @param[in] StdHeader + * + */ +VOID +ReadECmsg ( + IN UINT8 Address, + IN UINT8 OpFlag, + OUT VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Index; + + OpFlag = OpFlag & 0x7f; + if (OpFlag == 0x02) { + OpFlag = 0x03; + } + + for (Index = 0; Index <= OpFlag; Index++) { + /// EC_LDN9_MAILBOX_BASE_ADDRESS + LibAmdIoWrite (AccessWidth8, MailBoxPort, &Address, StdHeader); + Address++; + /// EC_LDN9_MAILBOX_BASE_ADDRESS + LibAmdIoRead (AccessWidth8, MailBoxPort + 1, (UINT8 *)Value + Index, StdHeader); + } +} + +/** + * WaitForEcLDN9MailboxCmdAck + * + * + * @param[in] StdHeader + * + */ +VOID +WaitForEcLDN9MailboxCmdAck ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Msgdata; + UINT16 Delaytime; + + Msgdata = 0; + + for (Delaytime = 0; Delaytime < 0xFFFF; Delaytime++) { + ReadECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader); + if ( Msgdata == 0xfa) { + break; + } + + FchStall (5, StdHeader); /// Wait for 1ms + } +} + +/** + * ImcSleep - IMC Sleep. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ImcSleep ( + IN VOID *FchDataPtr + ) +{ + UINT8 Msgdata; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + if (!(IsImcEnabled (StdHeader)) ) { + return; ///IMC is not enabled + } + + Msgdata = 0x00; + WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0xB4; + WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x00; + WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x96; + WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader); + WaitForEcLDN9MailboxCmdAck (StdHeader); +} + + +/** + * ImcEnableSurebootTimer - IMC Enable Sureboot Timer. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ImcEnableSurebootTimer ( + IN VOID *FchDataPtr + ) +{ + UINT8 Msgdata; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + ImcDisableSurebootTimer (LocalCfgPtr); + + Msgdata = 0x00; + + if (!(IsImcEnabled (StdHeader)) || (LocalCfgPtr->Imc.ImcSureBootTimer == 0)) { + return; ///IMC is not enabled + } + + ImcWakeup (FchDataPtr); + WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x01; + WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader); + Msgdata = ( (LocalCfgPtr->Imc.ImcSureBootTimer) << 6) -1; + WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x94; + WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader); + WaitForEcLDN9MailboxCmdAck (StdHeader); + ImcSleep (FchDataPtr); +} + +/** + * ImcDisableSurebootTimer - IMC Disable Sureboot Timer. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ImcDisableSurebootTimer ( + IN VOID *FchDataPtr + ) +{ + UINT8 Msgdata; + AMD_CONFIG_PARAMS *StdHeader; + + StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader; + + if (!(IsImcEnabled (StdHeader)) ) { + return; ///IMC is not enabled + } + + ImcWakeup (FchDataPtr); + Msgdata = 0x00; + WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x01; + WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x00; + WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x94; + WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader); + WaitForEcLDN9MailboxCmdAck (StdHeader); + ImcSleep (FchDataPtr); +} + +/** + * ImcWakeup - IMC Wakeup. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ImcWakeup ( + IN VOID *FchDataPtr + ) +{ + UINT8 Msgdata; + AMD_CONFIG_PARAMS *StdHeader; + + StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader; + if (!(IsImcEnabled (StdHeader)) ) { + return; ///IMC is not enabled + } + + Msgdata = 0x00; + WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0xB5; + WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x00; + WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x96; + WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader); + WaitForEcLDN9MailboxCmdAck (StdHeader); +} + +/** + * ImcIdle - IMC Idle. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +ImcIdle ( + IN VOID *FchDataPtr + ) +{ + UINT8 Msgdata; + AMD_CONFIG_PARAMS *StdHeader; + + StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader; + + if (!(IsImcEnabled (StdHeader)) ) { + return; ///IMC is not enabled + } + + Msgdata = 0x00; + WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x01; + WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x00; + WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader); + Msgdata = 0x98; + WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader); + WaitForEcLDN9MailboxCmdAck (StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcMid.c new file mode 100644 index 0000000000..6374c422a1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcMid.c @@ -0,0 +1,62 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Imc controller + * + * Init Imc Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_IMC_IMCMID_FILECODE + +/** + * FchInitMidImc - Config Imc controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidImc ( + IN VOID *FchDataPtr + ) +{ + FchInitMidEc (FchDataPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcReset.c new file mode 100644 index 0000000000..b9aee7b591 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Imc/ImcReset.c @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Imc controller + * + * Init Imc Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87213 $ @e \$Date: 2013-01-30 15:37:54 -0600 (Wed, 30 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_IMC_IMCRESET_FILECODE + +/** + * FchInitResetImc - Config Imc controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetImc ( + IN VOID *FchDataPtr + ) +{ + AMD_CONFIG_PARAMS *StdHeader; + + StdHeader = &((AMD_RESET_PARAMS *)FchDataPtr)->StdHeader; + if ((ReadFchSleepType (StdHeader) != ACPI_SLPTYP_S3)) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGD6 + 1, AccessWidth8, 0x7F, 0); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/Family/Yangtze/EnvDefYangtze.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/Family/Yangtze/EnvDefYangtze.c new file mode 100644 index 0000000000..888b83c186 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/Family/Yangtze/EnvDefYangtze.c @@ -0,0 +1,359 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Graphics Controller family specific service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 79969 $ @e \$Date: 2012-10-16 00:17:15 -0500 (Tue, 16 Oct 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "FchPlatform.h" +#include "Filecode.h" +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * Default FCH interface settings at InitEnv phase. + *---------------------------------------------------------------------------------------- + */ +CONST FCH_INTERFACE ROMDATA FchInterfaceDefault = { + SdAmda, // SdConfig + 2, + IrRxTx0Tx1, // IrConfig + TRUE, // UmiGen2 + SataAhci, //SataNativeIde, //simnow, // SataClass + TRUE, // SataEnable + TRUE, // IdeEnable + TRUE, // SataIdeMode + TRUE, // Ohci1Enable + TRUE, // Ohci2Enable + TRUE, // Ohci3Enable + TRUE, // Ohci4Enable + TRUE, // XhciSwitch + FALSE, // GppEnable + AlwaysOff // FchPowerFail +}; + + +/*---------------------------------------------------------------- + * InitEnv Phase Data Block Default (Failsafe) + *---------------------------------------------------------------- + */ +FCH_DATA_BLOCK InitEnvCfgDefault = { + NULL, // StdHeader + + { // FCH_ACPI + 0xB00, // Smbus0BaseAddress + 0xB20, // Smbus1BaseAddress + 0xE00, // SioPmeBaseAddress + 0xFEC000F0, // WatchDogTimerBase + 0x800, // AcpiPm1EvtBlkAddr + 0x804, // AcpiPm1CntBlkAddr + 0x808, // AcpiPmTmrBlkAddr + 0x810, // CpuControlBlkAddr + 0x820, // AcpiGpe0BlkAddr + 0x00B0, // SmiCmdPortAddr + 0xFE00, // AcpiPmaCntBlkAddr + TRUE, // AnyHt200MhzLink + TRUE, // SpreadSpectrum + AlwaysOff, // PwrFailShadow + 0, // StressResetMode + FALSE, // MtC1eEnable + NULL // OemProgrammingTablePtr + }, + + { // FCH_AB + TRUE, // AbMsiEnable + 0, // ALinkClkGateOff + 0, // BLinkClkGateOff + 0, // AbClockGating + 0, // GppClockGating + 0, // UmiL1TimerOverride + 0, // UmiLinkWidth + 0, // UmiDynamicSpeedChange + 0, // PcieRefClockOverClocking + 0, // UmiGppTxDriverStrength + TRUE, // NbSbGen2 + 0, // FchPcieOrderRule + 0, // SlowSpeedAbLinkClock + 0, // ResetCpuOnSyncFlood + FALSE, // AbDmaMemoryWrtie3264B + FALSE, // AbMemoryPowerSaving + FALSE, // SbgDmaMemoryWrtie3264ByteCount + FALSE // SbgMemoryPowerSaving + }, + + {{{0}}}, // FCH_GPP + + { // FCH_USB + TRUE, // Ohci1Enable + TRUE, // Ohci2Enable + TRUE, // Ohci3Enable + TRUE, // Ohci4Enable + TRUE, // Ehci1Enable + TRUE, // Ehci2Enable + TRUE, // Ehci3Enable + TRUE, // Xhci0Enable + TRUE, // Xhci1Enable + TRUE, // UsbMsiEnable + 0, // OhciSsid + 0, // Ohci4Ssid + 0, // EhciSsid + 0, // XhciSsid + FALSE, // UsbPhyPowerDown + 0, // UserDefineXhciRomAddr + {0x21, 0x21, 0x21, 0x21, 0x22}, // Ehci18Phy + {0x22, 0x22, 0x22, 0x21, 0x21}, // Ehci19Phy + {0x21, 0x21, 0x21, 0x21}, // Ehci22Phy + {0x24, 0x24, 0x21, 0x21} // Xhci20Phy + }, + + { // FCH_SATA + FALSE, // SataMsiEnable + 0x00000000, // SataIdeSsid + 0x00000000, // SataRaidSsid + 0x00000000, // SataRaid5Ssid + 0x00000000, // SataAhciSsid + { // SATA_ST + 0, // SataModeReg + TRUE, // SataEnable + 0, // Sata6AhciCap + TRUE, // SataSetMaxGen2 + FALSE, // IdeEnable + 01, // SataClkMode + }, + SataAhci, // SataClass + 1, // SataIdeMode + 0, // SataDisUnusedIdePChannel + 0, // SataDisUnusedIdeSChannel + 0, // IdeDisUnusedIdePChannel + 0, // IdeDisUnusedIdeSChannel + 0, // SataOptionReserved + { // SATA_PORT_ST + 0, // SataPortReg + FALSE, // Port0 + FALSE, // Port1 + FALSE, // Port2 + FALSE, // Port3 + FALSE, // Port4 + FALSE, // Port5 + FALSE, // Port6 + FALSE, // Port7 + }, + { // SATA_PORT_ST + 0, // SataPortReg + FALSE, // Port0 + FALSE, // Port1 + FALSE, // Port2 + FALSE, // Port3 + FALSE, // Port4 + FALSE, // Port5 + FALSE, // Port6 + FALSE, // Port7 + }, + { // SATA_PORT_MD + 0, // SataPortMode + 0, // Port0 + 0, // Port1 + 0, // Port2 + 0, // Port3 + 0, // Port4 + 0, // Port5 + 0, // Port6 + 0, // Port7 + }, + 0, // SataAggrLinkPmCap + 1, // SataPortMultCap + 0, // SataClkAutoOff + 0, // SataPscCap + 0, // BiosOsHandOff + 0, // SataFisBasedSwitching + 0, // SataCccSupport + 0, // SataSscCap + 0, // SataMsiCapability + 0, // SataForceRaid + 0, // SataInternal100Spread + 0, // SataDebugDummy + 0, // SataTargetSupport8Device + 0, // SataDisableGenericMode + FALSE, // SataAhciEnclosureManagement + 0, // SataSgpio0 + 0, // SataSgpio1 + 0, // SataPhyPllShutDown + TRUE, // SataHotRemovalEnh + { // SATA_PORT_ST + 0, // SataPortReg + FALSE, // Port0 + FALSE, // Port1 + FALSE, // Port2 + FALSE, // Port3 + FALSE, // Port4 + FALSE, // Port5 + FALSE, // Port6 + FALSE, // Port7 + }, + FALSE, // SataOobDetectionEnh + FALSE, // SataPowerSavingEnh + 0, // SataMemoryPowerSaving + FALSE, // SataRasSupport + FALSE, // SataAhciDisPrefetchFunction + TRUE, // SataDevSlpPort0 + TRUE, // SataDevSlpPort1 + 0 // TempMmio + }, + + { // FCH_SMBUS + 0x00000000 // SmbusSsid + }, + + { // FCH_IDE + TRUE, // IdeEnable + FALSE, // IdeMsiEnable + 0x00000000 // IdeSsid + }, + + { // FCH_AZALIA + 2, // AzaliaEnable + TRUE, // AzaliaMsiEnable + 0x00000000, // AzaliaSsid + 1, // AzaliaPinCfg + 0, // AzaliaFrontPanel + 0, // FrontPanelDetected + 0, // AzaliaSnoop + 0, // AzaliaDummy + { // AZALIA_PIN + 2, // AzaliaSdin0 + 2, // AzaliaSdin1 + 2, // AzaliaSdin2 + 2, // AzaliaSdin3 + }, + NULL, // *AzaliaOemCodecTablePtr + NULL, // *AzaliaOemFpCodecTablePtr + }, + + { // FCH_SPI + TRUE, // LpcMsiEnable + 0x00000000, // LpcSsid + 0, // RomBaseAddress + 0, // Speed + 0, // FastSpeed + 0, // WriteSpeed + 0, // Mode + 0, // AutoMode + 0, // BurstWrite + TRUE, // LpcClk0 + TRUE, // LpcClk1 + }, + + { // FCH_PCIB + FALSE, // PcibMsiEnable + 0x00000000, // PcibSsid + 0x0F, // PciClks + 0, // PcibClkStopOverride + FALSE, // PcibClockRun + }, + + { // FCH_F1 + FALSE, // GecEnable + }, + + { // FCH_SD + SdDisable, // SdConfig + 0, // Speed + 0, // BitWidth + 0x00000000, // SdSsid + Sd50MhzTraceCableLengthWithinSixInches, // SdClockControl + FALSE, + 0, + 1, + 0 + }, + + {0}, // FCH_HWM + + {0, // FCH_IR + 0x23, // IrPinControl + }, + + { // FCH_HPET + TRUE, // HpetEnable + TRUE, // HpetMsiDis + 0xFED00000 // HpetBase + }, + + { // FCH_GCPU + 0, // AcDcMsg + 1, // TimerTickTrack + 1, // ClockInterruptTag + 0, // OhciTrafficHanding + 0, // EhciTrafficHanding + 0, // GcpuMsgCMultiCore + 0, // GcpuMsgCStage + }, + + {0}, // FCH_IMC + + { // FCH_MISC + FALSE, // NativePcieSupport + FALSE, // S3Resume + FALSE, // RebootRequired + 0, // FchVariant + 0, // CG2PLL + { // TIMER_SMI-LongTimer + FALSE, // Enable + FALSE, // StartNow + 1000 // CycleDuration + }, + { // TIMER_SMI-ShortTimer + FALSE, // Enable + FALSE, // StartNow + 0x7FFF // CycleDuration + } + } +}; + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/Family/Yangtze/ResetDefYangtze.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/Family/Yangtze/ResetDefYangtze.c new file mode 100644 index 0000000000..77cb199c8e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/Family/Yangtze/ResetDefYangtze.c @@ -0,0 +1,185 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Graphics Controller family specific service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 85510 $ @e \$Date: 2013-01-08 16:26:41 -0600 (Tue, 08 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "FchPlatform.h" +#include "Filecode.h" +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------------------- + * Default FCH interface settings at InitReset phase. + *---------------------------------------------------------------------------------------- + */ +CONST FCH_RESET_INTERFACE ROMDATA FchResetInterfaceDefault = { + TRUE, // UmiGen2 + TRUE, // SataEnable + TRUE, // IdeEnable + TRUE, // GppEnable + TRUE, // Xhci0Enable + TRUE // Xhci1Enable +}; + + +/*---------------------------------------------------------------- + * InitReset Phase Data Block Default (Failsafe) + *---------------------------------------------------------------- + */ +FCH_RESET_DATA_BLOCK InitResetCfgDefault = { + NULL, // StdHeader + { TRUE, + TRUE, + FALSE, + FALSE, + TRUE, + TRUE + }, // FchReset + + 1, // FastSpeed + 3, // WriteSpeed + 5, // Mode + 0, // AutoMode + 0, // BurstWrite + FALSE, // SataIdeCombMdPriSecOpt + 0, // Cg2Pll + FALSE, // EcKbd + FALSE, // LegacyFree + FALSE, // SataSetMaxGen2 + 1, // SataClkMode + 0, // SataModeReg + FALSE, // SataInternal100Spread + 2, // SpiSpeed +// 0xFCFCFCFC, // 38 +// 0x88FC, // 3c +// 0, // 1d_34 + 1, // 20_0 + FALSE, // EcChannel0 + + { // FCH_GPP + { // Array of FCH_GPP_PORT_CONFIG PortCfg[4] + { + FALSE, // PortPresent + FALSE, // PortDetected + FALSE, // PortIsGen2 + FALSE, // PortHotPlug + 0, // PortMisc + }, + { + FALSE, // PortPresent + FALSE, // PortDetected + FALSE, // PortIsGen2 + FALSE, // PortHotPlug + 0, // PortMisc + }, + { + FALSE, // PortPresent + FALSE, // PortDetected + FALSE, // PortIsGen2 + FALSE, // PortHotPlug + 0, // PortMisc + }, + { + FALSE, // PortPresent + FALSE, // PortDetected + FALSE, // PortIsGen2 + FALSE, // PortHotPlug + 0, // PortMisc + }, + }, + PortA1B1C1D1, // GppLinkConfig + FALSE, // GppFunctionEnable + FALSE, // GppToggleReset + 0, // GppHotPlugGeventNum + 0, // GppFoundGfxDev + FALSE, // GppGen2 + 0, // GppGen2Strap + FALSE, // GppMemWrImprove + FALSE, // GppUnhidePorts + 0, // GppPortAspm + FALSE, // GppLaneReversal + FALSE, // GppPhyPllPowerDown + FALSE, // GppDynamicPowerSaving + FALSE, // PcieAer + FALSE, // PcieRas + FALSE, // PcieCompliance + FALSE, // PcieSoftwareDownGrade + FALSE, // UmiPhyPllPowerDown + FALSE, // SerialDebugBusEnable + 0, // GppHardwareDownGrade + 0, // GppL1ImmediateAck + FALSE, // NewGppAlgorithm + 0, // HotPlugPortsStatus + 0, // FailPortsStatus + 40, // GppPortMinPollingTime + FALSE, // IsCapsuleMode + }, + { // FCH_SPI + FALSE, // LpcMsiEnable + 0x00000000, // LpcSsid + 0, // RomBaseAddress + 0, // Speed + 0, // FastSpeed + 0, // WriteSpeed + 0, // Mode + 0, // AutoMode + 0, // BurstWrite + TRUE, // LpcClk0 + TRUE, // LpcClk1 + 0, // SPI100_Enable + {0} // SpiDeviceProfile + }, + FALSE, // QeEnabled + NULL // OemResetProgrammingTablePtr +}; + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitEnv.c new file mode 100644 index 0000000000..f1ce3abc9f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitEnv.c @@ -0,0 +1,114 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Initialization. + * + * Init IOAPIC/IOMMU/Misc NB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ + +#include "FchPlatform.h" +#include "FchTaskLauncher.h" +#include "heapManager.h" +#include "Ids.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_INTERFACE_FCHINITENV_FILECODE + +extern FCH_TASK_ENTRY *FchInitEnvTaskTable[]; +extern FCH_INTERFACE FchInterfaceDefault; + +FCH_DATA_BLOCK* +FchInitEnvCreatePrivateData ( + IN AMD_ENV_PARAMS *EnvParams + ); +AGESA_STATUS +FchInitEnv ( + IN AMD_ENV_PARAMS *EnvParams + ); + +AGESA_STATUS +FchEnvConstructor ( + IN AMD_ENV_PARAMS *EnvParams + ); +/*----------------------------------------------------------------------------------------*/ +/** + * FchInitEnv - Config Fch before PCI emulation + * + * + * + * @param[in] EnvParams + * + */ +AGESA_STATUS +FchInitEnv ( + IN AMD_ENV_PARAMS *EnvParams + ) +{ + FCH_DATA_BLOCK *FchParams; + AGESA_STATUS Status; + + IDS_HDT_CONSOLE (FCH_TRACE, " FchInitEnv Enter... \n"); + FchParams = FchInitEnvCreatePrivateData (EnvParams); + + // Override internal data with IDS (Optional, internal build only) + IDS_OPTION_CALLOUT (IDS_CALLOUT_FCH_INIT_ENV, FchParams, FchParams->StdHeader); + + AgesaFchOemCallout (FchParams); + Status = FchTaskLauncher (&FchInitEnvTaskTable[0], FchParams, TpFchInitEnvDispatching); + IDS_HDT_CONSOLE (FCH_TRACE, " FchInitEnv Exit... Status = [0x%x]\n", Status); + return Status; +} + + +/** + * A constructor for FCH build parameter structure at InitEnv stage + * + * Sets inputs to valid, basic level, defaults. + * + * @param[in,out] EnvParams InitEnv configuration data block + * + * @retval AGESA_SUCCESS Constructors are not allowed to fail +*/ +AGESA_STATUS +FchEnvConstructor ( + IN AMD_ENV_PARAMS *EnvParams + ) +{ + EnvParams->FchInterface = FchInterfaceDefault; + return AGESA_SUCCESS; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitLate.c new file mode 100644 index 0000000000..1f1bdc1d86 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitLate.c @@ -0,0 +1,101 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Initialization. + * + * Init IOAPIC/IOMMU/Misc NB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ + +#include "FchPlatform.h" +#include "FchTaskLauncher.h" +#include "heapManager.h" +#include "Ids.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_INTERFACE_FCHINITLATE_FILECODE + +extern FCH_TASK_ENTRY *FchInitLateTaskTable[]; + +AGESA_STATUS +FchInitLate ( + IN AMD_S3SAVE_PARAMS *LateParams + ); + +AGESA_STATUS +FchLateConstructor ( + IN AMD_LATE_PARAMS *LateParams + ); +/*----------------------------------------------------------------------------------------*/ +/** + * FchInitLate - Prepare Fch to boot to OS. + * + * + * + * @param[in] LateParams + * + */ +AGESA_STATUS +FchInitLate ( + IN AMD_S3SAVE_PARAMS *LateParams + ) +{ + FCH_DATA_BLOCK *FchParams; + AGESA_STATUS Status; + + IDS_HDT_CONSOLE (FCH_TRACE, " FchInitLate Enter... \n"); + FchParams = FchInitLoadDataBlock (&LateParams->FchInterface, &LateParams->StdHeader); + Status = FchTaskLauncher (&FchInitLateTaskTable[0], FchParams, TpFchInitLateDispatching); + IDS_HDT_CONSOLE (FCH_TRACE, " FchInitLate Exit... Status = [0x%x]\n", Status); + return Status; +} + + +/** + * A constructor for FCH build parameter structure at InitLate stage + * + * Sets inputs to valid, basic level, defaults. + * + * @param[in,out] LateParams + * + * @retval AGESA_SUCCESS Constructors are not allowed to fail +*/ +AGESA_STATUS +FchLateConstructor ( + IN AMD_LATE_PARAMS *LateParams + ) +{ + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitMid.c new file mode 100644 index 0000000000..50a08493d2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitMid.c @@ -0,0 +1,100 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Initialization. + * + * Init IOAPIC/IOMMU/Misc NB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ + +#include "FchPlatform.h" +#include "FchTaskLauncher.h" +#include "heapManager.h" +#include "Ids.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_INTERFACE_FCHINITMID_FILECODE + +extern FCH_TASK_ENTRY *FchInitMidTaskTable[]; + +AGESA_STATUS +FchInitMid ( + IN AMD_MID_PARAMS *MidParams + ); + +AGESA_STATUS +FchMidConstructor ( + IN AMD_MID_PARAMS *MidParams + ); +/** + * FchInitMid - Config Fch after PCI emulation + * + * + * + * @param[in] MidParams Fch configuration structure pointer. + * + */ +AGESA_STATUS +FchInitMid ( + IN AMD_MID_PARAMS *MidParams + ) +{ + FCH_DATA_BLOCK *FchParams; + AGESA_STATUS Status; + + IDS_HDT_CONSOLE (FCH_TRACE, " FchInitMid Enter... \n"); + FchParams = FchInitLoadDataBlock (&MidParams->FchInterface, &MidParams->StdHeader); + Status = FchTaskLauncher (&FchInitMidTaskTable[0], FchParams, TpFchInitMidDispatching); + IDS_HDT_CONSOLE (FCH_TRACE, " FchInitMid Exit... Status = [0x%x]\n", Status); + return Status; +} + + +/** + * A constructor for FCH build parameter structure at InitEnv stage + * + * Sets inputs to valid, basic level, defaults. + * + * @param[in] MidParams + * + * @retval AGESA_SUCCESS Constructors are not allowed to fail +*/ +AGESA_STATUS +FchMidConstructor ( + IN AMD_MID_PARAMS *MidParams + ) +{ + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitReset.c new file mode 100644 index 0000000000..97f60ddac5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitReset.c @@ -0,0 +1,115 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Init during Power-On Reset + * + * Prepare FCH environment during power on stage + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ + +#include "FchPlatform.h" +#include "FchTaskLauncher.h" +#include "heapManager.h" +#include "Ids.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_INTERFACE_FCHINITRESET_FILECODE + +extern FCH_TASK_ENTRY *FchInitResetTaskTable[]; +extern FCH_RESET_INTERFACE FchResetInterfaceDefault; + +FCH_RESET_DATA_BLOCK* +FchInitResetLoadPrivateDefault ( + IN AMD_RESET_PARAMS *ResetParams + ); + +AGESA_STATUS +FchInitReset ( + IN AMD_RESET_PARAMS *ResetParams + ); + +AGESA_STATUS +FchResetConstructor ( + IN AMD_RESET_PARAMS *ResetParams + ); +/** + * FchInitReset - Config Fch during power on stage. + * + * + * + * @param[in] ResetParams + * + */ +AGESA_STATUS +FchInitReset ( + IN AMD_RESET_PARAMS *ResetParams + ) +{ + FCH_RESET_DATA_BLOCK *FchParams; + + // Load private data block with default + FchParams = FchInitResetLoadPrivateDefault (ResetParams); + + // Override external data with input parameters + FchParams->StdHeader = &ResetParams->StdHeader; + FchParams->FchReset = ResetParams->FchInterface; + FchParams->Gpp.GppFunctionEnable = ResetParams->FchInterface.GppEnable; + + // Override internal data with IDS (Optional, internal build only) + IDS_OPTION_CALLOUT (IDS_CALLOUT_FCH_INIT_RESET, FchParams, &ResetParams->StdHeader); + + AgesaFchOemCallout (FchParams); + return FchTaskLauncher (&FchInitResetTaskTable[0], FchParams, TpFchInitResetDispatching); +} + + +/** + * A constructor for FCH build parameter structure at InitReset stage + * + * Sets inputs to valid, basic level, defaults. + * + * @param[in] ResetParams + * + * @retval AGESA_SUCCESS Constructors are not allowed to fail +*/ +AGESA_STATUS +FchResetConstructor ( + IN AMD_RESET_PARAMS *ResetParams + ) +{ + ResetParams->FchInterface = FchResetInterfaceDefault; + return AGESA_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitS3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitS3.c new file mode 100644 index 0000000000..e47611d79c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchInitS3.c @@ -0,0 +1,102 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH Initialization. + * + * Init IOAPIC/IOMMU/Misc NB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ + +#include "FchPlatform.h" +#include "FchTaskLauncher.h" +#define FILECODE PROC_FCH_INTERFACE_FCHINITS3_FILECODE + +extern FCH_TASK_ENTRY *FchInitS3EarlyTaskTable[]; +extern FCH_TASK_ENTRY *FchInitS3LateTaskTable[]; + +VOID +FchInitS3EarlyRestore ( + IN FCH_DATA_BLOCK *FchDataPtr + ); + +VOID +FchInitS3LateRestore ( + IN FCH_DATA_BLOCK *FchDataPtr + ); +/*----------------------------------------------------------------------------------------*/ +/** + * FchInitS3EarlyRestore - Config Fch before ACPI S3 resume PCI config device restore + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ + +VOID +FchInitS3EarlyRestore ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + AGESA_STATUS AgesaStatus; + + FchDataPtr->Misc.S3Resume = 1; + AgesaStatus = FchTaskLauncher (&FchInitS3EarlyTaskTable[0], FchDataPtr, TpFchInitS3EarlyDispatching); + FchDataPtr->Misc.S3Resume = 0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * FchInitS3LateRestore - Config Fch after ACPI S3 resume PCI config device restore + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ + +VOID +FchInitS3LateRestore ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + AGESA_STATUS AgesaStatus; + + FchDataPtr->Misc.S3Resume = 1; + AgesaStatus = FchTaskLauncher (&FchInitS3LateTaskTable[0], FchDataPtr, TpFchInitS3LateDispatching); + FchDataPtr->Misc.S3Resume = 0; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchTaskLauncher.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchTaskLauncher.c new file mode 100644 index 0000000000..cbf2dc7970 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchTaskLauncher.c @@ -0,0 +1,69 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH task launcher + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Ids.h" +#define FILECODE PROC_FCH_INTERFACE_FCHTASKLAUNCHER_FILECODE + +AGESA_STATUS +FchTaskLauncher ( + IN FCH_TASK_ENTRY **TaskPtr, + IN VOID *FchCfg, + IN AGESA_TP TestPoint + ); + +AGESA_STATUS +FchTaskLauncher ( + IN FCH_TASK_ENTRY **TaskPtr, + IN VOID *FchCfg, + IN AGESA_TP TestPoint + ) +{ + AGESA_TESTPOINT (TestPoint, *(AMD_CONFIG_PARAMS **) FchCfg); + while (*TaskPtr != NULL) { + (*TaskPtr) (FchCfg); + TaskPtr++; + } + return AGESA_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchTaskLauncher.h b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchTaskLauncher.h new file mode 100644 index 0000000000..776e6034be --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/FchTaskLauncher.h @@ -0,0 +1,62 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * FCH task launcher + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#ifndef _FCH_TASK_LAUNCHER_H_ +#define _FCH_TASK_LAUNCHER_H_ + +#include "Ids.h" + +FCH_DATA_BLOCK* +FchInitLoadDataBlock ( + IN FCH_INTERFACE *FchInterface, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +FchTaskLauncher ( + IN FCH_TASK_ENTRY **TaskPtr, + IN VOID *FchCfg, + IN AGESA_TP TestPoint + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/InitEnvDef.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/InitEnvDef.c new file mode 100644 index 0000000000..4bea9fbf99 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/InitEnvDef.c @@ -0,0 +1,196 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Fch Init during POWER-ON + * + * Prepare Fch environment during power on stage. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ + +#include "FchPlatform.h" +#include "Ids.h" +#include "heapManager.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_INTERFACE_INITENVDEF_FILECODE + +extern FCH_DATA_BLOCK InitEnvCfgDefault; + +FCH_DATA_BLOCK* +FchInitEnvCreatePrivateData ( + IN AMD_ENV_PARAMS *EnvParams + ); + +FCH_DATA_BLOCK* +FchInitLoadDataBlock ( + IN FCH_INTERFACE *FchInterface, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +FCH_DATA_BLOCK* +FchInitLoadDataBlock ( + IN FCH_INTERFACE *FchInterface, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + FCH_DATA_BLOCK *FchParams; + LOCATE_HEAP_PTR LocHeapPtr; + AMD_CONFIG_PARAMS TempStdHeader; + AGESA_STATUS AgesaStatus; + + TempStdHeader = *StdHeader; + TempStdHeader.HeapStatus = HEAP_SYSTEM_MEM; + + // Locate the internal data block via heap manager + LocHeapPtr.BufferHandle = AMD_FCH_DATA_BLOCK_HANDLE; + AgesaStatus = HeapLocateBuffer (&LocHeapPtr, &TempStdHeader); + ASSERT (!AgesaStatus); + + FchParams = (FCH_DATA_BLOCK *) LocHeapPtr.BufferPtr; + ASSERT (FchParams != NULL); + FchParams->StdHeader = StdHeader; + return FchParams; +} + + +STATIC VOID +RetrieveDataBlockFromInitReset ( + IN FCH_DATA_BLOCK *FchParams + ) +{ + LOCATE_HEAP_PTR LocHeapPtr; + FCH_RESET_DATA_BLOCK *ResetDb; + AGESA_STATUS AgesaStatus; + + LocHeapPtr.BufferHandle = AMD_FCH_RESET_DATA_BLOCK_HANDLE; + AgesaStatus = HeapLocateBuffer (&LocHeapPtr, FchParams->StdHeader); + if (AgesaStatus == AGESA_SUCCESS) { + ASSERT (LocHeapPtr.BufferPtr != NULL); + ResetDb = (FCH_RESET_DATA_BLOCK *) (LocHeapPtr.BufferPtr - sizeof (ResetDb) + sizeof (UINT32)); + // Override FchParams with contents in ResetDb + + FchParams->Usb.Xhci0Enable = ResetDb->FchReset.Xhci0Enable; + FchParams->Usb.Xhci1Enable = ResetDb->FchReset.Xhci1Enable; + FchParams->Spi.SpiFastSpeed = ResetDb->FastSpeed; + FchParams->Spi.WriteSpeed = ResetDb->WriteSpeed; + FchParams->Spi.SpiMode = ResetDb->Mode; + FchParams->Spi.AutoMode = ResetDb->AutoMode; + FchParams->Spi.SpiBurstWrite = ResetDb->BurstWrite; + FchParams->Sata.SataMode.Sata6AhciCap = (UINT8) ResetDb->Sata6AhciCap; + FchParams->Misc.Cg2Pll = ResetDb->Cg2Pll; + FchParams->Sata.SataMode.SataSetMaxGen2 = ResetDb->SataSetMaxGen2; + FchParams->Sata.SataMode.SataClkMode = ResetDb->SataClkMode; + FchParams->Sata.SataMode.SataModeReg = ResetDb->SataModeReg; + FchParams->Sata.SataInternal100Spread = (UINT8) ResetDb->SataInternal100Spread; + FchParams->Spi.SpiSpeed = ResetDb->SpiSpeed; + FchParams->Gpp = ResetDb->Gpp; + } +} + + +FCH_DATA_BLOCK* +FchInitEnvCreatePrivateData ( + IN AMD_ENV_PARAMS *EnvParams + ) +{ + FCH_DATA_BLOCK *FchParams; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + AGESA_STATUS AgesaStatus; + + // First allocate internal data block via heap manager + AllocHeapParams.RequestedBufferSize = sizeof (FCH_DATA_BLOCK); + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + AllocHeapParams.BufferHandle = AMD_FCH_DATA_BLOCK_HANDLE; + AgesaStatus = HeapAllocateBuffer (&AllocHeapParams, &EnvParams->StdHeader); + ASSERT (!AgesaStatus); + + FchParams = (FCH_DATA_BLOCK *) AllocHeapParams.BufferPtr; + ASSERT (FchParams != NULL); + IDS_HDT_CONSOLE (FCH_TRACE, " FCH Data Block Allocation: [0x%x], Ptr = 0x%08x\n", AgesaStatus, FchParams); + + // Load private data block with default + *FchParams = InitEnvCfgDefault; + FchParams->StdHeader = &EnvParams->StdHeader; + + RetrieveDataBlockFromInitReset (FchParams); + + // Update with external parameters + FchParams->Sd.SdConfig = EnvParams->FchInterface.SdConfig; + FchParams->Azalia.AzaliaEnable = EnvParams->FchInterface.AzaliaController; + FchParams->Ir.IrConfig = EnvParams->FchInterface.IrConfig; + FchParams->Ab.NbSbGen2 = EnvParams->FchInterface.UmiGen2; + FchParams->Sata.SataClass = EnvParams->FchInterface.SataClass; + FchParams->Sata.SataMode.SataEnable = EnvParams->FchInterface.SataEnable; + FchParams->Sata.SataMode.IdeEnable = EnvParams->FchInterface.IdeEnable; + FchParams->Sata.SataIdeMode = EnvParams->FchInterface.SataIdeMode; + FchParams->Usb.Ohci1Enable = EnvParams->FchInterface.Ohci1Enable; + FchParams->Usb.Ehci1Enable = EnvParams->FchInterface.Ohci1Enable; + FchParams->Usb.Ohci2Enable = EnvParams->FchInterface.Ohci2Enable; + FchParams->Usb.Ehci2Enable = EnvParams->FchInterface.Ohci2Enable; + FchParams->Usb.Ohci3Enable = EnvParams->FchInterface.Ohci3Enable; + FchParams->Usb.Ehci3Enable = EnvParams->FchInterface.Ohci3Enable; + FchParams->Usb.Ohci4Enable = EnvParams->FchInterface.Ohci4Enable; + FchParams->HwAcpi.PwrFailShadow = EnvParams->FchInterface.FchPowerFail; + FchParams->HwAcpi.Smbus0BaseAddress = UserOptions.FchBldCfg->CfgSmbus0BaseAddress; + FchParams->HwAcpi.Smbus1BaseAddress = UserOptions.FchBldCfg->CfgSmbus1BaseAddress; + FchParams->HwAcpi.SioPmeBaseAddress = UserOptions.FchBldCfg->CfgSioPmeBaseAddress; + FchParams->HwAcpi.AcpiPm1EvtBlkAddr = UserOptions.FchBldCfg->CfgAcpiPm1EvtBlkAddr; + FchParams->HwAcpi.AcpiPm1CntBlkAddr = UserOptions.FchBldCfg->CfgAcpiPm1CntBlkAddr; + FchParams->HwAcpi.AcpiPmTmrBlkAddr = UserOptions.FchBldCfg->CfgAcpiPmTmrBlkAddr; + FchParams->HwAcpi.CpuControlBlkAddr = UserOptions.FchBldCfg->CfgCpuControlBlkAddr; + FchParams->HwAcpi.AcpiGpe0BlkAddr = UserOptions.FchBldCfg->CfgAcpiGpe0BlkAddr; + FchParams->HwAcpi.SmiCmdPortAddr = UserOptions.FchBldCfg->CfgSmiCmdPortAddr; + FchParams->HwAcpi.AcpiPmaCntBlkAddr = UserOptions.FchBldCfg->CfgAcpiPmaCntBlkAddr; + FchParams->HwAcpi.WatchDogTimerBase = UserOptions.FchBldCfg->CfgWatchDogTimerBase; + FchParams->Sata.SataRaid5Ssid = UserOptions.FchBldCfg->CfgSataRaid5Ssid; + FchParams->Sata.SataRaidSsid = UserOptions.FchBldCfg->CfgSataRaidSsid; + FchParams->Sata.SataAhciSsid = UserOptions.FchBldCfg->CfgSataAhciSsid; + FchParams->Sata.SataIdeSsid = UserOptions.FchBldCfg->CfgSataIdeSsid; + FchParams->Spi.RomBaseAddress = UserOptions.FchBldCfg->CfgSpiRomBaseAddress; + FchParams->Sd.SdSsid = UserOptions.FchBldCfg->CfgSdSsid; + FchParams->Spi.LpcSsid = UserOptions.FchBldCfg->CfgLpcSsid; + FchParams->Hpet.HpetBase = UserOptions.FchBldCfg->CfgHpetBaseAddress; + FchParams->Azalia.AzaliaSsid = UserOptions.FchBldCfg->CfgAzaliaSsid; + FchParams->Smbus.SmbusSsid = UserOptions.FchBldCfg->CfgSmbusSsid; + FchParams->Ide.IdeSsid = UserOptions.FchBldCfg->CfgIdeSsid; + FchParams->Usb.EhciSsid = UserOptions.FchBldCfg->CfgEhciSsid; + FchParams->Usb.OhciSsid = UserOptions.FchBldCfg->CfgOhciSsid; + FchParams->Usb.XhciSsid = UserOptions.FchBldCfg->CfgXhciSsid; + FchParams->Ir.IrPinControl = UserOptions.FchBldCfg->CfgFchIrPinControl; + FchParams->Sd.SdClockControl = UserOptions.FchBldCfg->CfgFchSdClockControl; + return FchParams; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/InitResetDef.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/InitResetDef.c new file mode 100644 index 0000000000..9cbffd75b5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Interface/InitResetDef.c @@ -0,0 +1,90 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Fch Init during POWER-ON + * + * Prepare Fch environment during power on stage. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ + +#include "FchPlatform.h" +#include "Ids.h" +#include "heapManager.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_INTERFACE_INITRESETDEF_FILECODE + +extern FCH_RESET_DATA_BLOCK InitResetCfgDefault; + +FCH_RESET_DATA_BLOCK* +FchInitResetLoadPrivateDefault ( + IN AMD_RESET_PARAMS *ResetParams + ); + +FCH_RESET_DATA_BLOCK* +FchInitResetLoadPrivateDefault ( + IN AMD_RESET_PARAMS *ResetParams + ) +{ + FCH_RESET_DATA_BLOCK *FchParams; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + AGESA_STATUS AgesaStatus; + + // First allocate internal data block via heap manager + AllocHeapParams.RequestedBufferSize = sizeof (FCH_RESET_DATA_BLOCK); + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + AllocHeapParams.BufferHandle = AMD_FCH_RESET_DATA_BLOCK_HANDLE; + AgesaStatus = HeapAllocateBuffer (&AllocHeapParams, &ResetParams->StdHeader); + ASSERT (!AgesaStatus); + + FchParams = (FCH_RESET_DATA_BLOCK *) AllocHeapParams.BufferPtr; + ASSERT (FchParams != NULL); + IDS_HDT_CONSOLE (FCH_TRACE, " FCH Reset Data Block Allocation: [0x%x], Ptr = 0x%08x\n", AgesaStatus, FchParams); + + *FchParams = InitResetCfgDefault; + + FchParams->Gpp.GppLinkConfig = UserOptions.FchBldCfg->CfgFchGppLinkConfig; + FchParams->Gpp.PortCfg[0].PortPresent = UserOptions.FchBldCfg->CfgFchGppPort0Present; + FchParams->Gpp.PortCfg[1].PortPresent = UserOptions.FchBldCfg->CfgFchGppPort1Present; + FchParams->Gpp.PortCfg[2].PortPresent = UserOptions.FchBldCfg->CfgFchGppPort2Present; + FchParams->Gpp.PortCfg[3].PortPresent = UserOptions.FchBldCfg->CfgFchGppPort3Present; + FchParams->Gpp.PortCfg[0].PortHotPlug = UserOptions.FchBldCfg->CfgFchGppPort0HotPlug; + FchParams->Gpp.PortCfg[1].PortHotPlug = UserOptions.FchBldCfg->CfgFchGppPort1HotPlug; + FchParams->Gpp.PortCfg[2].PortHotPlug = UserOptions.FchBldCfg->CfgFchGppPort2HotPlug; + FchParams->Gpp.PortCfg[3].PortHotPlug = UserOptions.FchBldCfg->CfgFchGppPort3HotPlug; + + return FchParams; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbEnv.c new file mode 100644 index 0000000000..f8afabcf31 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbEnv.c @@ -0,0 +1,79 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Ab Bridge + * + * Init Ab Bridge features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_ABENV_FILECODE + +/** + * FchInitEnvAb - Config Ab Bridge before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvAb ( + IN VOID *FchDataPtr + ) +{ + FchInitEnvAbLinkInit (FchDataPtr); +} + +/** + * FchInitEnvAbSpecial - Config Ab Bridge special timing + * + * This routine must separate with FchInitEnvAb and give Ab + * bridge little time to get ready + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvAbSpecial ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbLate.c new file mode 100644 index 0000000000..7cbd3a3c78 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbLate.c @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Ab Bridge + * + * Init Ab Bridge features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_ABLATE_FILECODE + +/** + * FchInitLateAb - Prepare Ab Bridge to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateAb ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + FchAbLateProgram (FchDataPtr); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbMid.c new file mode 100644 index 0000000000..ee53b580b9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbMid.c @@ -0,0 +1,62 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Ab Bridge + * + * Init Ab Bridge features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_ABMID_FILECODE + +/** + * FchInitMidAb - Config Ab Bridge after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidAb ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbReset.c new file mode 100644 index 0000000000..0b96daf07d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/AbReset.c @@ -0,0 +1,64 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Ab Bridge + * + * Init Ab Bridge features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#include "FchDef.h" +#define FILECODE PROC_FCH_PCIE_ABRESET_FILECODE + +/** + * FchInitResetAb - Config Ab Bridge during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetAb ( + IN VOID *FchDataPtr + ) +{ + FchProgramAbPowerOnReset (FchDataPtr); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbEnvService.c new file mode 100644 index 0000000000..c274849748 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbEnvService.c @@ -0,0 +1,253 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config YANGTZE AB + * + * Init AB bridge. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87890 $ @e \$Date: 2013-02-12 13:09:22 -0600 (Tue, 12 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_FAMILY_YANGTZE_YANGTZEABENVSERVICE_FILECODE + +// +// Declaration of local functions +// +VOID AbCfgTbl (IN AB_TBL_ENTRY *ABTbl, IN AMD_CONFIG_PARAMS *StdHeader); + +/** + * YangtzeInitEnvAbTable - AB-Link Configuration Table for Yangtze + * + */ +AB_TBL_ENTRY YangtzeInitEnvAbTable[] = +{ + // + // Controls the USB OHCI controller prefetch used for enhancing performance of ISO out devices. + // Setting B-Link Prefetch Mode (ABCFG 0x80 [18:17] = 11) + // + {ABCFG, FCH_ABCFG_REG80, BIT0 + BIT17 + BIT18, BIT0 + BIT17 + BIT18}, + + // + // Enabled SMI ordering enhancement. ABCFG 0x90[21] + // USB Delay A-Link Express L1 State. ABCFG 0x90[17] + // + {ABCFG, FCH_ABCFG_REG90, BIT21, BIT21}, + + // + // Enabling Detection of Upstream Interrupts ABCFG 0x94 [20] = 1 + // ABCFG 0x94 [19:0] = cpu interrupt delivery address [39:20] + // + {ABCFG, FCH_ABCFG_REG94, BIT20, BIT20 + 0x00FEE}, + + // + // Programming cycle delay for AB and BIF clock gating + // Enable the AB and BIF clock-gating logic. + // Enable the A-Link int_arbiter enhancement to allow the A-Link bandwidth to be used more efficiently + // + {ABCFG, FCH_ABCFG_REG10054, 0x00FFFFFF, 0x000007FF}, + {ABCFG, 0x98, 0x0003FF00, 0x00034700}, + + // + // Host Outstanding Completion Clock Gating + // + {ABCFG, 0x208, 0xFFFFFFEF, 0x00081000}, + + // + // SD ALink prefetch + // + {ABCFG, 0x10060ul, 0xFBFFFFFF, 0}, + + {ABCFG, FCH_ABCFG_REG10090, BIT16, BIT16}, + {ABCFG, 0, 0, (UINT8) 0xFF}, /// This dummy entry is to clear ab index + { (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF}, +}; + +/** + * FchInitEnvAbLinkInit - Set ABCFG registers before PCI + * emulation. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvAbLinkInit ( + IN VOID *FchDataPtr + ) +{ + UINT16 AbTempVar; + UINT8 AbValue8; + AB_TBL_ENTRY *AbTblPtr; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + // AB CFG programming + // + if ( LocalCfgPtr->Ab.SlowSpeedAbLinkClock ) { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, (UINT32)~BIT1, BIT1); + } else { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, (UINT32)~BIT1, 0); + } + + // + // Read Arbiter address, Arbiter address is in PMIO 6Ch + // + ReadMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG6C, AccessWidth16, &AbTempVar); + /// Write 0 to enable the arbiter + AbValue8 = 0; + LibAmdIoWrite (AccessWidth8, AbTempVar, &AbValue8, StdHeader); + + AbTblPtr = (AB_TBL_ENTRY *) (&YangtzeInitEnvAbTable[0]); + AbCfgTbl (AbTblPtr, StdHeader); + + if ( LocalCfgPtr->Ab.ResetCpuOnSyncFlood ) { + RwAlink (0x10050ul | (UINT32) (ABCFG << 29), (UINT32)~BIT2, BIT2, StdHeader); + } + + if ( LocalCfgPtr->Ab.AbClockGating ) { + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 4), (UINT32) (0x1 << 4), StdHeader); + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x1 << 24), StdHeader); + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 20), (UINT32) (0x1 << 20), StdHeader); + RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x3 << 24), (UINT32) (0x3 << 24), StdHeader); + RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 20), (UINT32) (0x1 << 20), StdHeader); + } else { + RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 20), 0, StdHeader); + RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x3 << 24), 0, StdHeader); + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 20), 0, StdHeader); + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), 0, StdHeader); + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 4), 0, StdHeader); + } + + if ( LocalCfgPtr->Ab.AbDmaMemoryWrtie3264B ) { + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 0), (UINT32) (0x0 << 0), StdHeader); + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 2), (UINT32) (0x1 << 2), StdHeader); + } else { + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 0), (UINT32) (0x1 << 0), StdHeader); + RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 2), (UINT32) 0x0, StdHeader); + } + + if ( LocalCfgPtr->Ab.AbMemoryPowerSaving ) { + RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x68, AccessWidth8, 0xFB, 0x00); + RwAlink (FCH_ABCFG_REG58 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 29), (UINT32) (0x1 << 29), StdHeader); + RwAlink (FCH_ABCFG_REG58 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 31), (UINT32) (0x1 << 31), StdHeader); + } else { + RwAlink (FCH_ABCFG_REG58 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x5 << 29), (UINT32) 0x0, StdHeader); + RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x68, AccessWidth8, 0xFB, 0x04); + } + + // + // A/B Clock Gate-OFF + // + if ( LocalCfgPtr->Ab.ALinkClkGateOff ) { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFE, BIT0); + } else { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFE, 0); + } + if ( LocalCfgPtr->Ab.BLinkClkGateOff ) { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFD, BIT1); + } else { + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFD, 0); + } + if ( LocalCfgPtr->Ab.ALinkClkGateOff | LocalCfgPtr->Ab.BLinkClkGateOff ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG04 + 2, AccessWidth8, 0xFE, BIT0); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG04 + 2, AccessWidth8, 0xFE, 0); + } + +} + +/** + * AbCfgTbl - Program ABCFG by input table. + * + * + * @param[in] ABTbl ABCFG config table. + * @param[in] StdHeader + * + */ +VOID +AbCfgTbl ( + IN AB_TBL_ENTRY *ABTbl, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 AbValue; + + while ( (ABTbl->RegType) != 0xFF ) { + if ( ABTbl->RegType == 0 ) { + AbValue = 0x30 | (ABTbl->RegType << 29); + WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader); + AbValue = 0x34 | (ABTbl->RegType << 29); + WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader); + } else if ( ABTbl->RegType == 2 ) { + AbValue = 0x38 | (ABTbl->RegType << 29); + WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader); + AbValue = 0x3C | (ABTbl->RegType << 29); + WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader); + } else { + AbValue = ABTbl->RegIndex | (ABTbl->RegType << 29); + WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader); + } + + ++ABTbl; + } + + // + //Clear ALink Access Index + // + AbValue = 0; + LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &AbValue, StdHeader); +} + +/** + * Is UMI One Lane GEN1 Mode? + * + * + * @retval TRUE or FALSE + * + */ +BOOLEAN +IsUmiOneLaneGen1Mode ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return (TRUE); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbResetService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbResetService.c new file mode 100644 index 0000000000..506521d54a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbResetService.c @@ -0,0 +1,71 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze AB + * + * Init AB bridge. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_FAMILY_YANGTZE_YANGTZEABRESETSERVICE_FILECODE + + +/** + * FchProgramAbPowerOnReset - Config Ab Bridge during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchProgramAbPowerOnReset ( + IN VOID *FchDataPtr + ) +{ + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGE0, AccessWidth32, 00, ALINK_ACCESS_INDEX); + +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbService.c new file mode 100644 index 0000000000..bc29f4fc76 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/Family/Yangtze/YangtzeAbService.c @@ -0,0 +1,68 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze AB + * + * Init AB bridge. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_FAMILY_YANGTZE_YANGTZEABSERVICE_FILECODE + +VOID +FchGppDynamicPowerSaving ( + IN FCH_GPP *FchGpp, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ +} + +/** + * FchAbLateProgram - Set ABCFG registers during late POST + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchAbLateProgram ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieEnv.c new file mode 100644 index 0000000000..b77d2ee0e7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieEnv.c @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Pcie controller + * + * Init Pcie Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#include "FchDef.h" +#define FILECODE PROC_FCH_PCIE_PCIEENV_FILECODE + +/** + * FchInitEnvPcie - Config Pcie before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvPcie ( + IN VOID *FchDataPtr + ) +{ + // + // PCIE Native setting + // + ProgramPcieNativeMode (FchDataPtr); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieLate.c new file mode 100644 index 0000000000..a3639c705c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieLate.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Pcie controller + * + * Init Pcie Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_PCIELATE_FILECODE + +/** + * FchInitLatePcie - Prepare Pcie to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLatePcie ( + IN VOID *FchDataPtr + ) +{ +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieMid.c new file mode 100644 index 0000000000..12b8298f8d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieMid.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Pcie controller + * + * Init Pcie Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_PCIEMID_FILECODE + +/** + * FchInitMidPcie - Config Pcie after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidPcie ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieReset.c new file mode 100644 index 0000000000..e874420ae5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Pcie/PcieReset.c @@ -0,0 +1,63 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Pcie Component + * + * Init Pcie features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_PCIE_PCIERESET_FILECODE + +/** + * FchInitResetPcie - Config Pcie controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetPcie ( + IN VOID *FchDataPtr + ) +{ +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciEnv.c new file mode 100644 index 0000000000..0109f58f1e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciEnv.c @@ -0,0 +1,86 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (AHCI mode) + * + * Init SATA AHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_AHCIENV_FILECODE + +/** + * FchInitEnvSataAhci - Config SATA Ahci controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvSataAhci ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + // Class code + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x08), AccessWidth32, 0, 0x01060140, StdHeader); + // + // Device ID + // + if ( LocalCfgPtr->Sata.SataClass == SataAhci7804 ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x02), AccessWidth16, 0, FCH_SATA_AMDAHCI_DID, StdHeader); + } else { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x02), AccessWidth16, 0, FCH_SATA_AHCI_DID, StdHeader); + } + // + // SSID + // + if (LocalCfgPtr->Sata.SataAhciSsid != 0 ) { + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x2C, AccessWidth32, 0x00, LocalCfgPtr->Sata.SataAhciSsid, StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciLate.c new file mode 100644 index 0000000000..73dc4f7370 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciLate.c @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (AHCI mode) + * + * Init SATA AHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_AHCILATE_FILECODE + +/** + * FchInitLateSataAhci - Prepare SATA AHCI controller to boot to + * OS. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateSataAhci ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + SataBar5setting (LocalCfgPtr, &Bar5); + ShutdownUnconnectedSataPortClock (LocalCfgPtr, Bar5); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciLib.c new file mode 100644 index 0000000000..60f08991f2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciLib.c @@ -0,0 +1,68 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Fch SATA AHCI controller Library + * + * SATA AHCI Library + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_AHCILIB_FILECODE + +/** + * sataAhciSetDeviceNumMsi - Program AHCI controller support + * device number cap & MSI cap + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +SataAhciSetDeviceNumMsi ( + IN VOID *FchDataPtr + ) +{ + + FCH_INTERFACE *LocalCfgPtr; + + LocalCfgPtr = (FCH_INTERFACE *)FchDataPtr; + + SataSetDeviceNumMsi (LocalCfgPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciMid.c new file mode 100644 index 0000000000..dcffca50a6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/AhciMid.c @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (AHCI mode) + * + * Init SATA AHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_AHCIMID_FILECODE + +/** + * FchInitMidSataAhci - Config SATA Ahci controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidSataAhci ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + SataAhciSetDeviceNumMsi (LocalCfgPtr); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataEnvService.c new file mode 100644 index 0000000000..8abcac0f8a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataEnvService.c @@ -0,0 +1,224 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * SATA Controller family specific service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 86583 $ @e \$Date: 2013-01-23 12:31:06 -0600 (Wed, 23 Jan 2013) $ + * + */ + +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +*/ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_FAMILY_YANGTZE_YANGTZESATAENVSERVICE_FILECODE + + +SATA_PHY_SETTING SataPhyTable[] = +{ + {0x0030, 0x0040F407}, + {0x0120, 0x00403204}, + {0x0110, 0x00403103}, + + {0x0031, 0x0040F407}, + {0x0121, 0x00403204}, + {0x0111, 0x00403103}, + +}; + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +// +// Local Routine +// +VOID FchSataCombineControlDataByte (IN UINT8 *ControlReg); +VOID FchSataCombineControlDataWord (IN UINT16 *ControlReg); + + +/** + * FchInitEnvProgramSataPciRegs - Sata Pci Configuration Space + * register setting + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvProgramSataPciRegs ( + IN VOID *FchDataPtr + ) +{ + UINT8 *PortRegByte; + UINT16 *PortRegWord; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + // + //Caculate SataPortReg for SATA_ESP_PORT + // + PortRegByte = &(LocalCfgPtr->Sata.SataEspPort.SataPortReg); + FchSataCombineControlDataByte (PortRegByte); + PortRegByte = &(LocalCfgPtr->Sata.SataPortPower.SataPortReg); + FchSataCombineControlDataByte (PortRegByte); + PortRegWord = &(LocalCfgPtr->Sata.SataPortMd.SataPortMode); + FchSataCombineControlDataWord (PortRegWord); + PortRegByte = &(LocalCfgPtr->Sata.SataHotRemovalEnhPort.SataPortReg); + FchSataCombineControlDataByte (PortRegByte); + + // + // Set Sata PCI Configuration Space Write enable + // + SataEnableWriteAccess (StdHeader); + + // * + // Enables the SATA watchdog timer register prior to the SATA BIOS post + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x44), AccessWidth8, 0xff, BIT0, StdHeader); + + // * + // SATA PCI Watchdog timer setting + // Set timer out to 0x20 to fix IDE to SATA Bridge dropping drive issue. + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x44 + 2), AccessWidth8, 0, 0x20, StdHeader); + + // + // BIT4: Enable fast boot (SpeedupXPBoot) + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth8, 0xef, 0, StdHeader); + + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x48 + 3), AccessWidth8, 0xff, BIT7, StdHeader); + + // + // Unused SATA Ports Disabled + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040 + 2), AccessWidth8, 0, LocalCfgPtr->Sata.SataPortPower.SataPortReg, StdHeader); + + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x084), AccessWidth32, (UINT32) (~ (0x01 << 31)), (UINT32) (0x00 << 31), StdHeader); +} + +/** + * FchSataCombineControlDataByte - Combine port control options + * to one control byte. + * + * + * @param[in] *ControlReg - Data pointer for control byte. + * + */ +VOID +FchSataCombineControlDataByte ( + IN UINT8 *ControlReg + ) +{ + UINT8 Index; + UINT8 PortControl; + + *ControlReg = 0; + for ( Index = 0; Index < 8; Index++ ) { + PortControl = *( ControlReg + 1 + Index ); + *ControlReg |= PortControl << Index; + } +} +/** + * FchSataCombineControlDataWord - Combine port control options + * to one control Word. + * + * + * @param[in] *ControlReg - Data pointer for control byte. + * + */ +VOID +FchSataCombineControlDataWord ( + IN UINT16 *ControlReg + ) +{ + UINT8 Index; + UINT8 PortControl; + + *ControlReg = 0; + for ( Index = 0; Index < 8; Index++ ) { + PortControl = *( (UINT8 *)ControlReg + 2 + Index ); + *ControlReg |= PortControl << (Index * 2); + } +} + +/** + * FchProgramSataPhy - Program Sata PHY registers + * + * @param[in] StdHeader + * + */ +VOID +FchProgramSataPhy ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + SATA_PHY_SETTING *PhyTablePtr; + UINT16 Index; + UINT32 SquelchValue[2]; + UINT8 PortNum; + + PhyTablePtr = &SataPhyTable[0]; + + for (Index = 0; Index < (sizeof (SataPhyTable) / sizeof (SATA_PHY_SETTING)); Index++) { + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x080, AccessWidth16, 0xFC00, PhyTablePtr->PhyCoreControlWord, StdHeader); + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x98, AccessWidth32, 0x00, PhyTablePtr->PhyFineTuneDword, StdHeader); + ++PhyTablePtr; + } + SquelchValue[0] = (0x07 << 9); + SquelchValue[1] = (0x07 << 9); + for (PortNum = 0; PortNum < 2; PortNum ++) { + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x080, AccessWidth16, 0x00, ( 0x130 + PortNum), StdHeader); + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x09C, AccessWidth32, (UINT32) (~(0x7 << 9)), SquelchValue[PortNum], StdHeader); + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x09C, AccessWidth32, (UINT32) (~(0x7 << 13)), (UINT32) (0x0 << 13), StdHeader); + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x080, AccessWidth16, 0x00, ( 0x120 + PortNum), StdHeader); + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x09C, AccessWidth32, (UINT32) (~(0x7 << 9)), SquelchValue[PortNum], StdHeader); + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x080, AccessWidth16, 0x00, ( 0x110 + PortNum), StdHeader); + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x09C, AccessWidth32, (UINT32) (~(0x7 << 9)), SquelchValue[PortNum], StdHeader); + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x080, AccessWidth16, 0x00, 0x010, StdHeader); + } +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataResetService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataResetService.c new file mode 100644 index 0000000000..9b1446783e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataResetService.c @@ -0,0 +1,125 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Sata controller + * + * Init Sata Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 86582 $ @e \$Date: 2013-01-23 12:25:55 -0600 (Wed, 23 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_FAMILY_YANGTZE_YANGTZESATARESETSERVICE_FILECODE + +/** + * FchInitResetSataProgram - Config Sata controller during + * Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetSataProgram ( + IN VOID *FchDataPtr + ) +{ + UINT8 FchSataMode; + UINT8 FchSataClkMode; + + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + //New structure need calculate Sata Register value + // + FchSataMode = 0; + if ( LocalCfgPtr->FchReset.SataEnable ) { + FchSataMode |= 0x01; + } + if ( LocalCfgPtr->SataSetMaxGen2 ) { + FchSataMode |= 0x04; + } + FchSataMode |= 0x04; + + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x0A0), AccessWidth8, (UINT32)~(BIT2 + BIT3 + BIT4 + BIT5 + BIT6), 0, StdHeader); + FchSataClkMode = LocalCfgPtr->SataClkMode; + // + // Sata Setting for clock mode only + // + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDA, AccessWidth8, 0, FchSataMode); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDA, AccessWidth8, 0x0F, (FchSataClkMode << 4)); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x084 + 3), AccessWidth8, (UINT32)~BIT2, BIT2, StdHeader); + + // + // For Yangtze design (reference board) is connected both external and internal clock. + // Sata clock mode will set by AGESA FCH (FCH_RESET_DATA_BLOCK) SataClkMode. + // + switch ( FchSataClkMode ) { + case 0: + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x08C), AccessWidth32, 0xFFFFFF00, 0xF0, StdHeader); + break; + case 1: + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x08C), AccessWidth32, 0xFFFFFF00, 0x7D, StdHeader); + break; + case 9: + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x08C), AccessWidth32, 0xFFFFFF00, 0xF0, StdHeader); + break; + } + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x088), AccessWidth32, 0x0FFFFFFF, 0x20000000, StdHeader); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDC + 2, AccessWidth8, 0xFE, 0x01); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x084), AccessWidth32, 0xFFFFFFFB, 0x00, StdHeader); + FchStall (1000, StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x084), AccessWidth32, 0xFFFFFFFF, 0x04, StdHeader); + if ( LocalCfgPtr->FchReset.SataEnable ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x04C), AccessWidth32, 0xFDFDFCFE, 0x02020301, StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth32, (UINT32) (~ (0x3 << 1)), (UINT32) (0x00 << 1), StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x48), AccessWidth32, 0x00, 0xC0070800, StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth32, (UINT32) (~ (0x3 << 1)), (UINT32) (0x01 << 1), StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x48), AccessWidth32, 0x00, 0x2188, StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth32, (UINT32) (~ (0x3 << 1)), (UINT32) (0x02 << 1), StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x48), AccessWidth32, 0x00, 0x10EA, StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth32, (UINT32) (~ (0x1 << 13)), (UINT32) (0x01 << 13), StdHeader); + + } +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataService.c new file mode 100644 index 0000000000..ab3bbab37a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Family/Yangtze/YangtzeSataService.c @@ -0,0 +1,699 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Graphics Controller family specific service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87699 $ @e \$Date: 2013-02-07 12:51:09 -0600 (Thu, 07 Feb 2013) $ + * + */ + +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +*/ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_FAMILY_YANGTZE_YANGTZESATASERVICE_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +UINT8 NumOfSataPorts = 2; + +/** + * FchSataGpioInitial - Sata GPIO function Procedure + * + * - Private function + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchSataGpioInitial ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + UINT32 FchSataBarRegDword; + UINT32 EMb; + UINT32 SataEMbVariableDword; + UINT8 FchSataSgpio0; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + Bar5 = 0; + EMb = 0; + FchSataSgpio0 = (UINT8) LocalCfgPtr->Sata.SataSgpio0; + + SataBar5setting (LocalCfgPtr, &Bar5); + ReadMem (Bar5 + 0x1C , AccessWidth32, &FchSataBarRegDword); + EMb = (Bar5 + (( FchSataBarRegDword & 0xFFFF0000) >> 14)); + + if ( EMb ) { + SataEMbVariableDword = 0x03040C00; + WriteMem ( Bar5 + EMb, AccessWidth32, &SataEMbVariableDword); + SataEMbVariableDword = 0x00C08240; + WriteMem ( Bar5 + EMb + 4, AccessWidth32, &SataEMbVariableDword); + SataEMbVariableDword = 0x00000001; + WriteMem ( Bar5 + EMb + 8, AccessWidth32, &SataEMbVariableDword); + + if ( FchSataSgpio0 ) { + SataEMbVariableDword = 0x00000060; + } else { + SataEMbVariableDword = 0x00000061; + } + + WriteMem ( Bar5 + EMb + 0x0C, AccessWidth32, &SataEMbVariableDword); + RwMem ((Bar5 + 0x20), AccessWidth16, (UINT32)~(BIT8), BIT8); + + do { + ReadMem (Bar5 + 0x20 , AccessWidth32, &FchSataBarRegDword); + FchSataBarRegDword = FchSataBarRegDword & BIT8; + } while ( FchSataBarRegDword != 0 ); + + SataEMbVariableDword = 0x03040F00; + WriteMem ( Bar5 + EMb, AccessWidth32, &SataEMbVariableDword); + SataEMbVariableDword = 0x00008240; + WriteMem ( Bar5 + EMb + 4, AccessWidth32, &SataEMbVariableDword); + SataEMbVariableDword = 0x00000002; + WriteMem ( Bar5 + EMb + 8, AccessWidth32, &SataEMbVariableDword); + SataEMbVariableDword = 0x00800000; + WriteMem ( Bar5 + EMb + 0x0C, AccessWidth32, &SataEMbVariableDword); + SataEMbVariableDword = 0x0F003700; + WriteMem ( Bar5 + EMb + 0x0C, AccessWidth32, &SataEMbVariableDword); + RwMem ((Bar5 + 0x20), AccessWidth16, (UINT32)~(BIT8), BIT8); + + do { + ReadMem (Bar5 + 0x20 , AccessWidth32, &FchSataBarRegDword); + FchSataBarRegDword = FchSataBarRegDword & BIT8; + } while ( FchSataBarRegDword != 0 ); + } +} + +/** + * FchInitMidProgramSataRegs - Sata Pci Configuration Space + * register setting + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidProgramSataRegs ( + IN VOID *FchDataPtr + ) +{ + UINT8 FchSataMsiCapability; + UINT8 FchSataTargetSupport8Device; + UINT8 FchSataDisableGenericMode; + UINT8 FchSataSgpio0; + UINT8 FchSataSgpio1; + UINT8 FchSataPhyPllShutDown; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + FchSataMsiCapability = (UINT8) LocalCfgPtr->Sata.SataMsiCapability; + FchSataTargetSupport8Device = (UINT8) LocalCfgPtr->Sata.SataTargetSupport8Device; + FchSataDisableGenericMode = (UINT8) LocalCfgPtr->Sata.SataDisableGenericMode; + FchSataSgpio0 = (UINT8) LocalCfgPtr->Sata.SataSgpio0; + FchSataSgpio1 = (UINT8) LocalCfgPtr->Sata.SataSgpio1; + FchSataPhyPllShutDown = (UINT8) LocalCfgPtr->Sata.SataPhyPllShutDown; + + if ((LocalCfgPtr->Sata.SataClass == SataNativeIde) || (LocalCfgPtr->Sata.SataClass == SataLegacyIde)) { + FchSataMsiCapability = 0; + } + // + // Enabled SATA MSI capability + // SATA MSI and D3 Power State Capability MMC 0x2 + // + if ( !FchSataMsiCapability ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x70 + 1), AccessWidth8, 0, 0, StdHeader); + } + + // + // Sata Target Support 8 devices function + // + if ( FchSataTargetSupport8Device ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDA, AccessWidth16, (UINT32)~BIT12, BIT12); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDA, AccessWidth16, (UINT32)~BIT12, 0x00); + } + + // + // Sata Generic Mode setting + // + if ( FchSataDisableGenericMode ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDA, AccessWidth16, (UINT32)~BIT13, BIT13); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDA, AccessWidth16, (UINT32)~BIT13, 0x00); + } + + // + // Sata GPIO Initial + // + if ( FchSataSgpio0 ) { + FchSataGpioInitial ( LocalCfgPtr ); + } + + if ( FchSataSgpio1 ) { + FchSataGpioInitial ( LocalCfgPtr ); + } + + // + // Sata Phy Pll Shutdown setting + // + if ( FchSataPhyPllShutDown ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x87), AccessWidth8, (UINT32)~(BIT6), BIT6, StdHeader); + } else { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x87), AccessWidth8, (UINT32)~(BIT6), 0x00, StdHeader); + } + + //RwPci (((SATA_BUS_DEV_FUN << 16) + 0x4C), AccessWidth32, (UINT32) (~ (0xF8 << 26)), (UINT32) (0xF8 << 26), StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x084), AccessWidth32, (UINT32) ((UINT32)~ (0x01 << 31)), (UINT32) (0x00 << 31), StdHeader); + + // + // OOB Detection Enhancement + // + if ( LocalCfgPtr->Sata.SataOobDetectionEnh ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDC + 1, AccessWidth8, 0xFE, 0x01); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDC + 1, AccessWidth8, 0xFE, 0); + } + + // + // E-Sata Power Saving Enhancement + // + //if ( LocalCfgPtr->Sata.SataPowerSavingEnh ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x04C + 3), AccessWidth8, (UINT32)~(BIT5), BIT5, StdHeader); + //} else { + // RwPci (((SATA_BUS_DEV_FUN << 16) + 0x4C + 3), AccessWidth8, (UINT32)~(BIT5), 0, StdHeader); + //} + + // + // Sata Memory Power Saving + // + switch ( LocalCfgPtr->Sata.SataMemoryPowerSaving ) { + case 0: + RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x68 + 2, AccessWidth8, 0xFD, 0); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x04C), AccessWidth32, (UINT32) (~ (0x1801)), (UINT32) 0x0001, StdHeader); + break; + case 1: + RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x68 + 2, AccessWidth8, 0xFD, 0); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x04C), AccessWidth32, (UINT32) (~ (0x1801)), (UINT32) 0x0800, StdHeader); + break; + case 2: + RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x68 + 2, AccessWidth8, 0xFD, 0); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x04C), AccessWidth32, (UINT32) (~ (0x1801)), (UINT32) 0x0801, StdHeader); + break; + case 3: + RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x68 + 2, AccessWidth8, 0xFD, BIT1); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x04C), AccessWidth32, (UINT32) (~ (0x1801)), (UINT32) 0x0000, StdHeader); + } +} + + +/** + * FchInitLateProgramSataRegs - Sata Pci Configuration Space + * register setting + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateProgramSataRegs ( + IN VOID *FchDataPtr + ) +{ + UINT8 PortNumByte; + UINT32 Bar5; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + SataBar5setting (LocalCfgPtr, &Bar5); + // + //Clear error status + // + RwMem ((Bar5 + 0x130), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF); + RwMem ((Bar5 + 0x1B0), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF); + + for ( PortNumByte = 0; PortNumByte < NumOfSataPorts; PortNumByte++ ) { + RwMem ((Bar5 + 0x110 + (PortNumByte * 0x80)), AccessWidth32, 0xFFFFFFFF, 0x00); + } + if ( LocalCfgPtr->Sata.SataDevSlpPort0 ) { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + FCH_GPIO_REG55, AccessWidth8, 0, 0x3E); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + FCH_GPIO_REG55, AccessWidth8, 0, 0x01); + RwMem ((Bar5 + 0x0F4), AccessWidth32, 0xFFFFFEEF, BIT4 + BIT8); + } else { + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + FCH_GPIO_REG55, AccessWidth8, 0, 0x00); + RwMem ((Bar5 + 0x0F4), AccessWidth32, 0xFFFFFEFF, 0); + if ( !LocalCfgPtr->Sata.SataDevSlpPort1 ) { + RwMem ((Bar5 + 0x0F4), AccessWidth32, 0xFFFFFFEF, 0); + } + } + if ( LocalCfgPtr->Sata.SataDevSlpPort1 ) { + RwMem (ACPI_MMIO_BASE + GPIO_BASE + FCH_GPIO_REG59, AccessWidth8, 0, 0x3E); + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + FCH_GPIO_REG59, AccessWidth8, 0, 0x01); + RwMem ((Bar5 + 0x0F4), AccessWidth32, 0xFFFFFDEF, BIT4 + BIT9); + } else { + RwMem (ACPI_MMIO_BASE + IOMUX_BASE + FCH_GPIO_REG59, AccessWidth8, 0, 0x00); + RwMem ((Bar5 + 0x0F4), AccessWidth32, 0xFFFFFDFF, 0); + if ( !LocalCfgPtr->Sata.SataDevSlpPort0 ) { + RwMem ((Bar5 + 0x0F4), AccessWidth32, 0xFFFFFFEF, 0); + } + } + if ( LocalCfgPtr->Sata.SataAhciDisPrefetchFunction ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth32, (UINT32) (~ (0x01 << 13)), (UINT32) (0x01 << 13), StdHeader); + } else { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth32, (UINT32) (~ (0x01 << 13)), 0, StdHeader); + } +} + +/** + * sataBar5RegSet - Sata Bar5 register setting + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +SataBar5RegSet ( + IN VOID *FchDataPtr + ) +{ + UINT32 AndMaskDword; + UINT32 OrMaskDword; + UINT32 Bar5; + UINT8 FchSataAggrLinkPmCap; + UINT8 FchSataPortMultCap; + UINT8 FchSataPscCap; + UINT8 FchSataSscCap; + UINT8 FchSataFisBasedSwitching; + UINT8 FchSataCccSupport; + UINT8 FchSataAhciEnclosureManagement; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + FchSataAggrLinkPmCap = (UINT8) LocalCfgPtr->Sata.SataAggrLinkPmCap; + FchSataPortMultCap = (UINT8) LocalCfgPtr->Sata.SataPortMultCap; + FchSataPscCap = (UINT8) LocalCfgPtr->Sata.SataPscCap; + FchSataSscCap = (UINT8) LocalCfgPtr->Sata.SataSscCap; + FchSataFisBasedSwitching = (UINT8) LocalCfgPtr->Sata.SataFisBasedSwitching; + FchSataCccSupport = (UINT8) LocalCfgPtr->Sata.SataCccSupport; + FchSataAhciEnclosureManagement = (UINT8) LocalCfgPtr->Sata.SataAhciEnclosureManagement; + + AndMaskDword = 0; + OrMaskDword = 0; + Bar5 = 0; + + SataBar5setting (LocalCfgPtr, &Bar5); + + if ( !FchSataPortMultCap ) { + AndMaskDword |= BIT12; + } + + if ( FchSataFisBasedSwitching ) { + AndMaskDword |= BIT10; + } else { + AndMaskDword |= BIT10; + } + + if ( FchSataAggrLinkPmCap ) { + OrMaskDword |= BIT11; + } else { + AndMaskDword |= BIT11; + } + + if ( FchSataPscCap ) { + OrMaskDword |= BIT1; + } else { + AndMaskDword |= BIT1; + } + + if ( FchSataSscCap ) { + OrMaskDword |= BIT26; + } else { + AndMaskDword |= BIT26; + } + + // + // Disabling CCC (Command Completion Coalescing) support. + // + if ( FchSataCccSupport ) { + OrMaskDword |= BIT19; + } else { + AndMaskDword |= BIT19; + } + + if ( FchSataAhciEnclosureManagement ) { + OrMaskDword |= BIT27; + } else { + AndMaskDword |= BIT27; + } + + RwMem ((Bar5 + 0x0FC), AccessWidth32, ~AndMaskDword, OrMaskDword); + + // + // SATA ESP port setting + // These config bits are set for SATA driver to identify which ports are external SATA ports and need to + // support hotplug. If a port is set as an external SATA port and need to support hotplug, then driver will + // not enable power management (HIPM & DIPM) for these ports. + // + if ( LocalCfgPtr->Sata.SataEspPort.SataPortReg != 0 ) { + RwMem ((Bar5 + 0x0F8), AccessWidth32, ~(LocalCfgPtr->Sata.SataEspPort.SataPortReg), 0); + RwMem ((Bar5 + 0x0F8), AccessWidth32, 0xFF00FF00, (LocalCfgPtr->Sata.SataEspPort.SataPortReg << 16)); + // + // External SATA Port Indication Registers + // If any of the ports was programmed as an external port, HCAP.SXS should also be set + // + RwMem ((Bar5 + 0x0FC), AccessWidth32, (UINT32)~(BIT20), BIT20); + } else { + // + // External SATA Port Indication Registers + // If any of the ports was programmed as an external port, HCAP.SXS should also be set (Clear for no ESP port) + // + RwMem ((Bar5 + 0x0F8), AccessWidth32, 0xFF00FF00, 0x00); + RwMem ((Bar5 + 0x0FC), AccessWidth32, (UINT32)~(BIT20), 0x00); + } + + if ( FchSataFisBasedSwitching ) { + RwMem ((Bar5 + 0x0F8), AccessWidth32, 0x00FFFFFF, 0x00); + } else { + RwMem ((Bar5 + 0x0F8), AccessWidth32, 0x00FFFFFF, 0x00); + } + + if ( LocalCfgPtr->Sata.BiosOsHandOff == 1 ) { + RwMem ((Bar5 + 0x24), AccessWidth8, (UINT32)~BIT0, BIT0); + } else { + RwMem ((Bar5 + 0x24), AccessWidth8, (UINT32)~BIT0, 0x00); + } +} + +/** + * FchSataSetDeviceNumMsi - Program Sata controller support + * device number cap & MSI cap + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchSataSetDeviceNumMsi ( + IN VOID *FchDataPtr + ) +{ +} + + +/** + * FchSataDriveDetection - Sata drive detection + * + * - Sata Ide & Sata Ide to Ahci only + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * @param[in] *Bar5Ptr Sata BAR5 base address. + * + */ +VOID +FchSataDriveDetection ( + IN VOID *FchDataPtr, + IN UINT32 *Bar5Ptr + ) +{ + UINT32 SataBarInfo; + UINT8 PortNumByte; + UINT8 SataPortType; + UINT16 IoBaseWord; + UINT32 SataLoopVarDWord; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + for ( PortNumByte = 0; PortNumByte < 4; PortNumByte++ ) { + + ReadMem (*Bar5Ptr + 0x128 + PortNumByte * 0x80, AccessWidth32, &SataBarInfo); + + if ( ( SataBarInfo & 0x0F ) == 0x03 ) { + if ( PortNumByte & BIT0 ) { + // + //this port belongs to secondary channel + // + ReadPci (((UINT32) (SATA_BUS_DEV_FUN << 16) + 0x18), AccessWidth16, &IoBaseWord, StdHeader); + } else { + // + //this port belongs to primary channel + // + ReadPci (((UINT32) (SATA_BUS_DEV_FUN << 16) + 0x10), AccessWidth16, &IoBaseWord, StdHeader); + } + + // + //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them + // + if ( LocalCfgPtr->Sata.SataClass == SataLegacyIde ) { + IoBaseWord = ( (0x170) | ((UINT16) ( (~((UINT8) (PortNumByte & BIT0) << 7)) & 0x80 )) ); + } + + if ( PortNumByte & BIT1 ) { + // + //this port is slave + // + SataPortType = 0xB0; + } else { + // + //this port is master + // + SataPortType = 0xA0; + } + + IoBaseWord &= 0xFFF8; + LibAmdIoWrite (AccessWidth8, IoBaseWord + 6, &SataPortType, StdHeader); + + // + //Wait in loop for 30s for the drive to become ready + // + for ( SataLoopVarDWord = 0; SataLoopVarDWord < 300000; SataLoopVarDWord++ ) { + LibAmdIoRead (AccessWidth8, IoBaseWord + 7, &SataPortType, StdHeader); + if ( (SataPortType & 0x88) == 0 ) { + break; + } + FchStall (100, StdHeader); + } + } + } +} + +/** + * FchShutdownUnconnectedSataPortClock - Shutdown unconnected + * Sata port clock + * + * - Sata Ide & Sata Ide to Ahci only + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * @param[in] Bar5 Sata BAR5 base address. + * + */ +VOID +FchShutdownUnconnectedSataPortClock ( + IN VOID *FchDataPtr, + IN UINT32 Bar5 + ) +{ + UINT8 PortNumByte; + UINT8 PortSataStatusByte; + UINT8 NumOfPorts; + UINT8 FchSataClkAutoOff; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + UINT8 SaveLocation; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + FchSataClkAutoOff = (UINT8) LocalCfgPtr->Sata.SataClkAutoOff; + + NumOfPorts = 0; + // + // Enable SATA auto clock control by default + // + if ( FchSataClkAutoOff ) { + if ((ReadFchSleepType (StdHeader) != ACPI_SLPTYP_S3)) { + for ( PortNumByte = 0; PortNumByte < NumOfSataPorts; PortNumByte++ ) { + ReadMem (Bar5 + 0x128 + (PortNumByte * 0x80), AccessWidth8, &PortSataStatusByte); + // + // Shutdown the clock for the port and do the necessary port reporting changes. + // Error port status should be 1 not 3 + // + if ( ((PortSataStatusByte & 0x0F) != 0x03) && (! ((LocalCfgPtr->Sata.SataEspPort.SataPortReg) & (1 << PortNumByte))) ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040 + 2), AccessWidth8, 0xFF, (1 << PortNumByte), StdHeader); + RwMem (Bar5 + 0x0C, AccessWidth8, ~(1 << PortNumByte), 00); + } + } ///end of for (PortNumByte=0;PortNumByte<6;PortNumByte++) + SaveLocation = 0; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG72, &SaveLocation, StdHeader); + ReadPci (((SATA_BUS_DEV_FUN << 16) + 0x040 + 2), AccessWidth8, &PortSataStatusByte, StdHeader); + SaveLocation = 1; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG73, &PortSataStatusByte, StdHeader); + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG72, &SaveLocation, StdHeader); + ReadMem (Bar5 + 0x0C, AccessWidth8, &PortSataStatusByte); + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG73, &PortSataStatusByte, StdHeader); + } else { + SaveLocation = 0; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG72, &SaveLocation, StdHeader); + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REG73, &PortSataStatusByte, StdHeader); + WritePci (((SATA_BUS_DEV_FUN << 16) + 0x040 + 2), AccessWidth8, &PortSataStatusByte, StdHeader); + SaveLocation = 1; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG72, &SaveLocation, StdHeader); + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REG73, &PortSataStatusByte, StdHeader); + RwMem (Bar5 + 0x0C, AccessWidth8, 0, PortSataStatusByte); + } + } + + ReadMem (Bar5 + 0x0C, AccessWidth8, &PortSataStatusByte); + + // + //if all ports are in disabled state, report at least one port + // + if ( (PortSataStatusByte & 0xFF) == 0) { + RwMem (Bar5 + 0x0C, AccessWidth8, (UINT32) ~(0xFF), 01); + } + + ReadMem (Bar5 + 0x0C, AccessWidth8, &PortSataStatusByte); + + for (PortNumByte = 0; PortNumByte < NumOfSataPorts; PortNumByte ++) { + if (PortSataStatusByte & (1 << PortNumByte)) { + NumOfPorts++; + } + } + + if ( NumOfPorts == 0) { + NumOfPorts = 0x01; + } + + RwMem (Bar5 + 0x00, AccessWidth8, 0xE0, NumOfPorts - 1); +} + +/** + * FchSataSetPortGenMode - Set Sata port mode (each) for + * Gen1/Gen2/Gen3 + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchSataSetPortGenMode ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + UINT8 PortNumByte; + UINT8 PortModeByte; + UINT16 SataPortMode; + BOOLEAN FchSataHotRemovalEnh; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + FchSataHotRemovalEnh = LocalCfgPtr->Sata.SataHotRemovalEnh; + + SataBar5setting (LocalCfgPtr, &Bar5); + SataPortMode = (UINT16)LocalCfgPtr->Sata.SataPortMd.SataPortMode; + PortNumByte = 0; + + while ( PortNumByte < 8 ) { + PortModeByte = (UINT8) (SataPortMode & 3); + if ( (PortModeByte == BIT0) || (PortModeByte == BIT1) ) { + if ( PortModeByte == BIT0 ) { + // + // set GEN 1 + // + RwMem (Bar5 + 0x12C + PortNumByte * 0x80, AccessWidth8, 0x0F, 0x10); + } + + if ( PortModeByte == BIT1 ) { + // + // set GEN2 (default is GEN3) + // + RwMem (Bar5 + 0x12C + PortNumByte * 0x80, AccessWidth8, 0x0F, 0x20); + } + + RwMem (Bar5 + 0x12C + PortNumByte * 0x80, AccessWidth8, 0xFF, 0x01); + } + + SataPortMode >>= 2; + PortNumByte ++; + } + + FchStall (1000, StdHeader); + SataPortMode = (UINT16)LocalCfgPtr->Sata.SataPortMd.SataPortMode; + PortNumByte = 0; + + while ( PortNumByte < 8 ) { + PortModeByte = (UINT8) (SataPortMode & 3); + + if ( (PortModeByte == BIT0) || (PortModeByte == BIT1) ) { + RwMem (Bar5 + 0x12C + PortNumByte * 0x80, AccessWidth8, 0xFE, 0x00); + } + + PortNumByte ++; + SataPortMode >>= 2; + } + + // + // Sata Hot Removal Enhance setting + // + if ( FchSataHotRemovalEnh ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + 0xDC, AccessWidth8, 0x7F, 0x80); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciEnv.c new file mode 100644 index 0000000000..517bec013a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciEnv.c @@ -0,0 +1,82 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (Ide2Ahci mode) + * + * Init SATA Ide2Ahci features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_IDE2AHCIENV_FILECODE + +/** + * FchInitEnvSataIde2Ahci - Config SATA Ide2Ahci controller + * before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvSataIde2Ahci ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + // Class code + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x08), AccessWidth32, 0, 0x01018F40, StdHeader); + // + // Device ID + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x02), AccessWidth16, 0, FCH_SATA_DID, StdHeader); + // + // SSID + // + if (LocalCfgPtr->Sata.SataAhciSsid != 0 ) { + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x2C, AccessWidth32, 0x00, LocalCfgPtr->Sata.SataAhciSsid, StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLate.c new file mode 100644 index 0000000000..2d11bc012d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLate.c @@ -0,0 +1,89 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (Ide2Ahci mode) + * + * Init SATA Ide2Ahci features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_IDE2AHCILATE_FILECODE + +/** + * FchInitLateSataIde2Ahci - Prepare SATA Ide2Ahci controller to + * boot to OS. + * + * - Set class ID to Ide2Ahci (if set to Ide2Ahci * Mode) + * - Enable Ide2Ahci interrupt + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateSataIde2Ahci ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + //program the AHCI class code + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x08), AccessWidth32, 0, 0x01060100, StdHeader); + // + // Device ID + // + if ( LocalCfgPtr->Sata.SataClass == SataIde2Ahci7804 ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x02), AccessWidth16, 0, FCH_SATA_AMDAHCI_DID, StdHeader); + } else { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x02), AccessWidth16, 0, FCH_SATA_AHCI_DID, StdHeader); + } + SataBar5setting (LocalCfgPtr, &Bar5); + + // + //Set interrupt enable bit + // + RwMem ((Bar5 + 0x04), AccessWidth8, (UINT32)~0, BIT1); + ShutdownUnconnectedSataPortClock (LocalCfgPtr, Bar5); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLib.c new file mode 100644 index 0000000000..dd571988c2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciLib.c @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Fch SATA Ide2Ahci controller Library + * + * SATA Ide2Ahci Library + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_IDE2AHCILIB_FILECODE + +/** + * sataIde2AhciSetDeviceNumMsi - Program Ide2Ahci controller support + * device number cap & MSI cap + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +SataIde2AhciSetDeviceNumMsi ( + IN VOID *FchDataPtr + ) +{ + FCH_INTERFACE *LocalCfgPtr; + + LocalCfgPtr = (FCH_INTERFACE *)FchDataPtr; + + SataSetDeviceNumMsi (LocalCfgPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciMid.c new file mode 100644 index 0000000000..c4eb4ce97f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/Ide2AhciMid.c @@ -0,0 +1,76 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (Ide2Ahci mode) + * + * Init SATA Ide2Ahci features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_IDE2AHCIMID_FILECODE + +/** + * FchInitMidSataIde2Ahci - Config SATA Ide2Ahci controller + * after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidSataIde2Ahci ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + SataIde2AhciSetDeviceNumMsi (LocalCfgPtr); + + SataBar5setting (LocalCfgPtr, &Bar5); + // + //If this is not S3 resume and also if SATA set to one of IDE mode, them implement drive detection workaround. + // + if ( ! (LocalCfgPtr->Misc.S3Resume) ) { + SataDriveDetection (LocalCfgPtr, &Bar5); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidEnv.c new file mode 100644 index 0000000000..d91a572b3e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidEnv.c @@ -0,0 +1,74 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (Raid mode) + * + * Init SATA Raid features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_RAIDENV_FILECODE + + +// +// Declaration of local functions +// + +/** + * FchInitEnvSataRaid - Config SATA Raid controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvSataRaid ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidLate.c new file mode 100644 index 0000000000..0de856d9e0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidLate.c @@ -0,0 +1,65 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (Raid mode) + * + * Init SATA Raid features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_RAIDLATE_FILECODE +// +// Declaration of local functions +// + +/** + * FchInitLateSataRaid - Prepare SATA Raid controller to boot to + * OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateSataRaid ( + IN VOID *FchDataPtr + ) +{ +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidLib.c new file mode 100644 index 0000000000..26daf805bc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidLib.c @@ -0,0 +1,69 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Fch SATA AHCI/RAID controller Library + * + * SATA AHCI/RAID Library + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_RAIDLIB_FILECODE + +/** + * sataRaidSetDeviceNumMsi - Program RAID controller support + * device number cap & MSI cap + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +SataRaidSetDeviceNumMsi ( + IN VOID *FchDataPtr + ) +{ + FCH_INTERFACE *LocalCfgPtr; + + LocalCfgPtr = (FCH_INTERFACE *)FchDataPtr; + + SataSetDeviceNumMsi (LocalCfgPtr); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidMid.c new file mode 100644 index 0000000000..68af1ba181 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/RaidMid.c @@ -0,0 +1,74 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller (Raid mode) + * + * Init SATA Raid features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_RAIDMID_FILECODE +// +// Declaration of local functions +// + +/** + * FchInitMidSataRaid - Config SATA Raid controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidSataRaid ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + SataRaidSetDeviceNumMsi (LocalCfgPtr); + SataBar5setting (LocalCfgPtr, &Bar5); + ShutdownUnconnectedSataPortClock (LocalCfgPtr, Bar5); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataEnv.c new file mode 100644 index 0000000000..a5d83cf2b2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataEnv.c @@ -0,0 +1,104 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller + * + * Init SATA features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATAENV_FILECODE + + +/** + * FchInitEnvSata - Config SATA controller before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvSata ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + if ( LocalCfgPtr->Sata.SataMode.SataEnable == 0 ) { + return; //return if SATA controller is disabled. + } + + FchInitEnvProgramSataPciRegs (FchDataPtr); + // + // Call Sub-function for each Sata mode + // + if (( LocalCfgPtr->Sata.SataClass == SataAhci7804) || (LocalCfgPtr->Sata.SataClass == SataAhci )) { + FchInitEnvSataAhci ( LocalCfgPtr ); + } + + if (( LocalCfgPtr->Sata.SataClass == SataIde2Ahci) || (LocalCfgPtr->Sata.SataClass == SataIde2Ahci7804 )) { + FchInitEnvSataIde2Ahci ( LocalCfgPtr ); + } + + if (( LocalCfgPtr->Sata.SataClass == SataNativeIde) || (LocalCfgPtr->Sata.SataClass == SataLegacyIde )) { + FchInitEnvSataIde ( LocalCfgPtr ); + } + + if ( LocalCfgPtr->Sata.SataClass == SataRaid) { + FchInitEnvSataRaid ( LocalCfgPtr ); + } + + // + // SATA IRQ Resource + // + SataSetIrqIntResource (LocalCfgPtr, StdHeader); + + // + // SATA PHY Programming Sequence + // + FchProgramSataPhy (StdHeader); + + SataDisableWriteAccess (StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataEnvLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataEnvLib.c new file mode 100644 index 0000000000..7c6f7aa8b9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataEnvLib.c @@ -0,0 +1,88 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Fch SATA controller Library + * + * SATA Library + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATAENVLIB_FILECODE + +/** + * sataSetIrqIntResource - Config SATA IRQ/INT# resource + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * @param[in] StdHeader + * + */ +VOID +SataSetIrqIntResource ( + IN VOID *FchDataPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 ValueByte; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + // + // IRQ14/IRQ15 come from IDE or SATA + // + ValueByte = 0x08; + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &ValueByte, StdHeader); + LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGC01, &ValueByte, StdHeader); + ValueByte = ValueByte & 0x0F; + + if (LocalCfgPtr->Sata.SataClass == SataLegacyIde) { + ValueByte = ValueByte | 0x50; + } else { + if (LocalCfgPtr->Sata.SataIdeMode == 1) { + // + // Both IDE & SATA set to Native mode + // + ValueByte = ValueByte | 0xF0; + } + } + + LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &ValueByte, StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeEnv.c new file mode 100644 index 0000000000..11303a024d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeEnv.c @@ -0,0 +1,100 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA (IDE mode) controller + * + * Init SATA IDE (Native IDE) mode features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATAIDEENV_FILECODE + +/** + * FchInitEnvSataIde - Config SATA IDE controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvSataIde ( + IN VOID *FchDataPtr + ) +{ + UINT8 ChannelByte; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + // Class code + // + if ( LocalCfgPtr->Sata.SataClass == SataLegacyIde ) { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x08), AccessWidth32, 0, 0x01018A40, StdHeader); + } else { + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x08), AccessWidth32, 0, 0x01018F40, StdHeader); + } + // + // Device ID + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x02), AccessWidth16, 0, FCH_SATA_DID, StdHeader); + // + // SSID + // + if (LocalCfgPtr->Sata.SataIdeSsid != 0 ) { + RwPci ((SATA_BUS_DEV_FUN << 16) + 0x2C, AccessWidth32, 0x00, LocalCfgPtr->Sata.SataIdeSsid, StdHeader); + } + ChannelByte = 0x00; + ReadPci (((SATA_BUS_DEV_FUN << 16) + 0x48 + 3), AccessWidth8, &ChannelByte, StdHeader); + ChannelByte &= 0xCF; + + if ( LocalCfgPtr->Sata.SataDisUnusedIdePChannel ) { + ChannelByte |= 0x10; + } + + if ( LocalCfgPtr->Sata.SataDisUnusedIdeSChannel ) { + ChannelByte |= 0x20; + } + + WritePci (((SATA_BUS_DEV_FUN << 16) + 0x48 + 3), AccessWidth8, &ChannelByte, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLate.c new file mode 100644 index 0000000000..0366ea4cbf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLate.c @@ -0,0 +1,71 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA (IDE mode) controller + * + * Init SATA IDE (Native IDE) mode features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATAIDELATE_FILECODE + +/** + * FchInitLateSataIde - Prepare SATA controller to boot to OS. + * + * - Set class ID to AHCI (if set to AHCI * Mode) + * - Enable AHCI interrupt + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateSataIde ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + SataBar5setting (LocalCfgPtr, &Bar5); + ShutdownUnconnectedSataPortClock (LocalCfgPtr, Bar5); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLib.c new file mode 100644 index 0000000000..24e18acfa9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeLib.c @@ -0,0 +1,46 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Fch SATA Ide controller Library + * + * SATA Ide2Ahci Library + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATAIDELIB_FILECODE diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeMid.c new file mode 100644 index 0000000000..6be38a566b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataIdeMid.c @@ -0,0 +1,75 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA (IDE mode) controller + * + * Init SATA IDE (Native IDE) mode features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATAIDEMID_FILECODE + +/** + * FchInitMidSataIde - Config SATA controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidSataIde ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + Bar5 = 0; + SataBar5setting (LocalCfgPtr, &Bar5); + // + //If this is not S3 resume and also if SATA set to one of IDE mode, them implement drive detection workaround. + // + if ( ! (LocalCfgPtr->Misc.S3Resume) ) { + SataDriveDetection (LocalCfgPtr, &Bar5); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataLate.c new file mode 100644 index 0000000000..b732baab4a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataLate.c @@ -0,0 +1,116 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller + * + * Init SATA features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATALATE_FILECODE + +/** + * FchInitLateSata - Prepare SATA controller to boot to OS. + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateSata ( + IN VOID *FchDataPtr + ) +{ + UINT8 SataPciCommandByte; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + //Return immediately is sata controller is not enabled + // + if ( LocalCfgPtr->Sata.SataMode.SataEnable == 0 ) { + return; + } + + // + // Set Sata PCI Configuration Space Write enable + // + SataEnableWriteAccess (StdHeader); + + // + // Set Sata Controller Memory & IO access enable + // + ReadPci (((SATA_BUS_DEV_FUN << 16) + 0x04), AccessWidth8, &SataPciCommandByte, StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x04), AccessWidth8, 0xFF, 0x03, StdHeader); + + // + // Call Sub-function for each Sata mode + // + if (( LocalCfgPtr->Sata.SataClass == SataAhci7804) || (LocalCfgPtr->Sata.SataClass == SataAhci )) { + FchInitLateSataAhci ( LocalCfgPtr ); + } + + if (( LocalCfgPtr->Sata.SataClass == SataIde2Ahci) || (LocalCfgPtr->Sata.SataClass == SataIde2Ahci7804 )) { + FchInitLateSataIde2Ahci ( LocalCfgPtr ); + } + + if (( LocalCfgPtr->Sata.SataClass == SataNativeIde) || (LocalCfgPtr->Sata.SataClass == SataLegacyIde )) { + FchInitLateSataIde ( LocalCfgPtr ); + } + + if ( LocalCfgPtr->Sata.SataClass == SataRaid) { + FchInitLateSataRaid ( LocalCfgPtr ); + } + + FchInitLateProgramSataRegs ( LocalCfgPtr ); + + // + // Restore Sata Controller Memory & IO access status + // + WritePci (((SATA_BUS_DEV_FUN << 16) + 0x04), AccessWidth8, &SataPciCommandByte, StdHeader); + + // + // Set Sata PCI Configuration Space Write disable + // + SataDisableWriteAccess (StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataLib.c new file mode 100644 index 0000000000..0b88aa713f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataLib.c @@ -0,0 +1,258 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Fch SATA controller Library + * + * SATA Library + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84857 $ @e \$Date: 2012-12-20 16:43:46 -0600 (Thu, 20 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATALIB_FILECODE + +/** + * sataBar5setting - Config SATA BAR5 + * + * + * @param[in] FchDataPtr - Fch configuration structure pointer. + * @param[in] *Bar5Ptr - SATA BAR5 buffer. + * + */ +VOID +SataBar5setting ( + IN VOID *FchDataPtr, + IN UINT32 *Bar5Ptr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + //Get BAR5 value + // + ReadPci (((SATA_BUS_DEV_FUN << 16) + 0x24), AccessWidth32, Bar5Ptr, StdHeader); + + // + //Assign temporary BAR if is not already assigned + // + if ( (*Bar5Ptr == 0) || (*Bar5Ptr == - 1) ) { + // + //assign temporary BAR5 + // + if ( (LocalCfgPtr->Sata.TempMmio == 0) || (LocalCfgPtr->Sata.TempMmio == - 1) ) { + *Bar5Ptr = 0xFEC01000; + } else { + *Bar5Ptr = LocalCfgPtr->Sata.TempMmio; + } + WritePci (((SATA_BUS_DEV_FUN << 16) + 0x24), AccessWidth32, Bar5Ptr, StdHeader); + } + + // + //Clear Bits 9:0 + // + *Bar5Ptr = *Bar5Ptr & 0xFFFFFC00; +} + +/** + * sataEnableWriteAccess - Enable Sata PCI configuration space + * + * @param[in] StdHeader + * + */ +VOID +SataEnableWriteAccess ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // + // BIT0 Enable write access to PCI header + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth8, 0xff, BIT0, StdHeader); +} + +/** + * sataDisableWriteAccess - Disable Sata PCI configuration space + * + * @param[in] StdHeader + * + */ +VOID +SataDisableWriteAccess ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // + // Disable write access to PCI header + // + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x040), AccessWidth8, (UINT32)~BIT0, 0, StdHeader); +} + + + +#ifdef SATA_BUS_DEV_FUN_FPGA + +/** + * FchSataBar5settingFpga + * + * @param[in] LocalCfgPtr + * @param[in] Bar5 + * + */ +VOID +FchSataBar5settingFpga ( + IN FCH_DATA_BLOCK *LocalCfgPtr, + IN UINT32 *Bar5 + ) +{ + UINT8 Value; + + //Get BAR5 value + ReadPci (((SATA_BUS_DEV_FUN_FPGA << 16) + 0x24), AccWidthUint32, Bar5); + + //Assign temporary BAR if is not already assigned + if ( (*Bar5 == 0) || (*Bar5 == - 1) ) { + //assign temporary BAR5 + if ( (LocalCfgPtr->Sata.TempMMIO == 0) || (LocalCfgPtr->Sata.TempMMIO == - 1) ) { + *Bar5 = 0xFEC01000; + } else { + *Bar5 = LocalCfgPtr->Sata.TempMMIO; + } + WritePci (((SATA_BUS_DEV_FUN_FPGA << 16) + 0x24), AccWidthUint32, Bar5); + } + + //Clear Bits 9:0 + *Bar5 = *Bar5 & 0xFFFFFC00; + Value = 0x07; + WritePci (((SATA_BUS_DEV_FUN_FPGA << 16) + 0x04), AccWidthUint8, &Value); + WritePci (((PCIB_BUS_DEV_FUN << 16) + 0x04), AccWidthUint8, &Value); +} + +/** + * FchSataDriveDetectionFpga + * + * @param[in] LocalCfgPtr + * @param[in] Bar5 + * + */ +VOID +FchSataDriveDetectionFpga ( + IN FCH_DATA_BLOCK *LocalCfgPtr, + IN UINT32 *Bar5 + ) +{ + UINT32 SataBarFpgaInfo; + UINT8 PortNum; + UINT8 SataFpaPortType; + UINT16 IoBase; + UINT32 SataFpgaLoopVarWord; + AMD_CONFIG_PARAMS *StdHeader; + + StdHeader = LocalCfgPtr->StdHeader; + + TRACE ((DMSG_FCH_TRACE, "FCH - Entering sata drive detection procedure\n\n")); + TRACE ((DMSG_FCH_TRACE, "SATA BAR5 is %X \n", *pBar5)); + + for ( PortNum = 0; PortNum < 4; PortNum++ ) { + ReadMem (*Bar5 + FCH_SATA_BAR5_REG128 + PortNum * 0x80, AccWidthUint32, &SataBarFpgaInfo); + if ( ( SataBarFpgaInfo & 0x0F ) == 0x03 ) { + if ( PortNum & BIT0 ) { + //this port belongs to secondary channel + ReadPci (((UINT32) (SATA_BUS_DEV_FUN_FPGA << 16) + 0x18), AccWidthUint16, &IoBase); + } else { + //this port belongs to primary channel + ReadPci (((UINT32) (SATA_BUS_DEV_FUN_FPGA << 16) + 0x10), AccWidthUint16, &IoBase); + } + + //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them + if ( LocalCfgPtr->Sata.SataClass == SataLegacyIde ) { + IoBase = ( (0x170) | ((UINT16) ( (~((UINT8) (PortNum & BIT0) << 7)) & 0x80 )) ); + } + + if ( PortNum & BIT1 ) { + //this port is slave + SataFpaPortType = 0xB0; + } else { + //this port is master + SataFpaPortType = 0xA0; + } + + IoBase &= 0xFFF8; + LibAmdIoWrite (AccessWidth8, IoBase + 6, &SataFpaPortType, StdHeader); + + //Wait in loop for 30s for the drive to become ready + for ( SataFpgaLoopVarWord = 0; SataFpgaLoopVarWord < 300000; SataFpgaLoopVarWord++ ) { + LibAmdIoRead (AccessWidth8, IoBase + 7, &SataFpaPortType, StdHeader); + if ( (SataFpaPortType & 0x88) == 0 ) { + break; + } + FchStall (100, StdHeader); + } + } + } +} + +/** + * FchSataDriveFpga - + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchSataDriveFpga ( + IN VOID *FchDataPtr + ) +{ + UINT32 Bar5; + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + Bar5 = 0; + SataBar5setting (LocalCfgPtr, &Bar5); + + FchSataBar5settingFpga (LocalCfgPtr, &Bar5); + FchSataDriveDetectionFpga (LocalCfgPtr, &Bar5); +} + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataMid.c new file mode 100644 index 0000000000..7a13a1c589 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataMid.c @@ -0,0 +1,196 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SATA controller + * + * Init SATA features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATAMID_FILECODE + +/** + * FchInitMidSata - Config SATA controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidSata ( + IN VOID *FchDataPtr + ) +{ + UINT8 SataPciCommandByte; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + if ( LocalCfgPtr->Sata.SataMode.SataEnable == 0 ) { + return; ///return if SATA controller is disabled. + } + + // + // Set Sata PCI Configuration Space Write enable + // + SataEnableWriteAccess (StdHeader); + + // + // Set Sata Controller Memory & IO access enable + // + ReadPci (((SATA_BUS_DEV_FUN << 16) + 0x04), AccessWidth8, &SataPciCommandByte, StdHeader); + RwPci (((SATA_BUS_DEV_FUN << 16) + 0x04), AccessWidth8, 0xFF, 0x03, StdHeader); + + // + // Sata Bar5 register setting for Index 0xFC + // + SataBar5RegSet ( LocalCfgPtr ); + + FchInitMidProgramSataRegs ( LocalCfgPtr ); + + // + // Set Sata port mode (each) for Gen1/Gen2/Gen3 + // + SataSetPortGenMode ( LocalCfgPtr ); + + // + // Call Sub-function for each Sata mode + // + if (( LocalCfgPtr->Sata.SataClass == SataAhci7804) || (LocalCfgPtr->Sata.SataClass == SataAhci )) { + FchInitMidSataAhci ( LocalCfgPtr ); + } + + if (( LocalCfgPtr->Sata.SataClass == SataIde2Ahci) || (LocalCfgPtr->Sata.SataClass == SataIde2Ahci7804 )) { + FchInitMidSataIde2Ahci ( LocalCfgPtr ); + } + + if (( LocalCfgPtr->Sata.SataClass == SataNativeIde) || (LocalCfgPtr->Sata.SataClass == SataLegacyIde )) { + FchInitMidSataIde ( LocalCfgPtr ); + } + + if ( LocalCfgPtr->Sata.SataClass == SataRaid) { + FchInitMidSataRaid ( LocalCfgPtr ); + } + +#ifdef SATA_BUS_DEV_FUN_FPGA + FchSataDriveFpga ( LocalCfgPtr ); +#endif + + // + // Restore Sata Controller Memory & IO access status + // + WritePci (((SATA_BUS_DEV_FUN << 16) + 0x04), AccessWidth8, &SataPciCommandByte, StdHeader); + + // + // Set Sata PCI Configuration Space Write disable + // + SataDisableWriteAccess (StdHeader); +} + +/** + * SataSetDeviceNumMsi - Program Sata controller support device + * number cap & MSI cap + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +SataSetDeviceNumMsi ( + IN VOID *FchDataPtr + ) +{ + FchSataSetDeviceNumMsi ( FchDataPtr ); +} + +/** + * SataDriveDetection - Sata drive detection + * + * - Sata Ide & Sata Ide to Ahci only + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * @param[in] *Bar5Ptr Sata BAR5 base address. + * + */ +VOID +SataDriveDetection ( + IN VOID *FchDataPtr, + IN UINT32 *Bar5Ptr + ) +{ + FchSataDriveDetection ( FchDataPtr, Bar5Ptr ); +} + +/** + * shutdownUnconnectedSataPortClock - Shutdown unconnected Sata port clock + * + * - Sata Ide & Sata Ide to Ahci only + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * @param[in] Bar5 Sata BAR5 base address. + * + */ +VOID +ShutdownUnconnectedSataPortClock ( + IN VOID *FchDataPtr, + IN UINT32 Bar5 + ) +{ + FchShutdownUnconnectedSataPortClock ( FchDataPtr, Bar5); +} + +/** + * SataSetPortGenMode - Set Sata port mode (each) for + * Gen1/Gen2/Gen3 + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +SataSetPortGenMode ( + IN VOID *FchDataPtr + ) +{ + FchSataSetPortGenMode ( FchDataPtr ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataReset.c new file mode 100644 index 0000000000..70452dc1be --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sata/SataReset.c @@ -0,0 +1,63 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Sata controller + * + * Init Sata Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SATA_SATARESET_FILECODE + +/** + * FchInitResetSata - Config Sata controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetSata ( + IN VOID *FchDataPtr + ) +{ + FchInitResetSataProgram ( FchDataPtr ); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdEnvService.c new file mode 100644 index 0000000000..e9ded685a3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdEnvService.c @@ -0,0 +1,129 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze SD + * + * Init SD Controller. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 88054 $ @e \$Date: 2013-02-15 10:57:15 -0600 (Fri, 15 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SD_FAMILY_YANGTZE_YANGTZESDENVSERVICE_FILECODE +/** + * FchInitEnvSdProgram - Config SD controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvSdProgram ( + IN VOID *FchDataPtr + ) +{ + UINT32 SdData32; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + UINT32 Sd30Control; + UINT8 ApuStepping; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + ApuStepping = (UINT8) LocalCfgPtr->Misc.FchCpuId; + // + // SD Configuration + // + if ( LocalCfgPtr->Sd.SdConfig != SdDisable) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGE8, AccessWidth8, 0xFE, BIT0); + Sd30Control = 0; + SdData32 = 0x30FE00B2; + ReadPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGA4, AccessWidth32, &SdData32, StdHeader); + SdData32 &= 0xEFDF00FF; + SdData32 |= BIT19 + BIT22 + BIT20; ///ADMA + + if ( LocalCfgPtr->Sd.SdConfig == SdDma) { + SdData32 &= ~(BIT20 + BIT19); ///DMA + } else if ( LocalCfgPtr->Sd.SdConfig == SdPio) { + SdData32 &= ~(BIT20 + BIT22 + BIT19); ///PIO + } + SdData32 |= (LocalCfgPtr->Sd.SdSpeed << 21) + (LocalCfgPtr->Sd.SdBitWidth << 28); + SdData32 |= BIT24; + if ( LocalCfgPtr->Sd.SdHostControllerVersion == 1) { + SdData32 |= 0x3200; + if ( (ApuStepping & 0x0F) == 0) { + SdData32 &= ~BIT21; + } + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGB0, AccessWidth32, (UINT32) (~ (0x03 << 24)), (UINT32) (0x01 << 24), StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGB0, AccessWidth32, (UINT32) (~ (0xFF)), (UINT32) 0x19, StdHeader); + } else { + if ( LocalCfgPtr->Sd.SdHostControllerVersion == 2) { + SdData32 |= 0xC800; + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGB0, AccessWidth32, (UINT32) (~ (0x03 << 24)), (UINT32) (0x02 << 24), StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGB0, AccessWidth32, (UINT32) (~ (0xFF)), (UINT32) 0x19, StdHeader); + } + } + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGA4, AccessWidth32, 0, SdData32, StdHeader); + + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGB0, AccessWidth32, (UINT32) (~ (0x03 << 10)), (UINT32) (0x03 << 10), StdHeader); + if (LocalCfgPtr->Sd.SdSsid != 0 ) { + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REG2C, AccessWidth32, 0, LocalCfgPtr->Sd.SdSsid, StdHeader); + } + if ( LocalCfgPtr->Sd.SdClockMultiplier ) { + Sd30Control |= (BIT16 + BIT17); + } + Sd30Control &= ~(BIT0 + BIT1); + Sd30Control |= LocalCfgPtr->Sd.SdrCapabilities; + Sd30Control |= LocalCfgPtr->Sd.SdReTuningMode << 14; + if ( LocalCfgPtr->Sd.SdHostControllerVersion == 2) { + Sd30Control &= 0xFFFF00FF; + Sd30Control |= ( BIT4 + BIT5 + BIT6 + BIT8 + BIT10 + BIT13 ); + } + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGD0 + 1, AccessWidth8, 0xFD, BIT1, StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGA8, AccessWidth32, 0x3FFC, Sd30Control, StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGB0 + 3, AccessWidth8, 0, LocalCfgPtr->Sd.SdHostControllerVersion, StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGBC, AccessWidth32, 0, 0x0044CC98, StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGF0, AccessWidth32, 0, 0x000400FA, StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGF4, AccessWidth32, 0, 0x00040002, StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGF8, AccessWidth32, 0, 0x00010002, StdHeader); + RwPci ((SD_BUS_DEV_FUN << 16) + SD_PCI_REGFC, AccessWidth32, 0, 0x00014000, StdHeader); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGD3, AccessWidth8, 0xBF, 0x00); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdResetService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdResetService.c new file mode 100644 index 0000000000..a56100aa6d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdResetService.c @@ -0,0 +1,47 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze SD + * + * Init SD Controller. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SD_FAMILY_YANGTZE_YANGTZESDRESETSERVICE_FILECODE + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdService.c new file mode 100644 index 0000000000..8f2d9adcbb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/Family/Yangtze/YangtzeSdService.c @@ -0,0 +1,47 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze SD + * + * Init SD Controller. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SD_FAMILY_YANGTZE_YANGTZESDSERVICE_FILECODE + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdEnv.c new file mode 100644 index 0000000000..c959d5bfe7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdEnv.c @@ -0,0 +1,65 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SD controller + * + * Init SD Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SD_SDENV_FILECODE + +/** + * FchInitEnvSd - Config SD controller before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvSd ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + FchInitEnvSdProgram (FchDataPtr); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdLate.c new file mode 100644 index 0000000000..bb14e01235 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdLate.c @@ -0,0 +1,60 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SD controller + * + * Init SD Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SD_SDLATE_FILECODE + +/** + * FchInitLateSd - Prepare SD controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateSd ( + IN VOID *FchDataPtr + ) +{ +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdMid.c new file mode 100644 index 0000000000..b5cd869a94 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Sd/SdMid.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch SD controller + * + * Init SD Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SD_SDMID_FILECODE + +/** + * FchInitMidSd - Config SD controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidSd ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcEnvService.c new file mode 100644 index 0000000000..e2f37bbc25 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcEnvService.c @@ -0,0 +1,89 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch LPC controller + * + * Init LPC Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_SPI_FAMILY_YANGTZE_YANGTZELPCENVSERVICE_FILECODE + +/** + * FchInitYangtzeEnvLpcPciTable - PCI device registers initial + * during early POST. + * + */ +REG8_MASK FchInitYangtzeEnvLpcPciTable[] = +{ + // + // LPC Device (Bus 0, Dev 20, Func 3) + // + {0x00, LPC_BUS_DEV_FUN, 0}, + {FCH_LPC_REG40, (UINT8)~BIT2, BIT2}, + {FCH_LPC_REG48, 0x00, BIT0 + BIT1 + BIT2}, + {0x78, 0xFC, 00}, + {FCH_LPC_REGBB, 0xF2, BIT0 + BIT2 + BIT3}, + {0xFF, 0xFF, 0xFF}, +}; + +/** + * FchInitEnvLpcProgram - Config LPC controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvLpcProgram ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + ProgramPciByteTable ((REG8_MASK*) (&FchInitYangtzeEnvLpcPciTable[0]), sizeof (FchInitYangtzeEnvLpcPciTable) / sizeof (REG8_MASK), StdHeader); + + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG28, AccessWidth32, (UINT32)~(BIT21 + BIT20 + BIT19), 0); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c new file mode 100644 index 0000000000..eb0f54f473 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c @@ -0,0 +1,790 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch LPC controller + * + * Init LPC Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87493 $ @e \$Date: 2013-02-04 11:56:12 -0600 (Mon, 04 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" + +#define FILECODE PROC_FCH_SPI_FAMILY_YANGTZE_YANGTZELPCRESETSERVICE_FILECODE +#define SPI_BASE UserOptions.FchBldCfg->CfgSpiRomBaseAddress + +SPI_CONTROLLER_PROFILE SpiControllerProfile[4] = { + {128, 100, 100, 100, 100}, + {128, 66, 66, 66, 66}, + {128, 33, 33, 33, 33}, + {128, 16, 16, 16, 16}, + }; +SPI_DEVICE_PROFILE DefaultSpiDeviceTable[] = { + //JEDEC_ID,RomSize,SecSize;MaxNormal;MaxFast;MaxDual;MaxQuad;QeReadReg;QeWriteReg;QeRegSize;QeLocation; + {0x001524C2, 2 << 20, 4096, 33, 108, 150, 300, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25L1635D + {0x001525C2, 2 << 20, 4096, 33, 108, 160, 432, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25L1635E + {0x00165EC2, 4 << 20, 4096, 33, 104, 208, 400, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25L3235D +// {0x003625C2, 4 << 20, 4096, 33, 104, 168, 432, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25U3235F + {0x001720C2, 8 << 20, 4096, 33, 104, 208, 400, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25L6436E + {0x003725C2, 8 << 20, 4096, 33, 104, 168, 432, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25U6435F + + {0x0046159D, 4 << 20, 4096, 33, 104, 208, 400, 0x05, 0x01, 0x1, 0x0040}, //PFLASH Pm25LQ032C + + {0x001540EF, 2 << 20, 4096, 33, 104, 208, 416, 0x35, 0x01, 0x2, 0x0200}, //Wnbond_W25Q16CV + {0x001640EF, 4 << 20, 4096, 33, 104, 208, 320, 0x35, 0x01, 0x2, 0x0200}, //Wnbond_W25Q32BV + {0x001740EF, 8 << 20, 4096, 104, 104, 208, 416, 0x35, 0x01, 0x2, 0x0200}, //Wnbond_W25Q64 + + {0x004326BF, 8 << 20, 4096, 40, 104, 160, 416, 0x35, 0x01, 0x2, 0x0200}, //SST26VF064BA + + {0x001640C8, 4 << 20, 4096, 33, 100, 160, 320, 0x35, 0x01, 0x2, 0x0200}, //GigaDecice GD25Q32BSIGR + + {0x00164037, 4 << 20, 4096, 33, 100, 200, 400, 0x35, 0x01, 0x2, 0x0200}, //AMIC A25LQ32B + + {0x00000000, 4 << 20, 4096, 33, 33, 33, 33, 0x05, 0x01, 0x1, 0x0040} +}; + + +/** + * FchInitYangtzeResetLpcPciTable - Lpc (Spi) device registers + * initial during the power on stage. + * + * + * + * + */ +REG8_MASK FchInitYangtzeResetLpcPciTable[] = +{ + // + // LPC Device (Bus 0, Dev 20, Func 3) + // + {0x00, LPC_BUS_DEV_FUN, 0}, + + {FCH_LPC_REG48, 0x00, BIT0 + BIT1 + BIT2}, + {FCH_LPC_REG7C, 0x00, BIT0 + BIT2}, + {0x78, 0xF0, BIT2 + BIT3}, /// Enable LDRQ pin + {FCH_LPC_REGBA, 0x9F, BIT5 + BIT6}, + // Force EC_PortActive to 1 to fix possible IR non function issue when NO_EC_SUPPORT is defined + {FCH_LPC_REGA4, (UINT8)~ BIT0, BIT0}, + {0xFF, 0xFF, 0xFF}, +}; + +/** + * FchInitResetLpcProgram - Config Lpc controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetLpcProgram ( + IN VOID *FchDataPtr + ) +{ + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + // + // enable prefetch on Host, set LPC cfg 0xBB bit 0 to 1 + // + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGBA, AccessWidth16, 0xFFFF, BIT8, StdHeader); + + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG6C, AccessWidth32, 0xFFFFFF00, 0, StdHeader); + + ProgramPciByteTable ( (REG8_MASK*) (&FchInitYangtzeResetLpcPciTable[0]), sizeof (FchInitYangtzeResetLpcPciTable) / sizeof (REG8_MASK), StdHeader); + + if ( LocalCfgPtr->Spi.LpcClk0 ) { + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGD0 + 1, AccessWidth8, 0xDF, 0x20, StdHeader); + } else { + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGD0 + 1, AccessWidth8, 0xDF, 0, StdHeader); + } + if ( LocalCfgPtr->Spi.LpcClk1 ) { + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGD0 + 1, AccessWidth8, 0xBF, 0x40, StdHeader); + } else { + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGD0 + 1, AccessWidth8, 0xBF, 0, StdHeader); + } + if ( LocalCfgPtr->LegacyFree ) { + RwPci (((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG44), AccessWidth32, 00, 0x0003C000, StdHeader); + } else { + RwPci (((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG44), AccessWidth32, 00, 0xFF03FFD5, StdHeader); + } +} + +/** + * FchWriteSpiExtReg - Write SPI Extension Register + * + * + * + * @param[in] SpiExtRegIndex - Extension Register Index. + * @param[in] SpiExtRegData - Extension Register Data. + * + */ +STATIC VOID +FchWriteSpiExtReg ( + IN UINT8 SpiExtRegIndex, + IN UINT8 SpiExtRegData + ) +{ + ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG1E) = SpiExtRegIndex; + ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG1F) = SpiExtRegData; +} +/** + * FchSetSpiCounter - Set SPI RX/TX Counters + * + * + * + * @param[in] TxCounter - Transfer Counter. + * @param[in] RxCounter - Receive Counter. + * + */ +STATIC VOID +FchSetSpiCounter ( + IN UINT8 TxCounter, + IN UINT8 RxCounter + ) +{ + FchWriteSpiExtReg (FCH_SPI_MMIO_REG1F_X05_TX_BYTE_COUNT, TxCounter); + FchWriteSpiExtReg (FCH_SPI_MMIO_REG1F_X06_RX_BYTE_COUNT, RxCounter); +} +/** + * FchSpiControllerNotBusy - SPI Conroller Not Busy + * + * + * + * + */ +STATIC VOID +FchSpiControllerNotBusy ( + VOID) +{ + UINT32 SpiReg00; + SpiReg00 = FCH_SPI_BUSY + FCH_SPI_EXEC_OPCODE; + do { + SpiReg00 = ACPIMMIO32 (SPI_BASE + FCH_SPI_MMIO_REG00); + } while ((SpiReg00 & (FCH_SPI_BUSY + FCH_SPI_EXEC_OPCODE))); +} +/** + * FchResetFifo - Reset SPI FIFO + * + * + * + * + */ +STATIC VOID +FchResetFifo ( + VOID) +{ + ACPIMMIO32 (SPI_BASE + FCH_SPI_MMIO_REG00) |= BIT20; +} +/** + * WaitForSpiDeviceWriteEnabled - + * + * + * + * + */ +STATIC BOOLEAN +WaitForSpiDeviceWriteEnabled ( + VOID) +{ + UINT8 bStatus; + bStatus = 0; + do + { + FchSpiTransfer ( + 0, //IN UINT8 PrefixCode, + 0x05,//IN UINT8 Opcode, + &bStatus,//IN OUT UINT8 *DataPtr, + NULL,//IN UINT8 *AddressPtr, + 0,//IN UINT8 Length, + FALSE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + FALSE //IN BOOLEAN FinishedFlag + ); + } while ((bStatus & 2) == 0); + return TRUE; +} +/** + * WaitForSpiDeviceComplete - + * + * + * + * + */ +STATIC BOOLEAN +WaitForSpiDeviceComplete ( + VOID) +{ + UINT8 bStatus; + bStatus = 1; + do + { + FchSpiTransfer ( + 0, //IN UINT8 PrefixCode, + 0x05,//IN UINT8 Opcode, + &bStatus,//IN OUT UINT8 *DataPtr, + NULL,//IN UINT8 *AddressPtr, + 0,//IN UINT8 Length, + FALSE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + FALSE //IN BOOLEAN FinishedFlag + ); + } while (bStatus & 1); + return TRUE; +} +/** + * FchSpiTransfer - FCH Spi Transfer + * + * + * + * @param[in] PrefixCode - Prefix code. + * @param[in] Opcode - Opcode. + * @param[in] DataPtr - Data Pointer. + * @param[in] AddressPtr - Address Pointer. + * @param[in] Length - Read/Write Length. + * @param[in] WriteFlag - Write Flag. + * @param[in] AddressFlag - Address Flag. + * @param[in] DataFlag - Data Flag. + * @param[in] FinishedFlag - Finished Flag. + * + */ +//static +AGESA_STATUS +FchSpiTransfer ( + IN UINT8 PrefixCode, + IN UINT8 Opcode, + IN OUT UINT8 *DataPtr, + IN UINT8 *AddressPtr, + IN UINT8 Length, + IN BOOLEAN WriteFlag, + IN BOOLEAN AddressFlag, + IN BOOLEAN DataFlag, + IN BOOLEAN FinishedFlag + ) +{ + UINTN Addr; + UINTN Retry; + UINTN i; + UINTN index; + UINT8 WriteCount; + UINT8 ReadCount; + //UINT8 Dummy; + //UINT8 CurrFifoIndex; + + if (!((Opcode == 0x9f) && (!DataFlag))) { + if (PrefixCode) { + Retry = 0; + do { + ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG00 + 0) = PrefixCode; + //ACPIMMIO8(SPI_BASE + FCH_SPI_MMIO_REG00 + 1) = 0; + FchSetSpiCounter (0, 0); + ACPIMMIO32 (SPI_BASE + FCH_SPI_MMIO_REG00) |= FCH_SPI_EXEC_OPCODE; + FchSpiControllerNotBusy (); + + if (FinishedFlag) { + if (WaitForSpiDeviceWriteEnabled ()) { + Retry = 0; + } else { + Retry ++; + if (Retry >= FCH_SPI_RETRY_TIMES) { + return AGESA_ERROR; + } + } + } + } while (Retry); + } + Retry = 0; + do { + WriteCount = 0; + ReadCount = 0; + // + // Reset Fifo Ptr + // + FchResetFifo (); + // + // Check Address Mode + // + index = 0; + Addr = (UINTN) AddressPtr; + if (AddressFlag) { + //for (i = 16, Addr = (UINTN) AddressPtr; i >= 0; i -= 8) { + for (i = 0; i < 3; i ++) { + //ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG0C + 0) = (UINT8) ((Addr >> i) & 0xff); + ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG80_FIFO + index) = (UINT8) ((Addr >> (16 - i * 8)) & 0xff); + index ++; + } + WriteCount += 3; + } + if (DataFlag) { + // + // Check Read/Write Mode + // + if (WriteFlag) { + WriteCount += Length + 1; + for (i = 0; i < (UINTN) (Length + 1); i ++) { + //ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG0C + 0) = DataPtr[i]; + ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG80_FIFO + index) = DataPtr[i]; + index ++; + } + } else { + // + // Read operation must plus extra 1 byte + // + ReadCount += Length + 2; + } + } + ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG00 + 0) = Opcode; + //ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG00 + 1) = (ReadCount << 4) + WriteCount; + FchSetSpiCounter (WriteCount, ReadCount); + ACPIMMIO32 (SPI_BASE + FCH_SPI_MMIO_REG00) |= FCH_SPI_EXEC_OPCODE; + FchSpiControllerNotBusy (); + + if (FinishedFlag) { + if (WaitForSpiDeviceComplete ()) { + Retry = 0; + } else { + Retry ++; + if (Retry >= FCH_SPI_RETRY_TIMES) { + return AGESA_ERROR; + } + } + } + } while (Retry); + if (DataFlag && ReadCount) { + // + // Reset Fifo Ptr + // + FchResetFifo (); + //while (DataFlag && ReadCount) { + // CurrFifoIndex = ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG4E + 1) & 0x07; + // if (CurrFifoIndex != WriteCount) { + // Dummy = ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG0C + 0); + // } else break; + //} + for (i = 0; i < (UINTN) (Length + 1); i ++) { + //DataPtr[i] = ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG0C + 0); + DataPtr[i] = ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG80_FIFO + WriteCount + i); + } + } + } + return AGESA_SUCCESS; +} + +/** + * + * + * + * @param[in] SpiQualMode- Spi Qual Mode. + * @param[in] StdHeader - Standard Header. + * + */ +STATIC VOID +FchSetQualMode ( + IN UINT32 SpiQualMode, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0x69, AccessWidth8, (UINT32)~BIT3, BIT3); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGBB, AccessWidth8, (UINT32)~ BIT0, BIT0, StdHeader); + RwMem (SPI_BASE + FCH_SPI_MMIO_REG00, AccessWidth32, (UINT32)~( BIT18 + BIT29 + BIT30), ((SpiQualMode & 1) << 18) + ((SpiQualMode & 6) << 28)); + +} + +/** + * FchInitResetSpi - Config Spi controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetSpi ( + IN VOID *FchDataPtr + ) +{ + UINT32 SpiModeByte; + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + // Set Spi ROM Base Address + // + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGA0, AccessWidth32, 0x001F, SPI_BASE, StdHeader); + + RwMem (SPI_BASE + FCH_SPI_MMIO_REG00, AccessWidth32, 0xFFFFFFFF, (BIT19 + BIT24 + BIT25 + BIT26)); + RwMem (SPI_BASE + FCH_SPI_MMIO_REG0C, AccessWidth32, 0xFFC0FFFF, 0 ); + + RwMem (SPI_BASE + FCH_SPI_MMIO_REG20, AccessWidth8, 0xFE, (UINT8) ((LocalCfgPtr->SPI100_Enable) << 0)); + + if (LocalCfgPtr->SpiSpeed) { + RwMem (SPI_BASE + FCH_SPI_MMIO_REG22, AccessWidth32, ~((UINT32) (0xF << 12)), ((LocalCfgPtr->SpiSpeed - 1 ) << 12)); + } + + if (LocalCfgPtr->FastSpeed) { + RwMem (SPI_BASE + FCH_SPI_MMIO_REG22, AccessWidth32, ~((UINT32) (0xF << 8)), ((LocalCfgPtr->FastSpeed - 1 ) << 8)); + } + + RwMem (SPI_BASE + FCH_SPI_MMIO_REG1C, AccessWidth32, (UINT32)~(BIT10), ((LocalCfgPtr->BurstWrite) << 10)); + + SpiModeByte = LocalCfgPtr->Mode; + if (LocalCfgPtr->Mode) { + if ((SpiModeByte == FCH_SPI_MODE_QUAL_114) || (SpiModeByte == FCH_SPI_MODE_QUAL_144)) { + if (FchPlatformSpiQe (FchDataPtr)) { + FchSetQualMode (SpiModeByte, StdHeader); + } + } else { + RwMem (SPI_BASE + FCH_SPI_MMIO_REG00, AccessWidth32, (UINT32)~( BIT18 + BIT29 + BIT30), ((LocalCfgPtr->Mode & 1) << 18) + ((LocalCfgPtr->Mode & 6) << 28)); + } + } else { + if (FchPlatformSpiQe (FchDataPtr)) { + SpiModeByte = FCH_SPI_MODE_QUAL_144; + } + } + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGBA, AccessWidth16, 0xFFFF, BIT8, StdHeader); + + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGBA, AccessWidth16, 0xFFFF, BIT7, StdHeader); +} + + + +STATIC UINT32 +FchReadSpiId ( + IN BOOLEAN Flag + ) +{ + UINT32 DeviceID; + UINT8 *DeviceIdPtr; + DeviceID = 0; + DeviceIdPtr = (UINT8 *) (((UINTN) (&DeviceID))); + if (Flag) { + FchSpiTransfer ( + 0, //IN UINT8 PrefixCode, + 0x9F,//IN UINT8 Opcode, + DeviceIdPtr,//IN OUT UINT8 *DataPtr, + (UINT8 *) (NULL),//IN UINT8 *AddressPtr, + 2,//IN UINT8 Length, + FALSE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + FALSE //IN BOOLEAN FinishedFlag + ); + } else { + FchSpiTransfer ( + 0, //IN UINT8 PrefixCode, + 0x9F,//IN UINT8 Opcode, + DeviceIdPtr,//IN OUT UINT8 *DataPtr, + (UINT8 *) (NULL),//IN UINT8 *AddressPtr, + 2,//IN UINT8 Length, + FALSE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + FALSE,//IN BOOLEAN DataFlag, + FALSE //IN BOOLEAN FinishedFlag + ); + } + return DeviceID; +} +/** + * FchReadSpiQe - Read SPI Qual Enable + * + * + * + * @param[in] SpiDeviceProfilePtr - Spi Device Profile Pointer + * @param[in] SpiQeRegValue - Spi QuadEnable Register Value + * + */ +STATIC BOOLEAN +FchReadSpiQe ( + IN OUT SPI_DEVICE_PROFILE *SpiDeviceProfilePtr, + IN UINT16 SpiQeRegValue + ) +{ + UINT16 Value16; + SpiQeRegValue = 0; + Value16 = 0; + + FchSpiTransfer ( + 0, //IN UINT8 PrefixCode, + SpiDeviceProfilePtr->QeReadRegister,//IN UINT8 Opcode, + (UINT8 *)(&SpiQeRegValue),//IN OUT UINT8 *DataPtr, + NULL,//IN UINT8 *AddressPtr, + 0,//IN UINT8 Length, + FALSE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + FALSE //IN BOOLEAN FinishedFlag + ); + if (SpiDeviceProfilePtr->QeOperateSize == 2) { + FchSpiTransfer ( + 0, //IN UINT8 PrefixCode, + 0x05,//IN UINT8 Opcode, + (UINT8 *)(&SpiQeRegValue),//IN OUT UINT8 *DataPtr, + NULL,//IN UINT8 *AddressPtr, + 0,//IN UINT8 Length, + FALSE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + FALSE //IN BOOLEAN FinishedFlag + ); + FchSpiTransfer ( + 0, //IN UINT8 PrefixCode, + SpiDeviceProfilePtr->QeReadRegister,//IN UINT8 Opcode, + (UINT8 *)(&Value16),//IN OUT UINT8 *DataPtr, + NULL,//IN UINT8 *AddressPtr, + 0,//IN UINT8 Length, + FALSE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + FALSE //IN BOOLEAN FinishedFlag + ); + SpiQeRegValue |= (Value16 << 8); + } + + if (SpiDeviceProfilePtr->QeLocation & SpiQeRegValue) { + return TRUE; + } + SpiQeRegValue |= SpiDeviceProfilePtr->QeLocation; + return FALSE; +} +/** + * FchWriteSpiQe - Write SPI Qual Enable + * + * + * + * @param[in] SpiDeviceProfilePtr - Spi Device Profile Pointer + * @param[in] SpiQeRegValue - Spi QuadEnable Register Value + * + */ +STATIC VOID +FchWriteSpiQe ( + IN OUT SPI_DEVICE_PROFILE *SpiDeviceProfilePtr, + IN UINT16 SpiQeRegValue + ) +{ + + SpiQeRegValue |= SpiDeviceProfilePtr->QeLocation; + FchSpiTransfer ( + 0x06, //IN UINT8 PrefixCode, + SpiDeviceProfilePtr->QeWriteRegister,//IN UINT8 Opcode, + (UINT8 *)(&SpiQeRegValue),//IN OUT UINT8 *DataPtr, + NULL,//IN UINT8 *AddressPtr, + SpiDeviceProfilePtr->QeOperateSize - 1,//IN UINT8 Length, + TRUE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + TRUE //IN BOOLEAN FinishedFlag + ); +} + +/** + * FchFindSpiDeviceProfile - Find SPI Device Profile + * + * + * + * @param[in] DeviceID - Device ID + * @param[in] SpiDeviceProfilePtr - Spi Device Profile Pointer + * + */ +STATIC BOOLEAN +FchFindSpiDeviceProfile ( + IN UINT32 DeviceID, + IN OUT SPI_DEVICE_PROFILE *SpiDeviceProfilePtr + ) +{ + SPI_DEVICE_PROFILE *CurrentSpiDeviceProfilePtr; + UINT16 SpiQeRegValue; + SpiQeRegValue = 0; + CurrentSpiDeviceProfilePtr = SpiDeviceProfilePtr; + do { + if (CurrentSpiDeviceProfilePtr->JEDEC_ID == DeviceID) { + SpiDeviceProfilePtr = CurrentSpiDeviceProfilePtr; + if (!(FchReadSpiQe (SpiDeviceProfilePtr, SpiQeRegValue))) { + FchWriteSpiQe (SpiDeviceProfilePtr, SpiQeRegValue); + if (!(FchReadSpiQe (SpiDeviceProfilePtr, SpiQeRegValue))) { + return FALSE; + } + } + return TRUE; + } + CurrentSpiDeviceProfilePtr++; + } while (CurrentSpiDeviceProfilePtr->JEDEC_ID != 0); + return FALSE; +} + +/** + * FchConfigureSpiDeviceDummyCycle - Configure Spi Device Dummy + * Cycle + * + * + * + * @param[in] DeviceID - Device ID + * @param[in] FchDataPtr - FchData Pointer. + * + */ +STATIC BOOLEAN +FchConfigureSpiDeviceDummyCycle ( + IN UINT32 DeviceID, + IN OUT FCH_RESET_DATA_BLOCK *FchDataPtr + ) +{ + UINT16 Mode16; + UINT16 Value16; + UINT16 DummyValue16; + UINT16 CurrentDummyValue16; + UINT16 CurrentMode16; + AMD_CONFIG_PARAMS *StdHeader; + + StdHeader = FchDataPtr->StdHeader; + Value16 = 0; + DummyValue16 = 8; + + switch (DeviceID) { + case 0x17BA20: + + FchSpiTransfer ( + 0, //IN UINT8 PrefixCode, + 0xB5,//IN UINT8 Opcode, + (UINT8 *)(&Value16),//IN OUT UINT8 *DataPtr, + NULL,//IN UINT8 *AddressPtr, + 1,//IN UINT8 Length, + FALSE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + FALSE //IN BOOLEAN FinishedFlag + ); + CurrentDummyValue16 = Value16 >> 12; + CurrentMode16 = (Value16 >> 9) & 7; + + switch (FchDataPtr->Mode) { + case FCH_SPI_MODE_QUAL_144: + DummyValue16 = 6; + Mode16 = FCH_SPI_DEVICE_MODE_144; + break; + case FCH_SPI_MODE_QUAL_114: + DummyValue16 = 8; + Mode16 = FCH_SPI_DEVICE_MODE_114; + Mode16 = 7; + break; + case FCH_SPI_MODE_QUAL_122: + DummyValue16 = 4; + Mode16 = FCH_SPI_DEVICE_MODE_122; + break; + case FCH_SPI_MODE_QUAL_112: + DummyValue16 = 8; + Mode16 = FCH_SPI_DEVICE_MODE_112; + break; + case FCH_SPI_MODE_FAST: + DummyValue16 = 8; + Mode16 = FCH_SPI_DEVICE_MODE_FAST; + break; + default: + DummyValue16 = 15; + Mode16 = 7; + break; + } + if ((CurrentDummyValue16 != DummyValue16) || (CurrentMode16 != Mode16)) { + //FCH_DEADLOOP(); + Value16 &= ~ (0x7f << 9); + Value16 |= (DummyValue16 << 12); + Value16 |= (Mode16 << 9); + FchSpiTransfer ( + 0x06, //IN UINT8 PrefixCode, + 0xB1,//IN UINT8 Opcode, + (UINT8 *)(&Value16),//IN OUT UINT8 *DataPtr, + NULL,//IN UINT8 *AddressPtr, + 1,//IN UINT8 Length, + TRUE,//IN BOOLEAN WriteFlag, + FALSE,//IN BOOLEAN AddressFlag, + TRUE,//IN BOOLEAN DataFlag, + TRUE //IN BOOLEAN FinishedFlag + ); + FchStall (1000, StdHeader); + WriteIo8 ((UINT16) (0xCF9), 0x0E); + } + return TRUE; + default: + return FALSE; + } +} +/** + * FchPlatformSpiQe - Platform SPI Qual Enable + * + * + * + * @param[in] FchDataPtr - FchData Pointer. + * + */ +BOOLEAN +FchPlatformSpiQe ( + IN VOID *FchDataPtr + ) +{ + UINT32 DeviceID; + SPI_DEVICE_PROFILE *LocalSpiDeviceProfilePtr; + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + if (LocalCfgPtr->QeEnabled) { + return TRUE; + } + StdHeader = LocalCfgPtr->StdHeader; + FchReadSpiId (FALSE); + DeviceID = FchReadSpiId (TRUE); +// if (LocalCfgPtr->OemSpiDeviceTable != NULL) { +// LocalSpiDeviceProfilePtr = LocalCfgPtr->OemSpiDeviceTable; +// if (FchFindSpiDeviceProfile (DeviceID, LocalSpiDeviceProfilePtr)) { +// return TRUE; +// } +// } + LocalSpiDeviceProfilePtr = (SPI_DEVICE_PROFILE *) (&DefaultSpiDeviceTable); + if (FchConfigureSpiDeviceDummyCycle (DeviceID, LocalCfgPtr)) { + return TRUE; + } + if (FchFindSpiDeviceProfile (DeviceID, LocalSpiDeviceProfilePtr)) { + return TRUE; + } + return FALSE; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcEnv.c new file mode 100644 index 0000000000..4ddbe59b6c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcEnv.c @@ -0,0 +1,94 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch LPC controller + * + * Init LPC Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SPI_LPCENV_FILECODE + + +/** + * FchInitEnvLpc - Config LPC controller before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvLpc ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + // + // LPC CFG programming + // + // + // Turn on and configure LPC clock (48MHz) + // + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG28, AccessWidth32, (UINT32)~(BIT21 + BIT20 + BIT19), 2 << 19); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, (UINT32)~BIT7, 0); + + // + // Initialization of pci config space + // + FchInitEnvLpcProgram (FchDataPtr); + + // + // SSID for LPC Controller + // + if (LocalCfgPtr->Spi.LpcSsid != 0 ) { + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG2C, AccessWidth32, 0x00, LocalCfgPtr->Spi.LpcSsid, StdHeader); + } + // + // LPC MSI + // + if ( LocalCfgPtr->Spi.LpcMsiEnable ) { + RwPci ((LPC_BUS_DEV_FUN << 16) + 0x78, AccessWidth32, (UINT32)~BIT1, BIT1, StdHeader); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcLate.c new file mode 100644 index 0000000000..44ac896d7c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcLate.c @@ -0,0 +1,58 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch LPC controller + * + * Init LPC Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SPI_LPCLATE_FILECODE + +/** + * FchInitLateLpc - Prepare Ir controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateLpc ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcMid.c new file mode 100644 index 0000000000..cc1fbbb793 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcMid.c @@ -0,0 +1,60 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch LPC controller + * + * Init LPC Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SPI_LPCMID_FILECODE + +/** + * FchInitMidLpc - Config Lpc controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidLpc ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcReset.c new file mode 100644 index 0000000000..8cbd8eb886 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/LpcReset.c @@ -0,0 +1,70 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch LPC controller + * + * Init LPC Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SPI_LPCRESET_FILECODE + + +/** + * FchInitResetLpc - Config Lpc controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetLpc ( + IN VOID *FchDataPtr + ) +{ + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + FchInitResetLpcProgram (FchDataPtr); + +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiEnv.c new file mode 100644 index 0000000000..ad7cdfbbb0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiEnv.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Spi (Lpc) controller + * + * Init Spi (Lpc) Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SPI_SPIENV_FILECODE + +/** + * FchInitEnvSpi - Config Spi controller before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvSpi ( + IN VOID *FchDataPtr + ) +{ + FchInitEnvLpc (FchDataPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiLate.c new file mode 100644 index 0000000000..f143452533 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiLate.c @@ -0,0 +1,113 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Spi (Lpc) controller + * + * Init Spi (Lpc) Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SPI_SPILATE_FILECODE + +/** + * FchInitLateSpi - Prepare Spi controller to boot to OS. + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateSpi ( + IN VOID *FchDataPtr + ) +{ + FchInitLateLpc (FchDataPtr); +} + +/** + * FchSpiUnlock - Fch SPI Unlock + * + * + * @param[in] FchDataPtr + * + */ +VOID +FchSpiUnlock ( + IN VOID *FchDataPtr + ) +{ + UINT32 SpiRomBase; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + SpiRomBase = LocalCfgPtr->Spi.RomBaseAddress; + + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG50, AccessWidth32, (UINT32)~(BIT0 + BIT1), 0, StdHeader); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG54, AccessWidth32, (UINT32)~(BIT0 + BIT1), 0, StdHeader); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG58, AccessWidth32, (UINT32)~(BIT0 + BIT1), 0, StdHeader); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG5C, AccessWidth32, (UINT32)~(BIT0 + BIT1), 0, StdHeader); + RwMem (SpiRomBase + FCH_SPI_MMIO_REG00, AccessWidth32, (UINT32)~(BIT22 + BIT23), (BIT22 + BIT23)); +} + +/** + * FchSpiLock - Fch SPI lock + * + * + * @param[in] FchDataPtr + * + */ +VOID +FchSpiLock ( + IN VOID *FchDataPtr + ) +{ + UINT32 SpiRomBase; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + SpiRomBase = LocalCfgPtr->Spi.RomBaseAddress; + + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG50, AccessWidth32, (UINT32)~(BIT0 + BIT1), (BIT0 + BIT1), StdHeader); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG54, AccessWidth32, (UINT32)~(BIT0 + BIT1), (BIT0 + BIT1), StdHeader); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG58, AccessWidth32, (UINT32)~(BIT0 + BIT1), (BIT0 + BIT1), StdHeader); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG5C, AccessWidth32, (UINT32)~(BIT0 + BIT1), (BIT0 + BIT1), StdHeader); + RwMem (SpiRomBase + FCH_SPI_MMIO_REG00, AccessWidth32, (UINT32)~(BIT22 + BIT23), 0); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiMid.c new file mode 100644 index 0000000000..4f8b883551 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiMid.c @@ -0,0 +1,61 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Spi (Lpc) controller + * + * Init Spi (Lpc) Controller features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SPI_SPIMID_FILECODE + +/** + * FchInitMidSpi - Config Spi controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidSpi ( + IN VOID *FchDataPtr + ) +{ + FchInitMidLpc (FchDataPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiReset.c new file mode 100644 index 0000000000..dad50a823a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/SpiReset.c @@ -0,0 +1,45 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Spi controller + * + * Init Spi Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#define FILECODE PROC_FCH_SPI_SPIRESET_FILECODE diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciEnv.c new file mode 100644 index 0000000000..d78370bc36 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciEnv.c @@ -0,0 +1,60 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB EHCI controller + * + * Init USB EHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_EHCIENV_FILECODE + +/** + * FchInitEnvUsbEhci - Config USB EHCI controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvUsbEhci ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciLate.c new file mode 100644 index 0000000000..88f672f3d2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciLate.c @@ -0,0 +1,60 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB EHCI controller + * + * Init USB EHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_EHCILATE_FILECODE + +/** + * FchInitLateUsbEhci - Config USB EHCI controller before OS + * boot + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateUsbEhci ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciMid.c new file mode 100644 index 0000000000..dca9dc4211 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciMid.c @@ -0,0 +1,158 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB EHCI controller + * + * Init USB EHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_EHCIMID_FILECODE + +// +// Declaration of local functions +// +/** + * EhciInitAfterPciInit - Config USB controller after PCI emulation + * + * @param[in] Value Controller PCI config address (bus# + device# + function#) + * @param[in] FchDataPtr Fch configuration structure pointer. + */ +VOID EhciInitAfterPciInit (IN UINT32 Value, IN FCH_DATA_BLOCK* FchDataPtr); + +/** + * FchInitMidUsbEhci - Config USB EHCI controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbEhci ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + + FchInitMidUsbEhci1 (LocalCfgPtr); + FchInitMidUsbEhci2 (LocalCfgPtr); + FchInitMidUsbEhci3 (LocalCfgPtr); +} + +/** + * FchInitMidUsbEhci1 - Config USB1 EHCI controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbEhci1 ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINT32 DeviceId; + + DeviceId = (USB1_EHCI_BUS_DEV_FUN << 16); + EhciInitAfterPciInit (DeviceId, FchDataPtr); + +} + +/** + * FchInitMidUsbEhci2 - Config USB2 EHCI controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbEhci2 ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINT32 DeviceId; + + DeviceId = (USB2_EHCI_BUS_DEV_FUN << 16); + EhciInitAfterPciInit (DeviceId, FchDataPtr); + +} + +/** + * FchInitMidUsbEhci3 - Config USB3 EHCI controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ + +VOID +FchInitMidUsbEhci3 ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINT32 DeviceId; + + DeviceId = (USB3_EHCI_BUS_DEV_FUN << 16); + EhciInitAfterPciInit (DeviceId, FchDataPtr); + +} + +/** + * EhciInitAfterPciInit - Config EHCI controller after PCI + * emulation + * + * + * @param[in] Value EHCI Controler info. + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +EhciInitAfterPciInit ( + IN UINT32 Value, + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + FchEhciInitAfterPciInit ( Value, FchDataPtr); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciReset.c new file mode 100644 index 0000000000..d716606bed --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/EhciReset.c @@ -0,0 +1,62 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Ehci controller + * + * Init Ehci Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_EHCIRESET_FILECODE + +/** + * FchInitResetEhci - Config Ehci controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetEhci ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciEnvService.c new file mode 100644 index 0000000000..e3f8ca8d3c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciEnvService.c @@ -0,0 +1,44 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB EHCI controller + * + * Init USB EHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEEHCIENVSERVICE_FILECODE diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciLateService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciLateService.c new file mode 100644 index 0000000000..785064f61f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciLateService.c @@ -0,0 +1,47 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB EHCI controller + * + * Init USB EHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEEHCILATESERVICE_FILECODE +// +// Declaration of local functions +// diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciMidService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciMidService.c new file mode 100644 index 0000000000..977ee0e27a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeEhciMidService.c @@ -0,0 +1,188 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB EHCI controller + * + * Init USB EHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87830 $ @e \$Date: 2013-02-11 12:48:20 -0600 (Mon, 11 Feb 2013) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEEHCIMIDSERVICE_FILECODE +// +// Declaration of local functions +// + +/** + * FchEhciInitAfterPciInit - Config USB controller after PCI emulation + * + * @param[in] Value Controller PCI config address (bus# + device# + function#) + * @param[in] FchDataPtr Fch configuration structure pointer. + */ +VOID +FchEhciInitAfterPciInit ( + IN UINT32 Value, + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINT8 Index; + UINT32 BarAddress; + UINT32 Var; + UINT8 UsbS3WakeResumeOnlyDisable; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + UINT32 PortNum; + UINT32 DrivingStrength; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + // + //Get BAR address + // + ReadPci ((UINT32) Value + FCH_EHCI_REG10, AccessWidth32, &BarAddress, StdHeader); + if ( (BarAddress != - 1) && (BarAddress != 0) ) { + // + //Enable Memory access + // + RwPci ((UINT32) Value + FCH_EHCI_REG04, AccessWidth8, 0, BIT1, StdHeader); + if (FchDataPtr->Usb.EhciSsid != 0 ) { + RwPci ((UINT32) Value + FCH_EHCI_REG2C, AccessWidth32, 0x00, FchDataPtr->Usb.EhciSsid, StdHeader); + } + RwMem (BarAddress + FCH_EHCI_BAR_REGA4, AccessWidth32, 0xFF00FF00, 0x00400040); + RwMem (BarAddress + FCH_EHCI_BAR_REGBC, AccessWidth32, (UINT32)~( BIT12 + BIT14), BIT12 + BIT14); + RwMem (BarAddress + 0x0B0, AccessWidth32, (UINT32)~BIT5, BIT5); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth16, (UINT32)~BIT12, BIT12); + for (PortNum = 0; PortNum < 5; PortNum ++) { + if (Value == (USB1_EHCI_BUS_DEV_FUN << 16)) { + DrivingStrength = (UINT32) (LocalCfgPtr->Usb.Ehci1Phy[PortNum]); + } else if (Value == (USB2_EHCI_BUS_DEV_FUN << 16)) { + DrivingStrength = (UINT32) (LocalCfgPtr->Usb.Ehci2Phy[PortNum]); + } else if ((Value == (USB3_EHCI_BUS_DEV_FUN << 16)) && (PortNum < 4)) { + DrivingStrength = (UINT32) (LocalCfgPtr->Usb.Ehci3Phy[PortNum]); + } else { + break; + } + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, 0xFFFE0000, (PortNum << 13) + DrivingStrength); + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, (UINT32)~BIT12, BIT12); + DrivingStrength = 0x302; + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, 0xFFFFC000, (PortNum << 13) + BIT12 + DrivingStrength); + Index = 0; + do { + ReadMem ( BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, &Var); + Index++; + FchStall (10, StdHeader); + } while (( Var & BIT17) && (Index < 10 )); + Index = 0; + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, 0xFFFFC000, (PortNum << 13) + DrivingStrength); + do { + ReadMem ( BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, &Var); + Index++; + FchStall (10, StdHeader); + } while (( Var & BIT17) && (Index < 10 )); + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, 0xFFFFC000, (PortNum << 13) + BIT12 + DrivingStrength); + } + // Step3 + RwMem (BarAddress + FCH_EHCI_BAR_REGD0, AccessWidth32, ~((UINT32) (0x0F)), (UINT32) (0x6)); + RwMem (BarAddress + FCH_EHCI_BAR_REGC4, AccessWidth32, (UINT32) (~ 0xff00ffff), 0x90001221); + RwMem (BarAddress + FCH_EHCI_BAR_REGD4, AccessWidth32, ~((UINT32) (0xC2)), (UINT32) (0x40)); + FchStall (200, StdHeader); + RwMem (BarAddress + FCH_EHCI_BAR_REGD4, AccessWidth32, ~((UINT32) (0x02)), (UINT32) (0x02)); + FchStall (400, StdHeader); + RwMem (BarAddress + FCH_EHCI_BAR_REGD4, AccessWidth32, ~((UINT32) (0x02)), (UINT32) (0x0)); + RwMem (BarAddress + FCH_EHCI_BAR_REGC0, AccessWidth32, (UINT32) (~ 0x00010000), BIT16); + + RwPci ((UINT32) Value + 0x50, AccessWidth32, ~ ((UINT32) (0x01 << 6)), (UINT32) (0x01 << 6), StdHeader); + RwPci ((UINT32) Value + 0x50, AccessWidth32, ~ ((UINT32) (0x0F << 8)), (UINT32) (0x01 << 8), StdHeader); + RwPci ((UINT32) Value + 0x50, AccessWidth32, ~ ((UINT32) (0x0F << 12)), (UINT32) (0x01 << 12), StdHeader); + RwPci ((UINT32) Value + 0x50, AccessWidth32, ~ ((UINT32) (0x01 << 17)), (UINT32) (0x01 << 17), StdHeader); + RwPci ((UINT32) Value + 0x50, AccessWidth32, ~ ((UINT32) (0x01 << 21)), (UINT32) (0x01 << 21), StdHeader); + + RwPci ((UINT32) Value + 0x50, AccessWidth32, ~ ((UINT32) (0x01 << 29)), (UINT32) (0x01 << 29), StdHeader); + RwPci ((UINT32) Value + 0x50 + 2, AccessWidth16, (UINT16)0xFFFF, BIT16 + BIT10, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54, AccessWidth16, 0xCC04, 0x0000027b, StdHeader); + RwAlink ((FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29)), 0xFFFEFFFF, BIT16, StdHeader); + if ( FchDataPtr->Usb.UsbMsiEnable) { + RwPci ((UINT32) Value + 0x50, AccessWidth32, (UINT32)~BIT6, 0x00, StdHeader); + } + RwPci ((UINT32) Value + FCH_EHCI_REG54, AccessWidth32, (UINT32)~BIT4, BIT4, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54, AccessWidth32, (UINT32)~BIT11, BIT11, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54, AccessWidth16, (UINT16)0x5FFF, BIT15, StdHeader); + RwPci ((UINT32) Value + 0x50 + 2, AccessWidth16, (UINT32)~BIT3, BIT3, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT16)0xFFFC, BIT0 + BIT1, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT16)0xFFFB, BIT2, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT16)0xFFF7, BIT3, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT5, BIT5, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT8, BIT8, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT4, BIT4, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT6, BIT6, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT9, BIT9, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT11, BIT11, StdHeader); + RwPci ((UINT32) Value + 0x50, AccessWidth16, (UINT32)~BIT0, BIT0, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT12, BIT12, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT13, BIT13, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54, AccessWidth16, (UINT32)~BIT12, BIT12, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG54 + 2, AccessWidth16, (UINT32)~BIT14, BIT14, StdHeader); + for ( PortNum = 0; PortNum < 5; PortNum++ ) { + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, 0xFFFE0000, (UINT32) ((PortNum << 13) + BIT12 + (0x7 << 7))); + if (PortNum < 4) { + ReadMem (BarAddress + FCH_EHCI_BAR_REGA8, AccessWidth32, &Var); + Var = (Var >> (PortNum * 8)) & 0x000000FF; + } else { + ReadMem (BarAddress + FCH_EHCI_BAR_REGAC, AccessWidth32, &Var); + Var = Var & 0x000000FF; + } + Var &= 0xF8; + Var |= BIT0 + BIT2; + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, 0xFFFE0000, (UINT32) ((PortNum << 13) + BIT12 + (0x7 << 7) + Var)); + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, ~((UINT32) (1 << 12)), 0); + RwMem (BarAddress + FCH_EHCI_BAR_REGB4, AccessWidth32, ~((UINT32) (1 << 12)), (UINT32) (0x1 << 12)); + } + } else { + BarAddress = FCH_FAKE_USB_BAR_ADDRESS; + WritePci ((UINT32) Value + FCH_EHCI_REG10, AccessWidth32, &BarAddress, StdHeader); + RwPci ((UINT32) Value + FCH_EHCI_REG04, AccessWidth8, 0, BIT1, StdHeader); + RwMem (BarAddress + FCH_EHCI_BAR_REGBC, AccessWidth32, (UINT32)~( BIT12 + BIT14), BIT12 + BIT14); + RwPci ((UINT32) Value + FCH_EHCI_REG04, AccessWidth8, 0, 0, StdHeader); + } + + ReadPmio (FCH_PMIOA_REGF0, AccessWidth8, &UsbS3WakeResumeOnlyDisable, StdHeader); + if ( (UsbS3WakeResumeOnlyDisable &= BIT6) == BIT6 ) { + RwPmio (FCH_PMIOA_REGF4, AccessWidth8, (UINT32)~BIT2, 0, StdHeader); + } else { + RwPmio (FCH_PMIOA_REGF4, AccessWidth8, (UINT32)~BIT2, BIT2, StdHeader); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciEnvService.c new file mode 100644 index 0000000000..096e279d86 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciEnvService.c @@ -0,0 +1,96 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB OHCI controller + * + * Init USB OHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEOHCIENVSERVICE_FILECODE +// +// Declaration of local functions +// +/** + * FchSetUsbEnableReg + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchSetUsbEnableReg ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINT8 UsbModeReg; + UINT8 XhciReg00; + UsbModeReg = 0; + + // Overwrite EHCI3/OHCI3 by Xhci1Enable + ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth8, &XhciReg00); + if (XhciReg00 & BIT0) { + FchDataPtr->Usb.Ohci3Enable = FALSE; + FchDataPtr->Usb.Ehci3Enable = FALSE; + UsbModeReg |= 0x80; + } else { + UsbModeReg &= 0x7F; + } + + if ( FchDataPtr->Usb.Ohci1Enable ) { + UsbModeReg |= 0x01; + } + if ( FchDataPtr->Usb.Ehci1Enable ) { + UsbModeReg |= 0x02; + } + if ( FchDataPtr->Usb.Ohci2Enable ) { + UsbModeReg |= 0x04; + } + if ( FchDataPtr->Usb.Ehci2Enable ) { + UsbModeReg |= 0x08; + } + if ( FchDataPtr->Usb.Ohci3Enable ) { + UsbModeReg |= 0x10; + } + if ( FchDataPtr->Usb.Ehci3Enable ) { + UsbModeReg |= 0x20; + } + + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, 0, UsbModeReg); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciLateService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciLateService.c new file mode 100644 index 0000000000..15a19976fb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciLateService.c @@ -0,0 +1,48 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB OHCI controller + * + * Init USB OHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEOHCILATESERVICE_FILECODE +// +// Declaration of local functions +// + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciMidService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciMidService.c new file mode 100644 index 0000000000..54a076f9d8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeOhciMidService.c @@ -0,0 +1,107 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB OHCI controller + * + * Init USB OHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEOHCIMIDSERVICE_FILECODE +// +// Declaration of local functions +// + +/** + * FchOhciInitAfterPciInit - Config USB OHCI controller after + * PCI emulation + * + * @param[in] Value Controller PCI config address (bus# + device# + function#) + * @param[in] FchDataPtr Fch configuration structure pointer. + */ +VOID +FchOhciInitAfterPciInit ( + IN UINT32 Value, + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + // + // Disable the MSI capability of USB host controllers + // ?? + RwPci ((UINT32) Value + FCH_OHCI_REG40 + 1, AccessWidth8, 0xFF, BIT0, FchDataPtr->StdHeader); + RwPci ((UINT32) Value + 0x50, AccessWidth8, (UINT32)~(BIT0 + BIT5 + BIT12), BIT0, FchDataPtr->StdHeader); + // + // USB SMI Handshake + // + RwPci ((UINT32) Value + 0x50 + 1, AccessWidth8, (UINT32)~BIT4, 0x00, FchDataPtr->StdHeader); + + if (Value != (USB4_OHCI_BUS_DEV_FUN << 16)) { + if ( FchDataPtr->Usb.OhciSsid != 0 ) { + RwPci ((UINT32) Value + FCH_OHCI_REG2C, AccessWidth32, 0x00, FchDataPtr->Usb.OhciSsid, FchDataPtr->StdHeader); + } + } + // + // recommended setting to, enable fix to cover the corner case S3 wake up issue from some USB 1.1 devices + //OHCI 0_PCI_Config 0x50[30] = 1 + // + RwPci ((UINT32) Value + 0x50 + 3, AccessWidth8, (UINT32)~BIT6, BIT6, FchDataPtr->StdHeader); + // + // L1 Early Exit + // Set OHCI Arbiter Mode. + // Set Enable Global Clock Gating. + // RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth16, (UINT32)~BIT12, BIT12) For RPR* "prevent OHCI/EHCI could enable/disable separately." + // + RwPci ((UINT32) Value + 0x50, AccessWidth8, (UINT32)~BIT0, 0x00, FchDataPtr->StdHeader); + RwPci ((UINT32) Value + FCH_OHCI_REG80, AccessWidth8, (UINT32)~(BIT0 + BIT4 + BIT5 + BIT6 + BIT7), BIT0 + BIT4 + BIT7, FchDataPtr->StdHeader); + RwPci ((UINT32) Value + FCH_OHCI_REG80, AccessWidth16, (UINT32)~(BIT4 + BIT5 + BIT8), BIT4 + BIT5 + BIT8, FchDataPtr->StdHeader); + + // + // Enable OHCI SOF Synchronization. + // Enable OHCI Periodic List Advance. + // + RwPci ((UINT32) Value + 0x50 + 2, AccessWidth8, (UINT32)~(BIT3 + BIT4 + BIT6 + BIT7), BIT3 + BIT4 + BIT6 + BIT7, FchDataPtr->StdHeader); + if ( FchDataPtr->Usb.UsbMsiEnable) { + RwPci ((UINT32) Value + FCH_OHCI_REG40 + 1, AccessWidth8, (UINT32)~BIT0, 0x00, FchDataPtr->StdHeader); + RwPci ((UINT32) Value + 0x50, AccessWidth8, (UINT32)~BIT5, BIT5, FchDataPtr->StdHeader); + } + // USB1.1 full-speed false crc errors detected. Issue - fix enable + RwPci ((UINT32) Value + FCH_OHCI_REG80, AccessWidth32, (UINT32) (~(0x01 << 9)), (UINT32) (0x01 << 9), FchDataPtr->StdHeader); + RwPci ((UINT32) Value + FCH_OHCI_REG80, AccessWidth32, (UINT32) (~(0x01 << 10)), (UINT32) (0x01 << 10), FchDataPtr->StdHeader); + RwPci ((UINT32) Value + FCH_OHCI_REG80, AccessWidth32, (UINT32) (~(0x01 << 11)), (UINT32) (0x01 << 11), FchDataPtr->StdHeader); + RwPci ((UINT32) Value + FCH_OHCI_REG80, AccessWidth32, (UINT32) (~(0x01 << 12)), (UINT32) (0x01 << 12), FchDataPtr->StdHeader); + RwPci ((UINT32) Value + FCH_OHCI_REG80, AccessWidth32, (UINT32) (~(0x03 << 14)), (UINT32) (0x03 << 14), FchDataPtr->StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciEnvService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciEnvService.c new file mode 100644 index 0000000000..67fcaf6408 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciEnvService.c @@ -0,0 +1,482 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB3 controller + * + * Init USB3 features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 87830 $ @e \$Date: 2013-02-11 12:48:20 -0600 (Mon, 11 Feb 2013) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEXHCIENVSERVICE_FILECODE + +// +// Declaration of local functions +// + + +/** + * FchXhciUsbPhyCalibrated - Config XHCI Phy + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchXhciUsbPhyCalibrated ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINT8 Index; + UINT32 DrivingStrength; + UINT32 Port; + UINT32 Register; + UINT32 RegValue; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG8C, AccessWidth32, 0xFFF0FFFF, 0x00030000); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG8C, AccessWidth32, 0xFEFFFFFF, 0x01000000); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG8C, AccessWidth32, 0x3FFFFFFF, 0x80000000); + + + DrivingStrength = 0x302; + for (Port = 0; Port < 2; Port ++) { + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + DrivingStrength, StdHeader); + Register = FCH_XHCI_IND60_REG00; + Index = 0; + do { + WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x48, AccessWidth32, &Register, StdHeader); + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x4C, AccessWidth32, &RegValue, StdHeader); + Index++; + FchStall (10, StdHeader); + } while ((RegValue & BIT17) && (Index < 10 )); + Index = 0; + do { + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + DrivingStrength, StdHeader); + WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x48, AccessWidth32, &Register, StdHeader); + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x4C, AccessWidth32, &RegValue, StdHeader); + Index++; + FchStall (10, StdHeader); + } while ((RegValue & BIT17) && (Index < 10 )); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + DrivingStrength, StdHeader); + } + RwXhci0IndReg ( FCH_XHCI_IND60_REG50, ~ ((UINT32) (0x0f)), ((UINT32) (0x06)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f << 4)), ((UINT32) (0x02 << 4)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f << 8)), ((UINT32) (0x02 << 8)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f << 12)), ((UINT32) (0x01 << 12)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f)), ((UINT32) (0x01)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG0C, ~ ((UINT32) (0xff << 24)), ((UINT32) (0x90 << 24)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG54, ~ ((UINT32) (0x03 << 6)), ((UINT32) (0x01 << 6)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG54, ~ ((UINT32) (0x01 << 1)), ((UINT32) (0x00 << 1)), StdHeader); + FchStall (200, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG54, ~ ((UINT32) (0x01 << 1)), ((UINT32) (0x01 << 1)), StdHeader); + FchStall (400, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG54, ~ ((UINT32) (0x01 << 1)), ((UINT32) (0x00 << 1)), StdHeader); +} + +/** + * FchXhciInitIndirectReg - Config XHCI Indirect Registers + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchXhciInitIndirectReg ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINT8 Index; + UINT32 DrivingStrength; + UINT32 Port; + UINT32 Register; + UINT32 RegValue; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + DrivingStrength = 0; + + RwXhci0IndReg ( FCH_XHCI_IND_REG94, 0xFFFFFC00, 0x00000021, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND_REGD4, 0xFFFFFC00, 0x00000021, StdHeader); + + RwXhci0IndReg ( FCH_XHCI_IND_REG00, 0xF8FFFFFF, 0x07000000, StdHeader); + for (Port = 0; Port < 2; Port ++) { + DrivingStrength = (UINT32) (LocalCfgPtr->Usb.Xhci20Phy[Port]); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + DrivingStrength, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + DrivingStrength, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + DrivingStrength, StdHeader); + } + + + RwXhci0IndReg ( FCH_XHCI_IND60_REG50, ~ ((UINT32) (0x0f)), ((UINT32) (0x07)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f << 4)), ((UINT32) (0x02 << 4)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f << 8)), ((UINT32) (0x02 << 8)), StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG08, 0x80FC00FF, 0, StdHeader); // For BTS + + for (Port = 0; Port < 2; Port ++) { + DrivingStrength = 0x1E4; + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE0000, (Port << 13) + BIT12 + DrivingStrength, StdHeader); + Register = FCH_XHCI_IND60_REG00; + Index = 0; + do { + WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x48, AccessWidth32, &Register, StdHeader); + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x4C, AccessWidth32, &RegValue, StdHeader); + Index++; + FchStall (10, StdHeader); + } while ((RegValue & BIT17) && (Index < 10 )); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE0000, (Port << 13) + DrivingStrength, StdHeader); + Register = FCH_XHCI_IND60_REG00; + Index = 0; + do { + WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x48, AccessWidth32, &Register, StdHeader); + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x4C, AccessWidth32, &RegValue, StdHeader); + Index++; + FchStall (10, StdHeader); + } while ((RegValue & BIT17) && (Index < 10 )); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE0000, (Port << 13) + BIT12 + DrivingStrength, StdHeader); + } + for (Port = 0; Port < 2; Port ++) { + DrivingStrength = 0x1C4; + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + DrivingStrength, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + DrivingStrength, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + DrivingStrength, StdHeader); + } + + for (Port = 0; Port < 4; Port ++) { + if (Port < 2) { + ReadXhci0Phy (Port, (0x7 << 7), &DrivingStrength, StdHeader); + DrivingStrength &= 0x0000000F8; + DrivingStrength |= BIT0 + BIT2; + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + (0x7 << 7) + DrivingStrength, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + (0x7 << 7) + DrivingStrength, StdHeader); + RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFC000, (Port << 13) + BIT12 + (0x7 << 7) + DrivingStrength, StdHeader); + } + } + RwXhci0IndReg ( FCH_XHCI_IND60_REG48, 0xFFFFFFE0, BIT0, StdHeader); +} + +/** + * FchCombineSigRomInfo - Combine SIG ROM information + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +STATIC UINT32 +FchCombineSigRomInfo ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINTN RomSigStartingAddr; + UINT32 RomStore[NUM_OF_ROMSIG_FILED]; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + UINT32 SelNum; + UINT32 RomSignatureTag; + UINT16 XhciFwTag; + + LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + for ( SelNum = 0; SelNum < NUM_OF_ROMSIG_FILED; SelNum++) { + RomStore [SelNum] = 0; + } + GetRomSigPtr (&RomSigStartingAddr, StdHeader); + RomSignatureTag = ACPIMMIO32 (RomSigStartingAddr); + if ( RomSignatureTag == ROMSIG_SIG ) { + for ( SelNum = 0; SelNum < NUM_OF_ROMSIG_FILED; SelNum++) { + RomStore[SelNum] = ACPIMMIO32 (RomSigStartingAddr + (SelNum << 2)); + } + } else { + RomStore[XHCI_FILED_NUM] = 0; + } + if ( LocalCfgPtr->Usb.UserDefineXhciRomAddr != 0 ) { + RomStore[XHCI_FILED_NUM] = LocalCfgPtr->Usb.UserDefineXhciRomAddr; + } + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGC8 + 3, AccessWidth8, 0x7F, BIT7, StdHeader); + for ( SelNum = 1; SelNum < NUM_OF_ROMSIG_FILED; SelNum++) { + if (RomStore[SelNum] != 0) { + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, (UINT32)~ (BIT2 + BIT1 + BIT0), (BIT2 + SelNum), StdHeader); + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, ROMSIG_CFG_MASK, RomStore[SelNum], StdHeader); + } + } + XhciFwTag = (UINT16) ACPIMMIO32 ((RomStore[XHCI_FILED_NUM]) + XHCI_BOOT_RAM_OFFSET); + if ( XhciFwTag != INSTRUCTION_RAM_SIG ) { + RomStore[XHCI_FILED_NUM] = 0; + } + return RomStore[XHCI_FILED_NUM]; +} + +/** + * FchXhciInitBeforePciInit - Config XHCI controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchXhciInitBeforePciInit ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + UINT16 BcdAddress; + UINT16 BcdSize; + UINT16 AcdAddress; + UINT16 AcdSize; + UINT16 FwAddress; + UINT16 FwSize; + UINT32 XhciFwStarting; + UINT32 SpiValidBase; + UINT32 RegData; + UINT16 Index; + BOOLEAN Xhci0Enable; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + Xhci0Enable = LocalCfgPtr->Usb.Xhci0Enable; + + if ( Xhci0Enable == 0 ) { + return; + } + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0x00080000, 0x00400700); + FchStall (20, StdHeader); + + RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGC8 + 3, AccessWidth8, 0x7F, BIT7, StdHeader); + XhciFwStarting = FchCombineSigRomInfo (FchDataPtr); + if ( XhciFwStarting == 0 ) { + return; + } + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, 0xFFFFF9FF, 0x00000600); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90, AccessWidth32, 0xCFF00000, 0x000AAAAA); + + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG50 + 1, AccessWidth8, (UINT32)~BIT1, BIT1); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT4 + BIT5), 0); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT7), BIT7); /// Enable 2.0 devices + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xF0FFFFFC, 0x01); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xEFFFFFFF, 0x10000000); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA0, AccessWidth32, 0x00000000, (SPI_HEAD_LENGTH << 16)); + + BcdAddress = ACPIMMIO16 (XhciFwStarting + BCD_ADDR_OFFSET + XHC_BOOT_RAM_SIZE); + BcdSize = ACPIMMIO16 (XhciFwStarting + BCD_SIZE_OFFSET + XHC_BOOT_RAM_SIZE); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4, AccessWidth16, 0x0000, BcdAddress); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4 + 2, AccessWidth16, 0x0000, BcdSize); + + AcdAddress = ACPIMMIO16 (XhciFwStarting + ACD_ADDR_OFFSET + XHC_BOOT_RAM_SIZE); + AcdSize = ACPIMMIO16 (XhciFwStarting + ACD_SIZE_OFFSET + XHC_BOOT_RAM_SIZE); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8, AccessWidth16, 0x0000, AcdAddress); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8 + 2, AccessWidth16, 0x0000, AcdSize); + + SpiValidBase = SPI_BASE2 (XhciFwStarting + 4 + XHC_BOOT_RAM_SIZE) | SPI_BAR0_VLD | SPI_BASE0 | SPI_BAR1_VLD | SPI_BASE1 | SPI_BAR2_VLD; + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB0, AccessWidth32, 0x00000000, SpiValidBase); + for (Index = 0; Index < SPI_HEAD_LENGTH; Index++) { + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + XHC_BOOT_RAM_SIZE + Index)); + } + + for (Index = 0; Index < BcdSize; Index++) { + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + BcdAddress + Index)); + } + + for (Index = 0; Index < AcdSize; Index++) { + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + BcdSize + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + AcdAddress + Index)); + } + + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT0, BIT0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, 0); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04 + 2, AccessWidth16, 0x7FFF, BIT15); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04, AccessWidth16, 0x0000, 0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08 + 2, AccessWidth16, 0x0000, 0x8000); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08, AccessWidth16, 0x0000, 0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, BIT29); + + for (;;) { + ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); + if (RegData & BIT30) { + break; + } + } + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, 0); + + FwAddress = ACPIMMIO16 (XhciFwStarting + FW_ADDR_OFFSET + XHC_BOOT_RAM_SIZE); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth16, 0x0000, ACPIMMIO16 (XhciFwStarting + FwAddress)); + FwAddress += 2; + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04, AccessWidth16, 0x0000, FwAddress + XHC_BOOT_RAM_SIZE); + + FwSize = ACPIMMIO16 (XhciFwStarting + FW_SIZE_OFFSET + XHC_BOOT_RAM_SIZE); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08, AccessWidth16, 0x0000, 0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08 + 2, AccessWidth16, 0x0000, FwSize); + // + // Step 3.5 to enable the instruction RAM preload functionality. + // + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04 + 2, AccessWidth16, 0x7FFF, 0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, BIT29); + + for (;;) { + ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); + if (RegData & BIT30) { + break; + } + } + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, 0); + + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3PLL_RESET, 0); ///Release U3PLLreset + for (;;) { + ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); + if (RegData & U3PLL_LOCK) { + break; + } + } + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3PHY_RESET, 0); ///Release U3PHY + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3CORE_RESET, 0); ///Release core reset + + FchXhciUsbPhyCalibrated (LocalCfgPtr); + + FchXhciInitIndirectReg (LocalCfgPtr); + + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT4 + BIT5), 0); /// Disable Device 22 + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT7), BIT7); /// Enable 2.0 devices + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~(BIT21), BIT21); + // + // Step 5. + // + RwMem (ACPI_MMIO_BASE + XHCI_BASE + 0x00, AccessWidth32, (UINT32)~(BIT17 + BIT18 + BIT19), BIT17 + BIT18 + BIT19); + + // + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x3 << 11)), (UINT32) (0x3 << 11)); + // + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x1 << 16)), (UINT32) (0x1 << 16)); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x1 << 15)), (UINT32) (0x1 << 15)); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x7 << 18)), (UINT32) (0x7 << 18)); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth32, ~((UINT32) (0x1 << 13)), (UINT32) (0x1 << 13)); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth32, ~((UINT32) (0x1 << 14)), (UINT32) (0x1 << 14)); + + RwXhci0IndReg ( FCH_XHCI_IND_REG54, (UINT32)~(BIT15), BIT15, StdHeader); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, (UINT32)~(BIT25 + BIT24), BIT24); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, (UINT32)~(BIT22), BIT22); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT20), BIT20); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT15), BIT15); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT1), BIT1); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT2), BIT2); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT3), BIT3); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT6), BIT6); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT7), BIT7); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT8), BIT8); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT9), BIT9); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT10), BIT10); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT11), BIT11); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT12), BIT12); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT13), BIT13); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT14), BIT14); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT16), BIT16); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG40, AccessWidth32, (UINT32)~(BIT0), BIT0); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + 0x20, AccessWidth32, (UINT32)~(BIT13 + BIT14 + BIT21), BIT13 + BIT14 + BIT21); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT20), BIT20); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF2, AccessWidth8, (UINT32)~(BIT3), BIT3); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT22), BIT22); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT17), BIT17); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT18), BIT18); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT24), BIT24); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT25), BIT25); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT8), BIT8); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT9), BIT9); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT10), BIT10); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT12), BIT12); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT20 + BIT21 + BIT22), (BIT20 + BIT21 + BIT22)); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT23), BIT23); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT27), BIT27); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~BIT29, BIT29); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + 0x98, AccessWidth32, (UINT32)~(BIT30), BIT30); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + 0x98, AccessWidth32, (UINT32)~(BIT31), BIT31); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT27), BIT27); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT28), BIT28); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT0 + BIT1 + BIT2), BIT0 + BIT1 + BIT2); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG120); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT3), BIT3); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT21), BIT21); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG128); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT0), BIT0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT3 + BIT4), BIT3 + BIT4); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT5), BIT5); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG48); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT1), BIT1); + + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG48); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT14), BIT14); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT17), BIT17); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT15 + BIT14), BIT14); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT11), BIT11); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT16), BIT16); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + 0x28, AccessWidth32, (UINT32)~(BIT0), BIT0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT20 + BIT21 + BIT22), (BIT20 + BIT21 + BIT22)); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, (UINT32)~(BIT24 + BIT25 + BIT26), (BIT24 + BIT25 + BIT26)); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, (UINT32)~(BIT0 + BIT4 + BIT24), (BIT0 + BIT24)); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~ BIT5, BIT5); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG48); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, (UINT32)~(BIT16), BIT16); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG10, AccessWidth32, 0xFFFF00FF, 0x2A00); + RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG50 + 1, AccessWidth8, (UINT32)~BIT1, 0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, 0x80); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, 0xFFFFFFF8, 0x06); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, 0xC0); + RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, 0xFFFFFFF8, 0x06); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciLateService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciLateService.c new file mode 100644 index 0000000000..8c1cbaf591 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciLateService.c @@ -0,0 +1,130 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB3 controller + * + * Init USB3 features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEXHCILATESERVICE_FILECODE + +// +// Declaration of local functions +// + +/** + * FchInitLateUsbXhciProgram - Config USB3 controller before OS + * Boot + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateUsbXhciProgram ( + IN VOID *FchDataPtr + ) +{ + UINT8 IndexValue; + UINT8 Value; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + if ( LocalCfgPtr->Usb.Xhci1Enable == TRUE ) { + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x10, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI_REGISTER_BAR00; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x11, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI_REGISTER_BAR01; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x12, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI_REGISTER_BAR02; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x13, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI_REGISTER_BAR03; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x04, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI_REGISTER_04H; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x0C, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI_REGISTER_0CH; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x3C, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI_REGISTER_3CH; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x10, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI1_REGISTER_BAR00; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x11, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI1_REGISTER_BAR01; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x12, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI1_REGISTER_BAR02; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x13, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI1_REGISTER_BAR03; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x04, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI1_REGISTER_04H; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x0C, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI1_REGISTER_0CH; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + + ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x3C, AccessWidth8, &Value, StdHeader); + IndexValue = XHCI1_REGISTER_3CH; + WriteBiosram (IndexValue, AccessWidth8, &Value, StdHeader); + } + RwXhci0IndReg ( FCH_XHCI_IND_REG04, (UINT32)~ BIT8, BIT8, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciMidService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciMidService.c new file mode 100644 index 0000000000..7b784d09db --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciMidService.c @@ -0,0 +1,48 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Yangtze FCH USB3 controller + * + * Init USB3 features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEXHCIMIDSERVICE_FILECODE + +// +// Declaration of local functions +// diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciResetService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciResetService.c new file mode 100644 index 0000000000..5652974448 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/Family/Yangtze/YangtzeXhciResetService.c @@ -0,0 +1,118 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Xhci controller + * + * Init Xhci Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_FAMILY_YANGTZE_YANGTZEXHCIRESETSERVICE_FILECODE + +/** + * FchInitResetXhciProgram - Config Xhci controller during + * Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetXhciProgram ( + IN VOID *FchDataPtr + ) +{ + UINT8 IndexValue; + UINT32 ValueDword; + UINT8 ValueByte; + FCH_RESET_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x00, AccessWidth32, &ValueDword, StdHeader); + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x00, AccessWidth32, &ValueDword, StdHeader); + if ( ValueDword == (FCH_USB_XHCI_DID << 16) + FCH_USB_XHCI_VID) { + // + // First Xhci controller. + // + ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x00, AccessWidth32, &ValueDword, StdHeader); + ValueDword = 0; + + IndexValue = XHCI_REGISTER_BAR00; + ReadBiosram (IndexValue, AccessWidth32, &ValueDword, StdHeader); + WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x10, AccessWidth32, &ValueDword, StdHeader); + + IndexValue = XHCI_REGISTER_04H; + ReadBiosram (IndexValue, AccessWidth8, &ValueByte, StdHeader); + WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x04, AccessWidth8, &ValueByte, StdHeader); + + IndexValue = XHCI_REGISTER_0CH; + ReadBiosram (IndexValue, AccessWidth8, &ValueByte, StdHeader); + WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x0C, AccessWidth8, &ValueByte, StdHeader); + + IndexValue = XHCI_REGISTER_3CH; + ReadBiosram (IndexValue, AccessWidth8, &ValueByte, StdHeader); + WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x3C, AccessWidth8, &ValueByte, StdHeader); + // + // Second Xhci controller. + // + ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x00, AccessWidth32, &ValueDword, StdHeader); + ValueDword = 0; + + IndexValue = XHCI1_REGISTER_BAR00; + ReadBiosram (IndexValue, AccessWidth32, &ValueDword, StdHeader); + WritePci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x10, AccessWidth32, &ValueDword, StdHeader); + + IndexValue = XHCI1_REGISTER_04H; + ReadBiosram (IndexValue, AccessWidth8, &ValueByte, StdHeader); + WritePci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x04, AccessWidth8, &ValueByte, StdHeader); + + IndexValue = XHCI1_REGISTER_0CH; + ReadBiosram (IndexValue, AccessWidth8, &ValueByte, StdHeader); + WritePci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x0C, AccessWidth8, &ValueByte, StdHeader); + + IndexValue = XHCI1_REGISTER_3CH; + ReadBiosram (IndexValue, AccessWidth8, &ValueByte, StdHeader); + WritePci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x3C, AccessWidth8, &ValueByte, StdHeader); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciEnv.c new file mode 100644 index 0000000000..ca0523403c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciEnv.c @@ -0,0 +1,60 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB OHCI controller + * + * Init USB OHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_OHCIENV_FILECODE + +/** + * FchInitEnvUsbOhci - Config USB OHCI controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvUsbOhci ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciLate.c new file mode 100644 index 0000000000..d0837d3421 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciLate.c @@ -0,0 +1,60 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB OHCI controller + * + * Init USB OHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_OHCILATE_FILECODE + +/** + * FchInitLateUsbOhci - Config USB OHCI controller before OS + * Boot + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateUsbOhci ( + IN VOID *FchDataPtr + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciMid.c new file mode 100644 index 0000000000..c5f5434c3f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciMid.c @@ -0,0 +1,213 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB OHCI controller + * + * Init USB OHCI features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_OHCIMID_FILECODE +// +// Declaration of local functions +// + +/** + * OhciInitAfterPciInit - Config USB OHCI controller after PCI emulation + * + * @param[in] Value Controller PCI config address (bus# + device# + function#) + * @param[in] FchDataPtr Fch configuration structure pointer. + */ +VOID OhciInitAfterPciInit (IN UINT32 Value, IN FCH_DATA_BLOCK* FchDataPtr); + +/** + * FchInitMidUsbOhci - Config USB OHCI controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbOhci ( + IN VOID *FchDataPtr + ) +{ + FCH_INTERFACE *LocalCfgPtr; + + LocalCfgPtr = (FCH_INTERFACE *)FchDataPtr; + + FchInitMidUsbOhci1 (LocalCfgPtr); + FchInitMidUsbOhci2 (LocalCfgPtr); + FchInitMidUsbOhci3 (LocalCfgPtr); + FchInitMidUsbOhci4 (LocalCfgPtr); +} + +/** + * FchInitMidUsbOhci1 - Config USB1 OHCI controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbOhci1 ( + IN VOID *FchDataPtr + ) +{ + UINT32 DeviceId; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + DeviceId = (USB1_OHCI_BUS_DEV_FUN << 16); + OhciInitAfterPciInit (DeviceId, LocalCfgPtr); + + if (LocalCfgPtr->Usb.OhciSsid != 0 ) { + RwPci ((USB1_OHCI_BUS_DEV_FUN << 16) + FCH_OHCI_REG2C, AccessWidth32, 0x00, LocalCfgPtr->Usb.OhciSsid, StdHeader); + } +} + +/** + * FchInitMidUsbOhci2 - Config USB2 OHCI controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbOhci2 ( + IN VOID *FchDataPtr + ) +{ + UINT32 DeviceId; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + DeviceId = (USB2_OHCI_BUS_DEV_FUN << 16); + OhciInitAfterPciInit (DeviceId, LocalCfgPtr); + + if (LocalCfgPtr->Usb.OhciSsid != 0 ) { + RwPci ((USB2_OHCI_BUS_DEV_FUN << 16) + FCH_OHCI_REG2C, AccessWidth32, 0x00, LocalCfgPtr->Usb.OhciSsid, StdHeader); + } +} + +/** + * FchInitMidUsbOhci3 - Config USB3 OHCI controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbOhci3 ( + IN VOID *FchDataPtr + ) +{ + UINT32 DeviceId; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + DeviceId = (USB3_OHCI_BUS_DEV_FUN << 16); + OhciInitAfterPciInit (DeviceId, LocalCfgPtr); + + if (LocalCfgPtr->Usb.OhciSsid != 0 ) { + RwPci ((USB3_OHCI_BUS_DEV_FUN << 16) + FCH_OHCI_REG2C, AccessWidth32, 0x00, LocalCfgPtr->Usb.OhciSsid, StdHeader); + } +} + +/** + * FchInitMidUsbOhci4 - Config USB4 OHCI controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbOhci4 ( + IN VOID *FchDataPtr + ) +{ + UINT32 DeviceId; + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + DeviceId = (USB4_OHCI_BUS_DEV_FUN << 16); + OhciInitAfterPciInit (DeviceId, LocalCfgPtr); + + if (LocalCfgPtr->Usb.OhciSsid != 0 ) { + RwPci ((USB4_OHCI_BUS_DEV_FUN << 16) + FCH_OHCI_REG2C, AccessWidth32, 0x00, LocalCfgPtr->Usb.OhciSsid, StdHeader); + } +} + +/** + * OhciInitAfterPciInit - Config OHCI controller after PCI + * emulation + * + * + * @param[in] Value OHCI Controler info. + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +OhciInitAfterPciInit ( + IN UINT32 Value, + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + FchOhciInitAfterPciInit ( Value, FchDataPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciReset.c new file mode 100644 index 0000000000..5926acb6dc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/OhciReset.c @@ -0,0 +1,62 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Ohci controller + * + * Init Ohci Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_OHCIRESET_FILECODE + +/** + * FchInitResetOhci - Config Ohci controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetOhci ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbEnv.c new file mode 100644 index 0000000000..712c8c45c4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbEnv.c @@ -0,0 +1,69 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB controller + * + * Init USB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_USBENV_FILECODE + + +/** + * FchInitEnvUsb - Config USB controller before PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvUsb ( + IN VOID *FchDataPtr + ) +{ + // + // Disabled All USB controller *** Move to each controller *** + // + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, BIT7, 0); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth16, (UINT32)~BIT2, BIT2 + BIT7 + BIT8 + BIT9); + + FchSetUsbEnableReg (FchDataPtr); + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEE, AccessWidth8, (UINT32)~(BIT2), 0 ); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbLate.c new file mode 100644 index 0000000000..7a84ed782f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbLate.c @@ -0,0 +1,67 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB controller + * + * Init USB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_USBLATE_FILECODE + +/** + * FchInitLateUsb - Config USB controller before OS Boot + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateUsb ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + RwPmio (FCH_PMIOA_REGF4, AccessWidth8, (UINT32)~BIT0, BIT0, StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbMid.c new file mode 100644 index 0000000000..6b95148feb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbMid.c @@ -0,0 +1,68 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB controller + * + * Init USB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_USBMID_FILECODE + +/** + * FchInitMidUsb - Config USB controller after PCI emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsb ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; + if ( LocalCfgPtr->Usb.UsbPhyPowerDown ) { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth8, (UINT32)~BIT0, BIT0); + } else { + RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth8, (UINT32)~BIT0, 0); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbReset.c new file mode 100644 index 0000000000..d538f906fd --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/UsbReset.c @@ -0,0 +1,62 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Usb controller + * + * Init Usb Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_USBRESET_FILECODE + +/** + * FchInitResetUsb - Config Usb controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetUsb ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciEnv.c new file mode 100644 index 0000000000..ddcdbc9773 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciEnv.c @@ -0,0 +1,115 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB3 controller + * + * Init USB3 features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_XHCIENV_FILECODE + +// Declaration of local functions +// +VOID XhciInitBeforePciInit (IN FCH_DATA_BLOCK* FchDataPtr); +VOID XhciInitIndirectReg (IN FCH_DATA_BLOCK* FchDataPtr); + +/** + * FchInitEnvUsbXhci - Config XHCI controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitEnvUsbXhci ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + AMD_CONFIG_PARAMS *StdHeader; + + LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; + StdHeader = LocalCfgPtr->StdHeader; + + if ( LocalCfgPtr->Usb.Xhci0Enable == TRUE ) { + if ( LocalCfgPtr->Misc.S3Resume == 0 ) { + XhciInitBeforePciInit (LocalCfgPtr); + } else { + XhciInitIndirectReg (LocalCfgPtr); + } + } else { + // + // for power saving. + // + } +} + +/** + * XhciInitIndirectReg - Config XHCI Indirect Registers + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +XhciInitIndirectReg ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + FchXhciInitIndirectReg (FchDataPtr); +} + +/** + * XhciInitBeforePciInit - Config XHCI controller before PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +XhciInitBeforePciInit ( + IN FCH_DATA_BLOCK *FchDataPtr + ) +{ + FchXhciInitBeforePciInit ( FchDataPtr ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciLate.c new file mode 100644 index 0000000000..37926c2574 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciLate.c @@ -0,0 +1,62 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB3 controller + * + * Init USB3 features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_XHCILATE_FILECODE + + +/** + * FchInitLateUsbXhci - Config USB3 controller before OS Boot + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitLateUsbXhci ( + IN VOID *FchDataPtr + ) +{ + FchInitLateUsbXhciProgram ( FchDataPtr ); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciMid.c new file mode 100644 index 0000000000..7d8450e226 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciMid.c @@ -0,0 +1,77 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch USB3 controller + * + * Init USB3 features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/*;******************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;*********************************************************************************/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_XHCIMID_FILECODE + +/** + * FchInitMidUsbXhci - Config USB3 controller after PCI + * emulation + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitMidUsbXhci ( + IN VOID *FchDataPtr + ) +{ + FCH_DATA_BLOCK *LocalCfgPtr; + + LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; + if ( LocalCfgPtr->Usb.Xhci0Enable == TRUE ) { + RwPci ((USB_XHCI_BUS_DEV_FUN << 16) + FCH_XHCI_REG04, AccessWidth8, 0, BIT1, ((FCH_DATA_BLOCK *)FchDataPtr)->StdHeader); + if (((FCH_DATA_BLOCK *)FchDataPtr)->Usb.XhciSsid != 0 ) { + RwPci ((USB_XHCI_BUS_DEV_FUN << 16) + FCH_XHCI_REG2C, AccessWidth32, 0x00, ((FCH_DATA_BLOCK *)FchDataPtr)->Usb.XhciSsid, ((FCH_DATA_BLOCK *)FchDataPtr)->StdHeader); + } + } + + if ( LocalCfgPtr->Usb.Xhci1Enable == TRUE ) { + RwPci ((USB_XHCI1_BUS_DEV_FUN << 16) + FCH_XHCI_REG04, AccessWidth8, 0, BIT1, ((FCH_DATA_BLOCK *)FchDataPtr)->StdHeader); + if (((FCH_DATA_BLOCK *)FchDataPtr)->Usb.XhciSsid != 0 ) { + RwPci ((USB_XHCI1_BUS_DEV_FUN << 16) + FCH_XHCI_REG2C, AccessWidth32, 0x00, ((FCH_DATA_BLOCK *)FchDataPtr)->Usb.XhciSsid, ((FCH_DATA_BLOCK *)FchDataPtr)->StdHeader); + } + RwXhciIndReg (FCH_XHCI_IND_REG04, (UINT32)~BIT8, BIT8, ((FCH_DATA_BLOCK *)FchDataPtr)->StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciReset.c new file mode 100644 index 0000000000..3cb5663aae --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Usb/XhciReset.c @@ -0,0 +1,83 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Config Fch Xhci controller + * + * Init Xhci Controller features (PEI phase). + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: FCH + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**************************************************************************** +*/ +#include "FchPlatform.h" +#include "Filecode.h" +#define FILECODE PROC_FCH_USB_XHCIRESET_FILECODE + +VOID +FchInitRecoveryXhci ( + IN VOID *FchDataPtr + ); +/** + * FchInitResetXhci - Config Xhci controller during Power-On + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitResetXhci ( + IN VOID *FchDataPtr + ) +{ + FchInitResetXhciProgram ( FchDataPtr ); +} + +/** + * FchInitRecoveryLpc - Config Xhci controller during Crisis + * Recovery + * + * + * + * @param[in] FchDataPtr Fch configuration structure pointer. + * + */ +VOID +FchInitRecoveryXhci ( + IN VOID *FchDataPtr + ) +{ +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/Gnb.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/Gnb.h new file mode 100644 index 0000000000..100ae03036 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/Gnb.h @@ -0,0 +1,171 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Misc common definition + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87645 $ @e \$Date: 2013-02-06 13:08:17 -0600 (Wed, 06 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNB_H_ +#define _GNB_H_ + +#include "Ids.h" + +#pragma pack (push, 1) + +#define GNB_DEADLOOP() \ +{ \ + VOLATILE BOOLEAN k; \ + k = TRUE; \ + while (k) { \ + } \ +} +#ifdef IDSOPT_TRACING_ENABLED + #if (IDSOPT_TRACING_ENABLED == TRUE) + #define GNB_TRACE_ENABLE + #endif +#endif + + +#ifndef GNB_DEBUG_CODE + #ifdef GNB_TRACE_ENABLE + #define GNB_DEBUG_CODE(Code) Code + #else + #define GNB_DEBUG_CODE(Code) + #endif +#endif + +#ifndef MIN + #define MIN(x, y) (((x) > (y))? (y):(x)) +#endif + +#ifndef MAX + #define MAX(x, y) (((x) > (y))? (x):(y)) +#endif + +#define OFF 0 + +#define PVOID UINT32 + +#define STRING_TO_UINT32(a, b, c, d) ((UINT32) ((d << 24) | (c << 16) | (b << 8) | a)) + +#define GnbLibGetHeader(x) ((AMD_CONFIG_PARAMS*) (x)->StdHeader) + +#define AGESA_STATUS_UPDATE(Current, Aggregated) \ +if (Current > Aggregated) { \ + Aggregated = Current; \ +} + +#ifndef offsetof + #define offsetof(s, m) (UINTN)&(((s *)0)->m) +#endif + + +//Table properties + +#define TABLE_PROPERTY_DEFAULT 0x00000000ul +#define TABLE_PROPERTY_IGFX_DISABLED 0x00000001ul +#define TABLE_PROPERTY_IOMMU_DISABLED 0x00000002ul +#define TABLE_PROPERTY_LCLK_DEEP_SLEEP 0x00000004ul +#define TABLE_PROPERTY_BAPM 0x00000100ul +#define TABLE_PROPERTY_NBDPM 0x00000800ul +#define TABLE_PROPERTY_LOADLINE_ENABLE 0x00001000ul +#define TABLE_PROPERTY_LHTC 0x00010000ul +#define TABLE_PROPERTY_SVI2 0x00020000ul + +//Register access flags Flags +#define GNB_REG_ACC_FLAG_S3SAVE 0x00000001ul + +// Gnb PCIe Master PLL +#define GNB_PCIE_MASTERPLL_A 0xA +#define GNB_PCIE_MASTERPLL_B 0xB +#define GNB_PCIE_MASTERPLL_C 0xC +#define GNB_PCIE_MASTERPLL_D 0xD + +/// LCLK DPM enable control +typedef enum { + LclkDpmDisabled, ///LVDS translator chip +#define eDP_TO_LVDS_RX_DISABLE 0x00 +// common eDP->LVDS translator chip without AMD SW init +#define eDP_TO_LVDS_COMMON_ID 0x01 +// Third party translator which requires AMD SW init +#define eDP_TO_LVDS_SWINIT_ID 0x02 + + +#define ATOM_DEVICE_CRT1_SUPPORT 0x0001 +#define ATOM_DEVICE_DFP1_SUPPORT 0x0008 +#define ATOM_DEVICE_DFP6_SUPPORT 0x0040 +#define ATOM_DEVICE_DFP2_SUPPORT 0x0080 +#define ATOM_DEVICE_DFP3_SUPPORT 0x0200 +#define ATOM_DEVICE_DFP4_SUPPORT 0x0400 +#define ATOM_DEVICE_DFP5_SUPPORT 0x0800 +#define ATOM_DEVICE_LCD1_SUPPORT 0x0002 + +/// Graphics card information structure +typedef struct { + UINT32 AmdPcieGfxCardBitmap; ///< AMD PCIE graphics card information + UINT32 PcieGfxCardBitmap; ///< All PCIE graphics card information + UINT32 PciGfxCardBitmap; ///< All PCI graphics card information +} GFX_CARD_CARD_INFO; + +typedef enum { + iGpuVgaAdapter, ///< Configure iGPU as VGA adapter + iGpuVgaNonAdapter ///< Configure iGPU as non VGA adapter +} GFX_IGPU_VGA_MODE; + +/// UMA Steering Mode +typedef enum { + UMA_STEERING_ENUM0, + SystemTrafficOnion, ///< System traffic to onion + Onion, ///< Onion + UMA_STEERING_ENUM3, +} UMA_STEERING; + +/// User Options +typedef enum { + OptionDisabled, ///< Disabled + OptionEnabled ///< Enabled +} CONTROL_OPTION; + +/// GFX enable Policy +typedef enum { + GmcPowerGatingDisabled, ///< Disable Power gating + GmcPowerGatingStutterOnly, ///< GMC Stutter Only mode + GmcPowerGatingWithStutter ///< GMC Power gating with Stutter mode +} GMC_POWER_GATING; + +/// Internal GFX mode +typedef enum { + GfxControllerLegacyBridgeMode, ///< APC bridge Legacy mode + GfxControllerPcieEndpointMode, ///< IGFX PCIE Bus 0, Device 1 +} GFX_CONTROLLER_MODE; + +/// Graphics Platform Configuration +typedef struct { + PVOID StdHeader; ///< Standard Header + PCI_ADDR GfxPciAddress; ///< Graphics PCI Address + UMA_INFO UmaInfo; ///< UMA Information + UINT64 GmmBase; ///< GMM Base + UINT8 GnbHdAudio; ///< Control GFX HD Audio controller(Used for HDMI and DP display output), + ///< essentially it enables function 1 of graphics device. + ///< @li 0 = HD Audio disable + ///< @li 1 = HD Audio enable + UINT8 AbmSupport; ///< Automatic adjust LVDS/eDP Back light level support.It is + ///< characteristic specific to display panel which used by platform design. + ///< @li 0 = ABM support disabled + ///< @li 1 = ABM support enabled + UINT8 DynamicRefreshRate; ///< Adjust refresh rate on LVDS/eDP. + UINT16 LcdBackLightControl; ///< The PWM frequency to LCD backlight control. + ///< If equal to 0 backlight not controlled by iGPU. + UINT32 AmdPlatformType; ///< Platform type + UMA_STEERING UmaSteering; ///< UMA Steering + GFX_IGPU_VGA_MODE iGpuVgaMode; ///< iGPU VGA mode + BOOLEAN GmcClockGating; ///< Clock gating + BOOLEAN GmcLockRegisters; ///< GmcLock Registers + BOOLEAN GfxFusedOff; ///< Record if GFX is fused off. + GMC_POWER_GATING GmcPowerGating; ///< Gmc Power Gating. + UINT8 Gnb3dStereoPinIndex; ///< 3D Stereo Pin ID + GFX_CONTROLLER_MODE GfxControllerMode; ///< Gfx controller mode + UINT16 LvdsSpreadSpectrum; ///< Spread spectrum value in 0.01 % + UINT16 LvdsSpreadSpectrumRate; ///< Spread spectrum frequency used by SS hardware logic in unit of 10Hz, 0 - default frequency 40kHz + UINT8 LvdsPowerOnSeqDigonToDe; ///< Panel initialization timing. + UINT8 LvdsPowerOnSeqDeToVaryBl; ///< Panel initialization timing. + UINT8 LvdsPowerOnSeqDeToDigon; ///< Panel initialization timing. + UINT8 LvdsPowerOnSeqVaryBlToDe; ///< Panel initialization timing. + UINT8 LvdsPowerOnSeqOnToOffDelay; ///< Panel initialization timing. + UINT8 LvdsPowerOnSeqVaryBlToBlon; ///< Panel initialization timing. + UINT8 LvdsPowerOnSeqBlonToVaryBl; ///< Panel initialization timing. + UINT16 LvdsMaxPixelClockFreq; ///< The maximum pixel clock frequency supported. + UINT32 LcdBitDepthControlValue; ///< The LCD bit depth control settings. + UINT8 Lvds24bbpPanelMode; ///< The LVDS 24 BBP mode. + LVDS_MISC_CONTROL LvdsMiscControl; ///< THe LVDS swap/Hsync/Vsync/BLON/Volt-overwrite control + GFX_CARD_CARD_INFO GfxDiscreteCardInfo; ///< Discrete GFX card info + UINT16 PcieRefClkSpreadSpectrum; ///< Spread spectrum value in 0.01 % + BOOLEAN GnbRemoteDisplaySupport; ///< Wireless Display Enable + UINT8 LVDSVoltAdjust; ///< when ucLVDSMisc[5]=1, then this value will be programmed to register LVDS_CTRL_4 to adjust LVDS output voltage + DISPLAY_MISC_CONTROL DisplayMiscControl; ///< The Display misc control + DP_FIXED_VOLT_SWING_TYPE DpFixedVoltSwingType; ///< To indicate fixed voltage swing value + UINT8 MinAllowedBLLevel; ///< Minimum allowed LCD backlight level +} GFX_PLATFORM_CONFIG; + + +typedef UINT32 ULONG; +typedef UINT16 USHORT; +typedef UINT8 UCHAR; + +/// Driver interface header structure +typedef struct _ATOM_COMMON_TABLE_HEADER { + USHORT usStructureSize; ///< Structure size + UCHAR ucTableFormatRevision; ///< Format revision number + UCHAR ucTableContentRevision; ///< Contents revision number +} ATOM_COMMON_TABLE_HEADER; + +/// Link ping mapping for DP/eDP/LVDS +typedef struct _ATOM_DP_CONN_CHANNEL_MAPPING { + UCHAR ucDP_Lane0_Source :2; ///< Define which pin connect to DP connector DP_Lane0, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 + UCHAR ucDP_Lane1_Source :2; ///< Define which pin connect to DP connector DP_Lane1, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 + UCHAR ucDP_Lane2_Source :2; ///< Define which pin connect to DP connector DP_Lane2, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 + UCHAR ucDP_Lane3_Source :2; ///< Define which pin connect to DP connector DP_Lane3, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +} ATOM_DP_CONN_CHANNEL_MAPPING; + +/// Link ping mapping for DVI/HDMI +typedef struct _ATOM_DVI_CONN_CHANNEL_MAPPING { + UCHAR ucDVI_DATA2_Source :2; ///< Define which pin connect to DVI connector data Lane2, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 + UCHAR ucDVI_DATA1_Source :2; ///< Define which pin connect to DVI connector data Lane1, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 + UCHAR ucDVI_DATA0_Source :2; ///< Define which pin connect to DVI connector data Lane0, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 + UCHAR ucDVI_CLK_Source :2; ///< Define which pin connect to DVI connector clock lane, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +} ATOM_DVI_CONN_CHANNEL_MAPPING; + + +/// External Display Path +typedef struct _EXT_DISPLAY_PATH { + USHORT usDeviceTag; ///< A bit vector to show what devices are supported + USHORT usDeviceACPIEnum; ///< 16bit device ACPI id. + USHORT usDeviceConnector; ///< A physical connector for displays to plug in, using object connector definitions + UCHAR ucExtAUXDDCLutIndex; ///< An index into external AUX/DDC channel LUT + UCHAR ucExtHPDPINLutIndex; ///< An index into external HPD pin LUT + USHORT usExtEncoderObjId; ///< external encoder object id + union { ///< Lane mapping + UCHAR ucChannelMapping; ///< lane mapping on connector (ucChannelMapping=0 use default) + ATOM_DP_CONN_CHANNEL_MAPPING asDPMapping; ///< lane mapping on connector (ucChannelMapping=0 use default) + ATOM_DVI_CONN_CHANNEL_MAPPING asDVIMapping; ///< lane mapping on connector (ucChannelMapping=0 use default) + } ChannelMapping; + UCHAR ucChPNInvert; ///< Bit vector for up to 8 lanes. 0: P and N is not invert, 1: P and N is inverted + USHORT usCaps; ///< Capabilities IF BIT[0] == 1, downgrade phy link to DP1.1 + USHORT usReserved; ///< Reserved +} EXT_DISPLAY_PATH; + +/// External Display Connection Information +typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO { + ATOM_COMMON_TABLE_HEADER sHeader; ///< Standard Header + UCHAR ucGuid [16]; ///< Guid + EXT_DISPLAY_PATH sPath[7]; ///< External Display Path + UCHAR ucChecksum; ///< Checksum + UCHAR uc3DStereoPinId; ///< 3D Stereo Pin ID + UCHAR ucRemoteDisplayConfig; ///< Bit0=1:Enable Wireless Display through APU VCE HW function + UCHAR uceDPToLVDSRxId; ///< 3rd party eDP to LVDS translator chip presented. 0:no, 1:chip without AMD SW init, 2:Third party translator which require AMD SW init + UCHAR ucFixDPVoltageSwing; ///< The value match DPCD register DPx_LANE_SET defined in DP spec + UCHAR Reserved [3]; ///< Reserved +} ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO; + +/// DispClk to VID relation table +typedef struct _ATOM_CLK_VOLT_CAPABILITY { + ULONG ulVoltageIndex; ///< The Voltage Index indicated by FUSE, same voltage index shared with SCLK DPM fuse table + ULONG ulMaximumSupportedCLK;///< Maximum clock supported with specified voltage index, unit in 10kHz +} ATOM_CLK_VOLT_CAPABILITY; + +typedef struct _GnbGfx275_STRUCT { + ULONG GnbGfx275_STRUCT_fld0; + USHORT GnbGfx275_STRUCT_fld1; + USHORT GnbGfx275_STRUCT_fld2; +} GnbGfx275_STRUCT; + +/// TDP Configuration Bitfields +typedef struct _ATOM_TDP_CONFIG_BITS { + UINT32 uCTDP_Enable:2; ///< = (uCTDP_Value > uTDP_Value? 2: (uCTDP_Value < uTDP_Value)) + UINT32 uCTDP_Value:14; ///< Override value in tens of milli watts + UINT32 uTDP_Value:14; ///< Original TDP value in tens of milli watts + UINT32 uReserved:2; ///< Reserved +} ATOM_TDP_CONFIG_BITS; + +/// TDP Configuration Union +typedef union _ATOM_TDP_CONFIG { + ATOM_TDP_CONFIG_BITS TDP_config; ///< Field-wise access + ULONG TDP_config_all; ///< Access to all +} ATOM_TDP_CONFIG; + + +/// IntegrateSystemInfoTable is used for Kaveri & Kabini APU +typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 { + ATOM_COMMON_TABLE_HEADER sHeader; ///< + ULONG ulBootUpEngineClock; ///< + ULONG field2; ///< + ULONG ulBootUpUMAClock; ///< + ATOM_CLK_VOLT_CAPABILITY ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld4[4]; ///< + ULONG ulBootUpReqDisplayVector; ///< + ULONG ulVBIOSMisc; ///< + ULONG ulGPUCapInfo; ///< + ULONG ulReserved1; ///< + USHORT usRequestedPWMFreqInHz; ///< + UCHAR ucHtcTmpLmt; ///< + UCHAR ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11; ///< + ULONG ulReserved2; ///< + ULONG ulSystemConfig; ///< + ULONG ulCPUCapInfo; ///< + ULONG ulReserved3; ///< + USHORT usReserved1; ///< + USHORT usExtDispConnInfoOffset; ///< + USHORT usPanelRefreshRateRange; ///< + UCHAR ucMemoryType; ///< + UCHAR ucUMAChannelNumber; ///< + UCHAR strVBIOSMsg[40]; ///< + ULONG ulReserved[20]; ///< + GnbGfx275_STRUCT ATOM_INTEGRATED_SYSTEM_INFO_V1_8[5]; ///< + ULONG ulGMCRestoreResetTime; ///< + ULONG ulReserved4; ///< + ULONG ulIdleNClk; ///< + ULONG ulDDR_DLL_PowerUpTime; ///< + ULONG ulDDR_PLL_PowerUpTime; ///< + USHORT usPCIEClkSSPercentage; ///< + USHORT usPCIEClkSSType; ///< + USHORT usLvdsSSPercentage; ///< + USHORT usLvdsSSpreadRateIn10Hz; ///< + USHORT usHDMISSPercentage; ///< + USHORT usHDMISSpreadRateIn10Hz; ///< + USHORT usDVISSPercentage; ///< + USHORT usDVISSpreadRateIn10Hz; ///< + ULONG ulReserved5[5]; ///< + USHORT usMaxLVDSPclkFreqInSingleLink; ///< + UCHAR ucLvdsMisc; ///< + UCHAR ucLVDSVoltAdjust; ///< + UCHAR ucLVDSPwrOnSeqDIGONtoDE_in4Ms; ///< + UCHAR ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; ///< + UCHAR ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; ///< + UCHAR ucLVDSPwrOffSeqDEtoDIGON_in4Ms; ///< + UCHAR ucLVDSOffToOnDelay_in4Ms; ///< + UCHAR ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; ///< + UCHAR ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; ///< + UCHAR ucMinAllowedBL_Level; ///< + ULONG ulLCDBitDepthControlVal; ///< + ULONG ulNbpStateMemclkFreq[4]; ///< + ULONG ulReserved6; ///< + ULONG ulNbpStateNClkFreq[4]; ///< + USHORT usNBPStateVoltage[4]; ///< + USHORT usBootUpNBVoltage; ///< + USHORT usReserved2; ///< + ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; ///< +} ATOM_INTEGRATED_SYSTEM_INFO_V1_8; + +/// this Table is used for Kaveri/Kabini APU +typedef struct _ATOM_FUSION_SYSTEM_INFO_V3 { + ATOM_INTEGRATED_SYSTEM_INFO_V1_8 sIntegratedSysInfo; ///< Refer to ATOM_INTEGRATED_SYSTEM_INFO_V1_8 definition. + ULONG ulPowerplayTable[128]; ///< This 512 bytes memory is used to save ATOM_PPLIB_POWERPLAYTABLE3, starting form ulPowerplayTable[0] +} ATOM_FUSION_SYSTEM_INFO_V3; + +#define GNB_SBDFO MAKE_SBDFO(0, 0, 0, 0, 0) + +/// Define configuration values for ulGPUCapInfo +// BIT[0] - TMDS/HDMI Coherent Mode 0: use cascade PLL mode, 1: use single PLL mode. +#define GPUCAPINFO_TMDS_HDMI_USE_CASCADE_PLL_MODE 0x00ul +#define GPUCAPINFO_TMDS_HDMI_USE_SINGLE_PLL_MODE 0x01ul + +// BIT[1] - DP mode 0: use cascade PLL mode, 1: use single PLL mode +#define GPUCAPINFO_DP_MODE_USE_CASCADE_PLL_MODE 0x00ul +#define GPUCAPINFO_DP_USE_SINGLE_PLL_MODE 0x02ul + +// BIT[3] - AUX HW mode detection logic 0: Enable, 1: Disable +#define GPUCAPINFO_AUX_HW_MODE_DETECTION_ENABLE 0x00ul +#define GPUCAPINFO_AUX_HW_MODE_DETECTION_DISABLE 0x08ul + +// BIT[4] - DFS bypass 0: Disable, 1: Enable +#define GPUCAPINFO_DFS_BYPASS_DISABLE 0x00ul +#define GPUCAPINFO_DFS_BYPASS_ENABLE 0x10ul + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbGfxFamServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbGfxFamServices.h new file mode 100644 index 0000000000..b4160e6e87 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbGfxFamServices.h @@ -0,0 +1,102 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe family specific services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBGFXFAMSERVICES_H_ +#define _GNBGFXFAMSERVICES_H_ + +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbPcie.h" + +AGESA_STATUS +GfxFmMapEngineToDisplayPath ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +typedef AGESA_STATUS F_GFXMAPENGINETODISPLAYPATH ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +UINT32 +GfxFmCalculateClock ( + IN UINT8 Did, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef UINT32 F_GFXCALCULATECLOCK ( + IN UINT8 Did, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GfxFmIsVbiosPosted ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +typedef BOOLEAN F_GFXISVBIOSPOSTED ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxFmDisableController ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef VOID F_GFXDISABLECONTROLLER ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// GFX Family services +typedef struct { + F_GFXMAPENGINETODISPLAYPATH *GfxMapEngineToDisplayPath; ///< GfxMapEngineToDisplayPath + F_GFXDISABLECONTROLLER *GfxDisableController; ///< GfxDisableController + F_GFXCALCULATECLOCK *GfxCalculateClock; ///< GfxCalculateClock + F_GFXISVBIOSPOSTED *GfxIsVbiosPosted; ///< GfxIsVbiosPosted; +} GFX_FAM_SERVICES; + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbIommu.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbIommu.h new file mode 100644 index 0000000000..c37c2148fa --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbIommu.h @@ -0,0 +1,195 @@ +/** + * @file + * + * Misc common definition + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBIOMMU_H_ +#define _GNBIOMMU_H_ + +#pragma pack (push, 1) + + +/// IVRS block +typedef enum { + IvrsIvhdBlock = 0x10, ///< I/O Virtualization Hardware Definition Block + IvrsIvmdBlock = 0x20, ///< I/O Virtualization Memory Definition Block for all peripherals + IvrsIvmdBlockSingle = 0x21, ///< IVMD block for specified peripheral + IvrsIvmdBlockRange = 0x22, ///< IVMD block for peripheral range + IvrsIvhdrBlock = 0x40, ///< IVHDR (Relative) block + IvrsIvmdrBlock = 0x50, ///< IVMDR (Relative) block for all peripherals + IvrsIvmdrBlockSingle = 0x51 ///< IVMDR block for last IVHDR +} IVRS_BLOCK_TYPE; + +#define DEVICE_ID(PciAddress) (UINT16) (((PciAddress).Address.Bus << 8) | ((PciAddress).Address.Device << 3) | (PciAddress).Address.Function) + +/// IVHD entry types +typedef enum { + IvhdEntryPadding = 0, ///< Table padding + IvhdEntrySelect = 2, ///< Select + IvhdEntryStartRange = 3, ///< Start Range + IvhdEntryEndRange = 4, ///< End Range + IvhdEntryAliasSelect = 66, ///< Alias select + IvhdEntryAliasStartRange = 67, ///< Alias start range + IvhdEntryExtendedSelect = 70, ///< Extended select + IvhdEntryExtendedStartRange = 71, ///< Extended Start range + IvhdEntrySpecialDevice = 72 ///< Special device +} IVHD_ENTRY_TYPE; + +/// Special device variety +typedef enum { + IvhdSpecialDeviceIoapic = 0x1, ///< IOAPIC + IvhdSpecialDeviceHpet = 0x2 ///< HPET +} IVHD_SPECIAL_DEVICE; + + +#define IVHD_FLAG_COHERENT BIT5 +#define IVHD_FLAG_IOTLBSUP BIT4 +#define IVHD_FLAG_ISOC BIT3 +#define IVHD_FLAG_RESPASSPW BIT2 +#define IVHD_FLAG_PASSPW BIT1 +#define IVHD_FLAG_PPRSUB BIT7 +#define IVHD_FLAG_PREFSUP BIT6 + +#define IVHD_EFR_XTSUP_OFFSET 0 +#define IVHD_EFR_NXSUP_OFFSET 1 +#define IVHD_EFR_GTSUP_OFFSET 2 +#define IVHD_EFR_GLXSUP_OFFSET 3 +#define IVHD_EFR_IASUP_OFFSET 5 +#define IVHD_EFR_GASUP_OFFSET 6 +#define IVHD_EFR_HESUP_OFFSET 7 +#define IVHD_EFR_PASMAX_OFFSET 8 +#define IVHD_EFR_PNCOUNTERS_OFFSET 13 +#define IVHD_EFR_PNBANKS_OFFSET 17 +#define IVHD_EFR_MSINUMPPR_OFFSET 23 +#define IVHD_EFR_GATS_OFFSET 28 +#define IVHD_EFR_HATS_OFFSET 30 + +#define IVINFO_HTATSRESV_MASK 0x00400000ul +#define IVINFO_VASIZE_MASK 0x003F8000ul +#define IVINFO_PASIZE_MASK 0x00007F00ul +#define IVINFO_GASIZE_MASK 0x000000E0ul + +#define IVHD_INFO_MSINUM_OFFSET 0 +#define IVHD_INFO_UNITID_OFFSET 8 + +#define IVMD_FLAG_EXCLUSION_RANGE BIT3 +#define IVMD_FLAG_IW BIT2 +#define IVMD_FLAG_IR BIT1 +#define IVMD_FLAG_UNITY BIT0 + +/// IVRS header +typedef struct { + UINT8 Sign[4]; ///< Signature + UINT32 TableLength; ///< Table Length + UINT8 Revision; ///< Revision + UINT8 Checksum; ///< Checksum + UINT8 OemId[6]; ///< OEM ID + UINT8 OemTableId[8]; ///< OEM Tabled ID + UINT32 OemRev; ///< OEM Revision + UINT8 CreatorId[4]; ///< Creator ID + UINT32 CreatorRev; ///< Creator Revision + UINT32 IvInfo; ///< IvInfo + UINT64 Reserved; ///< Reserved +} IOMMU_IVRS_HEADER; + +/// IVRS IVHD Entry +typedef struct { + UINT8 Type; ///< Type + UINT8 Flags; ///< Flags + UINT16 Length; ///< Length + UINT16 DeviceId; ///< DeviceId + UINT16 CapabilityOffset; ///< CapabilityOffset + UINT64 BaseAddress; ///< BaseAddress + UINT16 PciSegment; ///< Pci segment + UINT16 IommuInfo; ///< IOMMU info + UINT32 IommuEfr; ///< reserved +} IVRS_IVHD_ENTRY; + +/// IVHD generic entry +typedef struct { + UINT8 Type; ///< Type + UINT16 DeviceId; ///< Device id + UINT8 DataSetting; ///< Data settings +} IVHD_GENERIC_ENTRY; + +///IVHD alias entry +typedef struct { + UINT8 Type; ///< Type + UINT16 DeviceId; ///< Device id + UINT8 DataSetting; ///< Data settings + UINT8 Reserved; ///< Reserved + UINT16 AliasDeviceId; ///< Alias device id + UINT8 Reserved2; ///< Reserved +} IVHD_ALIAS_ENTRY; + +///IVHD extended entry +typedef struct { + UINT8 Type; ///< Type + UINT16 DeviceId; ///< Device id + UINT8 DataSetting; ///< Data settings + UINT32 ExtSetting; ///< Extended settings +} IVHD_EXT_ENTRY; + +/// IVHD special entry +typedef struct { + UINT8 Type; ///< Type + UINT16 Reserved; ///< Reserved + UINT8 DataSetting; ///< Data settings + UINT8 Handle; ///< Handle + UINT16 AliasDeviceId; ///< Alis device id + UINT8 Variety; ///< Variety +} IVHD_SPECIAL_ENTRY; + +/// IVRS IVMD Entry +typedef struct { + UINT8 Type; ///< Type + UINT8 Flags; ///< Flags + UINT16 Length; ///< Length + UINT16 DeviceId; ///< DeviceId + UINT16 AuxiliaryData; ///< Auxiliary data + UINT64 Reserved; ///< Reserved (0000_0000_0000_0000) + UINT64 BlockStart; ///< IVMD start address + UINT64 BlockLength; ///< IVMD memory block length +} IVRS_IVMD_ENTRY; + +#pragma pack (pop) + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.c new file mode 100644 index 0000000000..4606d3d1a7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.c @@ -0,0 +1,111 @@ +/* $NoKeywords:$ */ + /** + * @file + * + * GNB register access services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "Gnb.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_COMMON_GNBLIBFEATURES_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +GnbLibDispatchFeatures ( + IN OPTION_GNB_CONFIGURATION *ConfigTable, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Dispatch feature table + * + * + */ + +AGESA_STATUS +GnbLibDispatchFeatures ( + IN OPTION_GNB_CONFIGURATION *ConfigTable, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + CPU_LOGICAL_ID LogicalId; + + AgesaStatus = AGESA_SUCCESS; + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + while (ConfigTable->GnbFeature != NULL) { + if ((ConfigTable->Type & LogicalId.Family) != 0) { + if (ConfigTable->TestPoint != 0) { + AGESA_TESTPOINT (ConfigTable->TestPoint, StdHeader); + } + Status = ConfigTable->GnbFeature (StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + ConfigTable++; + } + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.h new file mode 100644 index 0000000000..6d27c4b76b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbLibFeatures.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB register access services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBLIBFEATURES_H_ +#define _GNBLIBFEATURES_H_ + + +AGESA_STATUS +GnbLibDispatchFeatures ( + IN OPTION_GNB_CONFIGURATION *ConfigTable, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbPcie.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbPcie.h new file mode 100644 index 0000000000..87a8b357c1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbPcie.h @@ -0,0 +1,398 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe component definitions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** + +* +*/ + +#ifndef _GNBPCIE_H_ +#define _GNBPCIE_H_ + +#pragma pack (push, 1) + +#define MAX_NUMBER_OF_COMPLEXES 4 + +#define DESCRIPTOR_TERMINATE_GNB 0x40000000ull +#define DESCRIPTOR_TERMINATE_TOPOLOGY 0x20000000ull +#define DESCRIPTOR_ALLOCATED 0x10000000ull +#define DESCRIPTOR_VIRTUAL 0x08000000ull +#define DESCRIPTOR_PLATFORM 0x04000000ull +#define DESCRIPTOR_COMPLEX 0x02000000ull +#define DESCRIPTOR_SILICON 0x01000000ull +#define DESCRIPTOR_PCIE_WRAPPER 0x00800000ull +#define DESCRIPTOR_DDI_WRAPPER 0x00400000ull +#define DESCRIPTOR_PCIE_ENGINE 0x00200000ull +#define DESCRIPTOR_DDI_ENGINE 0x00100000ull + +#define DESCRIPTOR_ALL_WRAPPERS (DESCRIPTOR_DDI_WRAPPER | DESCRIPTOR_PCIE_WRAPPER) +#define DESCRIPTOR_ALL_ENGINES (DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_PCIE_ENGINE) + +#define DESCRIPTOR_ALL_TYPES (DESCRIPTOR_ALL_WRAPPERS | DESCRIPTOR_ALL_ENGINES | DESCRIPTOR_SILICON | DESCRIPTOR_PLATFORM) + +#define UNUSED_LANE_ID 128 +//#define PCIE_LINK_RECEIVER_DETECTION_POOLING (60 * 1000) +//#define PCIE_LINK_L0_POOLING (60 * 1000) +//#define PCIE_LINK_GPIO_RESET_ASSERT_TIME (2 * 1000) +//#define PCIE_LINK_RESET_TO_TRAINING_TIME (2 * 1000) + +// Get lowest PHY lane on engine +#define PcieLibGetLoPhyLane(Engine) (Engine != NULL ? ((Engine->EngineData.StartLane > Engine->EngineData.EndLane) ? Engine->EngineData.EndLane : Engine->EngineData.StartLane) : 0) +// Get highest PHY lane on engine +#define PcieLibGetHiPhyLane(Engine) (Engine != NULL ? ((Engine->EngineData.StartLane > Engine->EngineData.EndLane) ? Engine->EngineData.StartLane : Engine->EngineData.EndLane) : 0) +// Get number of lanes on wrapper +#define PcieLibWrapperNumberOfLanes(Wrapper) (Wrapper != NULL ? ((UINT8)(Wrapper->EndPhyLane - Wrapper->StartPhyLane + 1)) : 0) +// Check if virtual descriptor +#define PcieLibIsVirtualDesciptor(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_VIRTUAL) != 0) : FALSE) +// Check if it is allocated descriptor +#define PcieLibIsEngineAllocated(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_ALLOCATED) != 0) : FALSE) +// Check if it is last descriptor in list +#define PcieLibIsLastDescriptor(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_TERMINATE_LIST) != 0) : TRUE) +// Check if descriptor a PCIe engine +#define PcieLibIsPcieEngine(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_PCIE_ENGINE) != 0) : FALSE) +// Check if descriptor a DDI engine +#define PcieLibIsDdiEngine(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_DDI_ENGINE) != 0) : FALSE) +// Check if descriptor a DDI wrapper +#define PcieLibIsDdiWrapper(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_DDI_WRAPPER) != 0) : FALSE) +// Check if descriptor a PCIe wrapper +#define PcieLibIsPcieWrapper(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_PCIE_WRAPPER) != 0) : FALSE) +// Check if descriptor a PCIe wrapper +#define PcieLibGetNextDescriptor(Descriptor) (Descriptor != NULL ? (((Descriptor->Header.DescriptorFlags & DESCRIPTOR_TERMINATE_LIST) != 0) ? NULL : (Descriptor+1)) : NULL) + +#define LANE_TYPE_PCIE_CORE_CONFIG 0x00000001ul +#define LANE_TYPE_PCIE_CORE_ALLOC 0x00000002ul +#define LANE_TYPE_PCIE_CORE_ACTIVE 0x00000004ul +#define LANE_TYPE_PCIE_SB_CORE_CONFIG 0x00000008ul +#define LANE_TYPE_PCIE_CORE_HOTPLUG 0x00000010ul +#define LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE 0x00000020ul +#define LANE_TYPE_PCIE_PHY 0x00000100ul +#define LANE_TYPE_PCIE_PHY_NATIVE 0x00000200ul +#define LANE_TYPE_PCIE_PHY_NATIVE_ACTIVE 0x00000400ul +#define LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG 0x00000800ul +#define LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE 0x00001000ul +#define LANE_TYPE_DDI_PHY 0x00010000ul +#define LANE_TYPE_DDI_PHY_NATIVE 0x00020000ul +#define LANE_TYPE_DDI_PHY_NATIVE_ACTIVE 0x00040000ul +#define LANE_TYPE_PHY_NATIVE_ALL 0x00100000ul +#define LANE_TYPE_PCIE_PHY_NATIVE_MASTER_PLL 0x00200000ul +#define LANE_TYPE_CORE_ALL LANE_TYPE_PHY_NATIVE_ALL +#define LANE_TYPE_ALL LANE_TYPE_PHY_NATIVE_ALL + +#define LANE_TYPE_PCIE_LANES (LANE_TYPE_PCIE_CORE_ACTIVE | LANE_TYPE_PCIE_SB_CORE_CONFIG | \ + LANE_TYPE_PCIE_CORE_HOTPLUG | LANE_TYPE_PCIE_CORE_ALLOC | \ + LANE_TYPE_PCIE_PHY | LANE_TYPE_PCIE_PHY_NATIVE | \ + LANE_TYPE_PCIE_PHY_NATIVE_ACTIVE | LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG | \ + LANE_TYPE_PCIE_CORE_CONFIG | LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE | \ + LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE) + +#define LANE_TYPE_DDI_LANES (LANE_TYPE_DDI_PHY | LANE_TYPE_DDI_PHY_NATIVE | LANE_TYPE_DDI_PHY_NATIVE_ACTIVE) + + +#define INIT_STATUS_PCIE_PORT_GEN2_RECOVERY 0x00000001ull +#define INIT_STATUS_PCIE_PORT_BROKEN_LANE_RECOVERY 0x00000002ull +#define INIT_STATUS_PCIE_PORT_TRAINING_FAIL 0x00000004ull +#define INIT_STATUS_PCIE_TRAINING_SUCCESS 0x00000008ull +#define INIT_STATUS_PCIE_EP_NOT_PRESENT 0x00000010ull +#define INIT_STATUS_PCIE_PORT_IN_COMPLIANCE 0x00000020ull +#define INIT_STATUS_DDI_ACTIVE 0x00000040ull +#define INIT_STATUS_ALLOCATED 0x00000080ull + +#define PCIE_PORT_GEN_CAP_BOOT 0x00000001ul +#define PCIE_PORT_GEN_CAP_MAX 0x00000002ul +#define PCIE_GLOBAL_GEN_CAP_ALL_PORTS 0x00000010ul +#define PCIE_GLOBAL_GEN_CAP_TRAINED_PORTS 0x00000014ul +#define PCIE_GLOBAL_GEN_CAP_HOTPLUG_PORTS 0x00000018ul + +#define PCIE_POWERGATING_SKIP_CORE 0x00000001ul +#define PCIE_POWERGATING_SKIP_PHY 0x00000002ul + +/// PCIe Link Training State +typedef enum { + PcieTrainingStandard, ///< Standard training algorithm. Training contained to AmdEarlyInit. + ///< PCIe device accessible after AmdEarlyInit complete + PcieTrainingDistributed, ///< Distribute training algorithm. Training distributed across AmdEarlyInit/AmdPostInit/AmdS3LateRestore + ///< PCIe device accessible after AmdPostInit complete. + ///< Algorithm potentially save up to 60ms in S3 resume time by skipping training empty slots. +} PCIE_TRAINING_ALGORITHM; + +/// PCIe Link Training State +typedef enum { + LinkStateResetAssert, ///< Assert port GPIO reset + LinkStateResetDuration, ///< Timeout for reset duration + LinkStateResetExit, ///< Deassert port GPIO reset + LinkTrainingResetTimeout, ///< Port GPIO reset timeout + LinkStateReleaseTraining, ///< Release link training + LinkStateDetectPresence, ///< Detect device presence + LinkStateDetecting, ///< Detect link training. + LinkStateBrokenLane, ///< Check and handle broken lane + LinkStateGen2Fail, ///< Check and handle device that fail training if GEN2 capability advertised + LinkStateL0, ///< Device trained to L0 + LinkStateVcoNegotiation, ///< Check VCO negotiation complete + LinkStateRetrain, ///< Force retrain link. + LinkStateTrainingFail, ///< Link training fail + LinkStateTrainingSuccess, ///< Link training success + LinkStateGfxWorkaround, ///< GFX workaround + LinkStateCompliance, ///< Link in compliance mode + LinkStateDeviceNotPresent, ///< Link is not connected + LinkStateTrainingCompleted ///< Link training completed +} PCIE_LINK_TRAINING_STATE; + +/// PCIe Port Visibility +typedef enum { + UnhidePorts, ///< Command to unhide port + HidePorts, ///< Command to hide unused ports +} PCIE_PORT_VISIBILITY; + + +/// Table Register Entry +typedef struct { + UINT16 Reg; ///< Address + UINT32 Mask; ///< Mask + UINT32 Data; ///< Data +} PCIE_PORT_REGISTER_ENTRY; + +/// Table Register Entry +typedef struct { + PCIE_PORT_REGISTER_ENTRY *Table; ///< Table + UINT32 Length; ///< Length +} PCIE_PORT_REGISTER_TABLE_HEADER; + +/// Table Register Entry +typedef struct { + UINT32 Reg; ///< Address + UINT32 Mask; ///< Mask + UINT32 Data; ///< Data +} PCIE_HOST_REGISTER_ENTRY; + +/// Table Register Entry +typedef struct { + PCIE_HOST_REGISTER_ENTRY *Table; ///< Table + UINT32 Length; ///< Length +} PCIE_HOST_REGISTER_TABLE_HEADER; + +///Link ASPM info +typedef struct { + PCI_ADDR DownstreamPort; ///< PCI address of downstream port + PCIE_ASPM_TYPE DownstreamAspm; ///< Downstream Device Aspm + PCI_ADDR UpstreamPort; ///< PCI address of upstream port + PCIE_ASPM_TYPE UpstreamAspm; ///< Upstream Device Capability + PCIE_ASPM_TYPE RequestedAspm; ///< Requested ASPM + BOOLEAN BlackList; ///< Blacklist device +} PCIe_LINK_ASPM; + +///PCIe ASPM Latency Information +typedef struct { + UINT8 MaxL0sExitLatency; ///< Max L0s exit latency in us + UINT8 MaxL1ExitLatency; ///< Max L1 exit latency in us +} PCIe_ASPM_LATENCY_INFO; + +/// PCI address association +typedef struct { + UINT8 NewDeviceAddress; ///< New PCI address (Device,Fucntion) + UINT8 NativeDeviceAddress; ///< Native PCI address (Device,Fucntion) +} PCI_ADDR_LIST; + +/// The return status for GFX Card Workaround. +typedef enum { + GFX_WORKAROUND_DEVICE_NOT_READY, ///< GFX Workaround device is not ready. + GFX_WORKAROUND_RESET_DEVICE, ///< GFX Workaround device need reset. + GFX_WORKAROUND_SUCCESS ///< The service completed normally. +} GFX_WORKAROUND_STATUS; + +/// GFX workaround control +typedef enum { + GfxWorkaroundDisable, ///< GFX Workaround disabled + GfxWorkaroundEnable ///< GFX Workaround enabled +} GFX_WORKAROUND_CONTROL; + +/// PIF lane power state +typedef enum { + PifPowerStateL0, ///< + PifPowerStateLS1, ///< + PifPowerStateLS2, ///< + PifPowerStateOff = 0x7, ///< +} PCIE_PIF_POWER_STATE; + +/// PIF lane power control +typedef enum { + PowerDownPifs, ///< + PowerUpPifs ///< +} PCIE_PIF_POWER_CONTROL; + +///PLL rumup time +typedef enum { + NormalRampup, ///< + LongRampup, ///< +} PCIE_PLL_RAMPUP_TIME; + +typedef UINT16 PCIe_ENGINE_INIT_STATUS; + +/// PCIe port configuration info +typedef struct { + PCIe_PORT_DATA PortData; ///< Port data + UINT8 StartCoreLane; ///< Start Core Lane + UINT8 EndCoreLane; ///< End Core lane + UINT8 NativeDevNumber :5; ///< Native PCI device number of the port + UINT8 NativeFunNumber :3; ///< Native PCI function number of the port + UINT8 CoreId :4; ///< PCIe core ID + UINT8 PortId :4; ///< Port ID on wrapper + PCI_ADDR Address; ///< PCI address of the port + UINT8 State; ///< Training state + UINT8 PcieBridgeId:4; ///< IOC PCIe bridge ID + UINT16 UnitId:12; ///< Port start unit ID + UINT16 NumberOfUnitId:4; ///< Def number of unitIDs assigned to port + UINT8 GfxWrkRetryCount:4; ///< Number of retry for GFX workaround + UINT32 TimeStamp; ///< Time stamp used to during training process + UINT8 LogicalBridgeId; ///< Logical Bridge ID +} PCIe_PORT_CONFIG; + +///Descriptor header +typedef struct { + UINT32 DescriptorFlags; ///< Descriptor flags + UINT16 Parent; ///< Offset of parent descriptor + UINT16 Peer; ///< Offset of the peer descriptor + UINT16 Child; ///< Offset of the list of child descriptors +} PCIe_DESCRIPTOR_HEADER; + +/// DDI (Digital Display Interface) configuration info +typedef struct { + PCIe_DDI_DATA DdiData; ///< DDI Data + UINT8 DisplayPriorityIndex; ///< Display priority index + UINT8 ConnectorId; ///< Connector id determined by enumeration + UINT8 DisplayDeviceId; ///< Display device id determined by enumeration +} PCIe_DDI_CONFIG; + + +/// Engine configuration data +typedef struct { + PCIe_DESCRIPTOR_HEADER Header; ///< Descriptor header + PCIe_ENGINE_DATA EngineData; ///< Engine Data + PCIe_ENGINE_INIT_STATUS InitStatus; ///< Initialization Status + UINT8 Scratch; ///< Scratch pad + union { + PCIe_PORT_CONFIG Port; ///< PCIe port configuration data + PCIe_DDI_CONFIG Ddi; ///< DDI configuration data + } Type; +} PCIe_ENGINE_CONFIG; + +/// Wrapper configuration data +typedef struct { + PCIe_DESCRIPTOR_HEADER Header; ///< Descriptor Header + UINT8 WrapId; ///< Wrapper ID + UINT8 NumberOfPIFs; ///< Number of PIFs on wrapper + UINT8 StartPhyLane; ///< Start PHY Lane + UINT8 EndPhyLane; ///< End PHY Lane + UINT8 StartPcieCoreId:4; ///< Start PCIe Core ID + UINT8 EndPcieCoreId:4; ///< End PCIe Core ID + UINT8 NumberOfLanes; ///< Number of lanes + struct { + UINT8 PowerOffUnusedLanes:1; ///< Power Off unused lanes + UINT8 PowerOffUnusedPlls:1; ///< Power Off unused Plls + UINT8 ClkGating:1; ///< TXCLK gating + UINT8 LclkGating:1; ///< LCLK gating + UINT8 TxclkGatingPllPowerDown:1; ///< TXCLK clock gating PLL power down + UINT8 PllOffInL1:1; ///< PLL off in L1 + UINT8 AccessEncoding:1; ///< Reg access encoding + } Features; + UINT8 MasterPll; ///< Bitmap of master PLL +} PCIe_WRAPPER_CONFIG; + + +/// Silicon configuration data +typedef struct { + PCIe_DESCRIPTOR_HEADER Header; ///< Descriptor Header + UINT8 SiliconId; ///< Gnb silicon(module) ID + UINT8 NodeId; ///< Node to which GNB connected + UINT8 LinkId; ///< Link to which GNB connected if LinkId > 3 GNB connected to sublink = LinkId - 4 + PCI_ADDR Address; ///< PCI address of GNB host bridge +} PCIe_SILICON_CONFIG; + +typedef PCIe_SILICON_CONFIG GNB_HANDLE; + +/// Complex configuration data +typedef struct { + PCIe_DESCRIPTOR_HEADER Header; ///< Descriptor Header + UINT8 SocketId; ///< Processor socket ID +} PCIe_COMPLEX_CONFIG; + +/// PCIe platform configuration info +typedef struct { + PCIe_DESCRIPTOR_HEADER Header; ///< Descriptor Header + PVOID StdHeader; ///< Standard configuration header + UINT32 LinkReceiverDetectionPooling; ///< Receiver pooling detection time in us. + UINT32 LinkL0Pooling; ///< Pooling for link to get to L0 in us + UINT32 LinkGpioResetAssertionTime; ///< Gpio reset assertion time in us + UINT32 LinkResetToTrainingTime; ///< Time duration between deassert GPIO reset and release training in us /// + UINT8 GfxCardWorkaround; ///< GFX Card Workaround + UINT8 PsppPolicy; ///< PSPP policy + UINT8 TrainingExitState; ///< State at which training should exit (see PCIE_LINK_TRAINING_STATE) + UINT8 TrainingAlgorithm; ///< Training algorithm (see PCIE_TRAINING_ALGORITHM) + PCIe_COMPLEX_CONFIG ComplexList[MAX_NUMBER_OF_COMPLEXES]; ///< Complex +} PCIe_PLATFORM_CONFIG; + +/// PCIe Engine Description +typedef struct { + UINT32 Flags; /**< Descriptor flags + * @li @b Bit31 - last descriptor on wrapper + * @li @b Bit30 - Descriptor allocated for PCIe port or DDI + */ + PCIe_ENGINE_DATA EngineData; ///< Engine Data +} PCIe_ENGINE_DESCRIPTOR; + +/// PCIe Lane allocation descriptor +typedef struct { + UINT32 Flags; ///< Flags + UINT8 WrapId; ///< Wrapper ID + UINT8 EngineType; ///< Engine Type + UINT8 NumberOfEngines; ///< Number of engines to configure + UINT8 NumberOfConfigurations; ///< Number of possible configurations + UINT8 *ConfigTable; ///< Pointer to config table +} PCIe_LANE_ALLOC_DESCRIPTOR; + +/// Lane Control +typedef enum { + EnableLanes, ///< Enable Lanes + DisableLanes ///< Disable Lanes +} LANE_CONTROL; + +#pragma pack (pop) + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbPcieFamServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbPcieFamServices.h new file mode 100644 index 0000000000..6ec63993d3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbPcieFamServices.h @@ -0,0 +1,242 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe family specific services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBPCIEFAMSERVICES_H_ +#define _GNBPCIEFAMSERVICES_H_ + +#include "Gnb.h" +#include "GnbPcie.h" + +AGESA_STATUS +PcieFmGetComplexDataLength ( + IN UINT8 SocketId, + OUT UINTN *Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef AGESA_STATUS F_PCIEFMGETCOMPLEXDATALENGTH ( + IN UINT8 SocketId, + OUT UINTN *Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieFmBuildComplexConfiguration ( + IN UINT8 SocketId, + OUT VOID *Buffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef AGESA_STATUS F_PCIEFMBUILDCOMPLEXCONFIGURATION ( + IN UINT8 SocketId, + OUT VOID *Buffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieFmConfigureEnginesLaneAllocation ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIE_ENGINE_TYPE EngineType, + IN UINT8 ConfigurationId + ); + +typedef AGESA_STATUS F_PCIEFMCONFIGUREENGINESLANEALLOCATION ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIE_ENGINE_TYPE EngineType, + IN UINT8 ConfigurationId + ); + +AGESA_STATUS +PcieFmGetCoreConfigurationValue ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId, + IN UINT64 ConfigurationSignature, + IN UINT8 *ConfigurationValue + ); + +typedef AGESA_STATUS F_PCIEFMGETCORECONFIGURATIONVALUE ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId, + IN UINT64 ConfigurationSignature, + IN UINT8 *ConfigurationValue + ); + +BOOLEAN +PcieFmCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +typedef BOOLEAN F_PCIEFMCHECKPORTPCIDEVICEMAPPING ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +AGESA_STATUS +PcieFmMapPortPciAddress ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +typedef AGESA_STATUS F_PCIEFMMAPPORTPCIADDRESS ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +BOOLEAN +PcieFmCheckPortPcieLaneCanBeMuxed ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +typedef BOOLEAN F_PCIEFMCHECKPORTPCIELANECANBEMUXED ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +CONST CHAR8* +PcieFmDebugGetCoreConfigurationString ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 ConfigurationValue + ); + +typedef CONST CHAR8* F_PCIEFMDEBUGGETCORECONFIGURATIONSTRING ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 ConfigurationValue + ); + +CONST CHAR8* +PcieFmDebugGetWrapperNameString ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +typedef CONST CHAR8* F_PCIEFMDEBUGGETWRAPPERNAMESTRING ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +CONST CHAR8* +PcieFmDebugGetHostRegAddressSpaceString ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT16 AddressFrame + ); + +typedef CONST CHAR8* F_PCIEFMDEBUGGETHOSTREGADDRESSSPACESTRING ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT16 AddressFrame + ); + +PCIE_LINK_SPEED_CAP +PcieFmGetLinkSpeedCap ( + IN UINT32 Flags, + IN PCIe_ENGINE_CONFIG *Engine + ); + +typedef PCIE_LINK_SPEED_CAP F_PCIEFMGETLINKSPEEDCAP ( + IN UINT32 Flags, + IN PCIe_ENGINE_CONFIG *Engine + ); + +VOID +PcieFmSetLinkSpeedCap ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +typedef VOID F_PCIEFMSETLINKSPEEDCAP ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PcieFmGetNativePhyLaneBitmap ( + IN UINT32 PhyLaneBitmap, + IN PCIe_ENGINE_CONFIG *Engine + ); + +typedef UINT32 F_PCIEFMGETNATIVEPHYLANEBITMAP ( + IN UINT32 PhyLaneBitmap, + IN PCIe_ENGINE_CONFIG *Engine + ); + +AGESA_STATUS +PcieFmGetSbConfigInfo ( + IN UINT8 SocketId, + OUT PCIe_PORT_DESCRIPTOR *SbPort, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef AGESA_STATUS F_PCIEFMGETSBCONFIGINFO ( + IN UINT8 SocketId, + OUT PCIe_PORT_DESCRIPTOR *SbPort, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +/// PCIe config services +typedef struct { + F_PCIEFMGETCOMPLEXDATALENGTH *PcieFmGetComplexDataLength; ///< PcieFmGetComplexDataLength + F_PCIEFMBUILDCOMPLEXCONFIGURATION *PcieFmBuildComplexConfiguration; ///< PcieFmBuildComplexConfiguration + F_PCIEFMCONFIGUREENGINESLANEALLOCATION *PcieFmConfigureEnginesLaneAllocation; ///< PcieFmConfigureEnginesLaneAllocation + F_PCIEFMCHECKPORTPCIDEVICEMAPPING *PcieFmCheckPortPciDeviceMapping; ///< PcieFmCheckPortPciDeviceMapping + F_PCIEFMMAPPORTPCIADDRESS *PcieFmMapPortPciAddress; ///< PcieFmMapPortPciAddress + F_PCIEFMCHECKPORTPCIELANECANBEMUXED *PcieFmCheckPortPcieLaneCanBeMuxed; ///< PcieFmCheckPortPcieLaneCanBeMuxed + F_PCIEFMGETSBCONFIGINFO *PcieFmGetSbConfigInfo; ///< PcieFmGetSbConfigInfo +} PCIe_FAM_CONFIG_SERVICES; + +/// PCIe init services +typedef struct { + F_PCIEFMGETCORECONFIGURATIONVALUE *PcieFmGetCoreConfigurationValue; ///< PcieFmGetCoreConfigurationValue + F_PCIEFMGETLINKSPEEDCAP *PcieFmGetLinkSpeedCap; ///< PcieFmGetLinkSpeedCap + F_PCIEFMGETNATIVEPHYLANEBITMAP *PcieFmGetNativePhyLaneBitmap; ///< PcieFmGetNativePhyLaneBitmap + F_PCIEFMSETLINKSPEEDCAP *PcieFmSetLinkSpeedCap; ///< PcieFmSetLinkSpeedCap +} PCIe_FAM_INIT_SERVICES; + +///PCIe debug services +typedef struct { + F_PCIEFMDEBUGGETHOSTREGADDRESSSPACESTRING *PcieFmDebugGetHostRegAddressSpaceString; ///< PcieFmGetCoreConfigurationValue + F_PCIEFMDEBUGGETWRAPPERNAMESTRING *PcieFmDebugGetWrapperNameString; ///< PcieFmDebugGetWrapperNameString + F_PCIEFMDEBUGGETCORECONFIGURATIONSTRING *PcieFmDebugGetCoreConfigurationString; ///< PcieFmDebugGetCoreConfigurationString +} PCIe_FAM_DEBUG_SERVICES; + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersCommon.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersCommon.h new file mode 100644 index 0000000000..b67058f291 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersCommon.h @@ -0,0 +1,1557 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Register definitions + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBREGISTERSCOMMON_H_ +#define _GNBREGISTERSCOMMON_H_ + + +#define TYPE_D0F0 0x1 +#define TYPE_D0F0x64 0x2 +#define TYPE_D0F0x98 0x3 +#define TYPE_D0F0xE4 0x5 +#define TYPE_DxF0 0x6 +#define TYPE_DxF0xE4 0x7 +#define TYPE_D18F1 0xb +#define TYPE_D18F2 0xc +#define TYPE_D18F3 0xd +#define TYPE_MSR 0x10 +#define TYPE_D1F0 0x11 +#define D18F2x9C 0xe +#ifndef WRAP_SPACE + #define WRAP_SPACE(w, x) (0x01300000 | (w << 16) | (x)) +#endif +#ifndef CORE_SPACE + #define CORE_SPACE(c, x) (0x00010000 | (c << 24) | (x)) +#endif +#ifndef PHY_SPACE + #define PHY_SPACE(w, p, x) (0x00200000 | ((p + 1) << 24) | (w << 16) | (x)) +#endif +#ifndef PIF_SPACE + #define PIF_SPACE(w, p, x) (0x00100000 | ((p + 1) << 24) | (w << 16) | (x)) +#endif +// **** D0F0x00 Register Definition **** +// Address +#define D0F0x00_ADDRESS 0x0 + +// Type +#define D0F0x00_TYPE TYPE_D0F0 +// Field Data +#define D0F0x00_VendorID_OFFSET 0 +#define D0F0x00_VendorID_WIDTH 16 +#define D0F0x00_VendorID_MASK 0xffff +#define D0F0x00_DeviceID_OFFSET 16 +#define D0F0x00_DeviceID_WIDTH 16 +#define D0F0x00_DeviceID_MASK 0xffff0000 + +/// D0F0x00 +typedef union { + struct { ///< + UINT32 VendorID:16; ///< + UINT32 DeviceID:16; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x00_STRUCT; + +// **** D0F0x04 Register Definition **** +// Address +#define D0F0x04_ADDRESS 0x4 + +// Type +#define D0F0x04_TYPE TYPE_D0F0 +// Field Data +#define D0F0x04_IoAccessEn_OFFSET 0 +#define D0F0x04_IoAccessEn_WIDTH 1 +#define D0F0x04_IoAccessEn_MASK 0x1 +#define D0F0x04_MemAccessEn_OFFSET 1 +#define D0F0x04_MemAccessEn_WIDTH 1 +#define D0F0x04_MemAccessEn_MASK 0x2 +#define D0F0x04_BusMasterEn_OFFSET 2 +#define D0F0x04_BusMasterEn_WIDTH 1 +#define D0F0x04_BusMasterEn_MASK 0x4 +#define D0F0x04_Reserved_7_7_OFFSET 7 +#define D0F0x04_Reserved_7_7_WIDTH 1 +#define D0F0x04_Reserved_7_7_MASK 0x80 +#define D0F0x04_Reserved_19_10_OFFSET 10 +#define D0F0x04_Reserved_19_10_WIDTH 10 +#define D0F0x04_Reserved_19_10_MASK 0xffc00 +#define D0F0x04_CapList_OFFSET 20 +#define D0F0x04_CapList_WIDTH 1 +#define D0F0x04_CapList_MASK 0x100000 + +/// D0F0x04 +typedef union { + struct { ///< + UINT32 IoAccessEn:1 ; ///< + UINT32 MemAccessEn:1 ; ///< + UINT32 BusMasterEn:1 ; ///< + UINT32 Reserved_3_3:1 ; ///< + UINT32 Reserved_4_4:1 ; ///< + UINT32 Reserved_5_5:1 ; ///< + UINT32 Reserved_6_6:1 ; ///< + UINT32 Reserved_7_7:1 ; ///< + UINT32 Reserved_8_8:1 ; ///< + UINT32 Reserved_9_9:1 ; ///< + UINT32 Reserved_19_10:10; ///< + UINT32 CapList:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x04_STRUCT; + +// **** D0F0x60 Register Definition **** +// Address +#define D0F0x60_ADDRESS 0x60 + + +// **** D0F0x64 Register Definition **** +// Address +#define D0F0x64_ADDRESS 0x64 + +// Type +#define D0F0x64_TYPE TYPE_D0F0 +// Field Data +#define D0F0x64_MiscIndData_OFFSET 0 +#define D0F0x64_MiscIndData_WIDTH 32 +#define D0F0x64_MiscIndData_MASK 0xffffffff + +/// D0F0x64 +typedef union { + struct { ///< + UINT32 MiscIndData:32; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x64_STRUCT; + + + +// **** D0F0x90 Register Definition **** +// Address +#define D0F0x90_ADDRESS 0x90 + +// Type +#define D0F0x90_TYPE TYPE_D0F0 +// Field Data +#define D0F0x90_Reserved_22_0_OFFSET 0 +#define D0F0x90_Reserved_22_0_WIDTH 23 +#define D0F0x90_Reserved_22_0_MASK 0x7fffff +#define D0F0x90_TopOfDram_OFFSET 23 +#define D0F0x90_TopOfDram_WIDTH 9 +#define D0F0x90_TopOfDram_MASK 0xff800000 + +/// D0F0x90 +typedef union { + struct { ///< + UINT32 Reserved_22_0:23; ///< + UINT32 TopOfDram:9 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x90_STRUCT; + +// **** D0F0x94 Register Definition **** +// Address +#define D0F0x94_ADDRESS 0x94 + +// Type +#define D0F0x94_TYPE TYPE_D0F0 +// Field Data +#define D0F0x94_OrbIndAddr_OFFSET 0 +#define D0F0x94_OrbIndAddr_WIDTH 7 +#define D0F0x94_OrbIndAddr_MASK 0x7f +#define D0F0x94_Reserved_7_7_OFFSET 7 +#define D0F0x94_Reserved_7_7_WIDTH 1 +#define D0F0x94_Reserved_7_7_MASK 0x80 +#define D0F0x94_Reserved_31_9_OFFSET 9 +#define D0F0x94_Reserved_31_9_WIDTH 23 +#define D0F0x94_Reserved_31_9_MASK 0xfffffe00 + +/// D0F0x94 +typedef union { + struct { ///< + UINT32 OrbIndAddr:7 ; ///< + UINT32 Reserved_7_7:1 ; ///< + UINT32 Reserved_8_8:1 ; ///< + UINT32 Reserved_31_9:23; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x94_STRUCT; + + +// **** D0F0xE0 Register Definition **** +// Address +#define D0F0xE0_ADDRESS 0xe0 + +// Type +#define D0F0xE0_TYPE TYPE_D0F0 +// Field Data +#define D0F0xE0_PcieIndxAddr_OFFSET 0 +#define D0F0xE0_PcieIndxAddr_WIDTH 16 +#define D0F0xE0_PcieIndxAddr_MASK 0xffff +#define D0F0xE0_FrameType_OFFSET 16 +#define D0F0xE0_FrameType_WIDTH 8 +#define D0F0xE0_FrameType_MASK 0xff0000 +#define D0F0xE0_BlockSelect_OFFSET 24 +#define D0F0xE0_BlockSelect_WIDTH 8 +#define D0F0xE0_BlockSelect_MASK 0xff000000 + +/// D0F0xE0 +typedef union { + struct { ///< + UINT32 PcieIndxAddr:16; ///< + UINT32 FrameType:8 ; ///< + UINT32 BlockSelect:8 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE0_STRUCT; + + +// **** D18F3x15C Register Definition **** +// Address +#define D18F3x15C_ADDRESS 0x15c + +// Type +#define D18F3x15C_TYPE TYPE_D18F3 +// Field Data +#define D18F3x15C_SclkVidLevel0_OFFSET 0 +#define D18F3x15C_SclkVidLevel0_WIDTH 7 +#define D18F3x15C_SclkVidLevel0_MASK 0x7f +#define D18F3x15C_Reserved_7_7_OFFSET 7 +#define D18F3x15C_Reserved_7_7_WIDTH 1 +#define D18F3x15C_Reserved_7_7_MASK 0x80 +#define D18F3x15C_SclkVidLevel1_OFFSET 8 +#define D18F3x15C_SclkVidLevel1_WIDTH 7 +#define D18F3x15C_SclkVidLevel1_MASK 0x7f00 +#define D18F3x15C_Reserved_15_15_OFFSET 15 +#define D18F3x15C_Reserved_15_15_WIDTH 1 +#define D18F3x15C_Reserved_15_15_MASK 0x8000 +#define D18F3x15C_SclkVidLevel2_OFFSET 16 +#define D18F3x15C_SclkVidLevel2_WIDTH 7 +#define D18F3x15C_SclkVidLevel2_MASK 0x7f0000 +#define D18F3x15C_Reserved_23_23_OFFSET 23 +#define D18F3x15C_Reserved_23_23_WIDTH 1 +#define D18F3x15C_Reserved_23_23_MASK 0x800000 +#define D18F3x15C_SclkVidLevel3_OFFSET 24 +#define D18F3x15C_SclkVidLevel3_WIDTH 7 +#define D18F3x15C_SclkVidLevel3_MASK 0x7f000000 +#define D18F3x15C_Reserved_31_31_OFFSET 31 +#define D18F3x15C_Reserved_31_31_WIDTH 1 +#define D18F3x15C_Reserved_31_31_MASK 0x80000000 + +/// D18F3x15C +typedef union { + struct { ///< + UINT32 SclkVidLevel0:7 ; ///< + UINT32 Reserved_7_7:1 ; ///< + UINT32 SclkVidLevel1:7 ; ///< + UINT32 Reserved_15_15:1 ; ///< + UINT32 SclkVidLevel2:7 ; ///< + UINT32 Reserved_23_23:1 ; ///< + UINT32 SclkVidLevel3:7 ; ///< + UINT32 Reserved_31_31:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F3x15C_STRUCT; + +// **** D18F3x17C Register Definition **** + + + +// **** DxF0x18 Register Definition **** +// Address +#define DxF0x18_ADDRESS 0x18 + +// Type +#define DxF0x18_TYPE TYPE_D4F0 +// **** DxF0x58 Register Definition **** +// Address + + + + +// **** D0F0x64_x0C Register Definition **** +// Address +#define D0F0x64_x0C_ADDRESS 0xc + +// Type +#define D0F0x64_x0C_TYPE TYPE_D0F0x64 + +/// D0F0x64_x0C +typedef union { + UINT32 Value; ///< +} D0F0x64_x0C_STRUCT; + +// **** D0F0x64_x19 Register Definition **** +// Address +#define D0F0x64_x19_ADDRESS 0x19 + +// Type +#define D0F0x64_x19_TYPE TYPE_D0F0x64 +// Field Data +#define D0F0x64_x19_TomEn_OFFSET 0 +#define D0F0x64_x19_TomEn_WIDTH 1 +#define D0F0x64_x19_TomEn_MASK 0x1 +#define D0F0x64_x19_Reserved_22_1_OFFSET 1 +#define D0F0x64_x19_Reserved_22_1_WIDTH 22 +#define D0F0x64_x19_Reserved_22_1_MASK 0x7ffffe +#define D0F0x64_x19_Tom2_31_23__OFFSET 23 +#define D0F0x64_x19_Tom2_31_23__WIDTH 9 +#define D0F0x64_x19_Tom2_31_23__MASK 0xff800000 + +/// D0F0x64_x19 +typedef union { + struct { ///< + UINT32 TomEn:1 ; ///< + UINT32 Reserved_22_1:22; ///< + UINT32 Tom2_31_23_:9 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x64_x19_STRUCT; + +// **** D0F0x64_x1A Register Definition **** +// Address +#define D0F0x64_x1A_ADDRESS 0x1a + +// Type +#define D0F0x64_x1A_TYPE TYPE_D0F0x64 +// Field Data +#define D0F0x64_x1A_Tom2_39_32__OFFSET 0 +#define D0F0x64_x1A_Tom2_39_32__WIDTH 8 +#define D0F0x64_x1A_Tom2_39_32__MASK 0xff +#define D0F0x64_x1A_Reserved_31_8_OFFSET 8 +#define D0F0x64_x1A_Reserved_31_8_WIDTH 24 +#define D0F0x64_x1A_Reserved_31_8_MASK 0xffffff00 + +/// D0F0x64_x1A +typedef union { + struct { ///< + UINT32 Tom2_39_32_:8 ; ///< + UINT32 Reserved_31_8:24; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x64_x1A_STRUCT; + +// **** D0F0x64_x1D Register Definition **** +// Address +#define D0F0x64_x1D_ADDRESS 0x1d + +// Type +#define D0F0x64_x1D_TYPE TYPE_D0F0x64 +// Field Data +#define D0F0x64_x1D_VgaEn_OFFSET 1 +#define D0F0x64_x1D_VgaEn_WIDTH 1 +#define D0F0x64_x1D_VgaEn_MASK 0x2 +#define D0F0x64_x1D_Reserved_2_2_OFFSET 2 +#define D0F0x64_x1D_Reserved_2_2_WIDTH 1 +#define D0F0x64_x1D_Reserved_2_2_MASK 0x4 +#define D0F0x64_x1D_Vga16En_OFFSET 3 +#define D0F0x64_x1D_Vga16En_WIDTH 1 +#define D0F0x64_x1D_Vga16En_MASK 0x8 +#define D0F0x64_x1D_Reserved_31_4_OFFSET 4 +#define D0F0x64_x1D_Reserved_31_4_WIDTH 28 +#define D0F0x64_x1D_Reserved_31_4_MASK 0xfffffff0 + +/// D0F0x64_x1D +typedef union { + struct { ///< + UINT32 Reserved_1_1:1 ; ///< + UINT32 VgaEn:1 ; ///< + UINT32 Reserved_2_2:1 ; ///< + UINT32 Vga16En:1 ; ///< + UINT32 Reserved_31_4:28; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x64_x1D_STRUCT; + + +// **** D0F0x64_x6A Register Definition **** +// Address +#define D0F0x64_x6A_ADDRESS 0x6a + +// Type +#define D0F0x64_x6A_TYPE TYPE_D0F0x64 +// Field Data +#define D0F0x64_x6A_VoltageForceEn_OFFSET 0 +#define D0F0x64_x6A_VoltageForceEn_WIDTH 1 +#define D0F0x64_x6A_VoltageForceEn_MASK 0x1 +#define D0F0x64_x6A_VoltageChangeEn_OFFSET 1 +#define D0F0x64_x6A_VoltageChangeEn_WIDTH 1 +#define D0F0x64_x6A_VoltageChangeEn_MASK 0x2 +#define D0F0x64_x6A_VoltageChangeReq_OFFSET 2 +#define D0F0x64_x6A_VoltageChangeReq_WIDTH 1 +#define D0F0x64_x6A_VoltageChangeReq_MASK 0x4 +#define D0F0x64_x6A_VoltageLevel_OFFSET 3 +#define D0F0x64_x6A_VoltageLevel_WIDTH 2 +#define D0F0x64_x6A_VoltageLevel_MASK 0x18 +#define D0F0x64_x6A_Reserved_31_5_OFFSET 5 +#define D0F0x64_x6A_Reserved_31_5_WIDTH 27 +#define D0F0x64_x6A_Reserved_31_5_MASK 0xffffffe0 + +/// D0F0x64_x6A +typedef union { + struct { ///< + UINT32 VoltageForceEn:1 ; ///< + UINT32 VoltageChangeEn:1 ; ///< + UINT32 VoltageChangeReq:1 ; ///< + UINT32 VoltageLevel:2 ; ///< + UINT32 Reserved_31_5:27; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x64_x6A_STRUCT; + +// **** D0F0x64_x6B Register Definition **** +// Address +#define D0F0x64_x6B_ADDRESS 0x6b + +// Type +#define D0F0x64_x6B_TYPE TYPE_D0F0x64 +// Field Data +#define D0F0x64_x6B_VoltageChangeAck_OFFSET 0 +#define D0F0x64_x6B_VoltageChangeAck_WIDTH 1 +#define D0F0x64_x6B_VoltageChangeAck_MASK 0x1 +#define D0F0x64_x6B_CurrentVoltageLevel_OFFSET 1 +#define D0F0x64_x6B_CurrentVoltageLevel_WIDTH 2 +#define D0F0x64_x6B_CurrentVoltageLevel_MASK 0x6 +#define D0F0x64_x6B_Reserved_31_3_OFFSET 3 +#define D0F0x64_x6B_Reserved_31_3_WIDTH 29 +#define D0F0x64_x6B_Reserved_31_3_MASK 0xfffffff8 + +/// D0F0x64_x6B +typedef union { + struct { ///< + UINT32 VoltageChangeAck:1 ; ///< + UINT32 CurrentVoltageLevel:2 ; ///< + UINT32 Reserved_31_3:29; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x64_x6B_STRUCT; + +// **** D0F0x98_x06 Register Definition **** +// Address +#define D0F0x98_x06_ADDRESS 0x6 + +// Type +#define D0F0x98_x06_TYPE TYPE_D0F0x98 +// Field Data +#define D0F0x98_x06_Reserved_25_0_OFFSET 0 +#define D0F0x98_x06_Reserved_25_0_WIDTH 26 +#define D0F0x98_x06_Reserved_25_0_MASK 0x3ffffff +#define D0F0x98_x06_UmiNpMemWrEn_OFFSET 26 +#define D0F0x98_x06_UmiNpMemWrEn_WIDTH 1 +#define D0F0x98_x06_UmiNpMemWrEn_MASK 0x4000000 +#define D0F0x98_x06_Reserved_31_27_OFFSET 27 +#define D0F0x98_x06_Reserved_31_27_WIDTH 5 +#define D0F0x98_x06_Reserved_31_27_MASK 0xf8000000 + +/// D0F0x98_x06 +typedef union { + struct { ///< + UINT32 Reserved_25_0:26; ///< + UINT32 UmiNpMemWrEn:1 ; ///< + UINT32 Reserved_31_27:5 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x98_x06_STRUCT; + + +// **** D0F0x98_x2C Register Definition **** +// Address +#define D0F0x98_x2C_ADDRESS 0x2c + +// Type +#define D0F0x98_x2C_TYPE TYPE_D0F0x98 +// Field Data +#define D0F0x98_x2C_Reserved_0_0_OFFSET 0 +#define D0F0x98_x2C_Reserved_0_0_WIDTH 1 +#define D0F0x98_x2C_Reserved_0_0_MASK 0x1 +#define D0F0x98_x2C_DynWakeEn_OFFSET 1 +#define D0F0x98_x2C_DynWakeEn_WIDTH 1 +#define D0F0x98_x2C_DynWakeEn_MASK 0x2 +#define D0F0x98_x2C_Reserved_15_2_OFFSET 2 +#define D0F0x98_x2C_Reserved_15_2_WIDTH 14 +#define D0F0x98_x2C_Reserved_15_2_MASK 0xfffc +#define D0F0x98_x2C_WakeHysteresis_OFFSET 16 +#define D0F0x98_x2C_WakeHysteresis_WIDTH 16 +#define D0F0x98_x2C_WakeHysteresis_MASK 0xffff0000 + +/// D0F0x98_x2C +typedef union { + struct { ///< + UINT32 Reserved_0_0:1 ; ///< + UINT32 DynWakeEn:1 ; ///< + UINT32 Reserved_15_2:14; ///< + UINT32 WakeHysteresis:16; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x98_x2C_STRUCT; + +// **** D0F0x98_x3A Register Definition **** +// Address +#define D0F0x98_x3A_ADDRESS 0x3a + +// Type + + +// **** D0F0xE4_WRAP_0080 Register Definition **** +// Address +#define D0F0xE4_WRAP_0080_ADDRESS 0x80 + +// Type +#define D0F0xE4_WRAP_0080_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_0080_StrapBifLinkConfig_OFFSET 0 +#define D0F0xE4_WRAP_0080_StrapBifLinkConfig_WIDTH 4 +#define D0F0xE4_WRAP_0080_StrapBifLinkConfig_MASK 0xf +#define D0F0xE4_WRAP_0080_Reserved_31_4_OFFSET 4 +#define D0F0xE4_WRAP_0080_Reserved_31_4_WIDTH 28 +#define D0F0xE4_WRAP_0080_Reserved_31_4_MASK 0xfffffff0 + +/// D0F0xE4_WRAP_0080 +typedef union { + struct { ///< + UINT32 StrapBifLinkConfig:4 ; ///< + UINT32 Reserved_31_4:28; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_0080_STRUCT; + +// **** D0F0xE4_WRAP_0800 Register Definition **** +// Address +#define D0F0xE4_WRAP_0800_ADDRESS 0x800 + +// Type +#define D0F0xE4_WRAP_0800_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_0800_HoldTraining_OFFSET 0 +#define D0F0xE4_WRAP_0800_HoldTraining_WIDTH 1 +#define D0F0xE4_WRAP_0800_HoldTraining_MASK 0x1 +#define D0F0xE4_WRAP_0800_Reserved_31_1_OFFSET 1 +#define D0F0xE4_WRAP_0800_Reserved_31_1_WIDTH 31 +#define D0F0xE4_WRAP_0800_Reserved_31_1_MASK 0xfffffffe + +/// D0F0xE4_WRAP_0800 +typedef union { + struct { ///< + UINT32 HoldTraining:1 ; ///< + UINT32 Reserved_31_1:31; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_0800_STRUCT; + +// **** D0F0xE4_WRAP_0803 Register Definition **** +// Address +#define D0F0xE4_WRAP_0803_ADDRESS 0x803 + +// Type +#define D0F0xE4_WRAP_0803_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_0803_Reserved_4_0_OFFSET 0 +#define D0F0xE4_WRAP_0803_Reserved_4_0_WIDTH 5 +#define D0F0xE4_WRAP_0803_Reserved_4_0_MASK 0x1f +#define D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_OFFSET 5 +#define D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_WIDTH 1 +#define D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_MASK 0x20 +#define D0F0xE4_WRAP_0803_Reserved_31_6_OFFSET 6 +#define D0F0xE4_WRAP_0803_Reserved_31_6_WIDTH 26 +#define D0F0xE4_WRAP_0803_Reserved_31_6_MASK 0xffffffc0 + +/// D0F0xE4_WRAP_0803 +typedef union { + struct { ///< + UINT32 Reserved_4_0:5 ; ///< + UINT32 StrapBifDeemphasisSel:1 ; ///< + UINT32 Reserved_31_6:26; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_0803_STRUCT; + +// **** D0F0xE4_WRAP_0903 Register Definition **** +// Address +#define D0F0xE4_WRAP_0903_ADDRESS 0x903 + +// Type +#define D0F0xE4_WRAP_0903_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_0903_Reserved_4_0_OFFSET 0 +#define D0F0xE4_WRAP_0903_Reserved_4_0_WIDTH 5 +#define D0F0xE4_WRAP_0903_Reserved_4_0_MASK 0x1f +#define D0F0xE4_WRAP_0903_StrapBifDeemphasisSel_OFFSET 5 +#define D0F0xE4_WRAP_0903_StrapBifDeemphasisSel_WIDTH 1 +#define D0F0xE4_WRAP_0903_StrapBifDeemphasisSel_MASK 0x20 +#define D0F0xE4_WRAP_0903_Reserved_31_6_OFFSET 6 +#define D0F0xE4_WRAP_0903_Reserved_31_6_WIDTH 26 +#define D0F0xE4_WRAP_0903_Reserved_31_6_MASK 0xffffffc0 + +/// D0F0xE4_WRAP_0903 +typedef union { + struct { ///< + UINT32 Reserved_4_0:5 ; ///< + UINT32 StrapBifDeemphasisSel:1 ; ///< + UINT32 Reserved_31_6:26; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_0903_STRUCT; + + +// **** D0F0xE4_WRAP_8011 Register Definition **** +// Address +#define D0F0xE4_WRAP_8011_ADDRESS 0x8011 + +// Type +#define D0F0xE4_WRAP_8011_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_OFFSET 0 +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_MASK 0x3f +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_OFFSET 6 +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_MASK 0x40 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_OFFSET 7 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_MASK 0x80 +#define D0F0xE4_WRAP_8011_TxclkPermStop_OFFSET 8 +#define D0F0xE4_WRAP_8011_TxclkPermStop_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkPermStop_MASK 0x100 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_OFFSET 9 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_MASK 0x200 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_OFFSET 10 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_MASK 0xfc00 +#define D0F0xE4_WRAP_8011_RcvrDetClkEnable_OFFSET 16 +#define D0F0xE4_WRAP_8011_RcvrDetClkEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_RcvrDetClkEnable_MASK 0x10000 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_OFFSET 17 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_MASK 0x7e0000 +#define D0F0xE4_WRAP_8011_Reserved_23_23_OFFSET 23 +#define D0F0xE4_WRAP_8011_Reserved_23_23_WIDTH 1 +#define D0F0xE4_WRAP_8011_Reserved_23_23_MASK 0x800000 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_OFFSET 24 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_MASK 0x1000000 +#define D0F0xE4_WRAP_8011_Reserved_30_25_OFFSET 25 +#define D0F0xE4_WRAP_8011_Reserved_30_25_WIDTH 6 +#define D0F0xE4_WRAP_8011_Reserved_30_25_MASK 0x7e000000 + +/// D0F0xE4_WRAP_8011 +typedef union { + struct { ///< + UINT32 TxclkDynGateLatency:6 ; ///< + UINT32 TxclkPermGateEven:1 ; ///< + UINT32 TxclkDynGateEnable:1 ; ///< + UINT32 TxclkPermStop:1 ; ///< + UINT32 TxclkRegsGateEnable:1 ; ///< + UINT32 TxclkRegsGateLatency:6 ; ///< + UINT32 RcvrDetClkEnable:1 ; ///< + UINT32 TxclkPermGateLatency:6 ; ///< + UINT32 Reserved_23_23:1 ; ///< + UINT32 TxclkLcntGateEnable:1 ; ///< + UINT32 Reserved_30_25:6 ; ///< + UINT32 Reserved_31_31:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8011_STRUCT; + +// **** D0F0xE4_WRAP_8012 Register Definition **** +// Address +#define D0F0xE4_WRAP_8012_ADDRESS 0x8012 + +// Type +#define D0F0xE4_WRAP_8012_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_8012_Pif1xIdleGateLatency_OFFSET 0 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateLatency_MASK 0x3f +#define D0F0xE4_WRAP_8012_Reserved_6_6_OFFSET 6 +#define D0F0xE4_WRAP_8012_Reserved_6_6_WIDTH 1 +#define D0F0xE4_WRAP_8012_Reserved_6_6_MASK 0x40 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateEnable_OFFSET 7 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateEnable_MASK 0x80 +#define D0F0xE4_WRAP_8012_Pif1xIdleResumeLatency_OFFSET 8 +#define D0F0xE4_WRAP_8012_Pif1xIdleResumeLatency_WIDTH 6 +#define D0F0xE4_WRAP_8012_Pif1xIdleResumeLatency_MASK 0x3f00 + +/// D0F0xE4_WRAP_8012 +typedef union { + struct { ///< + UINT32 Pif1xIdleGateLatency:6 ; ///< + UINT32 Reserved_6_6:1 ; ///< + UINT32 Pif1xIdleGateEnable:1 ; ///< + UINT32 Pif1xIdleResumeLatency:6 ; ///< + UINT32 Reserved_15_14:2 ; ///< + UINT32 Reserved_21_16:6 ; ///< + UINT32 Reserved_22_22:1 ; ///< + UINT32 Reserved_23_23:1 ; ///< + UINT32 Reserved_24_29:6 ; ///< + UINT32 Reserved_31_30:2 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8012_STRUCT; + + +// **** D0F0xE4_WRAP_8021 Register Definition **** +// Address +#define D0F0xE4_WRAP_8021_ADDRESS 0x8021 + +// Type +#define D0F0xE4_WRAP_8021_TYPE TYPE_D0F0xE4 + +// **** D0F0xE4_WRAP_8022 Register Definition **** +// Address +#define D0F0xE4_WRAP_8022_ADDRESS 0x8022 + +// Type +#define D0F0xE4_WRAP_8022_TYPE TYPE_D0F0xE4 +// Field Data + +// **** D0F0xE4_WRAP_8023 Register Definition **** +// Address +#define D0F0xE4_WRAP_8023_ADDRESS 0x8023 + +// Type +#define D0F0xE4_WRAP_8023_TYPE TYPE_D0F0xE4 +/// D0F0xE4_WRAP_8023 +typedef union { + UINT32 Value; ///< +} D0F0xE4_WRAP_8023_STRUCT; + +// **** D0F0xE4_WRAP_8025 Register Definition **** +// Address +#define D0F0xE4_WRAP_8025_ADDRESS 0x8025 + +// Type +#define D0F0xE4_WRAP_8025_TYPE TYPE_D0F0xE4 +/// D0F0xE4_WRAP_8025 +typedef union { + UINT32 Value; ///< +} D0F0xE4_WRAP_8025_STRUCT; + + +// **** D0F0xE4_WRAP_8040 Register Definition **** +// Address +#define D0F0xE4_WRAP_8040_ADDRESS 0x8040 + +// Type +#define D0F0xE4_WRAP_8040_TYPE TYPE_D0F0xE4 + + +// **** D0F0xE4_WRAP_8060 Register Definition **** +// Address +#define D0F0xE4_WRAP_8060_ADDRESS 0x8060 + +// Type +#define D0F0xE4_WRAP_8060_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_8060_BifGlobalReset_OFFSET 16 +#define D0F0xE4_WRAP_8060_BifGlobalReset_WIDTH 1 +#define D0F0xE4_WRAP_8060_BifGlobalReset_MASK 0x10000 +#define D0F0xE4_WRAP_8060_BifCalibrationReset_OFFSET 17 +#define D0F0xE4_WRAP_8060_BifCalibrationReset_WIDTH 1 +#define D0F0xE4_WRAP_8060_BifCalibrationReset_MASK 0x20000 +#define D0F0xE4_WRAP_8060_Reserved_31_18_OFFSET 18 +#define D0F0xE4_WRAP_8060_Reserved_31_18_WIDTH 14 +#define D0F0xE4_WRAP_8060_Reserved_31_18_MASK 0xfffc0000 + +/// D0F0xE4_WRAP_8060 +typedef union { + struct { ///< + UINT32 Reconfigure:1 ; ///< + UINT32 Reserved_1_1:1 ; ///< + UINT32 ResetComplete:1 ; ///< + UINT32 Reserved_15_3:13; ///< + UINT32 BifGlobalReset:1 ; ///< + UINT32 BifCalibrationReset:1 ; ///< + UINT32 Reserved_31_18:14; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8060_STRUCT; + +// **** D0F0xE4_WRAP_8062 Register Definition **** +// Address +#define D0F0xE4_WRAP_8062_ADDRESS 0x8062 + +// Type +#define D0F0xE4_WRAP_8062_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_8062_ReconfigureEn_OFFSET 0 +#define D0F0xE4_WRAP_8062_ReconfigureEn_WIDTH 1 +#define D0F0xE4_WRAP_8062_ReconfigureEn_MASK 0x1 +#define D0F0xE4_WRAP_8062_Reserved_1_1_OFFSET 1 +#define D0F0xE4_WRAP_8062_Reserved_1_1_WIDTH 1 +#define D0F0xE4_WRAP_8062_Reserved_1_1_MASK 0x2 +#define D0F0xE4_WRAP_8062_ResetPeriod_OFFSET 2 +#define D0F0xE4_WRAP_8062_ResetPeriod_WIDTH 3 +#define D0F0xE4_WRAP_8062_ResetPeriod_MASK 0x1c +#define D0F0xE4_WRAP_8062_Reserved_9_5_OFFSET 5 +#define D0F0xE4_WRAP_8062_Reserved_9_5_WIDTH 5 +#define D0F0xE4_WRAP_8062_Reserved_9_5_MASK 0x3e0 +#define D0F0xE4_WRAP_8062_BlockOnIdle_OFFSET 10 +#define D0F0xE4_WRAP_8062_BlockOnIdle_WIDTH 1 +#define D0F0xE4_WRAP_8062_BlockOnIdle_MASK 0x400 +#define D0F0xE4_WRAP_8062_ConfigXferMode_OFFSET 11 +#define D0F0xE4_WRAP_8062_ConfigXferMode_WIDTH 1 +#define D0F0xE4_WRAP_8062_ConfigXferMode_MASK 0x800 +#define D0F0xE4_WRAP_8062_Reserved_31_12_OFFSET 12 +#define D0F0xE4_WRAP_8062_Reserved_31_12_WIDTH 20 +#define D0F0xE4_WRAP_8062_Reserved_31_12_MASK 0xfffff000 + +/// D0F0xE4_WRAP_8062 +typedef union { + struct { ///< + UINT32 ReconfigureEn:1 ; ///< + UINT32 Reserved_1_1:1 ; ///< + UINT32 ResetPeriod:3 ; ///< + UINT32 Reserved_9_5:5 ; ///< + UINT32 BlockOnIdle:1 ; ///< + UINT32 ConfigXferMode:1 ; ///< + UINT32 Reserved_31_12:20; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8062_STRUCT; + + +// **** D0F0xE4_PIF_0010 Register Definition **** +// Address +#define D0F0xE4_PIF_0010_ADDRESS 0x10 + +// Type +#define D0F0xE4_PIF_0010_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PIF_0010_Reserved_3_0_OFFSET 0 +#define D0F0xE4_PIF_0010_Reserved_3_0_WIDTH 4 +#define D0F0xE4_PIF_0010_Reserved_3_0_MASK 0xf +#define D0F0xE4_PIF_0010_EiDetCycleMode_OFFSET 4 +#define D0F0xE4_PIF_0010_EiDetCycleMode_WIDTH 1 +#define D0F0xE4_PIF_0010_EiDetCycleMode_MASK 0x10 +#define D0F0xE4_PIF_0010_Reserved_5_5_OFFSET 5 +#define D0F0xE4_PIF_0010_Reserved_5_5_WIDTH 1 +#define D0F0xE4_PIF_0010_Reserved_5_5_MASK 0x20 +#define D0F0xE4_PIF_0010_RxDetectFifoResetMode_OFFSET 6 +#define D0F0xE4_PIF_0010_RxDetectFifoResetMode_WIDTH 1 +#define D0F0xE4_PIF_0010_RxDetectFifoResetMode_MASK 0x40 +#define D0F0xE4_PIF_0010_RxDetectTxPwrMode_OFFSET 7 +#define D0F0xE4_PIF_0010_RxDetectTxPwrMode_WIDTH 1 +#define D0F0xE4_PIF_0010_RxDetectTxPwrMode_MASK 0x80 +#define D0F0xE4_PIF_0010_Reserved_16_8_OFFSET 8 +#define D0F0xE4_PIF_0010_Reserved_16_8_WIDTH 9 +#define D0F0xE4_PIF_0010_Reserved_16_8_MASK 0x1ff00 +#define D0F0xE4_PIF_0010_Ls2ExitTime_OFFSET 17 +#define D0F0xE4_PIF_0010_Ls2ExitTime_WIDTH 3 +#define D0F0xE4_PIF_0010_Ls2ExitTime_MASK 0xe0000 +#define D0F0xE4_PIF_0010_EiCycleOffTime_MASK 0x700000 +#define D0F0xE4_PIF_0010_Reserved_31_23_OFFSET 23 +#define D0F0xE4_PIF_0010_Reserved_31_23_WIDTH 9 +#define D0F0xE4_PIF_0010_Reserved_31_23_MASK 0xff800000 + +/// D0F0xE4_PIF_0010 +typedef union { + struct { ///< + UINT32 Reserved_3_0:4 ; ///< + UINT32 EiDetCycleMode:1 ; ///< + UINT32 Reserved_5_5:1 ; ///< + UINT32 RxDetectFifoResetMode:1 ; ///< + UINT32 RxDetectTxPwrMode:1 ; ///< + UINT32 Reserved_16_8:9 ; ///< + UINT32 Ls2ExitTime:3 ; ///< + UINT32 EiCycleOffTime:3 ; ///< + UINT32 Reserved_31_23:9 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PIF_0010_STRUCT; + +// **** D0F0xE4_PIF_0011 Register Definition **** +// Address +#define D0F0xE4_PIF_0011_ADDRESS 0x11 + +// Type +#define D0F0xE4_PIF_0011_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PIF_0011_X2Lane10_OFFSET 0 +#define D0F0xE4_PIF_0011_X2Lane10_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane10_MASK 0x1 +#define D0F0xE4_PIF_0011_X2Lane32_OFFSET 1 +#define D0F0xE4_PIF_0011_X2Lane32_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane32_MASK 0x2 +#define D0F0xE4_PIF_0011_X2Lane54_OFFSET 2 +#define D0F0xE4_PIF_0011_X2Lane54_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane54_MASK 0x4 +#define D0F0xE4_PIF_0011_X2Lane76_OFFSET 3 +#define D0F0xE4_PIF_0011_X2Lane76_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane76_MASK 0x8 +#define D0F0xE4_PIF_0011_Reserved_7_4_OFFSET 4 +#define D0F0xE4_PIF_0011_Reserved_7_4_WIDTH 4 +#define D0F0xE4_PIF_0011_Reserved_7_4_MASK 0xf0 +#define D0F0xE4_PIF_0011_X4Lane30_OFFSET 8 +#define D0F0xE4_PIF_0011_X4Lane30_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane30_MASK 0x100 +#define D0F0xE4_PIF_0011_X4Lane74_OFFSET 9 +#define D0F0xE4_PIF_0011_X4Lane74_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane74_MASK 0x200 +#define D0F0xE4_PIF_0011_Reserved_11_10_OFFSET 10 +#define D0F0xE4_PIF_0011_Reserved_11_10_WIDTH 2 +#define D0F0xE4_PIF_0011_Reserved_11_10_MASK 0xc00 +#define D0F0xE4_PIF_0011_Reserved_15_13_OFFSET 13 +#define D0F0xE4_PIF_0011_Reserved_15_13_WIDTH 3 +#define D0F0xE4_PIF_0011_Reserved_15_13_MASK 0xe000 +#define D0F0xE4_PIF_0011_X8Lane70_OFFSET 16 +#define D0F0xE4_PIF_0011_X8Lane70_WIDTH 1 +#define D0F0xE4_PIF_0011_X8Lane70_MASK 0x10000 +#define D0F0xE4_PIF_0011_Reserved_24_17_OFFSET 17 +#define D0F0xE4_PIF_0011_Reserved_24_17_WIDTH 8 +#define D0F0xE4_PIF_0011_Reserved_24_17_MASK 0x1fe0000 +#define D0F0xE4_PIF_0011_MultiPif_OFFSET 25 +#define D0F0xE4_PIF_0011_MultiPif_WIDTH 1 +#define D0F0xE4_PIF_0011_MultiPif_MASK 0x2000000 +#define D0F0xE4_PIF_0011_Reserved_31_26_OFFSET 26 +#define D0F0xE4_PIF_0011_Reserved_31_26_WIDTH 6 +#define D0F0xE4_PIF_0011_Reserved_31_26_MASK 0xfc000000 + +/// D0F0xE4_PIF_0011 +typedef union { + struct { ///< + UINT32 X2Lane10:1 ; ///< + UINT32 X2Lane32:1 ; ///< + UINT32 X2Lane54:1 ; ///< + UINT32 X2Lane76:1 ; ///< + UINT32 Reserved_7_4:4 ; ///< + UINT32 X4Lane30:1 ; ///< + UINT32 X4Lane74:1 ; ///< + UINT32 Reserved_11_10:2 ; ///< + UINT32 b12:1 ; ///< + UINT32 Reserved_15_13:3 ; ///< + UINT32 X8Lane70:1 ; ///< + UINT32 Reserved_24_17:8 ; ///< + UINT32 MultiPif:1 ; ///< + UINT32 Reserved_31_26:6 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PIF_0011_STRUCT; + +// **** D0F0xE4_PIF_0012 Register Definition **** +// Address +#define D0F0xE4_PIF_0012_ADDRESS 0x12 + +// Type +#define D0F0xE4_PIF_0012_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_OFFSET 0 +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_MASK 0x7 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_OFFSET 3 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_WIDTH 1 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_MASK 0x8 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_OFFSET 4 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_MASK 0x70 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_OFFSET 7 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_MASK 0x380 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_OFFSET 10 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_MASK 0x1c00 +#define D0F0xE4_PIF_0012_Reserved_15_13_OFFSET 13 +#define D0F0xE4_PIF_0012_Reserved_15_13_WIDTH 3 +#define D0F0xE4_PIF_0012_Reserved_15_13_MASK 0xe000 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_OFFSET 16 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_WIDTH 1 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_MASK 0x10000 +#define D0F0xE4_PIF_0012_Reserved_23_17_OFFSET 17 +#define D0F0xE4_PIF_0012_Reserved_23_17_WIDTH 7 +#define D0F0xE4_PIF_0012_Reserved_23_17_MASK 0xfe0000 +#define D0F0xE4_PIF_0012_PllRampUpTime_OFFSET 24 +#define D0F0xE4_PIF_0012_PllRampUpTime_WIDTH 3 +#define D0F0xE4_PIF_0012_PllRampUpTime_MASK 0x7000000 +#define D0F0xE4_PIF_0012_Reserved_27_27_OFFSET 27 +#define D0F0xE4_PIF_0012_Reserved_27_27_WIDTH 1 +#define D0F0xE4_PIF_0012_Reserved_27_27_MASK 0x8000000 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_OFFSET 28 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_WIDTH 1 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_MASK 0x10000000 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_OFFSET 29 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_MASK 0xe0000000 + +/// D0F0xE4_PIF_0012 +typedef union { + struct { ///< + UINT32 TxPowerStateInTxs2:3 ; ///< + UINT32 ForceRxEnInL0s:1 ; ///< + UINT32 RxPowerStateInRxs2:3 ; ///< + UINT32 PllPowerStateInTxs2:3 ; ///< + UINT32 PllPowerStateInOff:3 ; ///< + UINT32 Reserved_15_13:3 ; ///< + UINT32 Tx2p5clkClockGatingEn:1 ; ///< + UINT32 Reserved_23_17:7 ; ///< + UINT32 PllRampUpTime:3 ; ///< + UINT32 Reserved_27_27:1 ; ///< + UINT32 PllPwrOverrideEn:1 ; ///< + UINT32 PllPwrOverrideVal:3 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PIF_0012_STRUCT; + +// **** D0F0xE4_PIF_0013 Register Definition **** +// Address +#define D0F0xE4_PIF_0013_ADDRESS 0x13 + +// Type +#define D0F0xE4_PIF_0013_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PIF_0013_TxPowerStateInTxs2_OFFSET 0 +#define D0F0xE4_PIF_0013_TxPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0013_TxPowerStateInTxs2_MASK 0x7 +#define D0F0xE4_PIF_0013_ForceRxEnInL0s_OFFSET 3 +#define D0F0xE4_PIF_0013_ForceRxEnInL0s_WIDTH 1 +#define D0F0xE4_PIF_0013_ForceRxEnInL0s_MASK 0x8 +#define D0F0xE4_PIF_0013_RxPowerStateInRxs2_OFFSET 4 +#define D0F0xE4_PIF_0013_RxPowerStateInRxs2_WIDTH 3 +#define D0F0xE4_PIF_0013_RxPowerStateInRxs2_MASK 0x70 +#define D0F0xE4_PIF_0013_PllPowerStateInTxs2_OFFSET 7 +#define D0F0xE4_PIF_0013_PllPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0013_PllPowerStateInTxs2_MASK 0x380 +#define D0F0xE4_PIF_0013_PllPowerStateInOff_OFFSET 10 +#define D0F0xE4_PIF_0013_PllPowerStateInOff_WIDTH 3 +#define D0F0xE4_PIF_0013_PllPowerStateInOff_MASK 0x1c00 +#define D0F0xE4_PIF_0013_Reserved_15_13_OFFSET 13 +#define D0F0xE4_PIF_0013_Reserved_15_13_WIDTH 3 +#define D0F0xE4_PIF_0013_Reserved_15_13_MASK 0xe000 +#define D0F0xE4_PIF_0013_Tx2p5clkClockGatingEn_OFFSET 16 +#define D0F0xE4_PIF_0013_Tx2p5clkClockGatingEn_WIDTH 1 +#define D0F0xE4_PIF_0013_Tx2p5clkClockGatingEn_MASK 0x10000 +#define D0F0xE4_PIF_0013_Reserved_23_17_OFFSET 17 +#define D0F0xE4_PIF_0013_Reserved_23_17_WIDTH 7 +#define D0F0xE4_PIF_0013_Reserved_23_17_MASK 0xfe0000 +#define D0F0xE4_PIF_0013_PllRampUpTime_OFFSET 24 +#define D0F0xE4_PIF_0013_PllRampUpTime_WIDTH 3 +#define D0F0xE4_PIF_0013_PllRampUpTime_MASK 0x7000000 +#define D0F0xE4_PIF_0013_Reserved_27_27_OFFSET 27 +#define D0F0xE4_PIF_0013_Reserved_27_27_WIDTH 1 +#define D0F0xE4_PIF_0013_Reserved_27_27_MASK 0x8000000 +#define D0F0xE4_PIF_0013_PllPwrOverrideEn_OFFSET 28 +#define D0F0xE4_PIF_0013_PllPwrOverrideEn_WIDTH 1 +#define D0F0xE4_PIF_0013_PllPwrOverrideEn_MASK 0x10000000 +#define D0F0xE4_PIF_0013_PllPwrOverrideVal_OFFSET 29 +#define D0F0xE4_PIF_0013_PllPwrOverrideVal_WIDTH 3 +#define D0F0xE4_PIF_0013_PllPwrOverrideVal_MASK 0xe0000000 + +/// D0F0xE4_PIF_0013 +typedef union { + struct { ///< + UINT32 TxPowerStateInTxs2:3 ; ///< + UINT32 ForceRxEnInL0s:1 ; ///< + UINT32 RxPowerStateInRxs2:3 ; ///< + UINT32 PllPowerStateInTxs2:3 ; ///< + UINT32 PllPowerStateInOff:3 ; ///< + UINT32 Reserved_15_13:3 ; ///< + UINT32 Tx2p5clkClockGatingEn:1 ; ///< + UINT32 Reserved_23_17:7 ; ///< + UINT32 PllRampUpTime:3 ; ///< + UINT32 Reserved_27_27:1 ; ///< + UINT32 PllPwrOverrideEn:1 ; ///< + UINT32 PllPwrOverrideVal:3 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PIF_0013_STRUCT; + + +// **** D0F0xE4_CORE_0011 Register Definition **** +// Address +#define D0F0xE4_CORE_0011_ADDRESS 0x11 + +// Type +#define D0F0xE4_CORE_0011_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_CORE_0011_DynClkLatency_OFFSET 0 +#define D0F0xE4_CORE_0011_DynClkLatency_WIDTH 4 +#define D0F0xE4_CORE_0011_DynClkLatency_MASK 0xf +#define D0F0xE4_CORE_0011_Reserved_31_4_OFFSET 4 +#define D0F0xE4_CORE_0011_Reserved_31_4_WIDTH 28 +#define D0F0xE4_CORE_0011_Reserved_31_4_MASK 0xfffffff0 + +/// D0F0xE4_CORE_0011 +typedef union { + struct { ///< + UINT32 DynClkLatency:4 ; ///< + UINT32 Reserved_31_4:28; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_CORE_0011_STRUCT; + + + + + + + + +// **** DxF0xE4_x70 Register Definition **** +// Address + + +// **** D0F0xE4_WRAP_8013 Register Definition **** +// Address +#define D0F0xE4_WRAP_8013_ADDRESS 0x8013 + +// Field Data +#define D0F0xE4_WRAP_8013_MasterPciePllA_OFFSET 0 +#define D0F0xE4_WRAP_8013_MasterPciePllA_WIDTH 1 +#define D0F0xE4_WRAP_8013_MasterPciePllA_MASK 0x1 +#define D0F0xE4_WRAP_8013_Reserved_1_1_OFFSET 1 +#define D0F0xE4_WRAP_8013_Reserved_1_1_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_1_1_MASK 0x2 +#define D0F0xE4_WRAP_8013_Reserved_2_2_OFFSET 2 +#define D0F0xE4_WRAP_8013_Reserved_2_2_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_2_2_MASK 0x4 +#define D0F0xE4_WRAP_8013_Reserved_3_3_OFFSET 3 +#define D0F0xE4_WRAP_8013_Reserved_3_3_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_3_3_MASK 0x8 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideA_OFFSET 4 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideA_WIDTH 1 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideA_MASK 0x10 +#define D0F0xE4_WRAP_8013_Reserved_5_5_OFFSET 5 +#define D0F0xE4_WRAP_8013_Reserved_5_5_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_5_5_MASK 0x20 +#define D0F0xE4_WRAP_8013_Reserved_6_6_OFFSET 6 +#define D0F0xE4_WRAP_8013_Reserved_6_6_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_6_6_MASK 0x40 +#define D0F0xE4_WRAP_8013_Reserved_7_7_OFFSET 7 +#define D0F0xE4_WRAP_8013_Reserved_7_7_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_7_7_MASK 0x80 +#define D0F0xE4_WRAP_8013_TxclkSelCoreOverride_OFFSET 8 +#define D0F0xE4_WRAP_8013_TxclkSelCoreOverride_WIDTH 1 +#define D0F0xE4_WRAP_8013_TxclkSelCoreOverride_MASK 0x100 +#define D0F0xE4_WRAP_8013_TxclkSelPifAOverride_OFFSET 9 +#define D0F0xE4_WRAP_8013_TxclkSelPifAOverride_WIDTH 1 +#define D0F0xE4_WRAP_8013_TxclkSelPifAOverride_MASK 0x200 +#define D0F0xE4_WRAP_8013_Reserved_10_10_OFFSET 10 +#define D0F0xE4_WRAP_8013_Reserved_10_10_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_10_10_MASK 0x400 +#define D0F0xE4_WRAP_8013_Reserved_11_11_OFFSET 11 +#define D0F0xE4_WRAP_8013_Reserved_11_11_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_11_11_MASK 0x800 +#define D0F0xE4_WRAP_8013_Reserved_12_12_OFFSET 12 +#define D0F0xE4_WRAP_8013_Reserved_12_12_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_12_12_MASK 0x1000 +#define D0F0xE4_WRAP_8013_Reserved_15_13_OFFSET 13 +#define D0F0xE4_WRAP_8013_Reserved_15_13_WIDTH 3 +#define D0F0xE4_WRAP_8013_Reserved_15_13_MASK 0xe000 +#define D0F0xE4_WRAP_8013_Reserved_16_16_OFFSET 16 +#define D0F0xE4_WRAP_8013_Reserved_16_16_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_16_16_MASK 0x10000 +#define D0F0xE4_WRAP_8013_Reserved_19_17_OFFSET 17 +#define D0F0xE4_WRAP_8013_Reserved_19_17_WIDTH 3 +#define D0F0xE4_WRAP_8013_Reserved_19_17_MASK 0xe0000 +#define D0F0xE4_WRAP_8013_Reserved_20_20_OFFSET 20 +#define D0F0xE4_WRAP_8013_Reserved_20_20_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_20_20_MASK 0x100000 +#define D0F0xE4_WRAP_8013_Reserved_31_21_OFFSET 21 +#define D0F0xE4_WRAP_8013_Reserved_31_21_WIDTH 11 +#define D0F0xE4_WRAP_8013_Reserved_31_21_MASK 0xffe00000 + +/// D0F0xE4_WRAP_8013 +typedef union { + struct { ///< + UINT32 MasterPciePllA:1 ; ///< + UINT32 MasterPciePllB:1 ; ///< + UINT32 MasterPciePllC:1 ; ///< + UINT32 MasterPciePllD:1 ; ///< + UINT32 ClkDividerResetOverrideA:1 ; ///< + UINT32 Reserved_5_5:1 ; ///< + UINT32 Reserved_6_6:1 ; ///< + UINT32 Reserved_7_7:1 ; ///< + UINT32 TxclkSelCoreOverride:1 ; ///< + UINT32 TxclkSelPifAOverride:1 ; ///< + UINT32 Reserved_10_10:1 ; ///< + UINT32 Reserved_11_11:1 ; ///< + UINT32 Reserved_12_12:1 ; ///< + UINT32 Reserved_15_13:3 ; ///< + UINT32 Reserved_16_16:1 ; ///< + UINT32 Reserved_19_17:3 ; ///< + UINT32 Reserved_20_20:1 ; ///< + UINT32 Reserved_31_21:11; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8013_STRUCT; + +// **** D0F0xE4_WRAP_8014 Register Definition **** +// Address +#define D0F0xE4_WRAP_8014_ADDRESS 0x8014 + +// Field Data +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_OFFSET 0 +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_MASK 0x1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_OFFSET 1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_MASK 0x2 +#define D0F0xE4_WRAP_8014_Reserved_2_2_OFFSET 2 +#define D0F0xE4_WRAP_8014_Reserved_2_2_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_2_2_MASK 0x4 +#define D0F0xE4_WRAP_8014_Reserved_3_3_OFFSET 3 +#define D0F0xE4_WRAP_8014_Reserved_3_3_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_3_3_MASK 0x8 +#define D0F0xE4_WRAP_8014_Reserved_4_4_OFFSET 4 +#define D0F0xE4_WRAP_8014_Reserved_4_4_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_4_4_MASK 0x10 +#define D0F0xE4_WRAP_8014_Reserved_5_5_OFFSET 5 +#define D0F0xE4_WRAP_8014_Reserved_5_5_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_5_5_MASK 0x20 +#define D0F0xE4_WRAP_8014_Reserved_6_6_OFFSET 6 +#define D0F0xE4_WRAP_8014_Reserved_6_6_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_6_6_MASK 0x40 +#define D0F0xE4_WRAP_8014_Reserved_7_7_OFFSET 7 +#define D0F0xE4_WRAP_8014_Reserved_7_7_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_7_7_MASK 0x80 +#define D0F0xE4_WRAP_8014_Reserved_8_8_OFFSET 8 +#define D0F0xE4_WRAP_8014_Reserved_8_8_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_8_8_MASK 0x100 +#define D0F0xE4_WRAP_8014_Reserved_9_9_OFFSET 9 +#define D0F0xE4_WRAP_8014_Reserved_9_9_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_9_9_MASK 0x200 +#define D0F0xE4_WRAP_8014_Reserved_10_10_OFFSET 10 +#define D0F0xE4_WRAP_8014_Reserved_10_10_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_10_10_MASK 0x400 +#define D0F0xE4_WRAP_8014_Reserved_11_11_OFFSET 11 +#define D0F0xE4_WRAP_8014_Reserved_11_11_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_11_11_MASK 0x800 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_OFFSET 12 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_MASK 0x1000 +#define D0F0xE4_WRAP_8014_Reserved_13_13_OFFSET 13 +#define D0F0xE4_WRAP_8014_Reserved_13_13_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_13_13_MASK 0x2000 +#define D0F0xE4_WRAP_8014_Reserved_14_14_OFFSET 14 +#define D0F0xE4_WRAP_8014_Reserved_14_14_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_14_14_MASK 0x4000 +#define D0F0xE4_WRAP_8014_Reserved_15_15_OFFSET 15 +#define D0F0xE4_WRAP_8014_Reserved_15_15_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_15_15_MASK 0x8000 +#define D0F0xE4_WRAP_8014_PcieGatePifA2p5xEnable_OFFSET 16 +#define D0F0xE4_WRAP_8014_PcieGatePifA2p5xEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_PcieGatePifA2p5xEnable_MASK 0x10000 +#define D0F0xE4_WRAP_8014_Reserved_17_17_OFFSET 17 +#define D0F0xE4_WRAP_8014_Reserved_17_17_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_17_17_MASK 0x20000 +#define D0F0xE4_WRAP_8014_Reserved_18_18_OFFSET 18 +#define D0F0xE4_WRAP_8014_Reserved_18_18_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_18_18_MASK 0x40000 +#define D0F0xE4_WRAP_8014_Reserved_19_19_OFFSET 19 +#define D0F0xE4_WRAP_8014_Reserved_19_19_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_19_19_MASK 0x80000 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_OFFSET 20 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_MASK 0x100000 +#define D0F0xE4_WRAP_8014_Reserved_31_21_OFFSET 21 +#define D0F0xE4_WRAP_8014_Reserved_31_21_WIDTH 11 +#define D0F0xE4_WRAP_8014_Reserved_31_21_MASK 0xffe00000 + +/// D0F0xE4_WRAP_8014 +typedef union { + struct { + UINT32 TxclkPermGateEnable:1 ; ///< + UINT32 TxclkPrbsGateEnable:1 ; ///< + UINT32 DdiGatePifA1xEnable:1 ; ///< + UINT32 DdiGatePifB1xEnable:1 ; ///< + UINT32 DdiGatePifC1xEnable:1 ; ///< + UINT32 DdiGatePifD1xEnable:1 ; ///< + UINT32 DdiGateDigAEnable:1 ; ///< + UINT32 DdiGateDigBEnable:1 ; ///< + UINT32 DdiGatePifA2p5xEnable:1 ; ///< + UINT32 DdiGatePifB2p5xEnable:1 ; ///< + UINT32 DdiGatePifC2p5xEnable:1 ; ///< + UINT32 DdiGatePifD2p5xEnable:1 ; ///< + UINT32 PcieGatePifA1xEnable:1 ; ///< + UINT32 PcieGatePifB1xEnable:1 ; ///< + UINT32 PcieGatePifC1xEnable:1 ; ///< + UINT32 PcieGatePifD1xEnable:1 ; ///< + UINT32 PcieGatePifA2p5xEnable:1 ; ///< + UINT32 PcieGatePifB2p5xEnable:1 ; ///< + UINT32 PcieGatePifC2p5xEnable:1 ; ///< + UINT32 PcieGatePifD2p5xEnable:1 ; ///< + UINT32 TxclkPermGateOnlyWhenPllPwrDn:1 ; ///< + UINT32 Reserved_31_21:11; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8014_STRUCT; + +// **** D0F0x64_x51 Register Definition **** +// Address +#define D0F0x64_x51_ADDRESS 0x51 + +// Type +#define D0F0x64_x51_TYPE TYPE_D0F0x64 + + +// **** D0F0xE4_CORE_0010 Register Definition **** +// Address +#define D0F0xE4_CORE_0010_ADDRESS 0x10 + +// Type +#define D0F0xE4_CORE_0010_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_CORE_0010_HwInitWrLock_OFFSET 0 +#define D0F0xE4_CORE_0010_HwInitWrLock_WIDTH 1 +#define D0F0xE4_CORE_0010_HwInitWrLock_MASK 0x1 +#define D0F0xE4_CORE_0010_LcHotPlugDelSel_OFFSET 1 +#define D0F0xE4_CORE_0010_LcHotPlugDelSel_WIDTH 3 +#define D0F0xE4_CORE_0010_LcHotPlugDelSel_MASK 0xe +#define D0F0xE4_CORE_0010_Reserved_6_4_OFFSET 4 +#define D0F0xE4_CORE_0010_Reserved_6_4_WIDTH 3 +#define D0F0xE4_CORE_0010_Reserved_6_4_MASK 0x70 +#define D0F0xE4_CORE_0010_Reserved_8_8_OFFSET 8 +#define D0F0xE4_CORE_0010_Reserved_8_8_WIDTH 1 +#define D0F0xE4_CORE_0010_Reserved_8_8_MASK 0x100 +#define D0F0xE4_CORE_0010_UmiNpMemWrite_OFFSET 9 +#define D0F0xE4_CORE_0010_UmiNpMemWrite_WIDTH 1 +#define D0F0xE4_CORE_0010_UmiNpMemWrite_MASK 0x200 +#define D0F0xE4_CORE_0010_RxUmiAdjPayloadSize_OFFSET 10 +#define D0F0xE4_CORE_0010_RxUmiAdjPayloadSize_WIDTH 3 +#define D0F0xE4_CORE_0010_RxUmiAdjPayloadSize_MASK 0x1c00 +#define D0F0xE4_CORE_0010_Reserved_15_13_OFFSET 13 +#define D0F0xE4_CORE_0010_Reserved_15_13_WIDTH 3 +#define D0F0xE4_CORE_0010_Reserved_15_13_MASK 0xe000 + +/// D0F0xE4_CORE_0010 +typedef union { + struct { ///< + UINT32 HwInitWrLock:1 ; ///< + UINT32 LcHotPlugDelSel:3 ; ///< + UINT32 Reserved_6_4:3 ; ///< + UINT32 :1 ; ///< + UINT32 Reserved_8_8:1 ; ///< + UINT32 UmiNpMemWrite:1 ; ///< + UINT32 RxUmiAdjPayloadSize:3 ; ///< + UINT32 Reserved_15_13:3 ; ///< + UINT32 :1 ; ///< + UINT32 :1 ; ///< + UINT32 :1 ; ///< + UINT32 :1 ; ///< + UINT32 :1 ; ///< + UINT32 :1 ; ///< + UINT32 :1 ; ///< + UINT32 :1 ; ///< + UINT32 :6 ; ///< + UINT32 :1 ; ///< + UINT32 :1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_CORE_0010_STRUCT; + + +typedef union { + struct { ///< + UINT32 bit_0_0:1 ; ///< + UINT32 bit1:1 ; ///< + UINT32 bit2:1 ; ///< + UINT32 bit3:1 ; ///< + UINT32 bit4:1 ; ///< + UINT32 bit5:1 ; ///< + UINT32 bit6:1 ; ///< + UINT32 bit_7_7:1 ; ///< + UINT32 bit_9_8:2 ; ///< + UINT32 bit_10_10:1 ; ///< + UINT32 bit11:1 ; ///< + UINT32 bit12:1 ; ///< + UINT32 bit13:1 ; ///< + UINT32 bit14:1 ; ///< + UINT32 bit15:1 ; ///< + UINT32 bit16:1 ; ///< + UINT32 bit_17_17:1 ; ///< + UINT32 bit_19_18:2 ; ///< + UINT32 bit20:1 ; ///< + UINT32 bit_21_21:1 ; ///< + UINT32 bit_23_22:2 ; ///< + UINT32 bit24:1 ; ///< + UINT32 bit_25_25:1 ; ///< + UINT32 bit_27_26:2 ; ///< + UINT32 bit_31_28:4 ; ///< + } Field; ///< + UINT32 Value; ///< +} GNBREGCOMMON_STR1_STRUCT; + + + + +// **** D0F0xE4_PHY_6006 Register Definition **** +// Address +#define D0F0xE4_PHY_6006_ADDRESS 0x6006 + +// Type +#define D0F0xE4_PHY_6006_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PHY_6006_TxMarginNom_OFFSET 0 +#define D0F0xE4_PHY_6006_TxMarginNom_WIDTH 8 +#define D0F0xE4_PHY_6006_TxMarginNom_MASK 0xff +#define D0F0xE4_PHY_6006_DeemphGen1Nom_OFFSET 8 +#define D0F0xE4_PHY_6006_DeemphGen1Nom_WIDTH 8 +#define D0F0xE4_PHY_6006_DeemphGen1Nom_MASK 0xff00 +#define D0F0xE4_PHY_6006_Deemph35Gen2Nom_OFFSET 16 +#define D0F0xE4_PHY_6006_Deemph35Gen2Nom_WIDTH 8 +#define D0F0xE4_PHY_6006_Deemph35Gen2Nom_MASK 0xff0000 +#define D0F0xE4_PHY_6006_Deemph60Gen2Nom_OFFSET 24 +#define D0F0xE4_PHY_6006_Deemph60Gen2Nom_WIDTH 8 +#define D0F0xE4_PHY_6006_Deemph60Gen2Nom_MASK 0xff000000 + +/// D0F0xE4_PHY_6006 +typedef union { + struct { ///< + UINT32 TxMarginNom:8 ; ///< + UINT32 DeemphGen1Nom:8 ; ///< + UINT32 Deemph35Gen2Nom:8 ; ///< + UINT32 Deemph60Gen2Nom:8 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PHY_6006_STRUCT; + +// **** GMMx00 Register Definition **** +// Address +#define GMMx00_ADDRESS 0x0 + +// Type +#define GMMx00_TYPE TYPE_GMM +// Field Data +#define GMMx00_Offset_OFFSET 0 +#define GMMx00_Offset_WIDTH 31 +#define GMMx00_Offset_MASK 0x7fffffff +#define GMMx00_Aper_OFFSET 31 +#define GMMx00_Aper_WIDTH 1 +#define GMMx00_Aper_MASK 0x80000000 + +/// GMMx00 +typedef union { + struct { ///< + UINT32 Offset:31; ///< + UINT32 Aper:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} GMMx00_STRUCT; + +// **** GMMx04 Register Definition **** +// Address +#define GMMx04_ADDRESS 0x4 + +// Type +#define GMMx04_TYPE TYPE_GMM +// Field Data +#define GMMx04_Data_OFFSET 0 +#define GMMx04_Data_WIDTH 32 +#define GMMx04_Data_MASK 0xffffffff + +/// GMMx04 +typedef union { + struct { ///< + UINT32 Data:32; ///< + } Field; ///< + UINT32 Value; ///< +} GMMx04_STRUCT; + + +// **** D0F0xE4_WRAP_8016 Register Definition **** +// Address +#define D0F0xE4_WRAP_8016_ADDRESS 0x8016 + +// Type +#define D0F0xE4_WRAP_8016_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_8016_CalibAckLatency_OFFSET 0 +#define D0F0xE4_WRAP_8016_CalibAckLatency_WIDTH 6 +#define D0F0xE4_WRAP_8016_CalibAckLatency_MASK 0x3f +#define D0F0xE4_WRAP_8016_Reserved_7_6_OFFSET 6 +#define D0F0xE4_WRAP_8016_Reserved_7_6_WIDTH 2 +#define D0F0xE4_WRAP_8016_Reserved_7_6_MASK 0xc0 +#define D0F0xE4_WRAP_8016_CalibDoneSelPifA_OFFSET 8 +#define D0F0xE4_WRAP_8016_CalibDoneSelPifA_WIDTH 1 +#define D0F0xE4_WRAP_8016_CalibDoneSelPifA_MASK 0x100 +#define D0F0xE4_WRAP_8016_Reserved_9_9_OFFSET 9 +#define D0F0xE4_WRAP_8016_Reserved_9_9_WIDTH 1 +#define D0F0xE4_WRAP_8016_Reserved_9_9_MASK 0x200 +#define D0F0xE4_WRAP_8016_Reserved_10_10_OFFSET 10 +#define D0F0xE4_WRAP_8016_Reserved_10_10_WIDTH 1 +#define D0F0xE4_WRAP_8016_Reserved_10_10_MASK 0x400 +#define D0F0xE4_WRAP_8016_Reserved_11_11_OFFSET 11 +#define D0F0xE4_WRAP_8016_Reserved_11_11_WIDTH 1 +#define D0F0xE4_WRAP_8016_Reserved_11_11_MASK 0x800 +#define D0F0xE4_WRAP_8016_Gen1OnlyEngage_OFFSET 12 +#define D0F0xE4_WRAP_8016_Gen1OnlyEngage_WIDTH 1 +#define D0F0xE4_WRAP_8016_Gen1OnlyEngage_MASK 0x1000 +#define D0F0xE4_WRAP_8016_Gen1OnlyEngaged_OFFSET 13 +#define D0F0xE4_WRAP_8016_Gen1OnlyEngaged_WIDTH 1 +#define D0F0xE4_WRAP_8016_Gen1OnlyEngaged_MASK 0x2000 +#define D0F0xE4_WRAP_8016_Reserved_15_14_OFFSET 14 +#define D0F0xE4_WRAP_8016_Reserved_15_14_WIDTH 2 +#define D0F0xE4_WRAP_8016_Reserved_15_14_MASK 0xc000 +#define D0F0xE4_WRAP_8016_LclkDynGateLatency_OFFSET 16 +#define D0F0xE4_WRAP_8016_LclkDynGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8016_LclkDynGateLatency_MASK 0x3f0000 +#define D0F0xE4_WRAP_8016_LclkGateFree_OFFSET 22 +#define D0F0xE4_WRAP_8016_LclkGateFree_WIDTH 1 +#define D0F0xE4_WRAP_8016_LclkGateFree_MASK 0x400000 +#define D0F0xE4_WRAP_8016_LclkDynGateEnable_OFFSET 23 +#define D0F0xE4_WRAP_8016_LclkDynGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8016_LclkDynGateEnable_MASK 0x800000 +#define D0F0xE4_WRAP_8016_Reserved_31_24_OFFSET 24 +#define D0F0xE4_WRAP_8016_Reserved_31_24_WIDTH 8 +#define D0F0xE4_WRAP_8016_Reserved_31_24_MASK 0xff000000 + +/// D0F0xE4_WRAP_8016 +typedef union { + struct { ///< + UINT32 CalibAckLatency:6 ; ///< + UINT32 Reserved_7_6:2 ; ///< + UINT32 CalibDoneSelPifA:1 ; ///< + UINT32 Reserved_9_9:1 ; ///< + UINT32 Reserved_10_10:1 ; ///< + UINT32 Reserved_11_11:1 ; ///< + UINT32 Gen1OnlyEngage:1 ; ///< + UINT32 Gen1OnlyEngaged:1 ; ///< + UINT32 Reserved_15_14:2 ; ///< + UINT32 LclkDynGateLatency:6 ; ///< + UINT32 LclkGateFree:1 ; ///< + UINT32 LclkDynGateEnable:1 ; ///< + UINT32 Reserved_31_24:8 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8016_STRUCT; + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersCommonV2.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersCommonV2.h new file mode 100644 index 0000000000..4458039349 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersCommonV2.h @@ -0,0 +1,1445 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Register definitions + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87271 $ @e \$Date: 2013-01-31 10:11:23 -0600 (Thu, 31 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBREGISTERS_CV2_H_ +#define _GNBREGISTERS_CV2_H_ + +#define SMC_MSG_FIRMWARE_AUTH 0 + +#ifndef WRAP_SPACE + #define WRAP_SPACE(w, x) (0x01300000 | (w << 16) | (x)) +#endif + +#ifndef CORE_SPACE + #define CORE_SPACE(c, x) (0x00010000 | (c << 24) | (x)) +#endif + +#ifndef PHY_SPACE + #define PHY_SPACE(w, p, x) (0x00200000 | ((p + 1) << 24) | (w << 16) | (x)) +#endif + +#ifndef PIF_SPACE + #define PIF_SPACE(w, p, x) (0x00100000 | ((p + 1) << 24) | (w << 16) | (x)) +#endif + + +// **** D0F0xFC_x01 Register Definition **** +// Address +#define D0F0xFC_x01_ADDRESS 0x01 + +// **** D0F0xFC_x02 Register Definition **** +// Address +#define D0F0xFC_x02_ADDRESS 0x02 + +// **** D0F0xFC_x10 Register Definition **** +// Address +#define D0F0xFC_x10_ADDRESS 0x10 +// Type +#define D0F0xFC_x10_TYPE TYPE_D0F0xFC + +// Field Data +#define D0F0xFC_x10_BrExtIntrGrp_OFFSET 0 +#define D0F0xFC_x10_BrExtIntrGrp_WIDTH 3 +#define D0F0xFC_x10_BrExtIntrGrp_MASK 0x7 +#define D0F0xFC_x10_Reserved_3_3_OFFSET 3 +#define D0F0xFC_x10_Reserved_3_3_WIDTH 1 +#define D0F0xFC_x10_Reserved_3_3_MASK 0x8 +#define D0F0xFC_x10_BrExtIntrSwz_OFFSET 4 +#define D0F0xFC_x10_BrExtIntrSwz_WIDTH 2 +#define D0F0xFC_x10_BrExtIntrSwz_MASK 0x30 +#define D0F0xFC_x10_Reserved_15_6_OFFSET 6 +#define D0F0xFC_x10_Reserved_15_6_WIDTH 10 +#define D0F0xFC_x10_Reserved_15_6_MASK 0xFFC0 +#define D0F0xFC_x10_BrIntIntrMap_OFFSET 16 +#define D0F0xFC_x10_BrIntIntrMap_WIDTH 5 +#define D0F0xFC_x10_BrIntIntrMap_MASK 0x1F0000 +#define D0F0xFC_x10_Reserved_31_21_OFFSET 21 +#define D0F0xFC_x10_Reserved_31_21_WIDTH 11 +#define D0F0xFC_x10_Reserved_31_21_MASK 0xFFE00000 + +/// D0F0xFC_x10 +typedef union { + struct { ///< + UINT32 BrExtIntrGrp:3; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 BrExtIntrSwz:2; ///< + UINT32 Reserved_15_6:10; ///< + UINT32 BrIntIntrMap:5; ///< + UINT32 Reserved_31_21:11; ///< + + } Field; + + UINT32 Value; +} D0F0xFC_x10_STRUCT; + +// **** D0F0xB8 Register Definition **** +// Address +#define D0F0xB8_ADDRESS 0xb8 + +// **** DxF0xE4_xC1 Register Definition **** +// Address +#define D2FxxE4_xC1_ADDRESS 0xc1 + +// Type +#define D2FxxE4_xC1_TYPE TYPE_D4F0xE4 +// Field Data + +#define D2FxxE4_xC1_StrapReverseLanes_OFFSET 0 +#define D2FxxE4_xC1_StrapReverseLanes_WIDTH 1 +#define D2FxxE4_xC1_StrapReverseLanes_MASK 0x1 +#define D2FxxE4_xC1_StrapE2EPrefixEn_OFFSET 1 +#define D2FxxE4_xC1_StrapE2EPrefixEn_WIDTH 1 +#define D2FxxE4_xC1_StrapE2EPrefixEn_MASK 0x2 +#define D2FxxE4_xC1_StrapExtendedFmtSupported_OFFSET 2 +#define D2FxxE4_xC1_StrapExtendedFmtSupported_WIDTH 1 +#define D2FxxE4_xC1_StrapExtendedFmtSupported_MASK 0x4 +#define D2FxxE4_xC1_Reserved_31_3_OFFSET 3 +#define D2FxxE4_xC1_Reserved_31_3_WIDTH 29 +#define D2FxxE4_xC1_Reserved_31_3_MASK 0xfffffff8 + +// Type +// Address +#define D0F0xE4_WRAP_0046_ADDRESS 0x46 + +// Address +#define D0F0xE4_WRAP_8040_ADDRESS 0x8040 + + +// **** D0F0xE4_WRAP_8062 Register Definition **** +// Address +#define D0F0xE4_WRAP_8062_ADDRESS 0x8062 + + +/// D0F0xE4_WRAP_8062 +typedef union { + struct { ///< + UINT32 ReconfigureEn:1 ; ///< + UINT32 Reserved_1_1:1 ; ///< + UINT32 ResetPeriod:3 ; ///< + UINT32 Reserved_9_5:5 ; ///< + UINT32 BlockOnIdle:1 ; ///< + UINT32 ConfigXferMode:1 ; ///< + UINT32 Reserved_31_12:20; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8062_STRUCT; + + +// Type +#define D0F0xE4_WRAP_8040_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_8040_OwnSlice_OFFSET 0 +#define D0F0xE4_WRAP_8040_OwnSlice_WIDTH 1 +#define D0F0xE4_WRAP_8040_OwnSlice_MASK 0x1 + + +// **** D0F0xBC_x1F630 Register Definition **** +// Address +#define D0F0xBC_x1F630_ADDRESS 0x1f630 + +// Type +#define D0F0xBC_x1F630_TYPE TYPE_D0F0xBC +// Field Data +#define D0F0xBC_x1F630_RECONF_WRAPPER_OFFSET 8 +#define D0F0xBC_x1F630_RECONF_WRAPPER_WIDTH 8 +#define D0F0xBC_x1F630_RECONF_WRAPPER_MASK 0x00ff00 + + +// **** D0F0xE4_WRAP_8011 Register Definition **** +// Address +#define D0F0xE4_WRAP_8011_ADDRESS 0x8011 +// Type +#define D0F0xE4_WRAP_8011_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_OFFSET 0 +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_MASK 0x3F +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_OFFSET 6 +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_MASK 0x40 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_OFFSET 7 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_MASK 0x80 +#define D0F0xE4_WRAP_8011_TxclkPermStop_OFFSET 8 +#define D0F0xE4_WRAP_8011_TxclkPermStop_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkPermStop_MASK 0x100 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_OFFSET 9 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_MASK 0x200 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_OFFSET 10 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_MASK 0xFC00 +#define D0F0xE4_WRAP_8011_Bitfield_16_16_OFFSET 16 +#define D0F0xE4_WRAP_8011_Bitfield_16_16_WIDTH 1 +#define D0F0xE4_WRAP_8011_Bitfield_16_16_MASK 0x10000 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_OFFSET 17 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_MASK 0x7E0000 +#define D0F0xE4_WRAP_8011_Reserved_23_23_OFFSET 23 +#define D0F0xE4_WRAP_8011_Reserved_23_23_WIDTH 1 +#define D0F0xE4_WRAP_8011_Reserved_23_23_MASK 0x800000 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_OFFSET 24 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_MASK 0x1000000 +#define D0F0xE4_WRAP_8011_Reserved_25_25_OFFSET 25 +#define D0F0xE4_WRAP_8011_Reserved_25_25_WIDTH 1 +#define D0F0xE4_WRAP_8011_Reserved_25_25_MASK 0x2000000 +#define D0F0xE4_WRAP_8011_Reserved_31_26_OFFSET 26 +#define D0F0xE4_WRAP_8011_Reserved_31_26_WIDTH 6 +#define D0F0xE4_WRAP_8011_Reserved_31_26_MASK 0xFC000000 + +/// D0F0xE4_WRAP_8011 +typedef union { + struct { ///< + UINT32 TxclkDynGateLatency:6; ///< + UINT32 TxclkPermGateEven:1; ///< + UINT32 TxclkDynGateEnable:1; ///< + UINT32 TxclkPermStop:1; ///< + UINT32 TxclkRegsGateEnable:1; ///< + UINT32 TxclkRegsGateLatency:6; ///< + UINT32 Bitfield_16_16:1; ///< + UINT32 TxclkPermGateLatency:6; ///< + UINT32 Reserved_23_23:1; ///< + UINT32 TxclkLcntGateEnable:1; ///< + UINT32 Reserved_25_25:1; ///< + UINT32 Reserved_31_26:6; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8011_STRUCT; + + + +// **** D0F0xE4_WRAP_8016 Register Definition **** +// Address +#define D0F0xE4_WRAP_8016_ADDRESS 0x8016 + +// Type +#define D0F0xE4_WRAP_8016_TYPE TYPE_D0F0xE4 + +/// D0F0xE4_WRAP_8016 +typedef union { + struct { ///< + UINT32 CalibAckLatency:6 ; ///< + UINT32 Reserved_15_6:10; ///< + UINT32 LclkDynGateLatency:6 ; ///< + UINT32 LclkGateFree:1 ; ///< + UINT32 LclkDynGateEnable:1 ; ///< + UINT32 Reserved_31_24:8 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8016_STRUCT; + + +// **** D0F0xE4_CORE_0011 Register Definition **** +// Address +#define D0F0xE4_CORE_0011_ADDRESS 0x11 + +#define D0F0xE4_CORE_0011_DynClkLatency_OFFSET 0 +#define D0F0xE4_CORE_0011_DynClkLatency_WIDTH 4 +#define D0F0xE4_CORE_0011_DynClkLatency_MASK 0xf + + +// **** D0F0xE4_PIF_0010 Register Definition **** +// Address +#define D0F0xE4_PIF_0010_ADDRESS 0x10 + +// Type +#define D0F0xE4_PIF_0010_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PIF_0010_Reserved_3_0_OFFSET 0 +#define D0F0xE4_PIF_0010_Reserved_3_0_WIDTH 4 +#define D0F0xE4_PIF_0010_Reserved_3_0_MASK 0xf +#define D0F0xE4_PIF_0010_EiDetCycleMode_OFFSET 4 +#define D0F0xE4_PIF_0010_EiDetCycleMode_WIDTH 1 +#define D0F0xE4_PIF_0010_EiDetCycleMode_MASK 0x10 +#define D0F0xE4_PIF_0010_Reserved_5_5_OFFSET 5 +#define D0F0xE4_PIF_0010_Reserved_5_5_WIDTH 1 +#define D0F0xE4_PIF_0010_Reserved_5_5_MASK 0x20 +#define D0F0xE4_PIF_0010_RxDetectFifoResetMode_OFFSET 6 +#define D0F0xE4_PIF_0010_RxDetectFifoResetMode_WIDTH 1 +#define D0F0xE4_PIF_0010_RxDetectFifoResetMode_MASK 0x40 +#define D0F0xE4_PIF_0010_RxDetectTxPwrMode_OFFSET 7 +#define D0F0xE4_PIF_0010_RxDetectTxPwrMode_WIDTH 1 +#define D0F0xE4_PIF_0010_RxDetectTxPwrMode_MASK 0x80 +#define D0F0xE4_PIF_0010_Reserved_16_8_OFFSET 8 +#define D0F0xE4_PIF_0010_Reserved_16_8_WIDTH 9 +#define D0F0xE4_PIF_0010_Reserved_16_8_MASK 0x1ff00 +#define D0F0xE4_PIF_0010_Ls2ExitTime_OFFSET 17 +#define D0F0xE4_PIF_0010_Ls2ExitTime_WIDTH 3 +#define D0F0xE4_PIF_0010_Ls2ExitTime_MASK 0xe0000 +#define D0F0xE4_PIF_0010_Reserved_31_23_OFFSET 23 +#define D0F0xE4_PIF_0010_Reserved_31_23_WIDTH 9 +#define D0F0xE4_PIF_0010_Reserved_31_23_MASK 0xff800000 + +/// D0F0xE4_PIF_0010 +typedef union { + struct { ///< + UINT32 Reserved_3_0:4 ; ///< + UINT32 EiDetCycleMode:1 ; ///< + UINT32 Reserved_5_5:1 ; ///< + UINT32 RxDetectFifoResetMode:1 ; ///< + UINT32 RxDetectTxPwrMode:1 ; ///< + UINT32 Reserved_16_8:9 ; ///< + UINT32 Ls2ExitTime:3 ; ///< + UINT32 :3 ; ///< + UINT32 Reserved_31_23:9 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PIF_0010_STRUCT; + +// **** D2FxxE4_xA4 Register Definition **** +// Address +#define D2FxxE4_xA4_ADDRESS 0xa4 + +// Type +#define D2FxxE4_xA4_TYPE TYPE_D4F0xE4 +// Field Data +#define D2FxxE4_xA4_LcGen2EnStrap_OFFSET 0 +#define D2FxxE4_xA4_LcGen2EnStrap_WIDTH 1 +#define D2FxxE4_xA4_LcGen2EnStrap_MASK 0x1 +#define D2FxxE4_xA4_Reserved_5_1_OFFSET 1 +#define D2FxxE4_xA4_Reserved_5_1_WIDTH 5 +#define D2FxxE4_xA4_Reserved_5_1_MASK 0x3e +#define D2FxxE4_xA4_LcForceDisSwSpeedChange_OFFSET 6 +#define D2FxxE4_xA4_LcForceDisSwSpeedChange_WIDTH 1 +#define D2FxxE4_xA4_LcForceDisSwSpeedChange_MASK 0x40 +#define D2FxxE4_xA4_Reserved_8_7_OFFSET 7 +#define D2FxxE4_xA4_Reserved_8_7_WIDTH 2 +#define D2FxxE4_xA4_Reserved_8_7_MASK 0x180 +#define D2FxxE4_xA4_LcInitiateLinkSpeedChange_OFFSET 9 +#define D2FxxE4_xA4_LcInitiateLinkSpeedChange_WIDTH 1 +#define D2FxxE4_xA4_LcInitiateLinkSpeedChange_MASK 0x200 +#define D2FxxE4_xA4_Reserved_11_10_OFFSET 10 +#define D2FxxE4_xA4_Reserved_11_10_WIDTH 2 +#define D2FxxE4_xA4_Reserved_11_10_MASK 0xc00 +#define D2FxxE4_xA4_LcSpeedChangeAttemptFailed_OFFSET 12 +#define D2FxxE4_xA4_LcSpeedChangeAttemptFailed_WIDTH 1 +#define D2FxxE4_xA4_LcSpeedChangeAttemptFailed_MASK 0x1000 +#define D2FxxE4_xA4_Reserved_18_13_OFFSET 13 +#define D2FxxE4_xA4_Reserved_18_13_WIDTH 6 +#define D2FxxE4_xA4_Reserved_18_13_MASK 0x7e000 +#define D2FxxE4_xA4_LcOtherSideSupportsGen2_OFFSET 19 +#define D2FxxE4_xA4_LcOtherSideSupportsGen2_WIDTH 1 +#define D2FxxE4_xA4_LcOtherSideSupportsGen2_MASK 0x80000 +#define D2FxxE4_xA4_Reserved_26_20_OFFSET 20 +#define D2FxxE4_xA4_Reserved_26_20_WIDTH 7 +#define D2FxxE4_xA4_Reserved_26_20_MASK 0x7f00000 +#define D2FxxE4_xA4_LcMultUpstreamAutoSpdChngEn_OFFSET 27 +#define D2FxxE4_xA4_LcMultUpstreamAutoSpdChngEn_WIDTH 1 +#define D2FxxE4_xA4_LcMultUpstreamAutoSpdChngEn_MASK 0x8000000 +#define D2FxxE4_xA4_Reserved_31_28_OFFSET 28 +#define D2FxxE4_xA4_Reserved_31_28_WIDTH 4 +#define D2FxxE4_xA4_Reserved_31_28_MASK 0xf0000000 + +/// D2FxxE4_xA4 +typedef union { + struct { ///< + UINT32 LcGen2EnStrap:1 ; ///< + UINT32 Reserved_5_1:5 ; ///< + UINT32 LcForceDisSwSpeedChange:1 ; ///< + UINT32 Reserved_8_7:2 ; ///< + UINT32 LcInitiateLinkSpeedChange:1 ; ///< + UINT32 Reserved_11_10:2 ; ///< + UINT32 LcSpeedChangeAttemptFailed:1 ; ///< + UINT32 Reserved_18_13:6 ; ///< + UINT32 LcOtherSideSupportsGen2:1 ; ///< + UINT32 Reserved_26_20:7 ; ///< + UINT32 LcMultUpstreamAutoSpdChngEn:1 ; ///< + UINT32 Reserved_31_28:4 ; ///< + } Field; ///< + UINT32 Value; ///< +} D2FxxE4_xA4_STRUCT; + + +// **** D2FxxE4_xC0 Register Definition **** +// Address +#define D2FxxE4_xC0_ADDRESS 0xc0 + +// Type +#define D2FxxE4_xC0_TYPE TYPE_D4F0xE4 +// Field Data +#define D2FxxE4_xC0_Reserved_12_0_OFFSET 0 +#define D2FxxE4_xC0_Reserved_12_0_WIDTH 13 +#define D2FxxE4_xC0_Reserved_12_0_MASK 0x1fff +#define D2FxxE4_xC0_StrapForceCompliance_OFFSET 13 +#define D2FxxE4_xC0_StrapForceCompliance_WIDTH 1 +#define D2FxxE4_xC0_StrapForceCompliance_MASK 0x2000 +#define D2FxxE4_xC0_Reserved_14_14_OFFSET 14 +#define D2FxxE4_xC0_Reserved_14_14_WIDTH 1 +#define D2FxxE4_xC0_Reserved_14_14_MASK 0x4000 +#define D2FxxE4_xC0_StrapAutoRcSpeedNegotiationDis_OFFSET 15 +#define D2FxxE4_xC0_StrapAutoRcSpeedNegotiationDis_WIDTH 1 +#define D2FxxE4_xC0_StrapAutoRcSpeedNegotiationDis_MASK 0x8000 +#define D2FxxE4_xC0_Reserved_31_16_OFFSET 16 +#define D2FxxE4_xC0_Reserved_31_16_WIDTH 16 +#define D2FxxE4_xC0_Reserved_31_16_MASK 0xffff0000 + +/// D2FxxE4_xC0 +typedef union { + struct { ///< + UINT32 Reserved_12_0:13; ///< + UINT32 StrapForceCompliance:1 ; ///< + UINT32 Reserved_14_14:1 ; ///< + UINT32 StrapAutoRcSpeedNegotiationDis:1 ; ///< + UINT32 Reserved_31_16:16; ///< + } Field; ///< + UINT32 Value; ///< +} D2FxxE4_xC0_STRUCT; + + +// **** D2Fxx88 Register Definition **** +// Address +#define D2Fxx88_ADDRESS 0x88 + +// Type +#define D2Fxx88_TYPE TYPE_D4F0 +// Field Data +#define D2Fxx88_TargetLinkSpeed_OFFSET 0 +#define D2Fxx88_TargetLinkSpeed_WIDTH 4 +#define D2Fxx88_TargetLinkSpeed_MASK 0xf +#define D2Fxx88_EnterCompliance_OFFSET 4 +#define D2Fxx88_EnterCompliance_WIDTH 1 +#define D2Fxx88_EnterCompliance_MASK 0x10 +#define D2Fxx88_HwAutonomousSpeedDisable_OFFSET 5 +#define D2Fxx88_HwAutonomousSpeedDisable_WIDTH 1 +#define D2Fxx88_HwAutonomousSpeedDisable_MASK 0x20 +#define D2Fxx88_SelectableDeemphasis_OFFSET 6 +#define D2Fxx88_SelectableDeemphasis_WIDTH 1 +#define D2Fxx88_SelectableDeemphasis_MASK 0x40 +#define D2Fxx88_XmitMargin_OFFSET 7 +#define D2Fxx88_XmitMargin_WIDTH 3 +#define D2Fxx88_XmitMargin_MASK 0x380 +#define D2Fxx88_EnterModCompliance_OFFSET 10 +#define D2Fxx88_EnterModCompliance_WIDTH 1 +#define D2Fxx88_EnterModCompliance_MASK 0x400 +#define D2Fxx88_ComplianceSOS_OFFSET 11 +#define D2Fxx88_ComplianceSOS_WIDTH 1 +#define D2Fxx88_ComplianceSOS_MASK 0x800 +#define D2Fxx88_ComplianceDeemphasis_OFFSET 12 +#define D2Fxx88_ComplianceDeemphasis_WIDTH 1 +#define D2Fxx88_ComplianceDeemphasis_MASK 0x1000 +#define D2Fxx88_Reserved_15_13_OFFSET 13 +#define D2Fxx88_Reserved_15_13_WIDTH 3 +#define D2Fxx88_Reserved_15_13_MASK 0xe000 +#define D2Fxx88_CurDeemphasisLevel_OFFSET 16 +#define D2Fxx88_CurDeemphasisLevel_WIDTH 1 +#define D2Fxx88_CurDeemphasisLevel_MASK 0x10000 +#define D2Fxx88_Reserved_31_17_OFFSET 17 +#define D2Fxx88_Reserved_31_17_WIDTH 15 +#define D2Fxx88_Reserved_31_17_MASK 0xfffe0000 + +/// D2Fxx88 +typedef union { + struct { ///< + UINT32 TargetLinkSpeed:4 ; ///< + UINT32 EnterCompliance:1 ; ///< + UINT32 HwAutonomousSpeedDisable:1 ; ///< + UINT32 SelectableDeemphasis:1 ; ///< + UINT32 XmitMargin:3 ; ///< + UINT32 EnterModCompliance:1 ; ///< + UINT32 ComplianceSOS:1 ; ///< + UINT32 ComplianceDeemphasis:1 ; ///< + UINT32 Reserved_15_13:3 ; ///< + UINT32 CurDeemphasisLevel:1 ; ///< + UINT32 Reserved_31_17:15; ///< + } Field; ///< + UINT32 Value; ///< +} D2Fxx88_STRUCT; + + +// **** D0F0xE4_WRAP_0803 Register Definition **** +// Address +#define D0F0xE4_WRAP_0803_ADDRESS 0x803 + +// Type +#define D0F0xE4_WRAP_0803_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_0803_Reserved_4_0_OFFSET 0 +#define D0F0xE4_WRAP_0803_Reserved_4_0_WIDTH 5 +#define D0F0xE4_WRAP_0803_Reserved_4_0_MASK 0x1f +#define D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_OFFSET 5 +#define D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_WIDTH 1 +#define D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_MASK 0x20 +#define D0F0xE4_WRAP_0803_Reserved_31_6_OFFSET 6 +#define D0F0xE4_WRAP_0803_Reserved_31_6_WIDTH 26 +#define D0F0xE4_WRAP_0803_Reserved_31_6_MASK 0xffffffc0 + +/// D0F0xE4_WRAP_0803 +typedef union { + struct { ///< + UINT32 Reserved_4_0:5 ; ///< + UINT32 StrapBifDeemphasisSel:1 ; ///< + UINT32 Reserved_31_6:26; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_0803_STRUCT; + +/* + * Needed by GnbNbInitLibV4.c + */ + +// **** D0F0x60 Register Definition **** +// Address +#define D0F0x60_ADDRESS 0x60 + +// **** D0F0x90 Register Definition **** +// Address +#define D0F0x90_ADDRESS 0x90 + +// **** D0F0x64_x19 Register Definition **** +// Address +#define D0F0x64_x19_ADDRESS 0x19 + +// **** D0F0x64_x1A Register Definition **** +// Address +#define D0F0x64_x1A_ADDRESS 0x1a + + + + + +/// D0F0xBC_x80010000 +typedef union { +UINT32 Value; ///< +} GRC1_STRUCT; + + + + + + +// **** D0F0xE4_CORE_0010 Register Definition **** +// Address +#define D0F0xE4_CORE_0010_ADDRESS 0x10 + +// Type +#define D0F0xE4_CORE_0010_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_CORE_0010_HwInitWrLock_OFFSET 0 +#define D0F0xE4_CORE_0010_HwInitWrLock_WIDTH 1 +#define D0F0xE4_CORE_0010_HwInitWrLock_MASK 0x1 +#define D0F0xE4_CORE_0010_Reserved_8_1_OFFSET 1 +#define D0F0xE4_CORE_0010_Reserved_8_1_WIDTH 8 +#define D0F0xE4_CORE_0010_Reserved_8_1_MASK 0x1fe +#define D0F0xE4_CORE_0010_UmiNpMemWrite_OFFSET 9 +#define D0F0xE4_CORE_0010_UmiNpMemWrite_WIDTH 1 +#define D0F0xE4_CORE_0010_UmiNpMemWrite_MASK 0x200 +#define D0F0xE4_CORE_0010_RxSbAdjPayloadSize_OFFSET 10 +#define D0F0xE4_CORE_0010_RxSbAdjPayloadSize_WIDTH 3 +#define D0F0xE4_CORE_0010_RxSbAdjPayloadSize_MASK 0x1c00 +#define D0F0xE4_CORE_0010_Reserved_31_13_OFFSET 13 +#define D0F0xE4_CORE_0010_Reserved_31_13_WIDTH 19 +#define D0F0xE4_CORE_0010_Reserved_31_13_MASK 0xffffe000 + +/// D0F0xE4_CORE_0010 +typedef union { + struct { ///< + UINT32 HwInitWrLock:1 ; ///< + UINT32 Reserved_8_1:8 ; ///< + UINT32 UmiNpMemWrite:1 ; ///< + UINT32 RxSbAdjPayloadSize:3 ; ///< + UINT32 Reserved_31_13:19; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_CORE_0010_STRUCT; + + +// **** D0F0x94 Register Definition **** +// Address +#define D0F0x94_ADDRESS 0x94 + + +// **** D0F0x98_x3A Register Definition **** +// Address +#define D0F0x98_x3A_ADDRESS 0x3a + + +// **** D18F0x110 Register Definition **** +// Address +#define D18F0x110_ADDRESS 0x110 + + +// **** D0F0x98_x06 Register Definition **** +// Address +#define D0F0x98_x06_ADDRESS 0x6 + +#define D0F0x98_x06_UmiNpMemWrEn_OFFSET 26 +#define D0F0x98_x06_UmiNpMemWrEn_WIDTH 1 +#define D0F0x98_x06_UmiNpMemWrEn_MASK 0x4000000 + +/* + * Needed by GnbNbInitLibV4.c - end + */ + +/* + * Needed by GnbIommuScratch.c + */ + + + + +/* + * Needed by GnbIommuScratch.c - end + */ + +/* + * Needed by GnbIoapic.c + */ + + +// **** D0F0xF8 Register Definition **** +// Address +#define D0F0xF8_ADDRESS 0xf8 + +// **** D0F0xFC_x00 Register Definition **** +// Address +#define D0F0xFC_x00_ADDRESS 0x0 + +// Type +#define D0F0xFC_x00_TYPE TYPE_D0F0xFC +// Field Data +#define D0F0xFC_x00_IoapicEnable_OFFSET 0 +#define D0F0xFC_x00_IoapicEnable_WIDTH 1 +#define D0F0xFC_x00_IoapicEnable_MASK 0x01 +#define D0F0xFC_x00_Reserved_1_1_OFFSET 2 +#define D0F0xFC_x00_Reserved_1_1_WIDTH 1 +#define D0F0xFC_x00_Reserved_1_1_MASK 0x02 +#define D0F0xFC_x00_IoapicIdExtEn_OFFSET 3 +#define D0F0xFC_x00_IoapicIdExtEn_WIDTH 1 +#define D0F0xFC_x00_IoapicIdExtEn_MASK 0x04 +#define D0F0xFC_x00_Reserved_3_3_OFFSET 4 +#define D0F0xFC_x00_Reserved_3_3_WIDTH 1 +#define D0F0xFC_x00_Reserved_3_3_MASK 0x08 +#define D0F0xFC_x00_IoapicSbFeatureEn_OFFSET 4 +#define D0F0xFC_x00_IoapicSbFeatureEn_WIDTH 1 +#define D0F0xFC_x00_IoapicSbFeatureEn_MASK 0x10 +#define D0F0xFC_x00_Reserved_31_5_OFFSET 5 +#define D0F0xFC_x00_Reserved_31_5_WIDTH 27 +#define D0F0xFC_x00_Reserved_31_5_MASK 0xffffffe0 + +/// D0F0xFC_x00 +typedef union { + struct { ///< + UINT32 IoapicEnable:1 ; ///< + UINT32 Reserved_1_1:1 ; ///< + UINT32 IoapicIdExtEn:1 ; ///< + UINT32 Reserved_3_3:1 ; ///< + UINT32 IoapicSbFeatureEn:1 ; ///< + UINT32 Reserved_31_5:27; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xFC_x00_STRUCT; + +/* + * Needed by GnbIoapic.c - end + */ + +/* + * Needed by GnbPcieInitLibV5 + */ + + +// **** D0F0xE4_WRAP_8021 Register Definition **** +// Address +#define D0F0xE4_WRAP_8021_ADDRESS 0x8021 + + +// **** D0F0xCC_x01 Register Definition **** +// Address +#define D0F0xCC_x01_ADDRESS 0x1 + +// Type +#define D0F0xCC_x01_TYPE TYPE_D0F0xCC +// Field Data +#define D0F0xCC_x01_BridgeDis_OFFSET 0 +#define D0F0xCC_x01_BridgeDis_WIDTH 1 +#define D0F0xCC_x01_BridgeDis_MASK 0x1 +#define D0F0xCC_x01_Reserved_1_1_OFFSET 1 +#define D0F0xCC_x01_Reserved_1_1_WIDTH 1 +#define D0F0xCC_x01_Reserved_1_1_MASK 0x2 +#define D0F0xCC_x01_CfgDis_OFFSET 2 +#define D0F0xCC_x01_CfgDis_WIDTH 1 +#define D0F0xCC_x01_CfgDis_MASK 0x4 +#define D0F0xCC_x01_P2pDis_OFFSET 3 +#define D0F0xCC_x01_P2pDis_WIDTH 1 +#define D0F0xCC_x01_P2pDis_MASK 0x8 +#define D0F0xCC_x01_Reserved_15_4_OFFSET 4 +#define D0F0xCC_x01_Reserved_15_4_WIDTH 12 +#define D0F0xCC_x01_Reserved_15_4_MASK 0xfff0 +#define D0F0xCC_x01_ExtDevPlug_OFFSET 16 +#define D0F0xCC_x01_ExtDevPlug_WIDTH 1 +#define D0F0xCC_x01_ExtDevPlug_MASK 0x10000 +#define D0F0xCC_x01_ExtDevCsrEn_OFFSET 17 +#define D0F0xCC_x01_ExtDevCsrEn_WIDTH 1 +#define D0F0xCC_x01_ExtDevCsrEn_MASK 0x20000 +#define D0F0xCC_x01_CsrEnable_OFFSET 18 +#define D0F0xCC_x01_CsrEnable_WIDTH 1 +#define D0F0xCC_x01_CsrEnable_MASK 0x40000 +#define D0F0xCC_x01_SetPowEn_OFFSET 20 +#define D0F0xCC_x01_SetPowEn_WIDTH 1 +#define D0F0xCC_x01_SetPowEn_MASK 0x100000 +#define D0F0xCC_x01_Reserved_22_21_OFFSET 21 +#define D0F0xCC_x01_Reserved_22_21_WIDTH 2 +#define D0F0xCC_x01_Reserved_22_21_MASK 0x600000 +#define D0F0xCC_x01_ApicEnable_OFFSET 23 +#define D0F0xCC_x01_ApicEnable_WIDTH 1 +#define D0F0xCC_x01_ApicEnable_MASK 0x800000 +#define D0F0xCC_x01_ApicRange_OFFSET 24 +#define D0F0xCC_x01_ApicRange_WIDTH 8 +#define D0F0xCC_x01_ApicRange_MASK 0xff000000 + +/// D0F0xCC_x1 +typedef union { + struct { ///< + UINT32 BridgeDis:1 ; ///< + UINT32 Reserved_1_1:2 ; ///< + UINT32 CfgDis:1 ; ///< + UINT32 P2pDis:1 ; ///< + UINT32 Reserved_15_4:12; ///< + UINT32 ExtDevPlug:1 ; ///< + UINT32 ExtDevCsrEn:1 ; ///< + UINT32 CsrEnable:1 ; ///< + UINT32 Reserved_19_19:1 ; ///< + UINT32 SetPowEn:1 ; ///< + UINT32 Reserved_22_21:2 ; ///< + UINT32 ApicEnable:1 ; ///< + UINT32 ApicRange:8 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xCC_x01_STRUCT; + + +// **** D0F0xC8 Register Definition **** +// Address +#define D0F0xC8_ADDRESS 0xc8 + +// Type +#define D0F0xC8_TYPE TYPE_D0F0 +// Field Data +#define D0F0xC8_NB_DEV_IND_ADDR_OFFSET 0 +#define D0F0xC8_NB_DEV_IND_ADDR_WIDTH 7 +#define D0F0xC8_NB_DEV_IND_ADDR_MASK 0x7F +#define D0F0xC8_Reserved_15_7_OFFSET 7 +#define D0F0xC8_Reserved_15_7_WIDTH 9 +#define D0F0xC8_Reserved_15_7_MASK 0xFF80 +#define D0F0xC8_NB_DEV_IND_SEL_OFFSET 16 +#define D0F0xC8_NB_DEV_IND_SEL_WIDTH 8 +#define D0F0xC8_NB_DEV_IND_SEL_MASK 0xFF0000 +#define D0F0xC8_Reserved_31_24_OFFSET 24 +#define D0F0xC8_Reserved_31_24_WIDTH 8 +#define D0F0xC8_Reserved_31_24_MASK 0xFF000000 + +/// D0F0xC8 +typedef union { + struct { ///< + UINT32 NB_DEV_IND_ADDR:7; ///< + UINT32 Reserved_15_7:9; ///< + UINT32 NB_DEV_IND_SEL:8; ///< + UINT32 Reserved_31_24:8; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xC8_STRUCT; + + + +#ifdef _GNBPCIEINITLIBV4_H_ + +// **** D0F0xE4_WRAP_8014 Register Definition **** +// Address +#define D0F0xE4_WRAP_8014_ADDRESS 0x8014 + + +/// D0F0xE4_WRAP_8014 +typedef union { + struct { ///< + UINT32 TxclkPermGateEnable:1 ; ///< + UINT32 TxclkPrbsGateEnable:1 ; ///< + UINT32 DdiGatePifA1xEnable:1 ; ///< + UINT32 DdiGatePifB1xEnable:1 ; ///< + UINT32 DdiGatePifC1xEnable:1 ; ///< + UINT32 DdiGatePifD1xEnable:1 ; ///< + UINT32 Reserved_7_6:2 ; ///< + UINT32 DdiGatePifA2p5xEnable:1 ; ///< + UINT32 DdiGatePifB2p5xEnable:1 ; ///< + UINT32 DdiGatePifC2p5xEnable:1 ; ///< + UINT32 DdiGatePifD2p5xEnable:1 ; ///< + UINT32 PcieGatePifA1xEnable:1 ; ///< + UINT32 PcieGatePifB1xEnable:1 ; ///< + UINT32 PcieGatePifC1xEnable:1 ; ///< + UINT32 PcieGatePifD1xEnable:1 ; ///< + UINT32 PcieGatePifA2p5xEnable:1 ; ///< + UINT32 PcieGatePifB2p5xEnable:1 ; ///< + UINT32 PcieGatePifC2p5xEnable:1 ; ///< + UINT32 PcieGatePifD2p5xEnable:1 ; ///< + UINT32 TxclkPermGateOnlyWhenPllPwrDn:1 ; ///< + UINT32 Reserved_23_21:3 ; ///< + UINT32 DdiGateDigAEnable:1 ; ///< + UINT32 DdiGateDigBEnable:1 ; ///< + UINT32 DdiGateDigCEnable:1 ; ///< + UINT32 DdiGateDigDEnable:1 ; ///< + UINT32 SpareRegRw:4 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8014_STRUCT; + +#endif + +#ifdef _GNBPCIEINITLIBV5_H_ // KV version of WRAP_8014 + +// **** D0F0xE4_WRAP_8014 Register Definition **** +// Address +#define D0F0xE4_WRAP_8014_ADDRESS 0x8014 + +// Type +#define D0F0xE4_WRAP_8014_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_OFFSET 0 +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_MASK 0x1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_OFFSET 1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_MASK 0x2 +#define D0F0xE4_WRAP_8014_DdiPifa1xGateEnable_OFFSET 2 +#define D0F0xE4_WRAP_8014_DdiPifa1xGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_DdiPifa1xGateEnable_MASK 0x4 +#define D0F0xE4_WRAP_8014_DdiPifb1xGateEnable_OFFSET 3 +#define D0F0xE4_WRAP_8014_DdiPifb1xGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_DdiPifb1xGateEnable_MASK 0x8 +#define D0F0xE4_WRAP_8014_DdiPifc1xGateEnable_OFFSET 4 +#define D0F0xE4_WRAP_8014_DdiPifc1xGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_DdiPifc1xGateEnable_MASK 0x10 +#define D0F0xE4_WRAP_8014_DdiPifd1xGateEnable_OFFSET 5 +#define D0F0xE4_WRAP_8014_DdiPifd1xGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_DdiPifd1xGateEnable_MASK 0x20 +#define D0F0xE4_WRAP_8014_Reserved_11_6_OFFSET 6 +#define D0F0xE4_WRAP_8014_Reserved_11_6_WIDTH 6 +#define D0F0xE4_WRAP_8014_Reserved_11_6_MASK 0xfc0 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_OFFSET 12 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_MASK 0x1000 +#define D0F0xE4_WRAP_8014_PcieGatePifB1xEnable_OFFSET 13 +#define D0F0xE4_WRAP_8014_PcieGatePifB1xEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_PcieGatePifB1xEnable_MASK 0x2000 +#define D0F0xE4_WRAP_8014_PcieGatePifC1xEnable_OFFSET 14 +#define D0F0xE4_WRAP_8014_PcieGatePifC1xEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_PcieGatePifC1xEnable_MASK 0x4000 +#define D0F0xE4_WRAP_8014_PcieGatePifD1xEnable_OFFSET 15 +#define D0F0xE4_WRAP_8014_PcieGatePifD1xEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_PcieGatePifD1xEnable_MASK 0x8000 +#define D0F0xE4_WRAP_8014_Reserved_19_16_OFFSET 16 +#define D0F0xE4_WRAP_8014_Reserved_19_16_WIDTH 4 +#define D0F0xE4_WRAP_8014_Reserved_19_16_MASK 0xf0000 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_OFFSET 20 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_MASK 0x100000 +#define D0F0xE4_WRAP_8014_Reserved_23_21_OFFSET 21 +#define D0F0xE4_WRAP_8014_Reserved_23_21_WIDTH 3 +#define D0F0xE4_WRAP_8014_Reserved_23_21_MASK 0xe00000 +#define D0F0xE4_WRAP_8014_DdiDigaGateEnable_OFFSET 24 +#define D0F0xE4_WRAP_8014_DdiDigaGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_DdiDigaGateEnable_MASK 0x1000000 +#define D0F0xE4_WRAP_8014_DdiDigbGateEnable_OFFSET 25 +#define D0F0xE4_WRAP_8014_DdiDigbGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_DdiDigbGateEnable_MASK 0x2000000 +#define D0F0xE4_WRAP_8014_DdiDigcGateEnable_OFFSET 26 +#define D0F0xE4_WRAP_8014_DdiDigcGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_DdiDigcGateEnable_MASK 0x4000000 +#define D0F0xE4_WRAP_8014_DdiDigdGateEnable_OFFSET 27 +#define D0F0xE4_WRAP_8014_DdiDigdGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_DdiDigdGateEnable_MASK 0x8000000 +#define D0F0xE4_WRAP_8014_SpareRegRw_OFFSET 28 +#define D0F0xE4_WRAP_8014_SpareRegRw_WIDTH 4 +#define D0F0xE4_WRAP_8014_SpareRegRw_MASK 0xf0000000 + +/// D0F0xE4_WRAP_8014 +typedef union { + struct { ///< + UINT32 TxclkPermGateEnable:1 ; ///< + UINT32 TxclkPrbsGateEnable:1 ; ///< + UINT32 DdiPifa1xGateEnable:1 ; ///< + UINT32 DdiPifb1xGateEnable:1 ; ///< + UINT32 DdiPifc1xGateEnable:1 ; ///< + UINT32 DdiPifd1xGateEnable:1 ; ///< + UINT32 Reserved_11_6:6 ; ///< + UINT32 PcieGatePifA1xEnable:1 ; ///< + UINT32 PcieGatePifB1xEnable:1 ; ///< + UINT32 PcieGatePifC1xEnable:1 ; ///< + UINT32 PcieGatePifD1xEnable:1 ; ///< + UINT32 Reserved_19_16:4 ; ///< + UINT32 TxclkPermGateOnlyWhenPllPwrDn:1 ; ///< + UINT32 Reserved_23_21:3 ; ///< + UINT32 DdiDigaGateEnable:1 ; ///< + UINT32 DdiDigbGateEnable:1 ; ///< + UINT32 DdiDigcGateEnable:1 ; ///< + UINT32 DdiDigdGateEnable:1 ; ///< + UINT32 SpareRegRw:4 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8014_STRUCT; + +// **** D0F0xE4_WRAP_8029 Register Definition **** +// Address +#define D0F0xE4_WRAP_8029_ADDRESS 0x8029 +// Type +#define D0F0xE4_WRAP_8029_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8029_LaneEnable_OFFSET 0 +#define D0F0xE4_WRAP_8029_LaneEnable_WIDTH 16 +#define D0F0xE4_WRAP_8029_LaneEnable_MASK 0xFFFF +#define D0F0xE4_WRAP_8029_Reserved_31_16_OFFSET 16 +#define D0F0xE4_WRAP_8029_Reserved_31_16_WIDTH 16 +#define D0F0xE4_WRAP_8029_Reserved_31_16_MASK 0xFFFF0000 + +/// D0F0xE4_WRAP_8029 +typedef union { + struct { ///< + UINT32 LaneEnable:16; ///< + UINT32 Reserved_31_16:16; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8029_STRUCT; + +#endif + +#ifdef _GNBPCIETRAININGV2_H_ + +// **** DxFxx68 Register Definition **** +// Address +#define DxFxx68_ADDRESS 0x68 +// Type +#define DxFxx68_TYPE TYPE_D2F1 + +// Field Data +#define DxFxx68_PmControl_OFFSET 0 +#define DxFxx68_PmControl_WIDTH 2 +#define DxFxx68_PmControl_MASK 0x3 +#define DxFxx68_Reserved_2_2_OFFSET 2 +#define DxFxx68_Reserved_2_2_WIDTH 1 +#define DxFxx68_Reserved_2_2_MASK 0x4 +#define DxFxx68_ReadCplBoundary_OFFSET 3 +#define DxFxx68_ReadCplBoundary_WIDTH 1 +#define DxFxx68_ReadCplBoundary_MASK 0x8 +#define DxFxx68_LinkDis_OFFSET 4 +#define DxFxx68_LinkDis_WIDTH 1 +#define DxFxx68_LinkDis_MASK 0x10 +#define DxFxx68_RetrainLink_OFFSET 5 +#define DxFxx68_RetrainLink_WIDTH 1 +#define DxFxx68_RetrainLink_MASK 0x20 +#define DxFxx68_CommonClockCfg_OFFSET 6 +#define DxFxx68_CommonClockCfg_WIDTH 1 +#define DxFxx68_CommonClockCfg_MASK 0x40 +#define DxFxx68_ExtendedSync_OFFSET 7 +#define DxFxx68_ExtendedSync_WIDTH 1 +#define DxFxx68_ExtendedSync_MASK 0x80 +#define DxFxx68_ClockPowerManagementEn_OFFSET 8 +#define DxFxx68_ClockPowerManagementEn_WIDTH 1 +#define DxFxx68_ClockPowerManagementEn_MASK 0x100 +#define DxFxx68_HWAutonomousWidthDisable_OFFSET 9 +#define DxFxx68_HWAutonomousWidthDisable_WIDTH 1 +#define DxFxx68_HWAutonomousWidthDisable_MASK 0x200 +#define DxFxx68_LinkBWManagementEn_OFFSET 10 +#define DxFxx68_LinkBWManagementEn_WIDTH 1 +#define DxFxx68_LinkBWManagementEn_MASK 0x400 +#define DxFxx68_LinkAutonomousBWIntEn_OFFSET 11 +#define DxFxx68_LinkAutonomousBWIntEn_WIDTH 1 +#define DxFxx68_LinkAutonomousBWIntEn_MASK 0x800 +#define DxFxx68_Reserved_15_12_OFFSET 12 +#define DxFxx68_Reserved_15_12_WIDTH 4 +#define DxFxx68_Reserved_15_12_MASK 0xF000 +#define DxFxx68_LinkSpeed_OFFSET 16 +#define DxFxx68_LinkSpeed_WIDTH 4 +#define DxFxx68_LinkSpeed_MASK 0xF0000 +#define DxFxx68_NegotiatedLinkWidth_OFFSET 20 +#define DxFxx68_NegotiatedLinkWidth_WIDTH 6 +#define DxFxx68_NegotiatedLinkWidth_MASK 0x3F00000 +#define DxFxx68_Reserved_26_26_OFFSET 26 +#define DxFxx68_Reserved_26_26_WIDTH 1 +#define DxFxx68_Reserved_26_26_MASK 0x4000000 +#define DxFxx68_LinkTraining_OFFSET 27 +#define DxFxx68_LinkTraining_WIDTH 1 +#define DxFxx68_LinkTraining_MASK 0x8000000 +#define DxFxx68_SlotClockCfg_OFFSET 28 +#define DxFxx68_SlotClockCfg_WIDTH 1 +#define DxFxx68_SlotClockCfg_MASK 0x10000000 +#define DxFxx68_DlActive_OFFSET 29 +#define DxFxx68_DlActive_WIDTH 1 +#define DxFxx68_DlActive_MASK 0x20000000 +#define DxFxx68_LinkBWManagementStatus_OFFSET 30 +#define DxFxx68_LinkBWManagementStatus_WIDTH 1 +#define DxFxx68_LinkBWManagementStatus_MASK 0x40000000 +#define DxFxx68_LinkAutonomousBWStatus_OFFSET 31 +#define DxFxx68_LinkAutonomousBWStatus_WIDTH 1 +#define DxFxx68_LinkAutonomousBWStatus_MASK 0x80000000 + +/// DxFxx68 +typedef union { + struct { ///< + UINT32 PmControl:2; ///< + UINT32 Reserved_2_2:1; ///< + UINT32 ReadCplBoundary:1; ///< + UINT32 LinkDis:1; ///< + UINT32 RetrainLink:1; ///< + UINT32 CommonClockCfg:1; ///< + UINT32 ExtendedSync:1; ///< + UINT32 ClockPowerManagementEn:1; ///< + UINT32 HWAutonomousWidthDisable:1; ///< + UINT32 LinkBWManagementEn:1; ///< + UINT32 LinkAutonomousBWIntEn:1; ///< + UINT32 Reserved_15_12:4; ///< + UINT32 LinkSpeed:4; ///< + UINT32 NegotiatedLinkWidth:6; ///< + UINT32 Reserved_26_26:1; ///< + UINT32 LinkTraining:1; ///< + UINT32 SlotClockCfg:1; ///< + UINT32 DlActive:1; ///< + UINT32 LinkBWManagementStatus:1; ///< + UINT32 LinkAutonomousBWStatus:1; ///< + + } Field; + + UINT32 Value; +} DxFxx68_STRUCT; + +// **** D0F0xE4_WRAP_0800 Register Definition **** +// Address +#define D0F0xE4_WRAP_0800_ADDRESS 0x800 +// Type +#define D0F0xE4_WRAP_0800_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_0800_HoldTraining_OFFSET 0 +#define D0F0xE4_WRAP_0800_HoldTraining_WIDTH 1 +#define D0F0xE4_WRAP_0800_HoldTraining_MASK 0x1 +#define D0F0xE4_WRAP_0800_Reserved_31_1_OFFSET 1 +#define D0F0xE4_WRAP_0800_Reserved_31_1_WIDTH 31 +#define D0F0xE4_WRAP_0800_Reserved_31_1_MASK 0xFFFFFFFE + +/// D0F0xE4_WRAP_0800 +typedef union { + struct { ///< + UINT32 HoldTraining:1; ///< + UINT32 Reserved_31_1:31; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_0800_STRUCT; + +// **** DxFxx128 Register Definition **** +// Address +#define DxFxx128_ADDRESS 0x128 +// Type +#define DxFxx128_TYPE TYPE_D2F1 + +// Field Data +#define DxFxx128_Reserved_15_0_OFFSET 0 +#define DxFxx128_Reserved_15_0_WIDTH 16 +#define DxFxx128_Reserved_15_0_MASK 0xFFFF +#define DxFxx128_PortArbTableStatus_OFFSET 16 +#define DxFxx128_PortArbTableStatus_WIDTH 1 +#define DxFxx128_PortArbTableStatus_MASK 0x10000 +#define DxFxx128_VcNegotiationPending_OFFSET 17 +#define DxFxx128_VcNegotiationPending_WIDTH 1 +#define DxFxx128_VcNegotiationPending_MASK 0x20000 +#define DxFxx128_Reserved_31_18_OFFSET 18 +#define DxFxx128_Reserved_31_18_WIDTH 14 +#define DxFxx128_Reserved_31_18_MASK 0xFFFC0000 + +/// DxFxx128 +typedef union { + struct { ///< + UINT32 Reserved_15_0:16; ///< + UINT32 PortArbTableStatus:1; ///< + UINT32 VcNegotiationPending:1; ///< + UINT32 Reserved_31_18:14; ///< + + } Field; + + UINT32 Value; +} DxFxx128_STRUCT; + +// **** DxFxx18 Register Definition **** +// Address +#define DxFxx18_ADDRESS 0x18 +// Type +#define DxFxx18_TYPE TYPE_D2F1 + +// **** DxFxx20 Register Definition **** +// Address +#define DxFxx20_ADDRESS 0x20 +// Type +#define DxFxx20_TYPE TYPE_D2F1 + +// **** DxFxx24 Register Definition **** +// Address +#define DxFxx24_ADDRESS 0x24 +// Type +#define DxFxx24_TYPE TYPE_D2F1 + +// **** D0F0x04 Register Definition **** +// Address +#define D0F0x04_ADDRESS 0x4 +// Type +#define D0F0x04_TYPE TYPE_D0F0 + +// Field Data +#define D0F0x04_IoAccessEn_OFFSET 0 +#define D0F0x04_IoAccessEn_WIDTH 1 +#define D0F0x04_IoAccessEn_MASK 0x1 +#define D0F0x04_MemAccessEn_OFFSET 1 +#define D0F0x04_MemAccessEn_WIDTH 1 +#define D0F0x04_MemAccessEn_MASK 0x2 +#define D0F0x04_BusMasterEn_OFFSET 2 +#define D0F0x04_BusMasterEn_WIDTH 1 +#define D0F0x04_BusMasterEn_MASK 0x4 +#define D0F0x04_Reserved_19_3_OFFSET 3 +#define D0F0x04_Reserved_19_3_WIDTH 17 +#define D0F0x04_Reserved_19_3_MASK 0xFFFF8 +#define D0F0x04_CapList_OFFSET 20 +#define D0F0x04_CapList_WIDTH 1 +#define D0F0x04_CapList_MASK 0x100000 +#define D0F0x04_Reserved_31_21_OFFSET 21 +#define D0F0x04_Reserved_31_21_WIDTH 11 +#define D0F0x04_Reserved_31_21_MASK 0xFFE00000 + +/// D0F0x04 +typedef union { + struct { ///< + UINT32 IoAccessEn:1; ///< + UINT32 MemAccessEn:1; ///< + UINT32 BusMasterEn:1; ///< + UINT32 Reserved_19_3:17; ///< + UINT32 CapList:1; ///< + UINT32 Reserved_31_21:11; ///< + + } Field; + + UINT32 Value; +} D0F0x04_STRUCT; + +#endif + +// **** D0F0xE4_PIF_0011 Register Definition **** +// Address +#define D0F0xE4_PIF_0011_ADDRESS 0x11 + +// Type +#define D0F0xE4_PIF_0011_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PIF_0011_X2Lane10_OFFSET 0 +#define D0F0xE4_PIF_0011_X2Lane10_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane10_MASK 0x1 +#define D0F0xE4_PIF_0011_X2Lane32_OFFSET 1 +#define D0F0xE4_PIF_0011_X2Lane32_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane32_MASK 0x2 +#define D0F0xE4_PIF_0011_X2Lane54_OFFSET 2 +#define D0F0xE4_PIF_0011_X2Lane54_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane54_MASK 0x4 +#define D0F0xE4_PIF_0011_X2Lane76_OFFSET 3 +#define D0F0xE4_PIF_0011_X2Lane76_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane76_MASK 0x8 +#define D0F0xE4_PIF_0011_X2Lane98_OFFSET 4 +#define D0F0xE4_PIF_0011_X2Lane98_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane98_MASK 0x10 +#define D0F0xE4_PIF_0011_X2Lane1110_OFFSET 5 +#define D0F0xE4_PIF_0011_X2Lane1110_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane1110_MASK 0x20 +#define D0F0xE4_PIF_0011_X2Lane1312_OFFSET 6 +#define D0F0xE4_PIF_0011_X2Lane1312_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane1312_MASK 0x40 +#define D0F0xE4_PIF_0011_X2Lane1514_OFFSET 7 +#define D0F0xE4_PIF_0011_X2Lane1514_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane1514_MASK 0x80 +#define D0F0xE4_PIF_0011_X4Lane30_OFFSET 8 +#define D0F0xE4_PIF_0011_X4Lane30_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane30_MASK 0x100 +#define D0F0xE4_PIF_0011_X4Lane74_OFFSET 9 +#define D0F0xE4_PIF_0011_X4Lane74_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane74_MASK 0x200 +#define D0F0xE4_PIF_0011_X4Lane118_OFFSET 10 +#define D0F0xE4_PIF_0011_X4Lane118_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane118_MASK 0x400 +#define D0F0xE4_PIF_0011_X4Lane1512_OFFSET 11 +#define D0F0xE4_PIF_0011_X4Lane1512_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane1512_MASK 0x800 +#define D0F0xE4_PIF_0011_Reserved_15_12_OFFSET 12 +#define D0F0xE4_PIF_0011_Reserved_15_12_WIDTH 4 +#define D0F0xE4_PIF_0011_Reserved_15_12_MASK 0xf000 +#define D0F0xE4_PIF_0011_X8Lane70_OFFSET 16 +#define D0F0xE4_PIF_0011_X8Lane70_WIDTH 1 +#define D0F0xE4_PIF_0011_X8Lane70_MASK 0x10000 +#define D0F0xE4_PIF_0011_X8Lane158_OFFSET 17 +#define D0F0xE4_PIF_0011_X8Lane158_WIDTH 1 +#define D0F0xE4_PIF_0011_X8Lane158_MASK 0x20000 +#define D0F0xE4_PIF_0011_Reserved_19_18_OFFSET 18 +#define D0F0xE4_PIF_0011_Reserved_19_18_WIDTH 2 +#define D0F0xE4_PIF_0011_Reserved_19_18_MASK 0xc0000 +#define D0F0xE4_PIF_0011_X16Lane150_OFFSET 20 +#define D0F0xE4_PIF_0011_X16Lane150_WIDTH 1 +#define D0F0xE4_PIF_0011_X16Lane150_MASK 0x100000 +#define D0F0xE4_PIF_0011_Reserved_24_21_OFFSET 21 +#define D0F0xE4_PIF_0011_Reserved_24_21_WIDTH 4 +#define D0F0xE4_PIF_0011_Reserved_24_21_MASK 0x1e00000 +#define D0F0xE4_PIF_0011_MultiPif_OFFSET 25 +#define D0F0xE4_PIF_0011_MultiPif_WIDTH 1 +#define D0F0xE4_PIF_0011_MultiPif_MASK 0x2000000 +#define D0F0xE4_PIF_0011_Reserved_31_26_OFFSET 26 +#define D0F0xE4_PIF_0011_Reserved_31_26_WIDTH 6 +#define D0F0xE4_PIF_0011_Reserved_31_26_MASK 0xfc000000 + +/// D0F0xE4_PIF_0011 +typedef union { + struct { ///< + UINT32 X2Lane10:1 ; ///< + UINT32 X2Lane32:1 ; ///< + UINT32 X2Lane54:1 ; ///< + UINT32 X2Lane76:1 ; ///< + UINT32 X2Lane98:1 ; ///< + UINT32 X2Lane1110:1 ; ///< + UINT32 X2Lane1312:1 ; ///< + UINT32 X2Lane1514:1 ; ///< + UINT32 X4Lane30:1 ; ///< + UINT32 X4Lane74:1 ; ///< + UINT32 X4Lane118:1 ; ///< + UINT32 X4Lane1512:1 ; ///< + UINT32 Reserved_15_12:4 ; ///< + UINT32 X8Lane70:1 ; ///< + UINT32 X8Lane158:1 ; ///< + UINT32 Reserved_19_18:2 ; ///< + UINT32 X16Lane150:1 ; ///< + UINT32 Reserved_24_21:4 ; ///< + UINT32 MultiPif:1 ; ///< + UINT32 Reserved_31_26:6 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PIF_0011_STRUCT; + +// **** D0F0xE4_PIF_0012 Register Definition **** +// Address +#define D0F0xE4_PIF_0012_ADDRESS 0x12 + +// Type +#define D0F0xE4_PIF_0012_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_OFFSET 0 +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_MASK 0x7 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_OFFSET 3 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_WIDTH 1 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_MASK 0x8 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_OFFSET 4 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_MASK 0x70 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_OFFSET 7 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_MASK 0x380 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_OFFSET 10 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_MASK 0x1c00 +#define D0F0xE4_PIF_0012_Reserved_15_13_OFFSET 13 +#define D0F0xE4_PIF_0012_Reserved_15_13_WIDTH 3 +#define D0F0xE4_PIF_0012_Reserved_15_13_MASK 0xe000 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_OFFSET 16 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_WIDTH 1 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_MASK 0x10000 +#define D0F0xE4_PIF_0012_Reserved_23_17_OFFSET 17 +#define D0F0xE4_PIF_0012_Reserved_23_17_WIDTH 7 +#define D0F0xE4_PIF_0012_Reserved_23_17_MASK 0xfe0000 +#define D0F0xE4_PIF_0012_PllRampUpTime_OFFSET 24 +#define D0F0xE4_PIF_0012_PllRampUpTime_WIDTH 3 +#define D0F0xE4_PIF_0012_PllRampUpTime_MASK 0x7000000 +#define D0F0xE4_PIF_0012_Reserved_27_27_OFFSET 27 +#define D0F0xE4_PIF_0012_Reserved_27_27_WIDTH 1 +#define D0F0xE4_PIF_0012_Reserved_27_27_MASK 0x8000000 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_OFFSET 28 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_WIDTH 1 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_MASK 0x10000000 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_OFFSET 29 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_MASK 0xe0000000 + +/// D0F0xE4_PIF_0012 +typedef union { + struct { ///< + UINT32 TxPowerStateInTxs2:3 ; ///< + UINT32 ForceRxEnInL0s:1 ; ///< + UINT32 RxPowerStateInRxs2:3 ; ///< + UINT32 PllPowerStateInTxs2:3 ; ///< + UINT32 PllPowerStateInOff:3 ; ///< + UINT32 Reserved_15_13:3 ; ///< + UINT32 Tx2p5clkClockGatingEn:1 ; ///< + UINT32 Reserved_23_17:7 ; ///< + UINT32 PllRampUpTime:3 ; ///< + UINT32 Reserved_27_27:1 ; ///< + UINT32 PllPwrOverrideEn:1 ; ///< + UINT32 PllPwrOverrideVal:3 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PIF_0012_STRUCT; + + +// **** D0F0xE4_PIF_0017 Register Definition **** +// Address +#define D0F0xE4_PIF_0017_ADDRESS 0x17 + +// Type +#define D0F0xE4_PIF_0017_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_PIF_0017_TxPowerStateInTxs2_OFFSET 0 +#define D0F0xE4_PIF_0017_TxPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0017_TxPowerStateInTxs2_MASK 0x7 +#define D0F0xE4_PIF_0017_ForceRxEnInL0s_OFFSET 3 +#define D0F0xE4_PIF_0017_ForceRxEnInL0s_WIDTH 1 +#define D0F0xE4_PIF_0017_ForceRxEnInL0s_MASK 0x8 +#define D0F0xE4_PIF_0017_RxPowerStateInRxs2_OFFSET 4 +#define D0F0xE4_PIF_0017_RxPowerStateInRxs2_WIDTH 3 +#define D0F0xE4_PIF_0017_RxPowerStateInRxs2_MASK 0x70 +#define D0F0xE4_PIF_0017_PllPowerStateInTxs2_OFFSET 7 +#define D0F0xE4_PIF_0017_PllPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0017_PllPowerStateInTxs2_MASK 0x380 +#define D0F0xE4_PIF_0017_PllPowerStateInOff_OFFSET 10 +#define D0F0xE4_PIF_0017_PllPowerStateInOff_WIDTH 3 +#define D0F0xE4_PIF_0017_PllPowerStateInOff_MASK 0x1c00 +#define D0F0xE4_PIF_0017_Reserved_15_13_OFFSET 13 +#define D0F0xE4_PIF_0017_Reserved_15_13_WIDTH 3 +#define D0F0xE4_PIF_0017_Reserved_15_13_MASK 0xe000 +#define D0F0xE4_PIF_0017_Tx2p5clkClockGatingEn_OFFSET 16 +#define D0F0xE4_PIF_0017_Tx2p5clkClockGatingEn_WIDTH 1 +#define D0F0xE4_PIF_0017_Tx2p5clkClockGatingEn_MASK 0x10000 +#define D0F0xE4_PIF_0017_Reserved_23_17_OFFSET 17 +#define D0F0xE4_PIF_0017_Reserved_23_17_WIDTH 7 +#define D0F0xE4_PIF_0017_Reserved_23_17_MASK 0xfe0000 +#define D0F0xE4_PIF_0017_PllRampUpTime_OFFSET 24 +#define D0F0xE4_PIF_0017_PllRampUpTime_WIDTH 3 +#define D0F0xE4_PIF_0017_PllRampUpTime_MASK 0x7000000 +#define D0F0xE4_PIF_0017_Reserved_27_27_OFFSET 27 +#define D0F0xE4_PIF_0017_Reserved_27_27_WIDTH 1 +#define D0F0xE4_PIF_0017_Reserved_27_27_MASK 0x8000000 +#define D0F0xE4_PIF_0017_PllPwrOverrideEn_OFFSET 28 +#define D0F0xE4_PIF_0017_PllPwrOverrideEn_WIDTH 1 +#define D0F0xE4_PIF_0017_PllPwrOverrideEn_MASK 0x10000000 +#define D0F0xE4_PIF_0017_PllPwrOverrideVal_OFFSET 29 +#define D0F0xE4_PIF_0017_PllPwrOverrideVal_WIDTH 3 +#define D0F0xE4_PIF_0017_PllPwrOverrideVal_MASK 0xe0000000 + +/// D0F0xE4_PIF_0017 +typedef union { + struct { ///< + UINT32 TxPowerStateInTxs2:3 ; ///< + UINT32 ForceRxEnInL0s:1 ; ///< + UINT32 RxPowerStateInRxs2:3 ; ///< + UINT32 PllPowerStateInTxs2:3 ; ///< + UINT32 PllPowerStateInOff:3 ; ///< + UINT32 Reserved_15_13:3 ; ///< + UINT32 Tx2p5clkClockGatingEn:1 ; ///< + UINT32 Reserved_23_17:7 ; ///< + UINT32 PllRampUpTime:3 ; ///< + UINT32 Reserved_27_27:1 ; ///< + UINT32 PllPwrOverrideEn:1 ; ///< + UINT32 PllPwrOverrideVal:3 ; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_PIF_0017_STRUCT; + + +// **** D0F0xE4_CORE_00B0 Register Definition **** +// Address +#define D0F0xE4_CORE_00B0_ADDRESS 0xb0 + +// Type +#define D0F0xE4_CORE_00B0_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_CORE_00B0_Reserved_1_0_OFFSET 0 +#define D0F0xE4_CORE_00B0_Reserved_1_0_WIDTH 2 +#define D0F0xE4_CORE_00B0_Reserved_1_0_MASK 0x3 +#define D0F0xE4_CORE_00B0_StrapF0MsiEn_OFFSET 2 +#define D0F0xE4_CORE_00B0_StrapF0MsiEn_WIDTH 1 +#define D0F0xE4_CORE_00B0_StrapF0MsiEn_MASK 0x4 +#define D0F0xE4_CORE_00B0_Reserved_4_3_OFFSET 3 +#define D0F0xE4_CORE_00B0_Reserved_4_3_WIDTH 2 +#define D0F0xE4_CORE_00B0_Reserved_4_3_MASK 0x18 +#define D0F0xE4_CORE_00B0_StrapF0AerEn_OFFSET 5 +#define D0F0xE4_CORE_00B0_StrapF0AerEn_WIDTH 1 +#define D0F0xE4_CORE_00B0_StrapF0AerEn_MASK 0x20 +#define D0F0xE4_CORE_00B0_Bitfield_6_6_MASK 0x40 +#define D0F0xE4_CORE_00B0_Reserved_31_7_OFFSET 7 +#define D0F0xE4_CORE_00B0_Reserved_31_7_WIDTH 25 +#define D0F0xE4_CORE_00B0_Reserved_31_7_MASK 0xffffff80 + +/// D0F0xE4_CORE_00B0 +typedef union { + struct { ///< + UINT32 Reserved_1_0:2 ; ///< + UINT32 StrapF0MsiEn:1 ; ///< + UINT32 Reserved_4_3:2 ; ///< + UINT32 StrapF0AerEn:1 ; ///< + UINT32 Bitfield_6_6:1 ; ///< + UINT32 Reserved_31_7:25; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_CORE_00B0_STRUCT; +typedef union { + struct { ///< + UINT32 Bitfield_0_0:1; ///< + UINT32 Bitfield_1_1:1 ; ///< + UINT32 Reserved_15_2:14; ///< + UINT32 Bitfield_16_16:1; ///< + UINT32 Bitfield_17_17:1 ; ///< + UINT32 Reserved_31_18:14; ///< + } Field; ///< + UINT32 Value; ///< +} GRC2_STRUCT; + + + +#endif + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersKB.h new file mode 100644 index 0000000000..a469eb35a3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbRegistersKB.h @@ -0,0 +1,3954 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AGESA gnb file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 88282 $ @e \$Date: 2013-02-19 11:20:56 -0600 (Tue, 19 Feb 2013) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ +#ifndef _GNBREGISTERSKB_H_ +#define _GNBREGISTERSKB_H_ +#define TYPE_D0F0 0x1 +#define TYPE_D0F0x64 0x2 +#define TYPE_D0F0x98 0x3 +#define TYPE_D0F0xBC 0x4 +#define TYPE_D18F1 0xb +#define TYPE_D18F2 0xc +#define TYPE_D18F3 0xd +#define TYPE_D18F4 0xe +#define TYPE_D18F5 0xf +#define TYPE_MSR 0x10 +#define TYPE_D1F0 0x11 +#define TYPE_D18F2x9C_dct0 0x13 +#define TYPE_D18F2x9C_dct0_mp0 0x14 +#define TYPE_D18F2x9C_dct0_mp1 0x15 +#define TYPE_D18F2x9C_dct1 0x16 +#define TYPE_D18F2x9C_dct1_mp0 0x17 +#define TYPE_D18F2x9C_dct1_mp1 0x18 +#define TYPE_D18F2_dct0 0x19 +#define TYPE_D18F2_dct1 0x1a +#define TYPE_D18F2_dct0_mp0 0x1b +#define TYPE_D18F2_dct0_mp1 0x1c +#define TYPE_D1F1 0x1d +#define TYPE_D18F2_dct1_mp0 0x1e +#define TYPE_D18F2_dct1_mp1 0x1f +#define TYPE_CGIND 0x20 +#define TYPE_SMU_MSG 0x21 +#define TYPE_D0F0xD4 0x22 +#define TYPE_D18F0 0x24 + +#ifndef WRAP_SPACE + #define WRAP_SPACE(w, x) (0x01300000 | (w << 16) | (x)) +#endif +#ifndef CORE_SPACE + #define CORE_SPACE(c, x) (0x00010000 | (c << 24) | (x)) +#endif +#ifndef PHY_SPACE + #define PHY_SPACE(w, p, x) (0x00200000 | ((p + 1) << 24) | (w << 16) | (x)) +#endif +#ifndef PIF_SPACE + #define PIF_SPACE(w, p, x) (0x00100000 | ((p + 1) << 24) | (w << 16) | (x)) +#endif + +#define INVALID_SMU_MSG 0xFF +#define SMU_MSG_TYPE TYPE_SMU_MSG +#define SMC_MSG_TEST INVALID_SMU_MSG // 1 +#define SMC_MSG_PHY_LN_OFF INVALID_SMU_MSG // 2 +#define SMC_MSG_PHY_LN_ON INVALID_SMU_MSG // 3 +#define SMC_MSG_DDI_PHY_OFF INVALID_SMU_MSG // 4 +#define SMC_MSG_DDI_PHY_ON INVALID_SMU_MSG // 5 +#define SMC_MSG_CASCADE_PLL_OFF INVALID_SMU_MSG // 6 +#define SMC_MSG_CASCADE_PLL_ON INVALID_SMU_MSG // 7 +#define SMC_MSG_PWR_OFF_x16 INVALID_SMU_MSG // 8 +#define SMC_MSG_FLUSH_DATA_CACHE INVALID_SMU_MSG // 10 +#define SMC_MSG_FLUSH_INSTRUCTION_CACHE INVALID_SMU_MSG // 11 +#define SMC_MSG_CONFIG_VPC_ACCUMULATOR 12 +#define SMC_MSG_RECONFIGURE_SB 25 +#define SMC_MSG_UPDATE_BAPM INVALID_SMU_MSG // 26 +#define SMC_MSG_PCIE_PLLSWITCH INVALID_SMU_MSG // 27 +#define SMC_MSG_FORCE_LCLK_DPM_STATE INVALID_SMU_MSG // 28 +#define SMC_MSG_UNFORCE_LCLK_DPM_STATE INVALID_SMU_MSG // 29 +#define SMC_MSG_LCLK_DPM_ENABLE 30 +#define SMC_MSG_LCLK_DPM_DISABLE 31 +#define SMC_MSG_DDI_PHY_IDLE INVALID_SMU_MSG // 34 +#define SMC_MSG_DDI_PHY_BUSY INVALID_SMU_MSG // 35 +#define SMC_MSG_DSMU INVALID_SMU_MSG // 36 +#define SMC_MSG_NBDPM_DISABLE INVALID_SMU_MSG // 37 +#define SMC_MSG_NBDPM_FORCENOMINAL INVALID_SMU_MSG // 38 +#define SMC_MSG_NBDPM_FORCEPERFORMANCE INVALID_SMU_MSG // 39 +#define SMC_MSG_NBDPM_UNFORCE INVALID_SMU_MSG // 40 +#define SMC_MSG_RESET INVALID_SMU_MSG // 41 +#define SMC_MSG_AVS_ENABLE INVALID_SMU_MSG // 42 +#define SMC_MSG_AVS_DISABLE INVALID_SMU_MSG // 43 +#define SMC_MSG_LPMX_ENABLE INVALID_SMU_MSG // 44 +#define SMC_MSG_LPMX_DISABLE INVALID_SMU_MSG // 45 +#define SMC_MSG_TDC_LIMIT_DISABLE 47 +#define SMC_MSG_BAPM_DISABLE 49 +#define SMC_MSG_TDP_LIMIT_ENABLE INVALID_SMU_MSG // 50 +#define SMC_MSG_TDP_LIMIT_DISABLE INVALID_SMU_MSG // 51 +#define SMC_MSG_SPMI_ENABLE INVALID_SMU_MSG // 52 +#define SMC_MSG_SPMI_DISABLE INVALID_SMU_MSG // 53 +#define SMC_MSG_SPMI_TEST INVALID_SMU_MSG // 54 +#define SMC_MSG_EXT_API INVALID_SMU_MSG // 55 +#define SMC_MSG_THERMAL_CNTL_DISABLE 57 +#define SMC_MSG_VDDNB_REQUEST 58 +#define SMC_MSG_VOLTAGE_CNTL_ENABLE 59 +#define SMC_MSG_VOLTAGE_CNTL_DISABLE 60 +#define SMC_MSG_NBDPM_ENABLE INVALID_SMU_MSG +#define SMC_MSG_MCARB_UPDATE_ENABLE INVALID_SMU_MSG +#define SMC_MSG_MCARB_UPDATE_DISABLE INVALID_SMU_MSG +#define SMC_MSG_LHTC_LIMIT_DISABLE 71 +#define SMC_MSG_PWR_OFF_IOMMU INVALID_SMU_MSG +#define SMC_MSG_PWR_ON_IOMMU INVALID_SMU_MSG +#define SMC_MSG_MONITOR_PORT80_ENABLE INVALID_SMU_MSG +#define SMC_MSG_MONITOR_PORT80_DISABLE INVALID_SMU_MSG +#define SMC_MSG_LCLKDPM_SETENABLEMASK INVALID_SMU_MSG +#define SMC_MSG_READ_SCS 80 +#define SMC_MSG_ENABLE_PKGPWRLIMIT 81 +#define SMC_MSG_DISABLE_PKGPWRLIMIT 82 +#define SMC_MSG_ENABLE_ALLCLK_MONITOR 83 +#define SMC_MSG_DISABLE_ALLCLK_MONITOR INVALID_SMU_MSG +#define SMC_MSG_LHTC_LIMIT_SetLimit 90 // 0x5A + +#define L1_SEL_PPD 0 +#define L1_SEL_BIF 1 +#define L1_SEL_INTGEN 2 + +// **** D18F0x110 Register Definition **** +// Address +#define D18F0x110_ADDRESS 0x110 + +// Type +#define D18F0x110_TYPE TYPE_D18F0 + +// **** D18F1x44 Register Definition **** +// Address +#define D18F1x44_ADDRESS 0x44 +// Type +#define D18F1x44_TYPE TYPE_D18F1 + +// Field Data +#define D18F1x44_DstNode_OFFSET 0 +#define D18F1x44_DstNode_WIDTH 3 +#define D18F1x44_DstNode_MASK 0x7 +#define D18F1x44_Reserved_7_3_OFFSET 3 +#define D18F1x44_Reserved_7_3_WIDTH 5 +#define D18F1x44_Reserved_7_3_MASK 0xF8 +#define D18F1x44_Reserved_10_8_OFFSET 8 +#define D18F1x44_Reserved_10_8_WIDTH 3 +#define D18F1x44_Reserved_10_8_MASK 0x700 +#define D18F1x44_Reserved_15_11_OFFSET 11 +#define D18F1x44_Reserved_15_11_WIDTH 5 +#define D18F1x44_Reserved_15_11_MASK 0xF800 +#define D18F1x44_DramLimit_39_24_OFFSET 16 +#define D18F1x44_DramLimit_39_24_WIDTH 16 +#define D18F1x44_DramLimit_39_24_MASK 0xFFFF0000 + +/// D18F1x44 +typedef union { + struct { ///< + UINT32 DstNode:3; ///< + UINT32 Reserved_7_3:5; ///< + UINT32 Reserved_10_8:3; ///< + UINT32 Reserved_15_11:5; ///< + UINT32 DramLimit_39_24:16; ///< + + } Field; + + UINT32 Value; +} D18F1x44_STRUCT; + + + +// **** D18F2x90_dct0 Register Definition **** +// Address +#define D18F2x90_dct0_ADDRESS 0x90 +// Type +#define D18F2x90_dct0_TYPE TYPE_D18F2 + +// Field Data +#define D18F2x90_dct0_ExitSelfRef_OFFSET 1 +#define D18F2x90_dct0_ExitSelfRef_WIDTH 1 +#define D18F2x90_dct0_ExitSelfRef_MASK 0x2 +#define D18F2x90_dct0_Reserved_7_2_OFFSET 2 +#define D18F2x90_dct0_Reserved_7_2_WIDTH 6 +#define D18F2x90_dct0_Reserved_7_2_MASK 0xfc +#define D18F2x90_dct0_Reserved_8_8_OFFSET 8 +#define D18F2x90_dct0_Reserved_8_8_WIDTH 1 +#define D18F2x90_dct0_Reserved_8_8_MASK 0x100 +#define D18F2x90_dct0_Reserved_10_9_OFFSET 9 +#define D18F2x90_dct0_Reserved_10_9_WIDTH 2 +#define D18F2x90_dct0_Reserved_10_9_MASK 0x600 +#define D18F2x90_dct0_Reserved_11_11_OFFSET 11 +#define D18F2x90_dct0_Reserved_11_11_WIDTH 1 +#define D18F2x90_dct0_Reserved_11_11_MASK 0x800 +#define D18F2x90_dct0_Reserved_15_12_OFFSET 12 +#define D18F2x90_dct0_Reserved_15_12_WIDTH 4 +#define D18F2x90_dct0_Reserved_15_12_MASK 0xf000 +#define D18F2x90_dct0_UnbuffDimm_OFFSET 16 +#define D18F2x90_dct0_UnbuffDimm_WIDTH 1 +#define D18F2x90_dct0_UnbuffDimm_MASK 0x10000 +#define D18F2x90_dct0_UnbuffDimm_VALUE 0x1 +#define D18F2x90_dct0_EnterSelfRef_OFFSET 17 +#define D18F2x90_dct0_EnterSelfRef_WIDTH 1 +#define D18F2x90_dct0_EnterSelfRef_MASK 0x20000 +#define D18F2x90_dct0_PendRefPayback_OFFSET 18 +#define D18F2x90_dct0_PendRefPayback_WIDTH 1 +#define D18F2x90_dct0_PendRefPayback_MASK 0x40000 +#define D18F2x90_dct0_PendRefPayback_VALUE 0x0 +#define D18F2x90_dct0_DimmEccEn_OFFSET 19 +#define D18F2x90_dct0_DimmEccEn_WIDTH 1 +#define D18F2x90_dct0_DimmEccEn_MASK 0x80000 +#define D18F2x90_dct0_DynPageCloseEn_OFFSET 20 +#define D18F2x90_dct0_DynPageCloseEn_WIDTH 1 +#define D18F2x90_dct0_DynPageCloseEn_MASK 0x100000 +#define D18F2x90_dct0_IdleCycLowLimit_OFFSET 21 +#define D18F2x90_dct0_IdleCycLowLimit_WIDTH 2 +#define D18F2x90_dct0_IdleCycLowLimit_MASK 0x600000 +#define D18F2x90_dct0_ForceAutoPchg_OFFSET 23 +#define D18F2x90_dct0_ForceAutoPchg_WIDTH 1 +#define D18F2x90_dct0_ForceAutoPchg_MASK 0x800000 +#define D18F2x90_dct0_StagRefEn_OFFSET 24 +#define D18F2x90_dct0_StagRefEn_WIDTH 1 +#define D18F2x90_dct0_StagRefEn_MASK 0x1000000 +#define D18F2x90_dct0_StagRefEn_VALUE 0x1 +#define D18F2x90_dct0_PendRefPaybackS3En_OFFSET 25 +#define D18F2x90_dct0_PendRefPaybackS3En_WIDTH 1 +#define D18F2x90_dct0_PendRefPaybackS3En_MASK 0x2000000 +#define D18F2x90_dct0_PendRefPaybackS3En_VALUE 0x1 +#define D18F2x90_dct0_Reserved_26_26_OFFSET 26 +#define D18F2x90_dct0_Reserved_26_26_WIDTH 1 +#define D18F2x90_dct0_Reserved_26_26_MASK 0x4000000 +#define D18F2x90_dct0_DisDllShutdownSR_OFFSET 27 +#define D18F2x90_dct0_DisDllShutdownSR_WIDTH 1 +#define D18F2x90_dct0_DisDllShutdownSR_MASK 0x8000000 +#define D18F2x90_dct0_IdleCycLimit_OFFSET 28 +#define D18F2x90_dct0_IdleCycLimit_WIDTH 4 +#define D18F2x90_dct0_IdleCycLimit_MASK 0xf0000000 +#define D18F2x90_dct0_IdleCycLimit_VALUE 0x8 + +/// D18F2x90_dct0 +typedef union { + struct { ///< + UINT32 ExitSelfRef:1 ; ///< + UINT32 Reserved_7_2:6 ; ///< + UINT32 Reserved_8_8:1 ; ///< + UINT32 Reserved_10_9:2 ; ///< + UINT32 Reserved_11_11:1 ; ///< + UINT32 Reserved_15_12:4 ; ///< + UINT32 UnbuffDimm:1 ; ///< + UINT32 EnterSelfRef:1 ; ///< + UINT32 PendRefPayback:1 ; ///< + UINT32 DimmEccEn:1 ; ///< + UINT32 DynPageCloseEn:1 ; ///< + UINT32 IdleCycLowLimit:2 ; ///< + UINT32 ForceAutoPchg:1 ; ///< + UINT32 StagRefEn:1 ; ///< + UINT32 PendRefPaybackS3En:1 ; ///< + UINT32 Reserved_26_26:1 ; ///< + UINT32 DisDllShutdownSR:1 ; ///< + UINT32 IdleCycLimit:4 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F2x90_dct0_STRUCT; + + +// **** D18F2x94_dct0 Register Definition **** +// Address +#define D18F2x94_dct0_ADDRESS 0x94 +// Type +#define D18F2x94_dct0_TYPE TYPE_D18F2_dct0 + +// Field Data +#define D18F2x94_dct0_MemClkFreq_OFFSET 0 +#define D18F2x94_dct0_MemClkFreq_WIDTH 5 +#define D18F2x94_dct0_MemClkFreq_MASK 0x1f +#define D18F2x94_dct0_Reserved_6_5_OFFSET 5 +#define D18F2x94_dct0_Reserved_6_5_WIDTH 2 +#define D18F2x94_dct0_Reserved_6_5_MASK 0x60 +#define D18F2x94_dct0_MemClkFreqVal_OFFSET 7 +#define D18F2x94_dct0_MemClkFreqVal_WIDTH 1 +#define D18F2x94_dct0_MemClkFreqVal_MASK 0x80 +#define D18F2x94_dct0_Reserved_9_8_OFFSET 8 +#define D18F2x94_dct0_Reserved_9_8_WIDTH 2 +#define D18F2x94_dct0_Reserved_9_8_MASK 0x300 +#define D18F2x94_dct0_ZqcsInterval_OFFSET 10 +#define D18F2x94_dct0_ZqcsInterval_WIDTH 2 +#define D18F2x94_dct0_ZqcsInterval_MASK 0xc00 +#define D18F2x94_dct0_RDqsEn_OFFSET 12 +#define D18F2x94_dct0_RDqsEn_WIDTH 1 +#define D18F2x94_dct0_RDqsEn_MASK 0x1000 +#define D18F2x94_dct0_Reserved_13_13_OFFSET 13 +#define D18F2x94_dct0_Reserved_13_13_WIDTH 1 +#define D18F2x94_dct0_Reserved_13_13_MASK 0x2000 +#define D18F2x94_dct0_DisDramInterface_OFFSET 14 +#define D18F2x94_dct0_DisDramInterface_WIDTH 1 +#define D18F2x94_dct0_DisDramInterface_MASK 0x4000 +#define D18F2x94_dct0_PowerDownEn_OFFSET 15 +#define D18F2x94_dct0_PowerDownEn_WIDTH 1 +#define D18F2x94_dct0_PowerDownEn_MASK 0x8000 +#define D18F2x94_dct0_PowerDownMode_OFFSET 16 +#define D18F2x94_dct0_PowerDownMode_WIDTH 1 +#define D18F2x94_dct0_PowerDownMode_MASK 0x10000 +#define D18F2x94_dct0_PowerDownMode_VALUE 0x1 +#define D18F2x94_dct0_Reserved_17_17_OFFSET 17 +#define D18F2x94_dct0_Reserved_17_17_WIDTH 1 +#define D18F2x94_dct0_Reserved_17_17_MASK 0x20000 +#define D18F2x94_dct0_Reserved_18_18_OFFSET 18 +#define D18F2x94_dct0_Reserved_18_18_WIDTH 1 +#define D18F2x94_dct0_Reserved_18_18_MASK 0x40000 +#define D18F2x94_dct0_Reserved_19_19_OFFSET 19 +#define D18F2x94_dct0_Reserved_19_19_WIDTH 1 +#define D18F2x94_dct0_Reserved_19_19_MASK 0x80000 +#define D18F2x94_dct0_SlowAccessMode_OFFSET 20 +#define D18F2x94_dct0_SlowAccessMode_WIDTH 1 +#define D18F2x94_dct0_SlowAccessMode_MASK 0x100000 +#define D18F2x94_dct0_FreqChgInProg_OFFSET 21 +#define D18F2x94_dct0_FreqChgInProg_WIDTH 1 +#define D18F2x94_dct0_FreqChgInProg_MASK 0x200000 +#define D18F2x94_dct0_BankSwizzleMode_OFFSET 22 +#define D18F2x94_dct0_BankSwizzleMode_WIDTH 1 +#define D18F2x94_dct0_BankSwizzleMode_MASK 0x400000 +#define D18F2x94_dct0_ProcOdtDis_OFFSET 23 +#define D18F2x94_dct0_ProcOdtDis_WIDTH 1 +#define D18F2x94_dct0_ProcOdtDis_MASK 0x800000 +#define D18F2x94_dct0_DcqBypassMax_OFFSET 24 +#define D18F2x94_dct0_DcqBypassMax_WIDTH 5 +#define D18F2x94_dct0_DcqBypassMax_MASK 0x1f000000 +#define D18F2x94_dct0_Reserved_30_29_OFFSET 29 +#define D18F2x94_dct0_Reserved_30_29_WIDTH 2 +#define D18F2x94_dct0_Reserved_30_29_MASK 0x60000000 +#define D18F2x94_dct0_DphyMemPsSelEn_OFFSET 31 +#define D18F2x94_dct0_DphyMemPsSelEn_WIDTH 1 +#define D18F2x94_dct0_DphyMemPsSelEn_MASK 0x80000000 +#define D18F2x94_dct0_DphyMemPsSelEn_VALUE 0x1 + +/// D18F2x94_dct0 +typedef union { + struct { ///< + UINT32 MemClkFreq:5 ; ///< + UINT32 Reserved_6_5:2 ; ///< + UINT32 MemClkFreqVal:1 ; ///< + UINT32 Reserved_9_8:2 ; ///< + UINT32 ZqcsInterval:2 ; ///< + UINT32 RDqsEn:1 ; ///< + UINT32 Reserved_13_13:1 ; ///< + UINT32 DisDramInterface:1 ; ///< + UINT32 PowerDownEn:1 ; ///< + UINT32 PowerDownMode:1 ; ///< + UINT32 Reserved_17_17:1 ; ///< + UINT32 Reserved_18_18:1 ; ///< + UINT32 Reserved_19_19:1 ; ///< + UINT32 SlowAccessMode:1 ; ///< + UINT32 FreqChgInProg:1 ; ///< + UINT32 BankSwizzleMode:1 ; ///< + UINT32 ProcOdtDis:1 ; ///< + UINT32 DcqBypassMax:5 ; ///< + UINT32 Reserved_30_29:2 ; ///< + UINT32 DphyMemPsSelEn:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F2x94_dct0_STRUCT; + +#define D18F2xA8_dct0_MemPhyPllPdMode_OFFSET 16 +#define D18F2xA8_dct0_MemPhyPllPdMode_WIDTH 2 + +// **** D18F2x2E0_dct0 Register Definition **** +// Address +#define D18F2x2E0_dct0_ADDRESS 0x2e0 + +// Type +#define D18F2x2E0_dct0_TYPE TYPE_D18F2 +// Field Data + +#define D18F2x2E0_dct0_M1MemClkFreq_OFFSET 24 +#define D18F2x2E0_dct0_M1MemClkFreq_WIDTH 5 + +/// D18F2x2E0_dct0 +typedef union { + struct { ///< + UINT32 Reserved_1:1 ; ///< + UINT32 Reserved_19_1:19; ///< + UINT32 Reserved_22_20:3 ; ///< + UINT32 Reserved_23_23:1 ; ///< + UINT32 M1MemClkFreq:5 ; ///< + UINT32 Reserved_29_29:1 ; ///< + UINT32 Reserved_30_30:1 ; ///< + UINT32 Reserved_31_31:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F2x2E0_dct0_STRUCT; + +// **** D18F4x110 Register Definition **** +// Address +#define D18F4x110_ADDRESS 0x110 + +// Type +#define D18F4x110_TYPE TYPE_D18F4 +// Field Data +#define D18F4x110_CSampleTimer_OFFSET 0 +#define D18F4x110_CSampleTimer_WIDTH 12 +#define D18F4x110_CSampleTimer_MASK 0xfff +#define D18F4x110_CSampleTimer_VALUE 0x2 +#define D18F4x110_FastCSampleTimer_OFFSET 12 +#define D18F4x110_FastCSampleTimer_WIDTH 1 +#define D18F4x110_FastCSampleTimer_MASK 0x1000 +#define D18F4x110_MinResTmr_OFFSET 13 +#define D18F4x110_MinResTmr_WIDTH 8 +#define D18F4x110_MinResTmr_MASK 0x1fe000 +#define D18F4x110_Reserved_31_21_OFFSET 21 +#define D18F4x110_Reserved_31_21_WIDTH 11 +#define D18F4x110_Reserved_31_21_MASK 0xffe00000 + +/// D18F4x110 +typedef union { + struct { ///< + UINT32 CSampleTimer:12; ///< + UINT32 FastCSampleTimer:1 ; ///< + UINT32 MinResTmr:8 ; ///< + UINT32 Reserved_31_21:11; ///< + } Field; ///< + UINT32 Value; ///< +} D18F4x110_STRUCT; + +// **** D18F5xE0 Register Definition **** +// Address +#define D18F5xE0_ADDRESS 0xe0 + +// Type +#define D18F5xE0_TYPE TYPE_D18F5 +// Field Data +#define D18F5xE0_RunAvgRange_OFFSET 0 +#define D18F5xE0_RunAvgRange_WIDTH 4 +#define D18F5xE0_RunAvgRange_MASK 0xf +#define D18F5xE0_RunAvgRange_VALUE 0x2 +#define D18F5xE0_Reserved_31_4_OFFSET 4 +#define D18F5xE0_Reserved_31_4_WIDTH 28 +#define D18F5xE0_Reserved_31_4_MASK 0xfffffff0 + +/// D18F5xE0 +typedef union { + struct { ///< + UINT32 RunAvgRange:4 ; ///< + UINT32 Reserved_31_4:28 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F5xE0_STRUCT; + +// **** D18F5x160 Register Definition **** +// Address +#define D18F5x160_ADDRESS 0x160 + +// Type +#define D18F5x160_TYPE TYPE_D18F5 +#define D18F5x160_NbPstateEn_OFFSET 0 +#define D18F5x160_NbPstateEn_WIDTH 1 + +#define D18F5x160_MemPstate_OFFSET 18 +#define D18F5x160_MemPstate_WIDTH 1 +#define D18F5x160_NbFid_OFFSET 1 +#define D18F5x160_NbFid_WIDTH 6 +#define D18F5x160_NbDid_OFFSET 7 +#define D18F5x160_NbDid_WIDTH 1 +#define D18F5x160_NbVid_6_0_OFFSET 10 +#define D18F5x160_NbVid_6_0_WIDTH 7 +#define D18F5x160_NbVid_7_OFFSET 21 +#define D18F5x160_NbVid_7_WIDTH 1 + +#define D18F5x160_NbVid_7__OFFSET 21 +#define D18F5x160_NbVid_7__WIDTH 1 + +/// D18F5x160 +typedef union { + struct { ///< + UINT32 NbPstateEn:1 ; ///< + UINT32 NbFid:6 ; ///< + UINT32 NbDid:1 ; ///< + UINT32 Reserved_9_8:2 ; ///< + UINT32 NbVid_6_0_:7 ; ///< + UINT32 Reserved_17_17:1 ; ///< + UINT32 MemPstate:1 ; ///< + UINT32 Reserved_20_19:2 ; ///< + UINT32 NbVid_7_:1 ; ///< + UINT32 Reserved_23_22:2 ; ///< + UINT32 Reserved_31_24:8 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F5x160_STRUCT; + +// **** D18F5x164 Register Definition **** +// Address +#define D18F5x164_ADDRESS 0x164 + +// Type +#define D18F5x164_TYPE TYPE_D18F5 +#define D18F5x164_NbPstateEn_OFFSET 0 +#define D18F5x164_NbPstateEn_WIDTH 1 +#define D18F5x164_MemPstate_OFFSET 18 +#define D18F5x164_MemPstate_WIDTH 1 +#define D18F5x164_NbFid_OFFSET 1 +#define D18F5x164_NbFid_WIDTH 6 +#define D18F5x164_NbDid_OFFSET 7 +#define D18F5x164_NbDid_WIDTH 1 +#define D18F5x164_NbVid_6_0_OFFSET 10 +#define D18F5x164_NbVid_6_0_WIDTH 7 +#define D18F5x164_NbVid_7_OFFSET 21 +#define D18F5x164_NbVid_7_WIDTH 1 + +// **** D18F5x168 Register Definition **** +// Address +#define D18F5x168_ADDRESS 0x168 + +// Type +#define D18F5x168_TYPE TYPE_D18F5 +#define D18F5x168_NbPstateEn_OFFSET 0 +#define D18F5x168_NbPstateEn_WIDTH 1 +#define D18F5x168_NbFid_OFFSET 1 +#define D18F5x168_NbFid_WIDTH 6 +#define D18F5x168_NbDid_OFFSET 7 +#define D18F5x168_NbDid_WIDTH 1 +#define D18F5x168_NbVid_6_0_OFFSET 10 +#define D18F5x168_NbVid_6_0_WIDTH 7 +#define D18F5x168_MemPstate_OFFSET 18 +#define D18F5x168_MemPstate_WIDTH 1 +#define D18F5x168_NbVid_7_OFFSET 21 +#define D18F5x168_NbVid_7_WIDTH 1 + +// **** D18F5x16C Register Definition **** +// Address +#define D18F5x16C_ADDRESS 0x16c + +// Type +#define D18F5x16C_TYPE TYPE_D18F5 +#define D18F5x16C_NbPstateEn_OFFSET 0 +#define D18F5x16C_NbPstateEn_WIDTH 1 +#define D18F5x16C_NbFid_OFFSET 1 +#define D18F5x16C_NbFid_WIDTH 6 +#define D18F5x16C_NbDid_OFFSET 7 +#define D18F5x16C_NbDid_WIDTH 1 +#define D18F5x16C_NbVid_6_0_OFFSET 10 +#define D18F5x16C_NbVid_6_0_WIDTH 7 +#define D18F5x16C_MemPstate_OFFSET 18 +#define D18F5x16C_MemPstate_WIDTH 1 +#define D18F5x16C_NbVid_7_OFFSET 21 +#define D18F5x16C_NbVid_7_WIDTH 1 + +// **** D18F5x170 Register Definition **** +// Address +#define D18F5x170_ADDRESS 0x170 + +// Type +#define D18F5x170_TYPE TYPE_D18F5 +// Field Data +#define D18F5x170_NbPstateMaxVal_OFFSET 0 +#define D18F5x170_NbPstateMaxVal_WIDTH 2 +#define D18F5x170_NbPstateMaxVal_MASK 0x3 +#define D18F5x170_Reserved_2_2_OFFSET 2 +#define D18F5x170_Reserved_2_2_WIDTH 1 +#define D18F5x170_Reserved_2_2_MASK 0x4 +#define D18F5x170_NbPstateLo_OFFSET 3 +#define D18F5x170_NbPstateLo_WIDTH 2 +#define D18F5x170_NbPstateLo_MASK 0x18 +#define D18F5x170_Reserved_5_5_OFFSET 5 +#define D18F5x170_Reserved_5_5_WIDTH 1 +#define D18F5x170_Reserved_5_5_MASK 0x20 +#define D18F5x170_NbPstateHi_OFFSET 6 +#define D18F5x170_NbPstateHi_WIDTH 2 +#define D18F5x170_NbPstateHi_MASK 0xc0 +#define D18F5x170_Reserved_8_8_OFFSET 8 +#define D18F5x170_Reserved_8_8_WIDTH 1 +#define D18F5x170_Reserved_8_8_MASK 0x100 +#define D18F5x170_NbPstateThreshold_OFFSET 9 +#define D18F5x170_NbPstateThreshold_WIDTH 4 +#define D18F5x170_NbPstateThreshold_MASK 0x1e00 +#define D18F5x170_Reserved_12_12_OFFSET 12 +#define D18F5x170_Reserved_12_12_WIDTH 1 +#define D18F5x170_Reserved_12_12_MASK 0x1000 +#define D18F5x170_NbPstateDisOnP0_OFFSET 13 +#define D18F5x170_NbPstateDisOnP0_WIDTH 1 +#define D18F5x170_NbPstateDisOnP0_MASK 0x2000 +#define D18F5x170_SwNbPstateLoDis_OFFSET 14 +#define D18F5x170_SwNbPstateLoDis_WIDTH 1 +#define D18F5x170_SwNbPstateLoDis_MASK 0x4000 +#define D18F5x170_Reserved_22_15_OFFSET 15 +#define D18F5x170_Reserved_22_15_WIDTH 8 +#define D18F5x170_Reserved_22_15_MASK 0x3f8000 +#define D18F5x170_NbPstateGnbSlowDis_OFFSET 23 +#define D18F5x170_NbPstateGnbSlowDis_WIDTH 1 +#define D18F5x170_NbPstateGnbSlowDis_MASK 0x800000 +#define D18F5x170_NbPstateLoRes_OFFSET 24 +#define D18F5x170_NbPstateLoRes_WIDTH 3 +#define D18F5x170_NbPstateLoRes_MASK 0x7000000 +#define D18F5x170_NbPstateHiRes_OFFSET 27 +#define D18F5x170_NbPstateHiRes_WIDTH 3 +#define D18F5x170_NbPstateHiRes_MASK 0x38000000 +#define D18F5x170_NbPstateFidVidSbcEn_OFFSET 30 +#define D18F5x170_NbPstateFidVidSbcEn_WIDTH 1 +#define D18F5x170_NbPstateFidVidSbcEn_MASK 0x40000000 +#define D18F5x170_MemPstateDis_OFFSET 31 +#define D18F5x170_MemPstateDis_WIDTH 1 +#define D18F5x170_MemPstateDis_MASK 0x80000000 + +/// D18F5x170 +typedef union { + struct { ///< + UINT32 NbPstateMaxVal:2 ; ///< + UINT32 Reserved_2_2:1 ; ///< + UINT32 NbPstateLo:2 ; ///< + UINT32 Reserved_5_5:1 ; ///< + UINT32 NbPstateHi:2 ; ///< + UINT32 Reserved_8_8:1 ; ///< + UINT32 NbPstateThreshold:4 ; ///< + UINT32 NbPstateDisOnP0:1 ; ///< + UINT32 SwNbPstateLoDis:1 ; ///< + UINT32 Reserved_22_15:8 ; ///< + UINT32 NbPstateGnbSlowDis:1 ; ///< + UINT32 NbPstateLoRes:3 ; ///< + UINT32 NbPstateHiRes:3 ; ///< + UINT32 NbPstateFidVidSbcEn:1 ; ///< + UINT32 MemPstateDis:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F5x170_STRUCT; + +// **** D18F2x118 Register Definition **** +// Address +#define D18F2x118_ADDRESS 0x118 +// Type +#define D18F2x118_TYPE TYPE_D18F2 + +// Field Data +#define D18F2x118_MctPriCpuRd_OFFSET 0 +#define D18F2x118_MctPriCpuRd_WIDTH 2 +#define D18F2x118_MctPriCpuRd_MASK 0x3 +#define D18F2x118_MctPriCpuWr_OFFSET 2 +#define D18F2x118_MctPriCpuWr_WIDTH 2 +#define D18F2x118_MctPriCpuWr_MASK 0xC +#define D18F2x118_MctPriIsocRd_OFFSET 4 +#define D18F2x118_MctPriIsocRd_WIDTH 2 +#define D18F2x118_MctPriIsocRd_MASK 0x30 +#define D18F2x118_MctPriIsocWr_OFFSET 6 +#define D18F2x118_MctPriIsocWr_WIDTH 2 +#define D18F2x118_MctPriIsocWr_MASK 0xC0 +#define D18F2x118_MctPriDefault_OFFSET 8 +#define D18F2x118_MctPriDefault_WIDTH 2 +#define D18F2x118_MctPriDefault_MASK 0x300 +#define D18F2x118_MctPriWr_OFFSET 10 +#define D18F2x118_MctPriWr_WIDTH 2 +#define D18F2x118_MctPriWr_MASK 0xC00 +#define D18F2x118_MctPriIsoc_OFFSET 12 +#define D18F2x118_MctPriIsoc_WIDTH 2 +#define D18F2x118_MctPriIsoc_MASK 0x3000 +#define D18F2x118_MctPriTrace_OFFSET 14 +#define D18F2x118_MctPriTrace_WIDTH 2 +#define D18F2x118_MctPriTrace_MASK 0xC000 +#define D18F2x118_MctPriScrub_OFFSET 16 +#define D18F2x118_MctPriScrub_WIDTH 2 +#define D18F2x118_MctPriScrub_MASK 0x30000 +#define D18F2x118_CC6SaveEn_OFFSET 18 +#define D18F2x118_CC6SaveEn_WIDTH 1 +#define D18F2x118_CC6SaveEn_MASK 0x40000 +#define D18F2x118_LockDramCfg_OFFSET 19 +#define D18F2x118_LockDramCfg_WIDTH 1 +#define D18F2x118_LockDramCfg_MASK 0x80000 +#define D18F2x118_McqMedPriByPassMax_OFFSET 20 +#define D18F2x118_McqMedPriByPassMax_WIDTH 3 +#define D18F2x118_McqMedPriByPassMax_MASK 0x700000 +#define D18F2x118_Reserved_23_23_OFFSET 23 +#define D18F2x118_Reserved_23_23_WIDTH 1 +#define D18F2x118_Reserved_23_23_MASK 0x800000 +#define D18F2x118_McqHiPriByPassMax_OFFSET 24 +#define D18F2x118_McqHiPriByPassMax_WIDTH 3 +#define D18F2x118_McqHiPriByPassMax_MASK 0x7000000 +#define D18F2x118_Reserved_27_27_OFFSET 27 +#define D18F2x118_Reserved_27_27_WIDTH 1 +#define D18F2x118_Reserved_27_27_MASK 0x8000000 +#define D18F2x118_MctVarPriCntLmt_OFFSET 28 +#define D18F2x118_MctVarPriCntLmt_WIDTH 4 +#define D18F2x118_MctVarPriCntLmt_MASK 0xF0000000 + +/// D18F2x118 +typedef union { + struct { ///< + UINT32 MctPriCpuRd:2; ///< + UINT32 MctPriCpuWr:2; ///< + UINT32 MctPriIsocRd:2; ///< + UINT32 MctPriIsocWr:2; ///< + UINT32 MctPriDefault:2; ///< + UINT32 MctPriWr:2; ///< + UINT32 MctPriIsoc:2; ///< + UINT32 MctPriTrace:2; ///< + UINT32 MctPriScrub:2; ///< + UINT32 CC6SaveEn:1; ///< + UINT32 LockDramCfg:1; ///< + UINT32 McqMedPriByPassMax:3; ///< + UINT32 Reserved_23_23:1; ///< + UINT32 McqHiPriByPassMax:3; ///< + UINT32 Reserved_27_27:1; ///< + UINT32 MctVarPriCntLmt:4; ///< + + } Field; + + UINT32 Value; +} D18F2x118_STRUCT; + + +// **** D18F3x44 Register Definition **** +// Address +#define D18F3x44_ADDRESS 0x44 + +// Type +#define D18F3x44_TYPE TYPE_D18F3 +// Field Data +#define D18F3x44_Reserved_0_0_OFFSET 0 +#define D18F3x44_Reserved_0_0_WIDTH 1 +#define D18F3x44_Reserved_0_0_MASK 0x1 +#define D18F3x44_CpuRdDatErrEn_OFFSET 1 +#define D18F3x44_CpuRdDatErrEn_WIDTH 1 +#define D18F3x44_CpuRdDatErrEn_MASK 0x2 +#define D18F3x44_SyncFloodOnDramUcEcc_OFFSET 2 +#define D18F3x44_SyncFloodOnDramUcEcc_WIDTH 1 +#define D18F3x44_SyncFloodOnDramUcEcc_MASK 0x4 +#define D18F3x44_SyncFloodOnDramUcEcc_VALUE 0x1 +#define D18F3x44_SyncPktGenDis_OFFSET 3 +#define D18F3x44_SyncPktGenDis_WIDTH 1 +#define D18F3x44_SyncPktGenDis_MASK 0x8 +#define D18F3x44_SyncPktGenDis_VALUE 0x0 +#define D18F3x44_SyncPktPropDis_OFFSET 4 +#define D18F3x44_SyncPktPropDis_WIDTH 1 +#define D18F3x44_SyncPktPropDis_MASK 0x10 +#define D18F3x44_SyncPktPropDis_VALUE 0x0 +#define D18F3x44_IoMstAbortDis_OFFSET 5 +#define D18F3x44_IoMstAbortDis_WIDTH 1 +#define D18F3x44_IoMstAbortDis_MASK 0x20 +#define D18F3x44_CpuErrDis_OFFSET 6 +#define D18F3x44_CpuErrDis_WIDTH 1 +#define D18F3x44_CpuErrDis_MASK 0x40 +#define D18F3x44_CpuErrDis_VALUE 0x1 +#define D18F3x44_IoErrDis_OFFSET 7 +#define D18F3x44_IoErrDis_WIDTH 1 +#define D18F3x44_IoErrDis_MASK 0x80 +#define D18F3x44_WDTDis_OFFSET 8 +#define D18F3x44_WDTDis_WIDTH 1 +#define D18F3x44_WDTDis_MASK 0x100 +#define D18F3x44_WDTCntSel_2_0__OFFSET 9 +#define D18F3x44_WDTCntSel_2_0__WIDTH 3 +#define D18F3x44_WDTCntSel_2_0__MASK 0xe00 +#define D18F3x44_WDTBaseSel_OFFSET 12 +#define D18F3x44_WDTBaseSel_WIDTH 2 +#define D18F3x44_WDTBaseSel_MASK 0x3000 +#define D18F3x44_GenLinkSel_OFFSET 14 +#define D18F3x44_GenLinkSel_WIDTH 2 +#define D18F3x44_GenLinkSel_MASK 0xc000 +#define D18F3x44_GenCrcErrByte0_OFFSET 16 +#define D18F3x44_GenCrcErrByte0_WIDTH 1 +#define D18F3x44_GenCrcErrByte0_MASK 0x10000 +#define D18F3x44_GenCrcErrByte1_OFFSET 17 +#define D18F3x44_GenCrcErrByte1_WIDTH 1 +#define D18F3x44_GenCrcErrByte1_MASK 0x20000 +#define D18F3x44_GenSubLinkSel_OFFSET 18 +#define D18F3x44_GenSubLinkSel_WIDTH 2 +#define D18F3x44_GenSubLinkSel_MASK 0xc0000 +#define D18F3x44_SyncFloodOnWDT_OFFSET 20 +#define D18F3x44_SyncFloodOnWDT_WIDTH 1 +#define D18F3x44_SyncFloodOnWDT_MASK 0x100000 +#define D18F3x44_SyncFloodOnWDT_VALUE 0x1 +#define D18F3x44_SyncFloodOnAnyUcErr_OFFSET 21 +#define D18F3x44_SyncFloodOnAnyUcErr_WIDTH 1 +#define D18F3x44_SyncFloodOnAnyUcErr_MASK 0x200000 +#define D18F3x44_SyncFloodOnAnyUcErr_VALUE 0x1 +#define D18F3x44_DramEccEn_OFFSET 22 +#define D18F3x44_DramEccEn_WIDTH 1 +#define D18F3x44_DramEccEn_MASK 0x400000 +#define D18F3x44_ChipKillEccCap_OFFSET 23 +#define D18F3x44_ChipKillEccCap_WIDTH 1 +#define D18F3x44_ChipKillEccCap_MASK 0x800000 +#define D18F3x44_IoRdDatErrEn_OFFSET 24 +#define D18F3x44_IoRdDatErrEn_WIDTH 1 +#define D18F3x44_IoRdDatErrEn_MASK 0x1000000 +#define D18F3x44_DisPciCfgCpuErrRsp_OFFSET 25 +#define D18F3x44_DisPciCfgCpuErrRsp_WIDTH 1 +#define D18F3x44_DisPciCfgCpuErrRsp_MASK 0x2000000 +#define D18F3x44_FlagMcaCorrErr_OFFSET 26 +#define D18F3x44_FlagMcaCorrErr_WIDTH 1 +#define D18F3x44_FlagMcaCorrErr_MASK 0x4000000 +#define D18F3x44_NbMcaToMstCpuEn_OFFSET 27 +#define D18F3x44_NbMcaToMstCpuEn_WIDTH 1 +#define D18F3x44_NbMcaToMstCpuEn_MASK 0x8000000 +#define D18F3x44_NbMcaToMstCpuEn_VALUE 0x1 +#define D18F3x44_DisTgtAbortCpuErrRsp_OFFSET 28 +#define D18F3x44_DisTgtAbortCpuErrRsp_WIDTH 1 +#define D18F3x44_DisTgtAbortCpuErrRsp_MASK 0x10000000 +#define D18F3x44_DisMstAbortCpuErrRsp_OFFSET 29 +#define D18F3x44_DisMstAbortCpuErrRsp_WIDTH 1 +#define D18F3x44_DisMstAbortCpuErrRsp_MASK 0x20000000 +#define D18F3x44_SyncFloodOnDramAdrParErr_OFFSET 30 +#define D18F3x44_SyncFloodOnDramAdrParErr_WIDTH 1 +#define D18F3x44_SyncFloodOnDramAdrParErr_MASK 0x40000000 +#define D18F3x44_SyncFloodOnDramAdrParErr_VALUE 0x1 +#define D18F3x44_NbMcaLogEn_OFFSET 31 +#define D18F3x44_NbMcaLogEn_WIDTH 1 +#define D18F3x44_NbMcaLogEn_MASK 0x80000000 + +/// D18F3x44 +typedef union { + struct { ///< + UINT32 Reserved_0_0:1 ; ///< + UINT32 CpuRdDatErrEn:1 ; ///< + UINT32 SyncFloodOnDramUcEcc:1 ; ///< + UINT32 SyncPktGenDis:1 ; ///< + UINT32 SyncPktPropDis:1 ; ///< + UINT32 IoMstAbortDis:1 ; ///< + UINT32 CpuErrDis:1 ; ///< + UINT32 IoErrDis:1 ; ///< + UINT32 WDTDis:1 ; ///< + UINT32 WDTCntSel_2_0_:3 ; ///< + UINT32 WDTBaseSel:2 ; ///< + UINT32 GenLinkSel:2 ; ///< + UINT32 GenCrcErrByte0:1 ; ///< + UINT32 GenCrcErrByte1:1 ; ///< + UINT32 GenSubLinkSel:2 ; ///< + UINT32 SyncFloodOnWDT:1 ; ///< + UINT32 SyncFloodOnAnyUcErr:1 ; ///< + UINT32 DramEccEn:1 ; ///< + UINT32 ChipKillEccCap:1 ; ///< + UINT32 IoRdDatErrEn:1 ; ///< + UINT32 DisPciCfgCpuErrRsp:1 ; ///< + UINT32 FlagMcaCorrErr:1 ; ///< + UINT32 NbMcaToMstCpuEn:1 ; ///< + UINT32 DisTgtAbortCpuErrRsp:1 ; ///< + UINT32 DisMstAbortCpuErrRsp:1 ; ///< + UINT32 SyncFloodOnDramAdrParErr:1 ; ///< + UINT32 NbMcaLogEn:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F3x44_STRUCT; + +// **** D18F3x64 Register Definition **** +// Address +#define D18F3x64_ADDRESS 0x64 + +// Type +#define D18F3x64_TYPE TYPE_D18F3 +// Field Data +#define D18F3x64_HtcEn_OFFSET 0 +#define D18F3x64_HtcEn_WIDTH 1 +#define D18F3x64_HtcEn_MASK 0x1 +#define D18F3x64_HtcEn_VALUE 0x0 +#define D18F3x64_HtcAct_OFFSET 4 +#define D18F3x64_HtcAct_WIDTH 1 +#define D18F3x64_HtcAct_MASK 0x10 +#define D18F3x64_HtcActSts_OFFSET 5 +#define D18F3x64_HtcActSts_WIDTH 1 +#define D18F3x64_HtcActSts_MASK 0x20 +#define D18F3x64_PslApicHiEn_OFFSET 6 +#define D18F3x64_PslApicHiEn_WIDTH 1 +#define D18F3x64_PslApicHiEn_MASK 0x40 +#define D18F3x64_PslApicLoEn_OFFSET 7 +#define D18F3x64_PslApicLoEn_WIDTH 1 +#define D18F3x64_PslApicLoEn_MASK 0x80 +#define D18F3x64_HtcTmpLmt_OFFSET 16 +#define D18F3x64_HtcTmpLmt_WIDTH 7 +#define D18F3x64_HtcTmpLmt_MASK 0x7f0000 +#define D18F3x64_HtcSlewSel_OFFSET 23 +#define D18F3x64_HtcSlewSel_WIDTH 1 +#define D18F3x64_HtcSlewSel_MASK 0x800000 +#define D18F3x64_HtcHystLmt_OFFSET 24 +#define D18F3x64_HtcHystLmt_WIDTH 4 +#define D18F3x64_HtcHystLmt_MASK 0xf000000 +#define D18F3x64_HtcPstateLimit_OFFSET 28 +#define D18F3x64_HtcPstateLimit_WIDTH 3 +#define D18F3x64_HtcPstateLimit_MASK 0x70000000 +#define D18F3x64_Reserved_31_31_OFFSET 31 +#define D18F3x64_Reserved_31_31_WIDTH 1 +#define D18F3x64_Reserved_31_31_MASK 0x80000000 + +/// D18F3x64 +typedef union { + struct { ///< + UINT32 HtcEn:1 ; ///< + UINT32 bit1:1; + UINT32 bit2:1; + UINT32 Reserved_3_3:1 ; ///< + UINT32 HtcAct:1 ; ///< + UINT32 HtcActSts:1 ; ///< + UINT32 PslApicHiEn:1 ; ///< + UINT32 PslApicLoEn:1 ; ///< + UINT32 bit10_8:3; + UINT32 Reserved_11_11:1 ; ///< + UINT32 bit14_12:3 ; + UINT32 Reserved_15_15:1 ; ///< + UINT32 HtcTmpLmt:7 ; ///< + UINT32 HtcSlewSel:1 ; ///< + UINT32 HtcHystLmt:4 ; ///< + UINT32 HtcPstateLimit:3 ; ///< + UINT32 Reserved_31_31:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F3x64_STRUCT; + + +// **** D18F3xA0 Register Definition **** +// Address +#define D18F3xA0_ADDRESS 0xa0 + +// Type +#define D18F3xA0_TYPE TYPE_D18F3 +// Field Data +#define D18F3xA0_PsiVid_6_0__OFFSET 0 +#define D18F3xA0_PsiVid_6_0__WIDTH 7 +#define D18F3xA0_PsiVid_6_0__MASK 0x7f +#define D18F3xA0_PsiVidEn_OFFSET 7 +#define D18F3xA0_PsiVidEn_WIDTH 1 +#define D18F3xA0_PsiVidEn_MASK 0x80 +#define D18F3xA0_PsiVid_7__OFFSET 8 +#define D18F3xA0_PsiVid_7__WIDTH 1 +#define D18F3xA0_PsiVid_7__MASK 0x100 +#define D18F3xA0_Reserved_9_9_OFFSET 9 +#define D18F3xA0_Reserved_9_9_WIDTH 1 +#define D18F3xA0_Reserved_9_9_MASK 0x200 +#define D18F3xA0_IdleExitEn_OFFSET 10 +#define D18F3xA0_IdleExitEn_WIDTH 1 +#define D18F3xA0_IdleExitEn_MASK 0x400 +#define D18F3xA0_PllLockTime_OFFSET 11 +#define D18F3xA0_PllLockTime_WIDTH 3 +#define D18F3xA0_PllLockTime_MASK 0x3800 +#define D18F3xA0_PllLockTime_VALUE 0x1 +#define D18F3xA0_Svi2HighFreqSel_OFFSET 14 +#define D18F3xA0_Svi2HighFreqSel_WIDTH 1 +#define D18F3xA0_Svi2HighFreqSel_MASK 0x4000 +#define D18F3xA0_Svi2HighFreqSel_VALUE 0x1 +#define D18F3xA0_ConfigId_OFFSET 16 +#define D18F3xA0_ConfigId_WIDTH 12 +#define D18F3xA0_ConfigId_MASK 0xfff0000 +#define D18F3xA0_Reserved_29_29_OFFSET 29 +#define D18F3xA0_Reserved_29_29_WIDTH 1 +#define D18F3xA0_Reserved_29_29_MASK 0x20000000 +#define D18F3xA0_CofVidProg_OFFSET 31 +#define D18F3xA0_CofVidProg_WIDTH 1 +#define D18F3xA0_CofVidProg_MASK 0x80000000 + +/// D18F3xA0 +typedef union { + struct { ///< + UINT32 PsiVid_6_0_:7 ; ///< + UINT32 PsiVidEn:1 ; ///< + UINT32 PsiVid_7_:1 ; ///< + UINT32 Reserved_9_9:1 ; ///< + UINT32 IdleExitEn:1 ; ///< + UINT32 PllLockTime:3 ; ///< + UINT32 Svi2HighFreqSel:1 ; ///< + UINT32 :1 ; ///< + UINT32 ConfigId:12; ///< + UINT32 :1 ; ///< + UINT32 Reserved_29_29:1 ; ///< + UINT32 :1 ; ///< + UINT32 CofVidProg:1 ; ///< + } Field; ///< + UINT32 Value; ///< +} D18F3xA0_STRUCT; + + +// **** D18F3xA8 Register Definition **** +// Address +#define D18F3xA8_ADDRESS 0xA8 +// Type +#define D18F3xA8_TYPE TYPE_D18F3 + +// Field Data +#define D18F3xA8_Reserved_28_0_OFFSET 0 +#define D18F3xA8_Reserved_28_0_WIDTH 29 +#define D18F3xA8_Reserved_28_0_MASK 0x1FFFFFFF +#define D18F3xA8_PopDownPstate_OFFSET 29 +#define D18F3xA8_PopDownPstate_WIDTH 3 +#define D18F3xA8_PopDownPstate_MASK 0xE0000000 + +/// D18F3xA8 +typedef union { + struct { ///< + UINT32 Reserved_28_0:29; ///< + UINT32 PopDownPstate:3; ///< + + } Field; + + UINT32 Value; +} D18F3xA8_STRUCT; + +// **** D18F5x12C Register Definition **** +// Address +#define D18F5x12C_ADDRESS 0x12C +// Type +#define D18F5x12C_TYPE TYPE_D18F5 + +// Field Data +#define D18F5x12C_CoreOffsetTrim_OFFSET 0 +#define D18F5x12C_CoreOffsetTrim_WIDTH 2 +#define D18F5x12C_CoreOffsetTrim_MASK 0x3 +#define D18F5x12C_CoreLoadLineTrim_OFFSET 2 +#define D18F5x12C_CoreLoadLineTrim_WIDTH 3 +#define D18F5x12C_CoreLoadLineTrim_MASK 0x1C +#define D18F5x12C_CorePsi1En_OFFSET 5 +#define D18F5x12C_CorePsi1En_WIDTH 1 +#define D18F5x12C_CorePsi1En_MASK 0x20 +#define D18F5x12C_RAZ_29_7_OFFSET 7 +#define D18F5x12C_RAZ_29_7_WIDTH 23 +#define D18F5x12C_RAZ_29_7_MASK 0x3FFFFF80 +#define D18F5x12C_WaitVidCompDis_OFFSET 30 +#define D18F5x12C_WaitVidCompDis_WIDTH 1 +#define D18F5x12C_WaitVidCompDis_MASK 0x40000000 +#define D18F5x12C_Svi2CmdBusy_OFFSET 31 +#define D18F5x12C_Svi2CmdBusy_WIDTH 1 +#define D18F5x12C_Svi2CmdBusy_MASK 0x80000000 + +/// D18F5x12C +typedef union { + struct { ///< + UINT32 CoreOffsetTrim:2; ///< + UINT32 CoreLoadLineTrim:3; ///< + UINT32 CorePsi1En:1; ///< + UINT32 :1; ///< + UINT32 RAZ_29_7:23; ///< + UINT32 WaitVidCompDis:1; ///< + UINT32 Svi2CmdBusy:1; ///< + + } Field; + + UINT32 Value; +} D18F5x12C_STRUCT; + +// **** D18F5x178 Register Definition **** +// Address +#define D18F5x178_ADDRESS 0x178 +// Type +#define D18F5x178_TYPE TYPE_D18F5 + +// Field Data +#define D18F5x178_Reserved_1_0_OFFSET 0 +#define D18F5x178_Reserved_1_0_WIDTH 2 +#define D18F5x178_Reserved_1_0_MASK 0x3 +#define D18F5x178_CstateFusionDis_OFFSET 2 +#define D18F5x178_CstateFusionDis_WIDTH 1 +#define D18F5x178_CstateFusionDis_MASK 0x4 +#define D18F5x178_CstateThreeWayHsEn_OFFSET 3 +#define D18F5x178_CstateThreeWayHsEn_WIDTH 1 +#define D18F5x178_CstateThreeWayHsEn_MASK 0x8 +#define D18F5x178_Reserved_17_4_OFFSET 4 +#define D18F5x178_Reserved_17_4_WIDTH 14 +#define D18F5x178_Reserved_17_4_MASK 0x3FFF0 +#define D18F5x178_CstateFusionHsDis_OFFSET 18 +#define D18F5x178_CstateFusionHsDis_WIDTH 1 +#define D18F5x178_CstateFusionHsDis_MASK 0x40000 +#define D18F5x178_SwGfxDis_OFFSET 19 +#define D18F5x178_SwGfxDis_WIDTH 1 +#define D18F5x178_SwGfxDis_MASK 0x80000 +#define D18F5x178_Reserved_31_20_OFFSET 20 +#define D18F5x178_Reserved_31_20_WIDTH 12 +#define D18F5x178_Reserved_31_20_MASK 0xFFF00000 + +/// D18F5x178 +typedef union { + struct { ///< + UINT32 Reserved_1_0:2; ///< + UINT32 CstateFusionDis:1; ///< + UINT32 CstateThreeWayHsEn:1; ///< + UINT32 Reserved_17_4:14; ///< + UINT32 CstateFusionHsDis:1; ///< + UINT32 SwGfxDis:1; ///< + UINT32 Reserved_31_20:12; ///< + + } Field; + + UINT32 Value; +} D18F5x178_STRUCT; + +// **** D18F5x188 Register Definition **** +// Address +#define D18F5x188_ADDRESS 0x188 +// Type +#define D18F5x188_TYPE TYPE_D18F5 + +// Field Data +#define D18F5x188_NbOffsetTrim_OFFSET 0 +#define D18F5x188_NbOffsetTrim_WIDTH 2 +#define D18F5x188_NbOffsetTrim_MASK 0x3 +#define D18F5x188_NbLoadLineTrim_OFFSET 2 +#define D18F5x188_NbLoadLineTrim_WIDTH 3 +#define D18F5x188_NbLoadLineTrim_MASK 0x1C +#define D18F5x188_NbPsi1_OFFSET 5 +#define D18F5x188_NbPsi1_WIDTH 1 +#define D18F5x188_NbPsi1_MASK 0x20 +#define D18F5x188_RAZ_31_7_OFFSET 7 +#define D18F5x188_RAZ_31_7_WIDTH 25 +#define D18F5x188_RAZ_31_7_MASK 0xFFFFFF80 + +/// D18F5x188 +typedef union { + struct { ///< + UINT32 NbOffsetTrim:2; ///< + UINT32 NbLoadLineTrim:3; ///< + UINT32 NbPsi1:1; ///< + UINT32 :1; ///< + UINT32 RAZ_31_7:25; ///< + + } Field; + + UINT32 Value; +} D18F5x188_STRUCT; + +// **** D0F0x04 Register Definition **** +// Address +#define D0F0x04_ADDRESS 0x4 +// Type +#define D0F0x04_TYPE TYPE_D0F0 + +// Field Data +#define D0F0x04_IoAccessEn_OFFSET 0 +#define D0F0x04_IoAccessEn_WIDTH 1 +#define D0F0x04_IoAccessEn_MASK 0x1 +#define D0F0x04_MemAccessEn_OFFSET 1 +#define D0F0x04_MemAccessEn_WIDTH 1 +#define D0F0x04_MemAccessEn_MASK 0x2 +#define D0F0x04_BusMasterEn_OFFSET 2 +#define D0F0x04_BusMasterEn_WIDTH 1 +#define D0F0x04_BusMasterEn_MASK 0x4 +#define D0F0x04_Reserved_19_3_OFFSET 3 +#define D0F0x04_Reserved_19_3_WIDTH 17 +#define D0F0x04_Reserved_19_3_MASK 0xFFFF8 +#define D0F0x04_CapList_OFFSET 20 +#define D0F0x04_CapList_WIDTH 1 +#define D0F0x04_CapList_MASK 0x100000 +#define D0F0x04_Reserved_31_21_OFFSET 21 +#define D0F0x04_Reserved_31_21_WIDTH 11 +#define D0F0x04_Reserved_31_21_MASK 0xFFE00000 + +/// D0F0x04 +typedef union { + struct { ///< + UINT32 IoAccessEn:1; ///< + UINT32 MemAccessEn:1; ///< + UINT32 BusMasterEn:1; ///< + UINT32 Reserved_19_3:17; ///< + UINT32 CapList:1; ///< + UINT32 Reserved_31_21:11; ///< + + } Field; + + UINT32 Value; +} D0F0x04_STRUCT; + +// **** D0F0x64 Register Definition **** +// Address +#define D0F0x64_ADDRESS 0x64 +// Type +#define D0F0x64_TYPE TYPE_D0F0 + +// Field Data +#define D0F0x64_MiscIndData_OFFSET 0 +#define D0F0x64_MiscIndData_WIDTH 32 +#define D0F0x64_MiscIndData_MASK 0xFFFFFFFF + +/// D0F0x64 +typedef union { + struct { ///< + UINT32 MiscIndData:32; ///< + + } Field; + + UINT32 Value; +} D0F0x64_STRUCT; + +// **** DxF0x3C Register Definition **** +// Address +#define DxF0x3C_ADDRESS 0x3c + +// Type +#define DxF0x3C_TYPE TYPE_D4F0 +// Field Data +#define DxF0x3C_IntLine_OFFSET 0 +#define DxF0x3C_IntLine_WIDTH 8 +#define DxF0x3C_IntLine_MASK 0xff +#define DxF0x3C_IntPin_OFFSET 8 +#define DxF0x3C_IntPin_WIDTH 3 +#define DxF0x3C_IntPin_MASK 0x700 +#define DxF0x3C_IntPinR_OFFSET 11 +#define DxF0x3C_IntPinR_WIDTH 5 +#define DxF0x3C_IntPinR_MASK 0xf800 +#define DxF0x3C_ParityResponseEn_OFFSET 16 +#define DxF0x3C_ParityResponseEn_WIDTH 1 +#define DxF0x3C_ParityResponseEn_MASK 0x10000 +#define DxF0x3C_SerrEn_OFFSET 17 +#define DxF0x3C_SerrEn_WIDTH 1 +#define DxF0x3C_SerrEn_MASK 0x20000 +#define DxF0x3C_IsaEn_OFFSET 18 +#define DxF0x3C_IsaEn_WIDTH 1 +#define DxF0x3C_IsaEn_MASK 0x40000 +#define DxF0x3C_VgaEn_OFFSET 19 +#define DxF0x3C_VgaEn_WIDTH 1 +#define DxF0x3C_VgaEn_MASK 0x80000 +#define DxF0x3C_Vga16En_OFFSET 20 +#define DxF0x3C_Vga16En_WIDTH 1 +#define DxF0x3C_Vga16En_MASK 0x100000 +#define DxF0x3C_MasterAbortMode_OFFSET 21 +#define DxF0x3C_MasterAbortMode_WIDTH 1 +#define DxF0x3C_MasterAbortMode_MASK 0x200000 +#define DxF0x3C_SecondaryBusReset_OFFSET 22 +#define DxF0x3C_SecondaryBusReset_WIDTH 1 +#define DxF0x3C_SecondaryBusReset_MASK 0x400000 +#define DxF0x3C_FastB2BCap_OFFSET 23 +#define DxF0x3C_FastB2BCap_WIDTH 1 +#define DxF0x3C_FastB2BCap_MASK 0x800000 +#define DxF0x3C_Reserved_31_24_OFFSET 24 +#define DxF0x3C_Reserved_31_24_WIDTH 8 +#define DxF0x3C_Reserved_31_24_MASK 0xff000000 + +/// DxF0x3C +typedef union { + struct { ///< + UINT32 IntLine:8 ; ///< + UINT32 IntPin:3 ; ///< + UINT32 IntPinR:5 ; ///< + UINT32 ParityResponseEn:1 ; ///< + UINT32 SerrEn:1 ; ///< + UINT32 IsaEn:1 ; ///< + UINT32 VgaEn:1 ; ///< + UINT32 Vga16En:1 ; ///< + UINT32 MasterAbortMode:1 ; ///< + UINT32 SecondaryBusReset:1 ; ///< + UINT32 FastB2BCap:1 ; ///< + UINT32 Reserved_31_24:8 ; ///< + } Field; ///< + UINT32 Value; ///< +} DxF0x3C_STRUCT; + +// **** DxF0x58 Register Definition **** +// Address +#define DxF0x58_ADDRESS 0x58 + +// Type +#define DxF0x58_TYPE TYPE_D4F0 +// Field Data +#define DxF0x58_CapID_OFFSET 0 +#define DxF0x58_CapID_WIDTH 8 +#define DxF0x58_CapID_MASK 0xff +#define DxF0x58_NextPtr_OFFSET 8 +#define DxF0x58_NextPtr_WIDTH 8 +#define DxF0x58_NextPtr_MASK 0xff00 +#define DxF0x58_Version_OFFSET 16 +#define DxF0x58_Version_WIDTH 4 +#define DxF0x58_Version_MASK 0xf0000 +#define DxF0x58_DeviceType_OFFSET 20 +#define DxF0x58_DeviceType_WIDTH 4 +#define DxF0x58_DeviceType_MASK 0xf00000 +#define DxF0x58_SlotImplemented_OFFSET 24 +#define DxF0x58_SlotImplemented_WIDTH 1 +#define DxF0x58_SlotImplemented_MASK 0x1000000 +#define DxF0x58_IntMessageNum_OFFSET 25 +#define DxF0x58_IntMessageNum_WIDTH 5 +#define DxF0x58_IntMessageNum_MASK 0x3e000000 +#define DxF0x58_Reserved_31_30_OFFSET 30 +#define DxF0x58_Reserved_31_30_WIDTH 2 +#define DxF0x58_Reserved_31_30_MASK 0xc0000000 + +/// DxF0x58 +typedef union { + struct { ///< + UINT32 CapID:8 ; ///< + UINT32 NextPtr:8 ; ///< + UINT32 Version:4 ; ///< + UINT32 DeviceType:4 ; ///< + UINT32 SlotImplemented:1 ; ///< + UINT32 IntMessageNum:5 ; ///< + UINT32 Reserved_31_30:2 ; ///< + } Field; ///< + UINT32 Value; ///< +} DxF0x58_STRUCT; + +// **** DxFxx68 Register Definition **** +// Address +#define DxFxx68_ADDRESS 0x68 +// Type +#define DxFxx68_TYPE TYPE_D2F1 + +// Field Data +#define DxFxx68_PmControl_OFFSET 0 +#define DxFxx68_PmControl_WIDTH 2 +#define DxFxx68_PmControl_MASK 0x3 +#define DxFxx68_Reserved_2_2_OFFSET 2 +#define DxFxx68_Reserved_2_2_WIDTH 1 +#define DxFxx68_Reserved_2_2_MASK 0x4 +#define DxFxx68_ReadCplBoundary_OFFSET 3 +#define DxFxx68_ReadCplBoundary_WIDTH 1 +#define DxFxx68_ReadCplBoundary_MASK 0x8 +#define DxFxx68_LinkDis_OFFSET 4 +#define DxFxx68_LinkDis_WIDTH 1 +#define DxFxx68_LinkDis_MASK 0x10 +#define DxFxx68_RetrainLink_OFFSET 5 +#define DxFxx68_RetrainLink_WIDTH 1 +#define DxFxx68_RetrainLink_MASK 0x20 +#define DxFxx68_CommonClockCfg_OFFSET 6 +#define DxFxx68_CommonClockCfg_WIDTH 1 +#define DxFxx68_CommonClockCfg_MASK 0x40 +#define DxFxx68_ExtendedSync_OFFSET 7 +#define DxFxx68_ExtendedSync_WIDTH 1 +#define DxFxx68_ExtendedSync_MASK 0x80 +#define DxFxx68_ClockPowerManagementEn_OFFSET 8 +#define DxFxx68_ClockPowerManagementEn_WIDTH 1 +#define DxFxx68_ClockPowerManagementEn_MASK 0x100 +#define DxFxx68_HWAutonomousWidthDisable_OFFSET 9 +#define DxFxx68_HWAutonomousWidthDisable_WIDTH 1 +#define DxFxx68_HWAutonomousWidthDisable_MASK 0x200 +#define DxFxx68_LinkBWManagementEn_OFFSET 10 +#define DxFxx68_LinkBWManagementEn_WIDTH 1 +#define DxFxx68_LinkBWManagementEn_MASK 0x400 +#define DxFxx68_LinkAutonomousBWIntEn_OFFSET 11 +#define DxFxx68_LinkAutonomousBWIntEn_WIDTH 1 +#define DxFxx68_LinkAutonomousBWIntEn_MASK 0x800 +#define DxFxx68_Reserved_15_12_OFFSET 12 +#define DxFxx68_Reserved_15_12_WIDTH 4 +#define DxFxx68_Reserved_15_12_MASK 0xF000 +#define DxFxx68_LinkSpeed_OFFSET 16 +#define DxFxx68_LinkSpeed_WIDTH 4 +#define DxFxx68_LinkSpeed_MASK 0xF0000 +#define DxFxx68_NegotiatedLinkWidth_OFFSET 20 +#define DxFxx68_NegotiatedLinkWidth_WIDTH 6 +#define DxFxx68_NegotiatedLinkWidth_MASK 0x3F00000 +#define DxFxx68_Reserved_26_26_OFFSET 26 +#define DxFxx68_Reserved_26_26_WIDTH 1 +#define DxFxx68_Reserved_26_26_MASK 0x4000000 +#define DxFxx68_LinkTraining_OFFSET 27 +#define DxFxx68_LinkTraining_WIDTH 1 +#define DxFxx68_LinkTraining_MASK 0x8000000 +#define DxFxx68_SlotClockCfg_OFFSET 28 +#define DxFxx68_SlotClockCfg_WIDTH 1 +#define DxFxx68_SlotClockCfg_MASK 0x10000000 +#define DxFxx68_DlActive_OFFSET 29 +#define DxFxx68_DlActive_WIDTH 1 +#define DxFxx68_DlActive_MASK 0x20000000 +#define DxFxx68_LinkBWManagementStatus_OFFSET 30 +#define DxFxx68_LinkBWManagementStatus_WIDTH 1 +#define DxFxx68_LinkBWManagementStatus_MASK 0x40000000 +#define DxFxx68_LinkAutonomousBWStatus_OFFSET 31 +#define DxFxx68_LinkAutonomousBWStatus_WIDTH 1 +#define DxFxx68_LinkAutonomousBWStatus_MASK 0x80000000 + +/// DxFxx68 +typedef union { + struct { ///< + UINT32 PmControl:2; ///< + UINT32 Reserved_2_2:1; ///< + UINT32 ReadCplBoundary:1; ///< + UINT32 LinkDis:1; ///< + UINT32 RetrainLink:1; ///< + UINT32 CommonClockCfg:1; ///< + UINT32 ExtendedSync:1; ///< + UINT32 ClockPowerManagementEn:1; ///< + UINT32 HWAutonomousWidthDisable:1; ///< + UINT32 LinkBWManagementEn:1; ///< + UINT32 LinkAutonomousBWIntEn:1; ///< + UINT32 Reserved_15_12:4; ///< + UINT32 LinkSpeed:4; ///< + UINT32 NegotiatedLinkWidth:6; ///< + UINT32 Reserved_26_26:1; ///< + UINT32 LinkTraining:1; ///< + UINT32 SlotClockCfg:1; ///< + UINT32 DlActive:1; ///< + UINT32 LinkBWManagementStatus:1; ///< + UINT32 LinkAutonomousBWStatus:1; ///< + + } Field; + + UINT32 Value; +} DxFxx68_STRUCT; + +// **** D0F0x7C Register Definition **** +// Address +#define D0F0x7C_ADDRESS 0x7C +// Type +#define D0F0x7C_TYPE TYPE_D0F0 + +// Field Data +#define D0F0x7C_ForceIntGfxDisable_OFFSET 0 +#define D0F0x7C_ForceIntGfxDisable_WIDTH 1 +#define D0F0x7C_ForceIntGfxDisable_MASK 0x1 +#define D0F0x7C_Reserved_31_1_OFFSET 1 +#define D0F0x7C_Reserved_31_1_WIDTH 31 +#define D0F0x7C_Reserved_31_1_MASK 0xFFFFFFFE + +/// D0F0x7C +typedef union { + struct { ///< + UINT32 ForceIntGfxDisable:1; ///< + UINT32 Reserved_31_1:31; ///< + + } Field; + + UINT32 Value; +} D0F0x7C_STRUCT; + +// **** D0F0x98 Register Definition **** +// Address +#define D0F0x98_ADDRESS 0x98 +// Type +#define D0F0x98_TYPE TYPE_D0F0 + +// Field Data +#define D0F0x98_OrbIndData_OFFSET 0 +#define D0F0x98_OrbIndData_WIDTH 32 +#define D0F0x98_OrbIndData_MASK 0xFFFFFFFF + +/// D0F0x98 +typedef union { + struct { ///< + UINT32 OrbIndData:32; ///< + + } Field; + + UINT32 Value; +} D0F0x98_STRUCT; + +// **** D0F0xBC Register Definition **** +// Address +#define D0F0xBC_ADDRESS 0xBC +// Type +#define D0F0xBC_TYPE TYPE_D0F0 + +// Field Data +#define D0F0xBC_NbSmuIndData_OFFSET 0 +#define D0F0xBC_NbSmuIndData_WIDTH 32 +#define D0F0xBC_NbSmuIndData_MASK 0xFFFFFFFF + +/// D0F0xBC +typedef union { + struct { ///< + UINT32 NbSmuIndData:32; ///< + + } Field; + + UINT32 Value; +} D0F0xBC_STRUCT; + +// **** D0F0xC8 Register Definition **** +// Address +#define D0F0xC8_ADDRESS 0xC8 +// Type +#define D0F0xC8_TYPE TYPE_D0F0 + +// Field Data +#define D0F0xC8_NbDevIndAddr_OFFSET 0 +#define D0F0xC8_NbDevIndAddr_WIDTH 7 +#define D0F0xC8_NbDevIndAddr_MASK 0x7F +#define D0F0xC8_Reserved_15_7_OFFSET 7 +#define D0F0xC8_Reserved_15_7_WIDTH 9 +#define D0F0xC8_Reserved_15_7_MASK 0xFF80 +#define D0F0xC8_NbDevIndSel_OFFSET 16 +#define D0F0xC8_NbDevIndSel_WIDTH 8 +#define D0F0xC8_NbDevIndSel_MASK 0xFF0000 +#define D0F0xC8_Reserved_31_24_OFFSET 24 +#define D0F0xC8_Reserved_31_24_WIDTH 8 +#define D0F0xC8_Reserved_31_24_MASK 0xFF000000 + +/// D0F0xC8 +typedef union { + struct { ///< + UINT32 NbDevIndAddr:7; ///< + UINT32 Reserved_15_7:9; ///< + UINT32 NbDevIndSel:8; ///< + UINT32 Reserved_31_24:8; ///< + + } Field; + + UINT32 Value; +} D0F0xC8_STRUCT; + +// **** D0F0xCC Register Definition **** +// Address +#define D0F0xCC_ADDRESS 0xCC +// Type +#define D0F0xCC_TYPE TYPE_D0F0 + +// Field Data +#define D0F0xCC_NbDevIndData_OFFSET 0 +#define D0F0xCC_NbDevIndData_WIDTH 32 +#define D0F0xCC_NbDevIndData_MASK 0xFFFFFFFF + +/// D0F0xCC +typedef union { + struct { ///< + UINT32 NbDevIndData:32; ///< + + } Field; + + UINT32 Value; +} D0F0xCC_STRUCT; + +// **** D0F0xE4 Register Definition **** +// Address +#define D0F0xE4_ADDRESS 0xE4 +// Type +#define D0F0xE4_TYPE TYPE_D0F0 + +// Field Data +#define D0F0xE4_PcieIndxData_OFFSET 0 +#define D0F0xE4_PcieIndxData_WIDTH 32 +#define D0F0xE4_PcieIndxData_MASK 0xFFFFFFFF + +/// D0F0xE4 +typedef union { + struct { ///< + UINT32 PcieIndxData:32; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_STRUCT; + +// **** DxFxxE4_x6A Register Definition **** +// Address +#define DxFxxE4_x6A_ADDRESS 0x6A +// Type +#define DxFxxE4_x6A_TYPE TYPE_D2F1xE4 + +// Field Data +#define DxFxxE4_x6A_ErrReportingDis_OFFSET 0 +#define DxFxxE4_x6A_ErrReportingDis_WIDTH 1 +#define DxFxxE4_x6A_ErrReportingDis_MASK 0x1 + +// **** DxFxxE4_xA2 Register Definition **** +// Address +#define DxFxxE4_xA2_ADDRESS 0xA2 +// Type +#define DxFxxE4_xA2_TYPE TYPE_D2F1xE4 + +// Field Data +#define DxFxxE4_xA2_LcLinkWidth_OFFSET 0 +#define DxFxxE4_xA2_LcLinkWidth_WIDTH 3 +#define DxFxxE4_xA2_LcLinkWidth_MASK 0x7 +#define DxFxxE4_xA2_Reserved_3_3_OFFSET 3 +#define DxFxxE4_xA2_Reserved_3_3_WIDTH 1 +#define DxFxxE4_xA2_Reserved_3_3_MASK 0x8 +#define DxFxxE4_xA2_LcLinkWidthRd_OFFSET 4 +#define DxFxxE4_xA2_LcLinkWidthRd_WIDTH 3 +#define DxFxxE4_xA2_LcLinkWidthRd_MASK 0x70 +#define DxFxxE4_xA2_LcReconfigArcMissingEscape_OFFSET 7 +#define DxFxxE4_xA2_LcReconfigArcMissingEscape_WIDTH 1 +#define DxFxxE4_xA2_LcReconfigArcMissingEscape_MASK 0x80 +#define DxFxxE4_xA2_LcReconfigNow_OFFSET 8 +#define DxFxxE4_xA2_LcReconfigNow_WIDTH 1 +#define DxFxxE4_xA2_LcReconfigNow_MASK 0x100 +#define DxFxxE4_xA2_LcRenegotiationSupport_OFFSET 9 +#define DxFxxE4_xA2_LcRenegotiationSupport_WIDTH 1 +#define DxFxxE4_xA2_LcRenegotiationSupport_MASK 0x200 +#define DxFxxE4_xA2_LcRenegotiateEn_OFFSET 10 +#define DxFxxE4_xA2_LcRenegotiateEn_WIDTH 1 +#define DxFxxE4_xA2_LcRenegotiateEn_MASK 0x400 +#define DxFxxE4_xA2_LcShortReconfigEn_OFFSET 11 +#define DxFxxE4_xA2_LcShortReconfigEn_WIDTH 1 +#define DxFxxE4_xA2_LcShortReconfigEn_MASK 0x800 +#define DxFxxE4_xA2_LcUpconfigureSupport_OFFSET 12 +#define DxFxxE4_xA2_LcUpconfigureSupport_WIDTH 1 +#define DxFxxE4_xA2_LcUpconfigureSupport_MASK 0x1000 +#define DxFxxE4_xA2_LcUpconfigureDis_OFFSET 13 +#define DxFxxE4_xA2_LcUpconfigureDis_WIDTH 1 +#define DxFxxE4_xA2_LcUpconfigureDis_MASK 0x2000 +#define DxFxxE4_xA2_Reserved_19_14_OFFSET 14 +#define DxFxxE4_xA2_Reserved_19_14_WIDTH 6 +#define DxFxxE4_xA2_Reserved_19_14_MASK 0xFC000 +#define DxFxxE4_xA2_LcUpconfigCapable_OFFSET 20 +#define DxFxxE4_xA2_LcUpconfigCapable_WIDTH 1 +#define DxFxxE4_xA2_LcUpconfigCapable_MASK 0x100000 +#define DxFxxE4_xA2_LcDynLanesPwrState_OFFSET 21 +#define DxFxxE4_xA2_LcDynLanesPwrState_WIDTH 2 +#define DxFxxE4_xA2_LcDynLanesPwrState_MASK 0x600000 +#define DxFxxE4_xA2_Reserved_31_23_OFFSET 23 +#define DxFxxE4_xA2_Reserved_31_23_WIDTH 9 +#define DxFxxE4_xA2_Reserved_31_23_MASK 0xFF800000 + +/// DxFxxE4_xA2 +typedef union { + struct { ///< + UINT32 LcLinkWidth:3; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 LcLinkWidthRd:3; ///< + UINT32 LcReconfigArcMissingEscape:1; ///< + UINT32 LcReconfigNow:1; ///< + UINT32 LcRenegotiationSupport:1; ///< + UINT32 LcRenegotiateEn:1; ///< + UINT32 LcShortReconfigEn:1; ///< + UINT32 LcUpconfigureSupport:1; ///< + UINT32 LcUpconfigureDis:1; ///< + UINT32 Reserved_19_14:6; ///< + UINT32 LcUpconfigCapable:1; ///< + UINT32 LcDynLanesPwrState:2; ///< + UINT32 Reserved_31_23:9; ///< + + } Field; + + UINT32 Value; +} DxFxxE4_xA2_STRUCT; + +// **** DxFxx128 Register Definition **** +// Address +#define DxFxx128_ADDRESS 0x128 +// Type +#define DxFxx128_TYPE TYPE_D2F1 + +// Field Data +#define DxFxx128_Reserved_15_0_OFFSET 0 +#define DxFxx128_Reserved_15_0_WIDTH 16 +#define DxFxx128_Reserved_15_0_MASK 0xFFFF +#define DxFxx128_PortArbTableStatus_OFFSET 16 +#define DxFxx128_PortArbTableStatus_WIDTH 1 +#define DxFxx128_PortArbTableStatus_MASK 0x10000 +#define DxFxx128_VcNegotiationPending_OFFSET 17 +#define DxFxx128_VcNegotiationPending_WIDTH 1 +#define DxFxx128_VcNegotiationPending_MASK 0x20000 +#define DxFxx128_Reserved_31_18_OFFSET 18 +#define DxFxx128_Reserved_31_18_WIDTH 14 +#define DxFxx128_Reserved_31_18_MASK 0xFFFC0000 + +/// DxFxx128 +typedef union { + struct { ///< + UINT32 Reserved_15_0:16; ///< + UINT32 PortArbTableStatus:1; ///< + UINT32 VcNegotiationPending:1; ///< + UINT32 Reserved_31_18:14; ///< + + } Field; + + UINT32 Value; +} DxFxx128_STRUCT; + +// **** D0F0x64_x0D Register Definition **** +// Address +#define D0F0x64_x0D_ADDRESS 0xD +// Type +#define D0F0x64_x0D_TYPE TYPE_D0F0x64 + +// Field Data +#define D0F0x64_x0D_PciDev0Fn2RegEn_OFFSET 0 +#define D0F0x64_x0D_PciDev0Fn2RegEn_WIDTH 1 +#define D0F0x64_x0D_PciDev0Fn2RegEn_MASK 0x1 +#define D0F0x64_x0D_Reserved_30_1_OFFSET 1 +#define D0F0x64_x0D_Reserved_30_1_WIDTH 30 +#define D0F0x64_x0D_Reserved_30_1_MASK 0x7FFFFFFE +#define D0F0x64_x0D_IommuDis_OFFSET 31 +#define D0F0x64_x0D_IommuDis_WIDTH 1 +#define D0F0x64_x0D_IommuDis_MASK 0x80000000 + +/// D0F0x64_x0D +typedef union { + struct { ///< + UINT32 PciDev0Fn2RegEn:1; ///< + UINT32 Reserved_30_1:30; ///< + UINT32 IommuDis:1; ///< + + } Field; + + UINT32 Value; +} D0F0x64_x0D_STRUCT; + +// **** D0F0x64_x16 Register Definition **** +// Address +#define D0F0x64_x16_ADDRESS 0x16 + +// Type +#define D0F0x64_x16_TYPE TYPE_D0F0x64 +// Field Data +#define D0F0x64_x16_AerUrMsgEn_OFFSET 0 +#define D0F0x64_x16_AerUrMsgEn_WIDTH 1 +#define D0F0x64_x16_AerUrMsgEn_MASK 0x1 +#define D0F0x64_x16_Reserved_31_1_OFFSET 1 +#define D0F0x64_x16_Reserved_31_1_WIDTH 31 +#define D0F0x64_x16_Reserved_31_1_MASK 0xfffffffe + +/// D0F0x64_x16 +typedef union { + struct { ///< + UINT32 AerUrMsgEn:1 ; ///< + UINT32 Reserved_31_1:31; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x64_x16_STRUCT; + +// **** D0F0x64_x1D Register Definition **** +// Address +#define D0F0x64_x1D_ADDRESS 0x1D +// Type +#define D0F0x64_x1D_TYPE TYPE_D0F0x64 + +// Field Data +#define D0F0x64_x1D_Reserved_0_0_OFFSET 0 +#define D0F0x64_x1D_Reserved_0_0_WIDTH 1 +#define D0F0x64_x1D_Reserved_0_0_MASK 0x1 +#define D0F0x64_x1D_VgaEn_OFFSET 1 +#define D0F0x64_x1D_VgaEn_WIDTH 1 +#define D0F0x64_x1D_VgaEn_MASK 0x2 +#define D0F0x64_x1D_Reserved_2_2_OFFSET 2 +#define D0F0x64_x1D_Reserved_2_2_WIDTH 1 +#define D0F0x64_x1D_Reserved_2_2_MASK 0x4 +#define D0F0x64_x1D_Vga16En_OFFSET 3 +#define D0F0x64_x1D_Vga16En_WIDTH 1 +#define D0F0x64_x1D_Vga16En_MASK 0x8 +#define D0F0x64_x1D_Reserved_31_4_OFFSET 4 +#define D0F0x64_x1D_Reserved_31_4_WIDTH 28 +#define D0F0x64_x1D_Reserved_31_4_MASK 0xFFFFFFF0 + +/// D0F0x64_x1D +typedef union { + struct { ///< + UINT32 Reserved_0_0:1; ///< + UINT32 VgaEn:1; ///< + UINT32 Reserved_2_2:1; ///< + UINT32 Vga16En:1; ///< + UINT32 Reserved_31_4:28; ///< + + } Field; + + UINT32 Value; +} D0F0x64_x1D_STRUCT; + +// **** D0F0x64_x22 Register Definition **** +// Address +#define D0F0x64_x22_ADDRESS 0x22 +// Type +#define D0F0x64_x22_TYPE TYPE_D0F0x64 + + +// **** D0F0x64_x23 Register Definition **** +// Address +#define D0F0x64_x23_ADDRESS 0x23 +// Type +#define D0F0x64_x23_TYPE TYPE_D0F0x64 + + +// **** D0F0x64_x30 Register Definition **** +// Address +#define D0F0x64_x30_ADDRESS 0x30 +// Type +#define D0F0x64_x30_TYPE TYPE_D0F0x64 + +// Field Data +#define D0F0x64_x30_DevFnMap_OFFSET 0 +#define D0F0x64_x30_DevFnMap_WIDTH 8 +#define D0F0x64_x30_DevFnMap_MASK 0xFF +#define D0F0x64_x30_Reserved_31_8_OFFSET 8 +#define D0F0x64_x30_Reserved_31_8_WIDTH 24 +#define D0F0x64_x30_Reserved_31_8_MASK 0xFFFFFF00 + +/// D0F0x64_x30 +typedef union { + struct { ///< + UINT32 DevFnMap:8; ///< + UINT32 Reserved_31_8:24; ///< + + } Field; + + UINT32 Value; +} D0F0x64_x30_STRUCT; + +// **** D0F0x64_x46 Register Definition **** +// Address +#define D0F0x64_x46_ADDRESS 0x46 +// Type +#define D0F0x64_x46_TYPE TYPE_D0F0x64 + + +// **** D0F0x94 Register Definition **** +// Address +#define D0F0x94_ADDRESS 0x94 + +// Type +#define D0F0x94_TYPE TYPE_D0F0 +// Field Data +#define D0F0x94_OrbIndAddr_OFFSET 0 +#define D0F0x94_OrbIndAddr_WIDTH 7 +#define D0F0x94_OrbIndAddr_MASK 0x7f +#define D0F0x94_Reserved_7_7_OFFSET 7 +#define D0F0x94_Reserved_7_7_WIDTH 1 +#define D0F0x94_Reserved_7_7_MASK 0x80 +#define D0F0x94_Reserved_31_9_OFFSET 9 +#define D0F0x94_Reserved_31_9_WIDTH 23 +#define D0F0x94_Reserved_31_9_MASK 0xfffffe00 + +/// D0F0x94 +typedef union { + struct { ///< + UINT32 OrbIndAddr:7 ; ///< + UINT32 Reserved_7_7:1 ; ///< + UINT32 Reserved_8_8:1 ; ///< + UINT32 Reserved_31_9:23; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0x94_STRUCT; + +// **** D0F0x98_x07 Register Definition **** +// Address +#define D0F0x98_x07_ADDRESS 0x7 +// Type +#define D0F0x98_x07_TYPE TYPE_D0F0x98 + +// Field Data +#define D0F0x98_x07_IocBwOptEn_OFFSET 0 +#define D0F0x98_x07_IocBwOptEn_WIDTH 1 +#define D0F0x98_x07_IocBwOptEn_MASK 0x1 +#define D0F0x98_x07_IocWrROMapDis_OFFSET 1 +#define D0F0x98_x07_IocWrROMapDis_WIDTH 1 +#define D0F0x98_x07_IocWrROMapDis_MASK 0x2 +#define D0F0x98_x07_IocRdROMapDis_OFFSET 2 +#define D0F0x98_x07_IocRdROMapDis_WIDTH 1 +#define D0F0x98_x07_IocRdROMapDis_MASK 0x4 +#define D0F0x98_x07_Reserved_3_3_OFFSET 3 +#define D0F0x98_x07_Reserved_3_3_WIDTH 1 +#define D0F0x98_x07_Reserved_3_3_MASK 0x8 +#define D0F0x98_x07_IommuBwOptEn_OFFSET 4 +#define D0F0x98_x07_IommuBwOptEn_WIDTH 1 +#define D0F0x98_x07_IommuBwOptEn_MASK 0x10 +#define D0F0x98_x07_Reserved_5_5_OFFSET 5 +#define D0F0x98_x07_Reserved_5_5_WIDTH 1 +#define D0F0x98_x07_Reserved_5_5_MASK 0x20 +#define D0F0x98_x07_DmaReqRespPassPWMode_OFFSET 6 +#define D0F0x98_x07_DmaReqRespPassPWMode_WIDTH 1 +#define D0F0x98_x07_DmaReqRespPassPWMode_MASK 0x40 +#define D0F0x98_x07_IommuIsocPassPWMode_OFFSET 7 +#define D0F0x98_x07_IommuIsocPassPWMode_WIDTH 1 +#define D0F0x98_x07_IommuIsocPassPWMode_MASK 0x80 +#define D0F0x98_x07_Reserved_14_8_OFFSET 8 +#define D0F0x98_x07_Reserved_14_8_WIDTH 7 +#define D0F0x98_x07_Reserved_14_8_MASK 0x7F00 +#define D0F0x98_x07_DropZeroMaskWrEn_OFFSET 15 +#define D0F0x98_x07_DropZeroMaskWrEn_WIDTH 1 +#define D0F0x98_x07_DropZeroMaskWrEn_MASK 0x8000 +#define D0F0x98_x07_SyncFloodOnParityErr_OFFSET 16 +#define D0F0x98_x07_SyncFloodOnParityErr_WIDTH 1 +#define D0F0x98_x07_SyncFloodOnParityErr_MASK 0x10000 +#define D0F0x98_x07_Reserved_30_17_OFFSET 17 +#define D0F0x98_x07_Reserved_30_17_WIDTH 14 +#define D0F0x98_x07_Reserved_30_17_MASK 0x7FFE0000 +#define D0F0x98_x07_SMUCsrIsocEn_OFFSET 31 +#define D0F0x98_x07_SMUCsrIsocEn_WIDTH 1 +#define D0F0x98_x07_SMUCsrIsocEn_MASK 0x80000000 + +/// D0F0x98_x07 +typedef union { + struct { ///< + UINT32 IocBwOptEn:1; ///< + UINT32 IocWrROMapDis:1; ///< + UINT32 IocRdROMapDis:1; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 IommuBwOptEn:1; ///< + UINT32 Reserved_5_5:1; ///< + UINT32 DmaReqRespPassPWMode:1; ///< + UINT32 IommuIsocPassPWMode:1; ///< + UINT32 Reserved_14_8:7; ///< + UINT32 DropZeroMaskWrEn:1; ///< + UINT32 SyncFloodOnParityErr:1; ///< + UINT32 Reserved_30_17:14; ///< + UINT32 SMUCsrIsocEn:1; ///< + + } Field; + + UINT32 Value; +} D0F0x98_x07_STRUCT; + +// **** D0F0x98_x08 Register Definition **** +// Address +#define D0F0x98_x08_ADDRESS 0x8 +// Type +#define D0F0x98_x08_TYPE TYPE_D0F0x98 + +// Field Data +#define D0F0x98_x08_NpWrrLenA_OFFSET 0 +#define D0F0x98_x08_NpWrrLenA_WIDTH 8 +#define D0F0x98_x08_NpWrrLenA_MASK 0xFF +#define D0F0x98_x08_NpWrrLenB_OFFSET 8 +#define D0F0x98_x08_NpWrrLenB_WIDTH 8 +#define D0F0x98_x08_NpWrrLenB_MASK 0xFF00 +#define D0F0x98_x08_NpWrrLenC_OFFSET 16 +#define D0F0x98_x08_NpWrrLenC_WIDTH 8 +#define D0F0x98_x08_NpWrrLenC_MASK 0xFF0000 +#define D0F0x98_x08_Reserved_31_24_OFFSET 24 +#define D0F0x98_x08_Reserved_31_24_WIDTH 8 +#define D0F0x98_x08_Reserved_31_24_MASK 0xFF000000 + +/// D0F0x98_x08 +typedef union { + struct { ///< + UINT32 NpWrrLenA:8; ///< + UINT32 NpWrrLenB:8; ///< + UINT32 NpWrrLenC:8; ///< + UINT32 Reserved_31_24:8; ///< + + } Field; + + UINT32 Value; +} D0F0x98_x08_STRUCT; + +// **** D0F0x98_x0C Register Definition **** +// Address +#define D0F0x98_x0C_ADDRESS 0xC +// Type +#define D0F0x98_x0C_TYPE TYPE_D0F0x98 + +// Field Data +#define D0F0x98_x0C_GcmWrrLenA_OFFSET 0 +#define D0F0x98_x0C_GcmWrrLenA_WIDTH 8 +#define D0F0x98_x0C_GcmWrrLenA_MASK 0xFF +#define D0F0x98_x0C_GcmWrrLenB_OFFSET 8 +#define D0F0x98_x0C_GcmWrrLenB_WIDTH 8 +#define D0F0x98_x0C_GcmWrrLenB_MASK 0xFF00 +#define D0F0x98_x0C_Reserved_29_16_OFFSET 16 +#define D0F0x98_x0C_Reserved_29_16_WIDTH 14 +#define D0F0x98_x0C_Reserved_29_16_MASK 0x3FFF0000 +#define D0F0x98_x0C_Reserved_31_31_OFFSET 31 +#define D0F0x98_x0C_Reserved_31_31_WIDTH 1 +#define D0F0x98_x0C_Reserved_31_31_MASK 0x80000000 + +/// D0F0x98_x0C +typedef union { + struct { ///< + UINT32 GcmWrrLenA:8; ///< + UINT32 GcmWrrLenB:8; ///< + UINT32 Reserved_29_16:14; ///< + UINT32 Reserved_30_30:1; ///< + UINT32 Reserved_31_31:1; ///< + + } Field; + + UINT32 Value; +} D0F0x98_x0C_STRUCT; + +// **** D0F0x98_x1E Register Definition **** +// Address +#define D0F0x98_x1E_ADDRESS 0x1E +// Type +#define D0F0x98_x1E_TYPE TYPE_D0F0x98 + +// Field Data +#define D0F0x98_x1E_Reserved_0_0_OFFSET 0 +#define D0F0x98_x1E_Reserved_0_0_WIDTH 1 +#define D0F0x98_x1E_Reserved_0_0_MASK 0x1 +#define D0F0x98_x1E_HiPriEn_OFFSET 1 +#define D0F0x98_x1E_HiPriEn_WIDTH 1 +#define D0F0x98_x1E_HiPriEn_MASK 0x2 +#define D0F0x98_x1E_Reserved_23_2_OFFSET 2 +#define D0F0x98_x1E_Reserved_23_2_WIDTH 22 +#define D0F0x98_x1E_Reserved_23_2_MASK 0xFFFFFC +#define D0F0x98_x1E_RxErrStatusDelay_OFFSET 24 +#define D0F0x98_x1E_RxErrStatusDelay_WIDTH 8 +#define D0F0x98_x1E_RxErrStatusDelay_MASK 0xFF000000 + +/// D0F0x98_x1E +typedef union { + struct { ///< + UINT32 Reserved_0_0:1; ///< + UINT32 HiPriEn:1; ///< + UINT32 Reserved_23_2:22; ///< + UINT32 RxErrStatusDelay:8; ///< + + } Field; + + UINT32 Value; +} D0F0x98_x1E_STRUCT; + +// **** D0F0x98_x28 Register Definition **** +// Address +#define D0F0x98_x28_ADDRESS 0x28 +// Type +#define D0F0x98_x28_TYPE TYPE_D0F0x98 + +// Field Data +#define D0F0x98_x28_Reserved_0_0_OFFSET 0 +#define D0F0x98_x28_Reserved_0_0_WIDTH 1 +#define D0F0x98_x28_Reserved_0_0_MASK 0x1 +#define D0F0x98_x28_ForceCoherentIntr_OFFSET 1 +#define D0F0x98_x28_ForceCoherentIntr_WIDTH 1 +#define D0F0x98_x28_ForceCoherentIntr_MASK 0x2 +#define D0F0x98_x28_Reserved_31_2_OFFSET 2 +#define D0F0x98_x28_Reserved_31_2_WIDTH 30 +#define D0F0x98_x28_Reserved_31_2_MASK 0xFFFFFFFC + +/// D0F0x98_x28 +typedef union { + struct { ///< + UINT32 Reserved_0_0:1; ///< + UINT32 ForceCoherentIntr:1; ///< + UINT32 Reserved_31_2:30; ///< + + } Field; + + UINT32 Value; +} D0F0x98_x28_STRUCT; + +// **** D0F0x98_x2C Register Definition **** +// Address +#define D0F0x98_x2C_ADDRESS 0x2C +// Type +#define D0F0x98_x2C_TYPE TYPE_D0F0x98 + +// Field Data +#define D0F0x98_x2C_Reserved_0_0_OFFSET 0 +#define D0F0x98_x2C_Reserved_0_0_WIDTH 1 +#define D0F0x98_x2C_Reserved_0_0_MASK 0x1 +#define D0F0x98_x2C_DynWakeEn_OFFSET 1 +#define D0F0x98_x2C_DynWakeEn_WIDTH 1 +#define D0F0x98_x2C_DynWakeEn_MASK 0x2 +#define D0F0x98_x2C_CgttLclkOverride_OFFSET 2 +#define D0F0x98_x2C_CgttLclkOverride_WIDTH 1 +#define D0F0x98_x2C_CgttLclkOverride_MASK 0x4 +#define D0F0x98_x2C_Reserved_8_3_OFFSET 3 +#define D0F0x98_x2C_Reserved_8_3_WIDTH 6 +#define D0F0x98_x2C_Reserved_8_3_MASK 0x1F8 +#define D0F0x98_x2C_SBDmaActiveMask_OFFSET 9 +#define D0F0x98_x2C_SBDmaActiveMask_WIDTH 1 +#define D0F0x98_x2C_SBDmaActiveMask_MASK 0x200 +#define D0F0x98_x2C_Reserved_15_10_OFFSET 10 +#define D0F0x98_x2C_Reserved_15_10_WIDTH 6 +#define D0F0x98_x2C_Reserved_15_10_MASK 0xFC00 +#define D0F0x98_x2C_WakeHysteresis_OFFSET 16 +#define D0F0x98_x2C_WakeHysteresis_WIDTH 16 +#define D0F0x98_x2C_WakeHysteresis_MASK 0xFFFF0000 + +/// D0F0x98_x2C +typedef union { + struct { ///< + UINT32 Reserved_0_0:1; ///< + UINT32 DynWakeEn:1; ///< + UINT32 CgttLclkOverride:1; ///< + UINT32 Reserved_8_3:6; ///< + UINT32 SBDmaActiveMask:1; ///< + UINT32 Reserved_15_10:6; ///< + UINT32 WakeHysteresis:16; ///< + + } Field; + + UINT32 Value; +} D0F0x98_x2C_STRUCT; + +// **** D0F0x98_x3A Register Definition **** +// Address +#define D0F0x98_x3A_ADDRESS 0x3A +// Type +#define D0F0x98_x3A_TYPE TYPE_D0F0x98 + +// **** D0F0x98_x49 Register Definition **** +// Address +#define D0F0x98_x49_ADDRESS 0x49 +// Type +#define D0F0x98_x49_TYPE TYPE_D0F0x98 + +// Field Data +#define D0F0x98_x49_Reserved_23_0_OFFSET 0 +#define D0F0x98_x49_Reserved_23_0_WIDTH 24 +#define D0F0x98_x49_Reserved_23_0_MASK 0xFFFFFF +#define D0F0x98_x49_SoftOverrideClk6_OFFSET 24 +#define D0F0x98_x49_SoftOverrideClk6_WIDTH 1 +#define D0F0x98_x49_SoftOverrideClk6_MASK 0x1000000 +#define D0F0x98_x49_SoftOverrideClk5_OFFSET 25 +#define D0F0x98_x49_SoftOverrideClk5_WIDTH 1 +#define D0F0x98_x49_SoftOverrideClk5_MASK 0x2000000 +#define D0F0x98_x49_SoftOverrideClk4_OFFSET 26 +#define D0F0x98_x49_SoftOverrideClk4_WIDTH 1 +#define D0F0x98_x49_SoftOverrideClk4_MASK 0x4000000 +#define D0F0x98_x49_SoftOverrideClk3_OFFSET 27 +#define D0F0x98_x49_SoftOverrideClk3_WIDTH 1 +#define D0F0x98_x49_SoftOverrideClk3_MASK 0x8000000 +#define D0F0x98_x49_SoftOverrideClk2_OFFSET 28 +#define D0F0x98_x49_SoftOverrideClk2_WIDTH 1 +#define D0F0x98_x49_SoftOverrideClk2_MASK 0x10000000 +#define D0F0x98_x49_SoftOverrideClk1_OFFSET 29 +#define D0F0x98_x49_SoftOverrideClk1_WIDTH 1 +#define D0F0x98_x49_SoftOverrideClk1_MASK 0x20000000 +#define D0F0x98_x49_SoftOverrideClk0_OFFSET 30 +#define D0F0x98_x49_SoftOverrideClk0_WIDTH 1 +#define D0F0x98_x49_SoftOverrideClk0_MASK 0x40000000 +#define D0F0x98_x49_Reserved_31_31_OFFSET 31 +#define D0F0x98_x49_Reserved_31_31_WIDTH 1 +#define D0F0x98_x49_Reserved_31_31_MASK 0x80000000 + +/// D0F0x98_x49 +typedef union { + struct { ///< + UINT32 Reserved_23_0:24; ///< + UINT32 SoftOverrideClk6:1; ///< + UINT32 SoftOverrideClk5:1; ///< + UINT32 SoftOverrideClk4:1; ///< + UINT32 SoftOverrideClk3:1; ///< + UINT32 SoftOverrideClk2:1; ///< + UINT32 SoftOverrideClk1:1; ///< + UINT32 SoftOverrideClk0:1; ///< + UINT32 Reserved_31_31:1; ///< + + } Field; + + UINT32 Value; +} D0F0x98_x49_STRUCT; + +// **** D0F0x98_x4A Register Definition **** +// Address +#define D0F0x98_x4A_ADDRESS 0x4A +// Type +#define D0F0x98_x4A_TYPE TYPE_D0F0x98 + +// Field Data +#define D0F0x98_x4A_Reserved_23_0_OFFSET 0 +#define D0F0x98_x4A_Reserved_23_0_WIDTH 24 +#define D0F0x98_x4A_Reserved_23_0_MASK 0xFFFFFF +#define D0F0x98_x4A_SoftOverrideClk6_OFFSET 24 +#define D0F0x98_x4A_SoftOverrideClk6_WIDTH 1 +#define D0F0x98_x4A_SoftOverrideClk6_MASK 0x1000000 +#define D0F0x98_x4A_SoftOverrideClk5_OFFSET 25 +#define D0F0x98_x4A_SoftOverrideClk5_WIDTH 1 +#define D0F0x98_x4A_SoftOverrideClk5_MASK 0x2000000 +#define D0F0x98_x4A_SoftOverrideClk4_OFFSET 26 +#define D0F0x98_x4A_SoftOverrideClk4_WIDTH 1 +#define D0F0x98_x4A_SoftOverrideClk4_MASK 0x4000000 +#define D0F0x98_x4A_SoftOverrideClk3_OFFSET 27 +#define D0F0x98_x4A_SoftOverrideClk3_WIDTH 1 +#define D0F0x98_x4A_SoftOverrideClk3_MASK 0x8000000 +#define D0F0x98_x4A_SoftOverrideClk2_OFFSET 28 +#define D0F0x98_x4A_SoftOverrideClk2_WIDTH 1 +#define D0F0x98_x4A_SoftOverrideClk2_MASK 0x10000000 +#define D0F0x98_x4A_SoftOverrideClk1_OFFSET 29 +#define D0F0x98_x4A_SoftOverrideClk1_WIDTH 1 +#define D0F0x98_x4A_SoftOverrideClk1_MASK 0x20000000 +#define D0F0x98_x4A_SoftOverrideClk0_OFFSET 30 +#define D0F0x98_x4A_SoftOverrideClk0_WIDTH 1 +#define D0F0x98_x4A_SoftOverrideClk0_MASK 0x40000000 +#define D0F0x98_x4A_Reserved_31_31_OFFSET 31 +#define D0F0x98_x4A_Reserved_31_31_WIDTH 1 +#define D0F0x98_x4A_Reserved_31_31_MASK 0x80000000 + +/// D0F0x98_x4A +typedef union { + struct { ///< + UINT32 Reserved_23_0:24; ///< + UINT32 SoftOverrideClk6:1; ///< + UINT32 SoftOverrideClk5:1; ///< + UINT32 SoftOverrideClk4:1; ///< + UINT32 SoftOverrideClk3:1; ///< + UINT32 SoftOverrideClk2:1; ///< + UINT32 SoftOverrideClk1:1; ///< + UINT32 SoftOverrideClk0:1; ///< + UINT32 Reserved_31_31:1; ///< + + } Field; + + UINT32 Value; +} D0F0x98_x4A_STRUCT; + + + + + + + + + + + +/// D0F0xBC_x3FA04 +typedef union { + struct { ///< + UINT32 Bitfield_15_0:16; ///< + UINT32 Bitfield_31_16:16; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB4753_STRUCT; + +// **** D0F0xE4_PHY_0004 Register Definition **** +// Address +#define D0F0xE4_PHY_0004_ADDRESS 0x0004 +// Type +#define D0F0xE4_PHY_0004_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_PHY_0004_Reserved_15_0_OFFSET 0 +#define D0F0xE4_PHY_0004_Reserved_15_0_WIDTH 16 +#define D0F0xE4_PHY_0004_Reserved_15_0_MASK 0xFFFF +#define D0F0xE4_PHY_0004_CfgIdleDetTh_OFFSET 16 +#define D0F0xE4_PHY_0004_CfgIdleDetTh_WIDTH 2 +#define D0F0xE4_PHY_0004_CfgIdleDetTh_MASK 0x30000 +#define D0F0xE4_PHY_0004_Reserved_31_18_OFFSET 18 +#define D0F0xE4_PHY_0004_Reserved_31_18_WIDTH 14 +#define D0F0xE4_PHY_0004_Reserved_31_18_MASK 0xFFFC0000 + +/// D0F0xE4_PHY_0004 +typedef union { + struct { ///< + UINT32 Reserved_15_0:16; ///< + UINT32 CfgIdleDetTh:2 ; ///< + UINT32 Reserved_31_18:14; ///< + } Field; + UINT32 Value; +} D0F0xE4_PHY_0004_STRUCT; + +// **** D0F0xE4_PHY_4440 Register Definition **** +// Address +#define D0F0xE4_PHY_4440_ADDRESS 0x4440 +// Type +#define D0F0xE4_PHY_4440_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_PHY_4440_Reserved_12_0_OFFSET 0 +#define D0F0xE4_PHY_4440_Reserved_12_0_WIDTH 13 +#define D0F0xE4_PHY_4440_Reserved_12_0_MASK 0x1FFF +#define D0F0xE4_PHY_4440_PllDbgRoIPFDResetCntrl_OFFSET 13 +#define D0F0xE4_PHY_4440_PllDbgRoIPFDResetCntrl_WIDTH 2 +#define D0F0xE4_PHY_4440_PllDbgRoIPFDResetCntrl_MASK 0x6000 +#define D0F0xE4_PHY_4440_Reserved_31_15_OFFSET 15 +#define D0F0xE4_PHY_4440_Reserved_31_15_WIDTH 17 +#define D0F0xE4_PHY_4440_Reserved_31_15_MASK 0xFFFF1000 + +/// D0F0xE4_PHY_4440 +typedef union { + struct { ///< + UINT32 Reserved_12_0:13; ///< + UINT32 PllDbgRoIPFDResetCntrl:2 ; ///< + UINT32 Reserved_31_15:17; ///< + } Field; + UINT32 Value; +} D0F0xE4_PHY_4440_STRUCT; + +// **** D0F0xE4_PHY_4450 Register Definition **** +// Address +#define D0F0xE4_PHY_4450_ADDRESS 0x4450 +// Type +#define D0F0xE4_PHY_4450_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_PHY_4450_PllCfgROBWCntrlOvrdVal0_OFFSET 0 +#define D0F0xE4_PHY_4450_PllCfgROBWCntrlOvrdVal0_WIDTH 8 +#define D0F0xE4_PHY_4450_PllCfgROBWCntrlOvrdVal0_MASK 0xFF +#define D0F0xE4_PHY_4450_Reserved_29_8_OFFSET 8 +#define D0F0xE4_PHY_4450_Reserved_29_8_WIDTH 22 +#define D0F0xE4_PHY_4450_Reserved_29_8_MASK 0x3FFFFF00 +#define D0F0xE4_PHY_4450_PllCfgROVTOIBiasCntrlOvrdVal0_OFFSET 30 +#define D0F0xE4_PHY_4450_PllCfgROVTOIBiasCntrlOvrdVal0_WIDTH 1 +#define D0F0xE4_PHY_4450_PllCfgROVTOIBiasCntrlOvrdVal0_MASK 0x40000000 +#define D0F0xE4_PHY_4450_Reserved_31_31_OFFSET 31 +#define D0F0xE4_PHY_4450_Reserved_31_31_WIDTH 1 +#define D0F0xE4_PHY_4450_Reserved_31_31_MASK 0x80000000 + +/// D0F0xE4_PHY_4450 +typedef union { + struct { ///< + UINT32 PllCfgROBWCntrlOvrdVal0:8 ; ///< + UINT32 Reserved_29_8:22; ///< + UINT32 PllCfgROVTOIBiasCntrlOvrdVal0:1 ; ///< + UINT32 Reserved_31_31:1 ; ///< + } Field; + UINT32 Value; +} D0F0xE4_PHY_4450_STRUCT; + +// **** D0F0xE4_WRAP_0800 Register Definition **** +// Address +#define D0F0xE4_WRAP_0800_ADDRESS 0x800 +// Type +#define D0F0xE4_WRAP_0800_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_0800_HoldTraining_OFFSET 0 +#define D0F0xE4_WRAP_0800_HoldTraining_WIDTH 1 +#define D0F0xE4_WRAP_0800_HoldTraining_MASK 0x1 +#define D0F0xE4_WRAP_0800_Reserved_31_1_OFFSET 1 +#define D0F0xE4_WRAP_0800_Reserved_31_1_WIDTH 31 +#define D0F0xE4_WRAP_0800_Reserved_31_1_MASK 0xFFFFFFFE + +/// D0F0xE4_WRAP_0800 +typedef union { + struct { ///< + UINT32 HoldTraining:1; ///< + UINT32 Reserved_31_1:31; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_0800_STRUCT; + +typedef union { + struct { ///< + UINT32 Reserved_23_0:24; ///< + UINT32 bit_31_24; + + } Field; + + UINT32 Value; +} GnbRegistersKB4915_STRUCT; + +typedef union { + struct { ///< + UINT32 Reserved_23_0:24; ///< + UINT32 bit_31_24:8; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB4940_STRUCT; + +typedef union { + struct { ///< + UINT32 Reserved_23_0:24; ///< + UINT32 bit_31_24:8; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB4965_STRUCT; + +typedef union { + struct { ///< + UINT32 Reserved_23_0:24; ///< + UINT32 bit_31_24:8; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB4990_STRUCT; + +typedef union { + struct { ///< + UINT32 Reserved_23_0:24; ///< + UINT32 bit_31_24:8; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB5015_STRUCT; + +// **** D0F0xE4_WRAP_8011 Register Definition **** +// Address +#define D0F0xE4_WRAP_8011_ADDRESS 0x8011 +// Type +#define D0F0xE4_WRAP_8011_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_OFFSET 0 +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkDynGateLatency_MASK 0x3F +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_OFFSET 6 +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkPermGateEven_MASK 0x40 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_OFFSET 7 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkDynGateEnable_MASK 0x80 +#define D0F0xE4_WRAP_8011_TxclkPermStop_OFFSET 8 +#define D0F0xE4_WRAP_8011_TxclkPermStop_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkPermStop_MASK 0x100 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_OFFSET 9 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkRegsGateEnable_MASK 0x200 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_OFFSET 10 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkRegsGateLatency_MASK 0xFC00 +#define D0F0xE4_WRAP_8011_Reserved_16_16_OFFSET 16 +#define D0F0xE4_WRAP_8011_Reserved_16_16_WIDTH 1 +#define D0F0xE4_WRAP_8011_Reserved_16_16_MASK 0x10000 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_OFFSET 17 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8011_TxclkPermGateLatency_MASK 0x7E0000 +#define D0F0xE4_WRAP_8011_Bitfield_23_23_OFFSET 23 +#define D0F0xE4_WRAP_8011_Bitfield_23_23_WIDTH 1 +#define D0F0xE4_WRAP_8011_Bitfield_23_23_MASK 0x800000 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_OFFSET 24 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8011_TxclkLcntGateEnable_MASK 0x1000000 +#define D0F0xE4_WRAP_8011_Reserved_25_25_OFFSET 25 +#define D0F0xE4_WRAP_8011_Reserved_25_25_WIDTH 1 +#define D0F0xE4_WRAP_8011_Reserved_25_25_MASK 0x2000000 +#define D0F0xE4_WRAP_8011_Reserved_31_26_OFFSET 26 +#define D0F0xE4_WRAP_8011_Reserved_31_26_WIDTH 6 +#define D0F0xE4_WRAP_8011_Reserved_31_26_MASK 0xFC000000 + +/// D0F0xE4_WRAP_8011 +typedef union { + struct { ///< + UINT32 TxclkDynGateLatency:6; ///< + UINT32 TxclkPermGateEven:1; ///< + UINT32 TxclkDynGateEnable:1; ///< + UINT32 TxclkPermStop:1; ///< + UINT32 TxclkRegsGateEnable:1; ///< + UINT32 TxclkRegsGateLatency:6; ///< + UINT32 Reserved_16_16:1; ///< + UINT32 TxclkPermGateLatency:6; ///< + UINT32 Bitfield_23_23:1; ///< + UINT32 TxclkLcntGateEnable:1; ///< + UINT32 Reserved_25_25:1; ///< + UINT32 Reserved_31_26:6; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8011_STRUCT; + +// **** D0F0xE4_WRAP_8012 Register Definition **** +// Address +#define D0F0xE4_WRAP_8012_ADDRESS 0x8012 +// Type +#define D0F0xE4_WRAP_8012_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8012_Pif1xIdleGateLatency_OFFSET 0 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateLatency_MASK 0x3F +#define D0F0xE4_WRAP_8012_Reserved_6_6_OFFSET 6 +#define D0F0xE4_WRAP_8012_Reserved_6_6_WIDTH 1 +#define D0F0xE4_WRAP_8012_Reserved_6_6_MASK 0x40 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateEnable_OFFSET 7 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8012_Pif1xIdleGateEnable_MASK 0x80 +#define D0F0xE4_WRAP_8012_Pif1xIdleResumeLatency_OFFSET 8 +#define D0F0xE4_WRAP_8012_Pif1xIdleResumeLatency_WIDTH 6 +#define D0F0xE4_WRAP_8012_Pif1xIdleResumeLatency_MASK 0x3F00 +#define D0F0xE4_WRAP_8012_Reserved_31_14_OFFSET 14 +#define D0F0xE4_WRAP_8012_Reserved_31_14_WIDTH 18 +#define D0F0xE4_WRAP_8012_Reserved_31_14_MASK 0xFFFFC000 + +/// D0F0xE4_WRAP_8012 +typedef union { + struct { ///< + UINT32 Pif1xIdleGateLatency:6; ///< + UINT32 Reserved_6_6:1; ///< + UINT32 Pif1xIdleGateEnable:1; ///< + UINT32 Pif1xIdleResumeLatency:6; ///< + UINT32 Reserved_31_14:18; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8012_STRUCT; + +// **** D0F0xE4_WRAP_8013 Register Definition **** +// Address +#define D0F0xE4_WRAP_8013_ADDRESS 0x8013 +// Type +#define D0F0xE4_WRAP_8013_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8013_MasterPciePllA_OFFSET 0 +#define D0F0xE4_WRAP_8013_MasterPciePllA_WIDTH 1 +#define D0F0xE4_WRAP_8013_MasterPciePllA_MASK 0x1 +#define D0F0xE4_WRAP_8013_MasterPciePllB_OFFSET 1 +#define D0F0xE4_WRAP_8013_MasterPciePllB_WIDTH 1 +#define D0F0xE4_WRAP_8013_MasterPciePllB_MASK 0x2 +#define D0F0xE4_WRAP_8013_Reserved_2_2_OFFSET 2 +#define D0F0xE4_WRAP_8013_Reserved_2_2_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_2_2_MASK 0x4 +#define D0F0xE4_WRAP_8013_Reserved_3_3_OFFSET 3 +#define D0F0xE4_WRAP_8013_Reserved_3_3_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_3_3_MASK 0x8 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideA_OFFSET 4 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideA_WIDTH 1 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideA_MASK 0x10 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideB_OFFSET 5 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideB_WIDTH 1 +#define D0F0xE4_WRAP_8013_ClkDividerResetOverrideB_MASK 0x20 +#define D0F0xE4_WRAP_8013_Reserved_6_6_OFFSET 6 +#define D0F0xE4_WRAP_8013_Reserved_6_6_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_6_6_MASK 0x40 +#define D0F0xE4_WRAP_8013_Reserved_7_7_OFFSET 7 +#define D0F0xE4_WRAP_8013_Reserved_7_7_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_7_7_MASK 0x80 +#define D0F0xE4_WRAP_8013_TxclkSelCoreOverride_OFFSET 8 +#define D0F0xE4_WRAP_8013_TxclkSelCoreOverride_WIDTH 1 +#define D0F0xE4_WRAP_8013_TxclkSelCoreOverride_MASK 0x100 +#define D0F0xE4_WRAP_8013_TxclkSelPifAOverride_OFFSET 9 +#define D0F0xE4_WRAP_8013_TxclkSelPifAOverride_WIDTH 1 +#define D0F0xE4_WRAP_8013_TxclkSelPifAOverride_MASK 0x200 +#define D0F0xE4_WRAP_8013_TxclkSelPifBOverride_OFFSET 10 +#define D0F0xE4_WRAP_8013_TxclkSelPifBOverride_WIDTH 1 +#define D0F0xE4_WRAP_8013_TxclkSelPifBOverride_MASK 0x400 +#define D0F0xE4_WRAP_8013_Reserved_11_11_OFFSET 11 +#define D0F0xE4_WRAP_8013_Reserved_11_11_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_11_11_MASK 0x800 +#define D0F0xE4_WRAP_8013_Reserved_12_12_OFFSET 12 +#define D0F0xE4_WRAP_8013_Reserved_12_12_WIDTH 1 +#define D0F0xE4_WRAP_8013_Reserved_12_12_MASK 0x1000 +#define D0F0xE4_WRAP_8013_PhyRxIsoDis_OFFSET 13 +#define D0F0xE4_WRAP_8013_PhyRxIsoDis_WIDTH 2 +#define D0F0xE4_WRAP_8013_PhyRxIsoDis_MASK 0x6000 +#define D0F0xE4_WRAP_8013_Reserved_31_15_OFFSET 15 +#define D0F0xE4_WRAP_8013_Reserved_31_15_WIDTH 17 +#define D0F0xE4_WRAP_8013_Reserved_31_15_MASK 0xFFFF8000 + +/// D0F0xE4_WRAP_8013 +typedef union { + struct { ///< + UINT32 MasterPciePllA:1; ///< + UINT32 MasterPciePllB:1; ///< + UINT32 Reserved_2_2:1; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 ClkDividerResetOverrideA:1; ///< + UINT32 ClkDividerResetOverrideB:1; ///< + UINT32 Reserved_6_6:1; ///< + UINT32 Reserved_7_7:1; ///< + UINT32 TxclkSelCoreOverride:1; ///< + UINT32 TxclkSelPifAOverride:1; ///< + UINT32 TxclkSelPifBOverride:1; ///< + UINT32 Reserved_11_11:1; ///< + UINT32 Reserved_12_12:1; ///< + UINT32 PhyRxIsoDis:2; ///< + UINT32 Reserved_31_15:17; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8013_STRUCT; + +// **** D0F0xE4_WRAP_8014 Register Definition **** +// Address +#define D0F0xE4_WRAP_8014_ADDRESS 0x8014 +// Type +#define D0F0xE4_WRAP_8014_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_OFFSET 0 +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPermGateEnable_MASK 0x1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_OFFSET 1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPrbsGateEnable_MASK 0x2 +#define D0F0xE4_WRAP_8014_Reserved_2_2_OFFSET 2 +#define D0F0xE4_WRAP_8014_Reserved_2_2_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_2_2_MASK 0x4 +#define D0F0xE4_WRAP_8014_Reserved_3_3_OFFSET 3 +#define D0F0xE4_WRAP_8014_Reserved_3_3_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_3_3_MASK 0x8 +#define D0F0xE4_WRAP_8014_Reserved_4_4_OFFSET 4 +#define D0F0xE4_WRAP_8014_Reserved_4_4_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_4_4_MASK 0x10 +#define D0F0xE4_WRAP_8014_Reserved_5_5_OFFSET 5 +#define D0F0xE4_WRAP_8014_Reserved_5_5_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_5_5_MASK 0x20 +#define D0F0xE4_WRAP_8014_Reserved_11_6_OFFSET 6 +#define D0F0xE4_WRAP_8014_Reserved_11_6_WIDTH 6 +#define D0F0xE4_WRAP_8014_Reserved_11_6_MASK 0xFC0 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_OFFSET 12 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_PcieGatePifA1xEnable_MASK 0x1000 +#define D0F0xE4_WRAP_8014_PcieGatePifB1xEnable_OFFSET 13 +#define D0F0xE4_WRAP_8014_PcieGatePifB1xEnable_WIDTH 1 +#define D0F0xE4_WRAP_8014_PcieGatePifB1xEnable_MASK 0x2000 +#define D0F0xE4_WRAP_8014_Reserved_14_14_OFFSET 14 +#define D0F0xE4_WRAP_8014_Reserved_14_14_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_14_14_MASK 0x4000 +#define D0F0xE4_WRAP_8014_Reserved_15_15_OFFSET 15 +#define D0F0xE4_WRAP_8014_Reserved_15_15_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_15_15_MASK 0x8000 +#define D0F0xE4_WRAP_8014_Reserved_19_16_OFFSET 16 +#define D0F0xE4_WRAP_8014_Reserved_19_16_WIDTH 4 +#define D0F0xE4_WRAP_8014_Reserved_19_16_MASK 0xF0000 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_OFFSET 20 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_WIDTH 1 +#define D0F0xE4_WRAP_8014_TxclkPermGateOnlyWhenPllPwrDn_MASK 0x100000 +#define D0F0xE4_WRAP_8014_Reserved_23_21_OFFSET 21 +#define D0F0xE4_WRAP_8014_Reserved_23_21_WIDTH 3 +#define D0F0xE4_WRAP_8014_Reserved_23_21_MASK 0xE00000 +#define D0F0xE4_WRAP_8014_Reserved_24_24_OFFSET 24 +#define D0F0xE4_WRAP_8014_Reserved_24_24_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_24_24_MASK 0x1000000 +#define D0F0xE4_WRAP_8014_Reserved_25_25_OFFSET 25 +#define D0F0xE4_WRAP_8014_Reserved_25_25_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_25_25_MASK 0x2000000 +#define D0F0xE4_WRAP_8014_Reserved_26_26_OFFSET 26 +#define D0F0xE4_WRAP_8014_Reserved_26_26_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_26_26_MASK 0x4000000 +#define D0F0xE4_WRAP_8014_Reserved_27_27_OFFSET 27 +#define D0F0xE4_WRAP_8014_Reserved_27_27_WIDTH 1 +#define D0F0xE4_WRAP_8014_Reserved_27_27_MASK 0x8000000 +#define D0F0xE4_WRAP_8014_SpareRegRw_OFFSET 28 +#define D0F0xE4_WRAP_8014_SpareRegRw_WIDTH 4 +#define D0F0xE4_WRAP_8014_SpareRegRw_MASK 0xF0000000 + +/// D0F0xE4_WRAP_8014 +typedef union { + struct { ///< + UINT32 TxclkPermGateEnable:1; ///< + UINT32 TxclkPrbsGateEnable:1; ///< + UINT32 Reserved_2_2:1; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 Reserved_4_4:1; ///< + UINT32 Reserved_5_5:1; ///< + UINT32 Reserved_11_6:6; ///< + UINT32 PcieGatePifA1xEnable:1; ///< + UINT32 PcieGatePifB1xEnable:1; ///< + UINT32 Reserved_14_14:1; ///< + UINT32 Reserved_15_15:1; ///< + UINT32 Reserved_19_16:4; ///< + UINT32 TxclkPermGateOnlyWhenPllPwrDn:1; ///< + UINT32 Reserved_23_21:3; ///< + UINT32 Reserved_24_24:1; ///< + UINT32 Reserved_25_25:1; ///< + UINT32 Reserved_26_26:1; ///< + UINT32 Reserved_27_27:1; ///< + UINT32 SpareRegRw:4; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8014_STRUCT; + +// **** D0F0xE4_WRAP_8015 Register Definition **** +// Address +#define D0F0xE4_WRAP_8015_ADDRESS 0x8015 +// Type +#define D0F0xE4_WRAP_8015_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8015_Bitfield_0_0_OFFSET 0 +#define D0F0xE4_WRAP_8015_Bitfield_0_0_WIDTH 1 +#define D0F0xE4_WRAP_8015_Bitfield_0_0_MASK 0x1 +#define D0F0xE4_WRAP_8015_Reserved_1_1_OFFSET 1 +#define D0F0xE4_WRAP_8015_Reserved_1_1_WIDTH 1 +#define D0F0xE4_WRAP_8015_Reserved_1_1_MASK 0x2 +#define D0F0xE4_WRAP_8015_Reserved_7_2_OFFSET 2 +#define D0F0xE4_WRAP_8015_Reserved_7_2_WIDTH 6 +#define D0F0xE4_WRAP_8015_Reserved_7_2_MASK 0xFC +#define D0F0xE4_WRAP_8015_Reserved_8_8_OFFSET 8 +#define D0F0xE4_WRAP_8015_Reserved_8_8_WIDTH 1 +#define D0F0xE4_WRAP_8015_Reserved_8_8_MASK 0x100 +#define D0F0xE4_WRAP_8015_Bitfield_9_9_OFFSET 9 +#define D0F0xE4_WRAP_8015_Bitfield_9_9_WIDTH 1 +#define D0F0xE4_WRAP_8015_Bitfield_9_9_MASK 0x200 +#define D0F0xE4_WRAP_8015_Bitfield_10_10_OFFSET 10 +#define D0F0xE4_WRAP_8015_Bitfield_10_10_WIDTH 1 +#define D0F0xE4_WRAP_8015_Bitfield_10_10_MASK 0x400 +#define D0F0xE4_WRAP_8015_Bitfield_11_11_OFFSET 11 +#define D0F0xE4_WRAP_8015_Bitfield_11_11_WIDTH 1 +#define D0F0xE4_WRAP_8015_Bitfield_11_11_MASK 0x800 +#define D0F0xE4_WRAP_8015_Reserved_13_12_OFFSET 12 +#define D0F0xE4_WRAP_8015_Reserved_13_12_WIDTH 2 +#define D0F0xE4_WRAP_8015_Reserved_13_12_MASK 0x3000 +#define D0F0xE4_WRAP_8015_Bitfield_15_14_OFFSET 14 +#define D0F0xE4_WRAP_8015_Bitfield_15_14_WIDTH 2 +#define D0F0xE4_WRAP_8015_Bitfield_15_14_MASK 0xC000 +#define D0F0xE4_WRAP_8015_RefclkRegsGateLatency_OFFSET 16 +#define D0F0xE4_WRAP_8015_RefclkRegsGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8015_RefclkRegsGateLatency_MASK 0x3F0000 +#define D0F0xE4_WRAP_8015_Reserved_22_22_OFFSET 22 +#define D0F0xE4_WRAP_8015_Reserved_22_22_WIDTH 1 +#define D0F0xE4_WRAP_8015_Reserved_22_22_MASK 0x400000 +#define D0F0xE4_WRAP_8015_RefclkRegsGateEnable_OFFSET 23 +#define D0F0xE4_WRAP_8015_RefclkRegsGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8015_RefclkRegsGateEnable_MASK 0x800000 +#define D0F0xE4_WRAP_8015_Reserved_31_24_OFFSET 24 +#define D0F0xE4_WRAP_8015_Reserved_31_24_WIDTH 8 +#define D0F0xE4_WRAP_8015_Reserved_31_24_MASK 0xFF000000 + +/// D0F0xE4_WRAP_8015 +typedef union { + struct { ///< + UINT32 Bitfield_0_0:1; ///< + UINT32 Reserved_1_1:1; ///< + UINT32 Reserved_7_2:6; ///< + UINT32 Reserved_8_8:1; ///< + UINT32 Bitfield_9_9:1; ///< + UINT32 Bitfield_10_10:1; ///< + UINT32 Bitfield_11_11:1; ///< + UINT32 Reserved_13_12:2; ///< + UINT32 Bitfield_15_14:2; ///< + UINT32 RefclkRegsGateLatency:6; ///< + UINT32 Reserved_22_22:1; ///< + UINT32 RefclkRegsGateEnable:1; ///< + UINT32 Reserved_31_24:8; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8015_STRUCT; + +// **** D0F0xE4_WRAP_8016 Register Definition **** +// Address +#define D0F0xE4_WRAP_8016_ADDRESS 0x8016 +// Type +#define D0F0xE4_WRAP_8016_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8016_CalibAckLatency_OFFSET 0 +#define D0F0xE4_WRAP_8016_CalibAckLatency_WIDTH 6 +#define D0F0xE4_WRAP_8016_CalibAckLatency_MASK 0x3F +#define D0F0xE4_WRAP_8016_Reserved_15_6_OFFSET 6 +#define D0F0xE4_WRAP_8016_Reserved_15_6_WIDTH 10 +#define D0F0xE4_WRAP_8016_Reserved_15_6_MASK 0xFFC0 +#define D0F0xE4_WRAP_8016_LclkDynGateLatency_OFFSET 16 +#define D0F0xE4_WRAP_8016_LclkDynGateLatency_WIDTH 6 +#define D0F0xE4_WRAP_8016_LclkDynGateLatency_MASK 0x3F0000 +#define D0F0xE4_WRAP_8016_LclkGateFree_OFFSET 22 +#define D0F0xE4_WRAP_8016_LclkGateFree_WIDTH 1 +#define D0F0xE4_WRAP_8016_LclkGateFree_MASK 0x400000 +#define D0F0xE4_WRAP_8016_LclkDynGateEnable_OFFSET 23 +#define D0F0xE4_WRAP_8016_LclkDynGateEnable_WIDTH 1 +#define D0F0xE4_WRAP_8016_LclkDynGateEnable_MASK 0x800000 +#define D0F0xE4_WRAP_8016_Reserved_31_24_OFFSET 24 +#define D0F0xE4_WRAP_8016_Reserved_31_24_WIDTH 8 +#define D0F0xE4_WRAP_8016_Reserved_31_24_MASK 0xFF000000 + +/// D0F0xE4_WRAP_8016 +typedef union { + struct { ///< + UINT32 CalibAckLatency:6; ///< + UINT32 Reserved_15_6:10; ///< + UINT32 LclkDynGateLatency:6; ///< + UINT32 LclkGateFree:1; ///< + UINT32 LclkDynGateEnable:1; ///< + UINT32 Reserved_31_24:8; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8016_STRUCT; + +// **** D0F0xE4_WRAP_8029 Register Definition **** +// Address +#define D0F0xE4_WRAP_8029_ADDRESS 0x8029 +// Type +#define D0F0xE4_WRAP_8029_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_WRAP_8029_LaneEnable_OFFSET 0 +#define D0F0xE4_WRAP_8029_LaneEnable_WIDTH 16 +#define D0F0xE4_WRAP_8029_LaneEnable_MASK 0xFFFF +#define D0F0xE4_WRAP_8029_Reserved_31_16_OFFSET 16 +#define D0F0xE4_WRAP_8029_Reserved_31_16_WIDTH 16 +#define D0F0xE4_WRAP_8029_Reserved_31_16_MASK 0xFFFF0000 + +/// D0F0xE4_WRAP_8029 +typedef union { + struct { ///< + UINT32 LaneEnable:16; ///< + UINT32 Reserved_31_16:16; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_WRAP_8029_STRUCT; + +// **** D0F0xE4_WRAP_8062 Register Definition **** +// Address +#define D0F0xE4_WRAP_8062_ADDRESS 0x8062 + +// Type +#define D0F0xE4_WRAP_8062_TYPE TYPE_D0F0xE4 +// Field Data +#define D0F0xE4_WRAP_8062_ReconfigureEn_OFFSET 0 +#define D0F0xE4_WRAP_8062_ReconfigureEn_WIDTH 1 +#define D0F0xE4_WRAP_8062_ReconfigureEn_MASK 0x1 +#define D0F0xE4_WRAP_8062_Reserved_1_1_OFFSET 1 +#define D0F0xE4_WRAP_8062_Reserved_1_1_WIDTH 1 +#define D0F0xE4_WRAP_8062_Reserved_1_1_MASK 0x2 +#define D0F0xE4_WRAP_8062_ResetPeriod_OFFSET 2 +#define D0F0xE4_WRAP_8062_ResetPeriod_WIDTH 3 +#define D0F0xE4_WRAP_8062_ResetPeriod_MASK 0x1c +#define D0F0xE4_WRAP_8062_Reserved_9_5_OFFSET 5 +#define D0F0xE4_WRAP_8062_Reserved_9_5_WIDTH 5 +#define D0F0xE4_WRAP_8062_Reserved_9_5_MASK 0x3e0 +#define D0F0xE4_WRAP_8062_BlockOnIdle_OFFSET 10 +#define D0F0xE4_WRAP_8062_BlockOnIdle_WIDTH 1 +#define D0F0xE4_WRAP_8062_BlockOnIdle_MASK 0x400 +#define D0F0xE4_WRAP_8062_ConfigXferMode_OFFSET 11 +#define D0F0xE4_WRAP_8062_ConfigXferMode_WIDTH 1 +#define D0F0xE4_WRAP_8062_ConfigXferMode_MASK 0x800 +#define D0F0xE4_WRAP_8062_Reserved_31_12_OFFSET 12 +#define D0F0xE4_WRAP_8062_Reserved_31_12_WIDTH 20 +#define D0F0xE4_WRAP_8062_Reserved_31_12_MASK 0xfffff000 + +/// D0F0xE4_WRAP_8062 +typedef union { + struct { ///< + UINT32 ReconfigureEn:1 ; ///< + UINT32 Reserved_1_1:1 ; ///< + UINT32 ResetPeriod:3 ; ///< + UINT32 Reserved_9_5:5 ; ///< + UINT32 BlockOnIdle:1 ; ///< + UINT32 ConfigXferMode:1 ; ///< + UINT32 Reserved_31_12:20; ///< + } Field; ///< + UINT32 Value; ///< +} D0F0xE4_WRAP_8062_STRUCT; + +// **** D0F0xE4_PIF_0011 Register Definition **** +// Address +#define D0F0xE4_PIF_0011_ADDRESS 0x11 +// Type +#define D0F0xE4_PIF_0011_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_PIF_0011_X2Lane10_OFFSET 0 +#define D0F0xE4_PIF_0011_X2Lane10_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane10_MASK 0x1 +#define D0F0xE4_PIF_0011_X2Lane32_OFFSET 1 +#define D0F0xE4_PIF_0011_X2Lane32_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane32_MASK 0x2 +#define D0F0xE4_PIF_0011_X2Lane54_OFFSET 2 +#define D0F0xE4_PIF_0011_X2Lane54_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane54_MASK 0x4 +#define D0F0xE4_PIF_0011_X2Lane76_OFFSET 3 +#define D0F0xE4_PIF_0011_X2Lane76_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane76_MASK 0x8 +#define D0F0xE4_PIF_0011_X2Lane98_OFFSET 4 +#define D0F0xE4_PIF_0011_X2Lane98_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane98_MASK 0x10 +#define D0F0xE4_PIF_0011_X2Lane1110_OFFSET 5 +#define D0F0xE4_PIF_0011_X2Lane1110_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane1110_MASK 0x20 +#define D0F0xE4_PIF_0011_X2Lane1312_OFFSET 6 +#define D0F0xE4_PIF_0011_X2Lane1312_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane1312_MASK 0x40 +#define D0F0xE4_PIF_0011_X2Lane1514_OFFSET 7 +#define D0F0xE4_PIF_0011_X2Lane1514_WIDTH 1 +#define D0F0xE4_PIF_0011_X2Lane1514_MASK 0x80 +#define D0F0xE4_PIF_0011_X4Lane30_OFFSET 8 +#define D0F0xE4_PIF_0011_X4Lane30_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane30_MASK 0x100 +#define D0F0xE4_PIF_0011_X4Lane74_OFFSET 9 +#define D0F0xE4_PIF_0011_X4Lane74_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane74_MASK 0x200 +#define D0F0xE4_PIF_0011_X4Lane118_OFFSET 10 +#define D0F0xE4_PIF_0011_X4Lane118_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane118_MASK 0x400 +#define D0F0xE4_PIF_0011_X4Lane1512_OFFSET 11 +#define D0F0xE4_PIF_0011_X4Lane1512_WIDTH 1 +#define D0F0xE4_PIF_0011_X4Lane1512_MASK 0x800 +#define D0F0xE4_PIF_0011_Reserved_15_12_OFFSET 12 +#define D0F0xE4_PIF_0011_Reserved_15_12_WIDTH 4 +#define D0F0xE4_PIF_0011_Reserved_15_12_MASK 0xF000 +#define D0F0xE4_PIF_0011_X8Lane70_OFFSET 16 +#define D0F0xE4_PIF_0011_X8Lane70_WIDTH 1 +#define D0F0xE4_PIF_0011_X8Lane70_MASK 0x10000 +#define D0F0xE4_PIF_0011_X8Lane158_OFFSET 17 +#define D0F0xE4_PIF_0011_X8Lane158_WIDTH 1 +#define D0F0xE4_PIF_0011_X8Lane158_MASK 0x20000 +#define D0F0xE4_PIF_0011_Reserved_19_18_OFFSET 18 +#define D0F0xE4_PIF_0011_Reserved_19_18_WIDTH 2 +#define D0F0xE4_PIF_0011_Reserved_19_18_MASK 0xC0000 +#define D0F0xE4_PIF_0011_X16Lane150_OFFSET 20 +#define D0F0xE4_PIF_0011_X16Lane150_WIDTH 1 +#define D0F0xE4_PIF_0011_X16Lane150_MASK 0x100000 +#define D0F0xE4_PIF_0011_Reserved_24_21_OFFSET 21 +#define D0F0xE4_PIF_0011_Reserved_24_21_WIDTH 4 +#define D0F0xE4_PIF_0011_Reserved_24_21_MASK 0x1E00000 +#define D0F0xE4_PIF_0011_MultiPif_OFFSET 25 +#define D0F0xE4_PIF_0011_MultiPif_WIDTH 1 +#define D0F0xE4_PIF_0011_MultiPif_MASK 0x2000000 +#define D0F0xE4_PIF_0011_Reserved_31_26_OFFSET 26 +#define D0F0xE4_PIF_0011_Reserved_31_26_WIDTH 6 +#define D0F0xE4_PIF_0011_Reserved_31_26_MASK 0xFC000000 + +/// D0F0xE4_PIF_0011 +typedef union { + struct { ///< + UINT32 X2Lane10:1; ///< + UINT32 X2Lane32:1; ///< + UINT32 X2Lane54:1; ///< + UINT32 X2Lane76:1; ///< + UINT32 X2Lane98:1; ///< + UINT32 X2Lane1110:1; ///< + UINT32 X2Lane1312:1; ///< + UINT32 X2Lane1514:1; ///< + UINT32 X4Lane30:1; ///< + UINT32 X4Lane74:1; ///< + UINT32 X4Lane118:1; ///< + UINT32 X4Lane1512:1; ///< + UINT32 Reserved_15_12:4; ///< + UINT32 X8Lane70:1; ///< + UINT32 X8Lane158:1; ///< + UINT32 Reserved_19_18:2; ///< + UINT32 X16Lane150:1; ///< + UINT32 Reserved_24_21:4; ///< + UINT32 MultiPif:1; ///< + UINT32 Reserved_31_26:6; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_PIF_0011_STRUCT; + +// **** D0F0xE4_PIF_0012 Register Definition **** +// Address +#define D0F0xE4_PIF_0012_ADDRESS 0x12 +// Type +#define D0F0xE4_PIF_0012_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_OFFSET 0 +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_TxPowerStateInTxs2_MASK 0x7 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_OFFSET 3 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_WIDTH 1 +#define D0F0xE4_PIF_0012_ForceRxEnInL0s_MASK 0x8 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_OFFSET 4 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_RxPowerStateInRxs2_MASK 0x70 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_OFFSET 7 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPowerStateInTxs2_MASK 0x380 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_OFFSET 10 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPowerStateInOff_MASK 0x1C00 +#define D0F0xE4_PIF_0012_Reserved_15_13_OFFSET 13 +#define D0F0xE4_PIF_0012_Reserved_15_13_WIDTH 3 +#define D0F0xE4_PIF_0012_Reserved_15_13_MASK 0xE000 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_OFFSET 16 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_WIDTH 1 +#define D0F0xE4_PIF_0012_Tx2p5clkClockGatingEn_MASK 0x10000 +#define D0F0xE4_PIF_0012_Reserved_23_17_OFFSET 17 +#define D0F0xE4_PIF_0012_Reserved_23_17_WIDTH 7 +#define D0F0xE4_PIF_0012_Reserved_23_17_MASK 0xFE0000 +#define D0F0xE4_PIF_0012_PllRampUpTime_OFFSET 24 +#define D0F0xE4_PIF_0012_PllRampUpTime_WIDTH 3 +#define D0F0xE4_PIF_0012_PllRampUpTime_MASK 0x7000000 +#define D0F0xE4_PIF_0012_Reserved_27_27_OFFSET 27 +#define D0F0xE4_PIF_0012_Reserved_27_27_WIDTH 1 +#define D0F0xE4_PIF_0012_Reserved_27_27_MASK 0x8000000 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_OFFSET 28 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_WIDTH 1 +#define D0F0xE4_PIF_0012_PllPwrOverrideEn_MASK 0x10000000 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_OFFSET 29 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_WIDTH 3 +#define D0F0xE4_PIF_0012_PllPwrOverrideVal_MASK 0xE0000000 + +/// D0F0xE4_PIF_0012 +typedef union { + struct { ///< + UINT32 TxPowerStateInTxs2:3; ///< + UINT32 ForceRxEnInL0s:1; ///< + UINT32 RxPowerStateInRxs2:3; ///< + UINT32 PllPowerStateInTxs2:3; ///< + UINT32 PllPowerStateInOff:3; ///< + UINT32 Reserved_15_13:3; ///< + UINT32 Tx2p5clkClockGatingEn:1; ///< + UINT32 Reserved_23_17:7; ///< + UINT32 PllRampUpTime:3; ///< + UINT32 Reserved_27_27:1; ///< + UINT32 PllPwrOverrideEn:1; ///< + UINT32 PllPwrOverrideVal:3; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_PIF_0012_STRUCT; + +// **** D0F0xE4_CORE_0002 Register Definition **** +// Address +#define D0F0xE4_CORE_0002_ADDRESS 0x0002 +// Type +#define D0F0xE4_CORE_0002_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_CORE_0002_HwDebug_0_OFFSET 0 +#define D0F0xE4_CORE_0002_HwDebug_0_WIDTH 1 +#define D0F0xE4_CORE_0002_HwDebug_0_MASK 0x1 +#define D0F0xE4_CORE_0002_Reserved_31_1_OFFSET 1 +#define D0F0xE4_CORE_0002_Reserved_31_1_WIDTH 31 +#define D0F0xE4_CORE_0002_Reserved_31_1_MASK 0xFFFFFFFE + +/// D0F0xE4_CORE_0002 +typedef union { + struct { ///< + UINT32 HwDebug_0:1; ///< + UINT32 Reserved_31_1:31; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_CORE_0002_STRUCT; + +// **** D0F0xE4_CORE_0010 Register Definition **** +// Address +#define D0F0xE4_CORE_0010_ADDRESS 0x10 +// Type +#define D0F0xE4_CORE_0010_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_CORE_0010_HwInitWrLock_OFFSET 0 +#define D0F0xE4_CORE_0010_HwInitWrLock_WIDTH 1 +#define D0F0xE4_CORE_0010_HwInitWrLock_MASK 0x1 +#define D0F0xE4_CORE_0010_Reserved_8_1_OFFSET 1 +#define D0F0xE4_CORE_0010_Reserved_8_1_WIDTH 8 +#define D0F0xE4_CORE_0010_Reserved_8_1_MASK 0x1FE +#define D0F0xE4_CORE_0010_UmiNpMemWrite_OFFSET 9 +#define D0F0xE4_CORE_0010_UmiNpMemWrite_WIDTH 1 +#define D0F0xE4_CORE_0010_UmiNpMemWrite_MASK 0x200 +#define D0F0xE4_CORE_0010_RxUmiAdjPayloadSize_OFFSET 10 +#define D0F0xE4_CORE_0010_RxUmiAdjPayloadSize_WIDTH 3 +#define D0F0xE4_CORE_0010_RxUmiAdjPayloadSize_MASK 0x1C00 +#define D0F0xE4_CORE_0010_Reserved_31_13_OFFSET 13 +#define D0F0xE4_CORE_0010_Reserved_31_13_WIDTH 19 +#define D0F0xE4_CORE_0010_Reserved_31_13_MASK 0xFFFFE000 + +/// D0F0xE4_CORE_0010 +typedef union { + struct { ///< + UINT32 HwInitWrLock:1; ///< + UINT32 Reserved_8_1:8; ///< + UINT32 UmiNpMemWrite:1; ///< + UINT32 RxUmiAdjPayloadSize:3; ///< + UINT32 Reserved_31_13:19; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_CORE_0010_STRUCT; + +// **** D0F0xE4_CORE_0011 Register Definition **** +// Address +#define D0F0xE4_CORE_0011_ADDRESS 0x11 +// Type +#define D0F0xE4_CORE_0011_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_CORE_0011_DynClkLatency_OFFSET 0 +#define D0F0xE4_CORE_0011_DynClkLatency_WIDTH 4 +#define D0F0xE4_CORE_0011_DynClkLatency_MASK 0xF +#define D0F0xE4_CORE_0011_Reserved_31_4_OFFSET 4 +#define D0F0xE4_CORE_0011_Reserved_31_4_WIDTH 28 +#define D0F0xE4_CORE_0011_Reserved_31_4_MASK 0xFFFFFFF0 + +/// D0F0xE4_CORE_0011 +typedef union { + struct { ///< + UINT32 DynClkLatency:4; ///< + UINT32 Reserved_31_4:28; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_CORE_0011_STRUCT; + +// **** D0F0xE4_CORE_001C Register Definition **** +// Address +#define D0F0xE4_CORE_001C_ADDRESS 0x1C +// Type +#define D0F0xE4_CORE_001C_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_CORE_001C_TxArbRoundRobinEn_OFFSET 0 +#define D0F0xE4_CORE_001C_TxArbRoundRobinEn_WIDTH 1 +#define D0F0xE4_CORE_001C_TxArbRoundRobinEn_MASK 0x1 +#define D0F0xE4_CORE_001C_TxArbSlvLimit_OFFSET 1 +#define D0F0xE4_CORE_001C_TxArbSlvLimit_WIDTH 5 +#define D0F0xE4_CORE_001C_TxArbSlvLimit_MASK 0x3E +#define D0F0xE4_CORE_001C_TxArbMstLimit_OFFSET 6 +#define D0F0xE4_CORE_001C_TxArbMstLimit_WIDTH 5 +#define D0F0xE4_CORE_001C_TxArbMstLimit_MASK 0x7C0 +#define D0F0xE4_CORE_001C_Reserved_31_11_OFFSET 11 +#define D0F0xE4_CORE_001C_Reserved_31_11_WIDTH 21 +#define D0F0xE4_CORE_001C_Reserved_31_11_MASK 0xFFFFF800 + +/// D0F0xE4_CORE_001C +typedef union { + struct { ///< + UINT32 TxArbRoundRobinEn:1; ///< + UINT32 TxArbSlvLimit:5; ///< + UINT32 TxArbMstLimit:5; ///< + UINT32 Reserved_31_11:21; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_CORE_001C_STRUCT; + +// **** D0F0xE4_CORE_0020 Register Definition **** +// Address +#define D0F0xE4_CORE_0020_ADDRESS 0x0020 +// Type +#define D0F0xE4_CORE_0020_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_CORE_0020_Reserved_7_0_OFFSET 0 +#define D0F0xE4_CORE_0020_Reserved_7_0_WIDTH 8 +#define D0F0xE4_CORE_0020_Reserved_7_0_MASK 0xFF +#define D0F0xE4_CORE_0020_CiSlvOrderingDis_OFFSET 8 +#define D0F0xE4_CORE_0020_CiSlvOrderingDis_WIDTH 1 +#define D0F0xE4_CORE_0020_CiSlvOrderingDis_MASK 0x100 +#define D0F0xE4_CORE_0020_CiRcOrderingDis_OFFSET 9 +#define D0F0xE4_CORE_0020_CiRcOrderingDis_WIDTH 1 +#define D0F0xE4_CORE_0020_CiRcOrderingDis_MASK 0x200 +#define D0F0xE4_CORE_0020_Reserved_31_10_OFFSET 10 +#define D0F0xE4_CORE_0020_Reserved_31_10_WIDTH 22 +#define D0F0xE4_CORE_0020_Reserved_31_10_MASK 0xFFFFFC00 + +/// D0F0xE4_CORE_0020 +typedef union { + struct { ///< + UINT32 Reserved_7_0:8; ///< + UINT32 CiSlvOrderingDis:1; ///< + UINT32 CiRcOrderingDis:1; ///< + UINT32 Reserved_31_10:22; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_CORE_0020_STRUCT; + +// **** D0F0xE4_CORE_0040 Register Definition **** +// Address +#define D0F0xE4_CORE_0040_ADDRESS 0x40 +// Type +#define D0F0xE4_CORE_0040_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_CORE_0040_Reserved_13_0_OFFSET 0 +#define D0F0xE4_CORE_0040_Reserved_13_0_WIDTH 14 +#define D0F0xE4_CORE_0040_Reserved_13_0_MASK 0x3FFF +#define D0F0xE4_CORE_0040_PElecIdleMode_OFFSET 14 +#define D0F0xE4_CORE_0040_PElecIdleMode_WIDTH 2 +#define D0F0xE4_CORE_0040_PElecIdleMode_MASK 0xC000 +#define D0F0xE4_CORE_0040_Reserved_31_16_OFFSET 16 +#define D0F0xE4_CORE_0040_Reserved_31_16_WIDTH 16 +#define D0F0xE4_CORE_0040_Reserved_31_16_MASK 0xFFFF0000 + +/// D0F0xE4_CORE_0040 +typedef union { + struct { ///< + UINT32 Reserved_13_0:14; ///< + UINT32 PElecIdleMode:2; ///< + UINT32 Reserved_31_16:16; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_CORE_0040_STRUCT; + +// **** D0F0xE4_CORE_00B0 Register Definition **** +// Address +#define D0F0xE4_CORE_00B0_ADDRESS 0xB0 +// Type +#define D0F0xE4_CORE_00B0_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_CORE_00B0_Reserved_1_0_OFFSET 0 +#define D0F0xE4_CORE_00B0_Reserved_1_0_WIDTH 2 +#define D0F0xE4_CORE_00B0_Reserved_1_0_MASK 0x3 +#define D0F0xE4_CORE_00B0_StrapF0MsiEn_OFFSET 2 +#define D0F0xE4_CORE_00B0_StrapF0MsiEn_WIDTH 1 +#define D0F0xE4_CORE_00B0_StrapF0MsiEn_MASK 0x4 +#define D0F0xE4_CORE_00B0_Reserved_4_3_OFFSET 3 +#define D0F0xE4_CORE_00B0_Reserved_4_3_WIDTH 2 +#define D0F0xE4_CORE_00B0_Reserved_4_3_MASK 0x18 +#define D0F0xE4_CORE_00B0_StrapF0AerEn_OFFSET 5 +#define D0F0xE4_CORE_00B0_StrapF0AerEn_WIDTH 1 +#define D0F0xE4_CORE_00B0_StrapF0AerEn_MASK 0x20 +#define D0F0xE4_CORE_00B0_Reserved_31_6_OFFSET 6 +#define D0F0xE4_CORE_00B0_Reserved_31_6_WIDTH 26 +#define D0F0xE4_CORE_00B0_Reserved_31_6_MASK 0xFFFFFFC0 + +/// D0F0xE4_CORE_00B0 +typedef union { + struct { ///< + UINT32 Reserved_1_0:2; ///< + UINT32 StrapF0MsiEn:1; ///< + UINT32 Reserved_4_3:2; ///< + UINT32 StrapF0AerEn:1; ///< + UINT32 Reserved_31_6:26; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_CORE_00B0_STRUCT; + +// **** D0F0xE4_CORE_00C1 Register Definition **** +// Address +#define D0F0xE4_CORE_00C1_ADDRESS 0xC1 +// Type +#define D0F0xE4_CORE_00C1_TYPE TYPE_D0F0xE4 + +// Field Data +#define D0F0xE4_CORE_00C1_StrapLinkBwNotificationCapEn_OFFSET 0 +#define D0F0xE4_CORE_00C1_StrapLinkBwNotificationCapEn_WIDTH 1 +#define D0F0xE4_CORE_00C1_StrapLinkBwNotificationCapEn_MASK 0x1 +#define D0F0xE4_CORE_00C1_StrapGen2Compliance_OFFSET 1 +#define D0F0xE4_CORE_00C1_StrapGen2Compliance_WIDTH 1 +#define D0F0xE4_CORE_00C1_StrapGen2Compliance_MASK 0x2 +#define D0F0xE4_CORE_00C1_Reserved_31_2_OFFSET 2 +#define D0F0xE4_CORE_00C1_Reserved_31_2_WIDTH 30 +#define D0F0xE4_CORE_00C1_Reserved_31_2_MASK 0xFFFFFFFC + +/// D0F0xE4_CORE_00C1 +typedef union { + struct { ///< + UINT32 StrapLinkBwNotificationCapEn:1; ///< + UINT32 StrapGen2Compliance:1; ///< + UINT32 Reserved_31_2:30; ///< + + } Field; + + UINT32 Value; +} D0F0xE4_CORE_00C1_STRUCT; + +// **** DxFxxE4_x70 Register Definition **** +// Address +#define DxFxxE4_x70_ADDRESS 0x70 +// Type +#define DxFxxE4_x70_TYPE TYPE_D2F1xE4 + +// Field Data +#define DxFxxE4_x70_Reserved_15_0_OFFSET 0 +#define DxFxxE4_x70_Reserved_15_0_WIDTH 16 +#define DxFxxE4_x70_Reserved_15_0_MASK 0xFFFF +#define DxFxxE4_x70_RxRcbCplTimeout_OFFSET 16 +#define DxFxxE4_x70_RxRcbCplTimeout_WIDTH 3 +#define DxFxxE4_x70_RxRcbCplTimeout_MASK 0x70000 +#define DxFxxE4_x70_RxRcbCplTimeoutMode_OFFSET 19 +#define DxFxxE4_x70_RxRcbCplTimeoutMode_WIDTH 1 +#define DxFxxE4_x70_RxRcbCplTimeoutMode_MASK 0x80000 +#define DxFxxE4_x70_Reserved_31_20_OFFSET 20 +#define DxFxxE4_x70_Reserved_31_20_WIDTH 12 +#define DxFxxE4_x70_Reserved_31_20_MASK 0xFFF00000 + +/// DxFxxE4_x70 +typedef union { + struct { ///< + UINT32 Reserved_15_0:16; ///< + UINT32 RxRcbCplTimeout:3; ///< + UINT32 RxRcbCplTimeoutMode:1; ///< + UINT32 Reserved_31_20:12; ///< + + } Field; + + UINT32 Value; +} DxFxxE4_x70_STRUCT; + +// **** DxFxxE4_xA0 Register Definition **** +// Address +#define DxFxxE4_xA0_ADDRESS 0xA0 +// Type +#define DxFxxE4_xA0_TYPE TYPE_D2F1xE4 + +// Field Data +#define DxFxxE4_xA0_Reserved_3_0_OFFSET 0 +#define DxFxxE4_xA0_Reserved_3_0_WIDTH 4 +#define DxFxxE4_xA0_Reserved_3_0_MASK 0xF +#define DxFxxE4_xA0_Lc16xClearTxPipe_OFFSET 4 +#define DxFxxE4_xA0_Lc16xClearTxPipe_WIDTH 4 +#define DxFxxE4_xA0_Lc16xClearTxPipe_MASK 0xF0 +#define DxFxxE4_xA0_LcL0sInactivity_OFFSET 8 +#define DxFxxE4_xA0_LcL0sInactivity_WIDTH 4 +#define DxFxxE4_xA0_LcL0sInactivity_MASK 0xF00 +#define DxFxxE4_xA0_LcL1Inactivity_OFFSET 12 +#define DxFxxE4_xA0_LcL1Inactivity_WIDTH 4 +#define DxFxxE4_xA0_LcL1Inactivity_MASK 0xF000 +#define DxFxxE4_xA0_Reserved_22_16_OFFSET 16 +#define DxFxxE4_xA0_Reserved_22_16_WIDTH 7 +#define DxFxxE4_xA0_Reserved_22_16_MASK 0x7F0000 +#define DxFxxE4_xA0_LcL1ImmediateAck_OFFSET 23 +#define DxFxxE4_xA0_LcL1ImmediateAck_WIDTH 1 +#define DxFxxE4_xA0_LcL1ImmediateAck_MASK 0x800000 +#define DxFxxE4_xA0_Reserved_31_24_OFFSET 24 +#define DxFxxE4_xA0_Reserved_31_24_WIDTH 8 +#define DxFxxE4_xA0_Reserved_31_24_MASK 0xFF000000 + +/// DxFxxE4_xA0 +typedef union { + struct { ///< + UINT32 Reserved_3_0:4; ///< + UINT32 Lc16xClearTxPipe:4; ///< + UINT32 LcL0sInactivity:4; ///< + UINT32 LcL1Inactivity:4; ///< + UINT32 Reserved_22_16:7; ///< + UINT32 LcL1ImmediateAck:1; ///< + UINT32 Reserved_31_24:8; ///< + + } Field; + + UINT32 Value; +} DxFxxE4_xA0_STRUCT; + +// **** DxFxxE4_xA1 Register Definition **** +// Address +#define DxFxxE4_xA1_ADDRESS 0xA1 +// Type +#define DxFxxE4_xA1_TYPE TYPE_D2F1xE4 + +// Field Data +#define DxFxxE4_xA1_Reserved_10_0_OFFSET 0 +#define DxFxxE4_xA1_Reserved_10_0_WIDTH 11 +#define DxFxxE4_xA1_Reserved_10_0_MASK 0x7FF +#define DxFxxE4_xA1_LcDontGotoL0sifL1Armed_OFFSET 11 +#define DxFxxE4_xA1_LcDontGotoL0sifL1Armed_WIDTH 1 +#define DxFxxE4_xA1_LcDontGotoL0sifL1Armed_MASK 0x800 +#define DxFxxE4_xA1_Reserved_31_12_OFFSET 12 +#define DxFxxE4_xA1_Reserved_31_12_WIDTH 20 +#define DxFxxE4_xA1_Reserved_31_12_MASK 0xFFFFF000 + +/// DxFxxE4_xA1 +typedef union { + struct { ///< + UINT32 Reserved_10_0:11; ///< + UINT32 LcDontGotoL0sifL1Armed:1; ///< + UINT32 Reserved_31_12:20; ///< + + } Field; + + UINT32 Value; +} DxFxxE4_xA1_STRUCT; + +// **** DxFxxE4_xA3 Register Definition **** +// Address +#define DxFxxE4_xA3_ADDRESS 0xA3 +// Type +#define DxFxxE4_xA3_TYPE TYPE_D2F1xE4 + +// Field Data +#define DxFxxE4_xA3_Reserved_8_0_OFFSET 0 +#define DxFxxE4_xA3_Reserved_8_0_WIDTH 9 +#define DxFxxE4_xA3_Reserved_8_0_MASK 0x1FF +#define DxFxxE4_xA3_LcXmitFtsBeforeRecovery_OFFSET 9 +#define DxFxxE4_xA3_LcXmitFtsBeforeRecovery_WIDTH 1 +#define DxFxxE4_xA3_LcXmitFtsBeforeRecovery_MASK 0x200 +#define DxFxxE4_xA3_Reserved_31_10_OFFSET 10 +#define DxFxxE4_xA3_Reserved_31_10_WIDTH 22 +#define DxFxxE4_xA3_Reserved_31_10_MASK 0xFFFFFC00 + +/// DxFxxE4_xA3 +typedef union { + struct { ///< + UINT32 Reserved_8_0:9; ///< + UINT32 LcXmitFtsBeforeRecovery:1; ///< + UINT32 Reserved_31_10:22; ///< + + } Field; + + UINT32 Value; +} DxFxxE4_xA3_STRUCT; + +// **** DxFxxE4_xB1 Register Definition **** +// Address +#define DxFxxE4_xB1_ADDRESS 0xB1 +// Type +#define DxFxxE4_xB1_TYPE TYPE_D2F1xE4 + +// Field Data +#define DxFxxE4_xB1_Reserved_13_0_OFFSET 0 +#define DxFxxE4_xB1_Reserved_13_0_WIDTH 14 +#define DxFxxE4_xB1_Reserved_13_0_MASK 0x3FFF +#define DxFxxE4_xB1_LcElecIdleMode_OFFSET 14 +#define DxFxxE4_xB1_LcElecIdleMode_WIDTH 2 +#define DxFxxE4_xB1_LcElecIdleMode_MASK 0xc000 +#define DxFxxE4_xB1_Reserved_18_16_OFFSET 16 +#define DxFxxE4_xB1_Reserved_18_16_WIDTH 3 +#define DxFxxE4_xB1_Reserved_18_16_MASK 0x70000 +#define DxFxxE4_xB1_LcDeassertRxEnInL0s_OFFSET 19 +#define DxFxxE4_xB1_LcDeassertRxEnInL0s_WIDTH 1 +#define DxFxxE4_xB1_LcDeassertRxEnInL0s_MASK 0x80000 +#define DxFxxE4_xB1_LcBlockElIdleinL0_OFFSET 20 +#define DxFxxE4_xB1_LcBlockElIdleinL0_WIDTH 1 +#define DxFxxE4_xB1_LcBlockElIdleinL0_MASK 0x100000 +#define DxFxxE4_xB1_Reserved_31_21_OFFSET 21 +#define DxFxxE4_xB1_Reserved_31_21_WIDTH 11 +#define DxFxxE4_xB1_Reserved_31_21_MASK 0xFFE00000 + +/// DxFxxE4_xB1 +typedef union { + struct { ///< + UINT32 Reserved_13_0:14; ///< + UINT32 LcElecIdleMode:2 ; ///< + UINT32 Reserved_18_16:3 ; ///< + UINT32 LcDeassertRxEnInL0s:1; ///< + UINT32 LcBlockElIdleinL0:1; ///< + UINT32 Reserved_31_21:11; ///< + + } Field; + UINT32 Value; +} DxFxxE4_xB1_STRUCT; + +// **** DxFxxE4_xC0 Register Definition **** +// Address +// Type +#define DxFxxE4_xC0_TYPE TYPE_D2F1xE4 + +// Field Data +#define DxFxxE4_xC0_Reserved_3_0_OFFSET 0 +#define DxFxxE4_xC0_Reserved_3_0_WIDTH 4 +#define DxFxxE4_xC0_Reserved_3_0_MASK 0xF +#define DxFxxE4_xC0_Reserved_12_6_OFFSET 6 +#define DxFxxE4_xC0_Reserved_12_6_WIDTH 7 +#define DxFxxE4_xC0_Reserved_12_6_MASK 0x1FC0 +#define DxFxxE4_xC0_StrapForceCompliance_OFFSET 13 +#define DxFxxE4_xC0_StrapForceCompliance_WIDTH 1 +#define DxFxxE4_xC0_StrapForceCompliance_MASK 0x2000 +#define DxFxxE4_xC0_Reserved_14_14_OFFSET 14 +#define DxFxxE4_xC0_Reserved_14_14_WIDTH 1 +#define DxFxxE4_xC0_Reserved_14_14_MASK 0x4000 +#define DxFxxE4_xC0_StrapAutoRcSpeedNegotiationDis_OFFSET 15 +#define DxFxxE4_xC0_StrapAutoRcSpeedNegotiationDis_WIDTH 1 +#define DxFxxE4_xC0_StrapAutoRcSpeedNegotiationDis_MASK 0x8000 +#define DxFxxE4_xC0_Reserved_31_19_OFFSET 19 +#define DxFxxE4_xC0_Reserved_31_19_WIDTH 13 +#define DxFxxE4_xC0_Reserved_31_19_MASK 0xfff80000 + +/// DxFxxE4_xC0 +typedef union { + struct { ///< + UINT32 Reserved_3_0:4 ; ///< + UINT32 StrapMedyTSxCount:2 ; ///< + UINT32 Reserved_12_6:7 ; ///< + UINT32 StrapForceCompliance:1 ; ///< + UINT32 Reserved_14_14:1 ; ///< + UINT32 StrapAutoRcSpeedNegotiationDis:1 ; ///< + UINT32 StrapLaneNegotiation:3 ; ///< + UINT32 Reserved_31_19:13; ///< + } Field; + UINT32 Value; +} DxFxxE4_xC0_STRUCT; + + + + +typedef union { + struct { ///< + UINT32 Reserved_1_0:2; ///< + UINT32 bit2:1; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 Reserved_7_4:4; ///< + UINT32 Reserved_8_8:1; ///< + UINT32 Reserved_31_9:23; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB7208_STRUCT; + + +typedef union { + struct { ///< + UINT32 Reserved_16_0:17; ///< + UINT32 bit17:1 ; ///< + UINT32 Reserved_31_18:14; ///< + } Field; ///< + UINT32 Value; ///< +} GnbRegistersKB7236_STRUCT; + +typedef union { + struct { ///< + UINT32 Reserved_15_0:16; ///< + UINT32 bit16:1; ///< + UINT32 Reserved_17_17:1; ///< + UINT32 Reserved_31_18:14; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB7269_STRUCT; + +typedef union { + struct { ///< + UINT32 Reserved_7_0:8; ///< + UINT32 StrapBifF0LegacyDeviceTypeDis:1; ///< + UINT32 Reserved_9_9:1; ///< + UINT32 bita:1; ///< + UINT32 Reserved_12_11:2; ///< + UINT32 bit13:1; ///< + UINT32 Reserved_31_14:18; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB7314_STRUCT; + +typedef union { + struct { ///< + UINT32 Reserved_19_0:20; ///< + UINT32 bit_20:1; ///< + UINT32 Reserved_31_21:11; ///< + } Field; ///< + UINT32 Value; ///< +} GnbRegistersKB7341_STRUCT; + + +// **** D0F0xD4_x010914E1 Register Definition **** +// Address +#define D0F0xD4_x010914E1_ADDRESS 0x10914E1 +// Type +#define D0F0xD4_x010914E1_TYPE TYPE_D0F0xD4 + +// Field Data +#define D0F0xD4_x010914E1_Reserved_0_0_OFFSET 0 +#define D0F0xD4_x010914E1_Reserved_0_0_WIDTH 1 +#define D0F0xD4_x010914E1_Reserved_0_0_MASK 0x1 +#define D0F0xD4_x010914E1_StrapBifRegApSize_OFFSET 1 +#define D0F0xD4_x010914E1_StrapBifRegApSize_WIDTH 2 +#define D0F0xD4_x010914E1_StrapBifRegApSize_MASK 0x6 +#define D0F0xD4_x010914E1_StrapBifMemApSize_OFFSET 3 +#define D0F0xD4_x010914E1_StrapBifMemApSize_WIDTH 3 +#define D0F0xD4_x010914E1_StrapBifMemApSize_MASK 0x38 +#define D0F0xD4_x010914E1_Reserved_11_6_OFFSET 6 +#define D0F0xD4_x010914E1_Reserved_11_6_WIDTH 6 +#define D0F0xD4_x010914E1_Reserved_11_6_MASK 0xFC0 +#define D0F0xD4_x010914E1_StrapBifDoorbellBarDis_OFFSET 12 +#define D0F0xD4_x010914E1_StrapBifDoorbellBarDis_WIDTH 1 +#define D0F0xD4_x010914E1_StrapBifDoorbellBarDis_MASK 0x1000 +#define D0F0xD4_x010914E1_Bitfield_13_13_OFFSET 13 +#define D0F0xD4_x010914E1_Bitfield_13_13_WIDTH 1 +#define D0F0xD4_x010914E1_Bitfield_13_13_MASK 0x2000 +#define D0F0xD4_x010914E1_Bitfield_15_14_OFFSET 14 +#define D0F0xD4_x010914E1_Bitfield_15_14_WIDTH 2 +#define D0F0xD4_x010914E1_Bitfield_15_14_MASK 0xC000 +#define D0F0xD4_x010914E1_Reserved_31_13_OFFSET 16 +#define D0F0xD4_x010914E1_Reserved_31_13_WIDTH 16 +#define D0F0xD4_x010914E1_Reserved_31_13_MASK 0xFFFF0000 + +/// D0F0xD4_x010914E1 +typedef union { + struct { ///< + UINT32 Reserved_0_0:1; ///< + UINT32 StrapBifRegApSize:2; ///< + UINT32 StrapBifMemApSize:3; ///< + UINT32 Reserved_11_6:6; ///< + UINT32 StrapBifDoorbellBarDis:1; ///< + UINT32 Bitfield_13_13:1; ///< + UINT32 Bitfield_15_14:2; ///< + UINT32 Reserved_31_13:16; ///< + + } Field; + + UINT32 Value; +} D0F0xD4_x010914E1_STRUCT; + +// **** D0F0xD4_x010914E2 Register Definition **** +// Address +#define D0F0xD4_x010914E2_ADDRESS 0x10914E2 +// Type +#define D0F0xD4_x010914E2_TYPE TYPE_D0F0xD4 + +// Field Data +#define D0F0xD4_x010914E2_Reserved_0_0_OFFSET 0 +#define D0F0xD4_x010914E2_Reserved_0_0_WIDTH 1 +#define D0F0xD4_x010914E2_Reserved_0_0_MASK 0x1 +#define D0F0xD4_x010914E2_StrapBifIoBarDis_OFFSET 1 +#define D0F0xD4_x010914E2_StrapBifIoBarDis_WIDTH 1 +#define D0F0xD4_x010914E2_StrapBifIoBarDis_MASK 0x2 +#define D0F0xD4_x010914E2_StrapBifF064BarDisA_OFFSET 3 +#define D0F0xD4_x010914E2_StrapBifF064BarDisA_WIDTH 1 +#define D0F0xD4_x010914E2_StrapBifF064BarDisA_MASK 0x8 + +/// D0F0xD4_x010914E2 +typedef union { + struct { ///< + UINT32 Reserved_0_0:1; ///< + UINT32 StrapBifIoBarDis:1; ///< + UINT32 Reserved_2_2:1; ///< + UINT32 StrapBifF064BarDisA:1; ///< + UINT32 Reserved_7_4:4; ///< + UINT32 bit8:1; ///< + UINT32 Reserved_9_9:1; ///< + UINT32 bita:1; ///< + UINT32 Reserved_12_11:2; ///< + UINT32 bit13:1; ///< + UINT32 Reserved_31_14:18; ///< + + } Field; + + UINT32 Value; +} D0F0xD4_x010914E2_STRUCT; + +// **** D0F0xD4_x01091507 Register Definition **** +// Address +#define D0F0xD4_x01091507_ADDRESS 0x1091507 +// Type +#define D0F0xD4_x01091507_TYPE TYPE_D0F0xD4 + +// Field Data +#define D0F0xD4_x01091507_StrapBifMemApSizePin_OFFSET 5 +#define D0F0xD4_x01091507_StrapBifMemApSizePin_WIDTH 3 +#define D0F0xD4_x01091507_StrapBifMemApSizePin_MASK 0xE0 + +/// D0F0xD4_x01091507 +typedef union { + struct { ///< + UINT32 Reserved_4_0:5; ///< + UINT32 StrapBifMemApSizePin:3; ///< + UINT32 Reserved_15_8:8; ///< + UINT32 bit16:1; ///< + UINT32 Reserved_31_17:15; ///< + + } Field; + + UINT32 Value; +} D0F0xD4_x01091507_STRUCT; + +typedef union { + struct { ///< + UINT32 bit0:1; ///< + UINT32 Reserved_31_1:31; ///< + + } Field; + + UINT32 Value; +} GnbRegistersKB7514_STRUCT; + + +// **** D0F0xFC_x00 Register Definition **** +// Address +#define D0F0xFC_x00_ADDRESS 0x0 +// Type +#define D0F0xFC_x00_TYPE TYPE_D0F0xFC + +// Field Data +#define D0F0xFC_x00_IoapicEnable_OFFSET 0 +#define D0F0xFC_x00_IoapicEnable_WIDTH 1 +#define D0F0xFC_x00_IoapicEnable_MASK 0x1 +#define D0F0xFC_x00_Reserved_1_1_OFFSET 1 +#define D0F0xFC_x00_Reserved_1_1_WIDTH 1 +#define D0F0xFC_x00_Reserved_1_1_MASK 0x2 +#define D0F0xFC_x00_IoapicIdExtEn_OFFSET 2 +#define D0F0xFC_x00_IoapicIdExtEn_WIDTH 1 +#define D0F0xFC_x00_IoapicIdExtEn_MASK 0x4 +#define D0F0xFC_x00_Reserved_3_3_OFFSET 3 +#define D0F0xFC_x00_Reserved_3_3_WIDTH 1 +#define D0F0xFC_x00_Reserved_3_3_MASK 0x8 +#define D0F0xFC_x00_IoapicSbFeatureEn_OFFSET 4 +#define D0F0xFC_x00_IoapicSbFeatureEn_WIDTH 1 +#define D0F0xFC_x00_IoapicSbFeatureEn_MASK 0x10 +#define D0F0xFC_x00_Reserved_31_5_OFFSET 5 +#define D0F0xFC_x00_Reserved_31_5_WIDTH 27 +#define D0F0xFC_x00_Reserved_31_5_MASK 0xFFFFFFE0 + +/// D0F0xFC_x00 +typedef union { + struct { ///< + UINT32 IoapicEnable:1; ///< + UINT32 Reserved_1_1:1; ///< + UINT32 IoapicIdExtEn:1; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 IoapicSbFeatureEn:1; ///< + UINT32 Reserved_31_5:27; ///< + + } Field; + + UINT32 Value; +} D0F0xFC_x00_STRUCT; + +// **** D0F0xFC_x0F Register Definition **** +// Address +#define D0F0xFC_x0F_ADDRESS 0x0F +// Type +#define D0F0xFC_x0F_TYPE TYPE_D0F0xFC + +// Field Data +#define D0F0xFC_x0F_GBIFExtIntrGrp_OFFSET 0 +#define D0F0xFC_x0F_GBIFExtIntrGrp_WIDTH 3 +#define D0F0xFC_x0F_GBIFExtIntrGrp_MASK 0x7 +#define D0F0xFC_x0F_Reserved_3_3_OFFSET 3 +#define D0F0xFC_x0F_Reserved_3_3_WIDTH 1 +#define D0F0xFC_x0F_Reserved_3_3_MASK 0x8 +#define D0F0xFC_x0F_GBIFExtIntrSwz_OFFSET 4 +#define D0F0xFC_x0F_GBIFExtIntrSwz_WIDTH 2 +#define D0F0xFC_x0F_GBIFExtIntrSwz_MASK 0x30 +#define D0F0xFC_x0F_Reserved_31_6_OFFSET 6 +#define D0F0xFC_x0F_Reserved_31_6_WIDTH 26 +#define D0F0xFC_x0F_Reserved_31_6_MASK 0xFFFFFFC0 + +/// D0F0xFC_xOF +typedef union { + struct { ///< + UINT32 GBIFExtIntrGrp:3; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 GBIFExtIntrSwz:2; ///< + UINT32 Reserved_31_6:26; ///< + } Field; + + UINT32 Value; +} D0F0xFC_x0F_STRUCT; + +// **** D0F0xFC_x10 Register Definition **** +// Address +#define D0F0xFC_x10_ADDRESS 0x10 +// Type +#define D0F0xFC_x10_TYPE TYPE_D0F0xFC + +// Field Data +#define D0F0xFC_x10_BrExtIntrGrp_OFFSET 0 +#define D0F0xFC_x10_BrExtIntrGrp_WIDTH 3 +#define D0F0xFC_x10_BrExtIntrGrp_MASK 0x7 +#define D0F0xFC_x10_Reserved_3_3_OFFSET 3 +#define D0F0xFC_x10_Reserved_3_3_WIDTH 1 +#define D0F0xFC_x10_Reserved_3_3_MASK 0x8 +#define D0F0xFC_x10_BrExtIntrSwz_OFFSET 4 +#define D0F0xFC_x10_BrExtIntrSwz_WIDTH 2 +#define D0F0xFC_x10_BrExtIntrSwz_MASK 0x30 +#define D0F0xFC_x10_Reserved_15_6_OFFSET 6 +#define D0F0xFC_x10_Reserved_15_6_WIDTH 10 +#define D0F0xFC_x10_Reserved_15_6_MASK 0xFFC0 +#define D0F0xFC_x10_BrIntIntrMap_OFFSET 16 +#define D0F0xFC_x10_BrIntIntrMap_WIDTH 5 +#define D0F0xFC_x10_BrIntIntrMap_MASK 0x1F0000 +#define D0F0xFC_x10_Reserved_31_21_OFFSET 21 +#define D0F0xFC_x10_Reserved_31_21_WIDTH 11 +#define D0F0xFC_x10_Reserved_31_21_MASK 0xFFE00000 + +/// D0F0xFC_x10 +typedef union { + struct { ///< + UINT32 BrExtIntrGrp:3; ///< + UINT32 Reserved_3_3:1; ///< + UINT32 BrExtIntrSwz:2; ///< + UINT32 Reserved_15_6:10; ///< + UINT32 BrIntIntrMap:5; ///< + UINT32 Reserved_31_21:11; ///< + + } Field; + + UINT32 Value; +} D0F0xFC_x10_STRUCT; + + +// **** D0F0x90 Register Definition **** +// Address +#define D0F0x90_ADDRESS 0x90 +// Type +#define D0F0x90_TYPE TYPE_D0F0 + +// **** D0F0x94 Register Definition **** +// Address +#define D0F0x94_ADDRESS 0x94 +// Type +#define D0F0x94_TYPE TYPE_D0F0 + + +// **** D18F1xF0 Register Definition **** +// Address +#define D18F1xF0_ADDRESS 0xF0 +// Type +#define D18F1xF0_TYPE TYPE_D18F1 + +// **** D18F1x200 Register Definition **** +// Address +#define D18F1x200_ADDRESS 0x200 +// Type +#define D18F1x200_TYPE TYPE_D18F1 + +// **** D18F1x204 Register Definition **** +// Address +#define D18F1x204_ADDRESS 0x204 +// Type +#define D18F1x204_TYPE TYPE_D18F1 + +// **** D18F1x240 Register Definition **** +// Address +#define D18F1x240_ADDRESS 0x240 +// Type +#define D18F1x240_TYPE TYPE_D18F1 + +// **** D18F2x40_dct0 Register Definition **** +// Address +#define D18F2x40_dct0_ADDRESS 0x40 +// Type +#define D18F2x40_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2x44_dct0 Register Definition **** +// Address +#define D18F2x44_dct0_ADDRESS 0x44 +// Type +#define D18F2x44_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2x48_dct0 Register Definition **** +// Address +#define D18F2x48_dct0_ADDRESS 0x48 +// Type +#define D18F2x48_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2x4C_dct0 Register Definition **** +// Address +#define D18F2x4C_dct0_ADDRESS 0x4C +// Type +#define D18F2x4C_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2x60_dct0 Register Definition **** +// Address +#define D18F2x60_dct0_ADDRESS 0x60 +// Type +#define D18F2x60_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2x64_dct0 Register Definition **** +// Address +#define D18F2x64_dct0_ADDRESS 0x64 +// Type +#define D18F2x64_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2x80_dct0 Register Definition **** +// Address +#define D18F2x80_dct0_ADDRESS 0x80 +// Type +#define D18F2x80_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2xA8_dct0 Register Definition **** +// Address +#define D18F2xA8_dct0_ADDRESS 0xA8 +// Type +#define D18F2xA8_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2x78_dct0 Register Definition **** +// Address +#define D18F2x78_dct0_ADDRESS 0x78 +// Type +#define D18F2x78_dct0_TYPE TYPE_D18F2_dct0 + +// **** D18F2x110 Register Definition **** +// Address +#define D18F2x110_ADDRESS 0x110 +// Type +#define D18F2x110_TYPE TYPE_D18F2 + +// **** D18F2x114 Register Definition **** +// Address +#define D18F2x114_ADDRESS 0x114 +// Type +#define D18F2x114_TYPE TYPE_D18F2 + +// **** DxFxx18 Register Definition **** +// Address +#define DxFxx18_ADDRESS 0x18 +// Type +#define DxFxx18_TYPE TYPE_D2F1 + +// **** DxFxx20 Register Definition **** +// Address +#define DxFxx20_ADDRESS 0x20 +// Type +#define DxFxx20_TYPE TYPE_D2F1 + +// **** DxFxx24 Register Definition **** +// Address +#define DxFxx24_ADDRESS 0x24 +// Type +#define DxFxx24_TYPE TYPE_D2F1 + +// **** D0F0x60 Register Definition **** +// Address +#define D0F0x60_ADDRESS 0x60 +// Type +#define D0F0x60_TYPE TYPE_D0F0 + +// **** D0F0xB8 Register Definition **** +// Address +#define D0F0xB8_ADDRESS 0xB8 +// Type +#define D0F0xB8_TYPE TYPE_D0F0 + +// **** D0F0xE0 Register Definition **** +// Address +#define D0F0xE0_ADDRESS 0xE0 +// Type +#define D0F0xE0_TYPE TYPE_D0F0 +// **** D0F0x64_x1F Register Definition **** +// Address +#define D0F0x64_x1F_ADDRESS 0x1F +// Type +#define D0F0x64_x1F_TYPE TYPE_D0F0x64 + +// **** D0F0xE4_PIF_0017 Register Definition **** +// Address +#define D0F0xE4_PIF_0017_ADDRESS 0x17 +// Type +#define D0F0xE4_PIF_0017_TYPE TYPE_D0F0xE4 + +// **** D0F2xF4_x49 Register Definition **** +// Address +// Type + + +// **** D0F0xE4_WRAP_8021 Register Definition **** +// Address +#define D0F0xE4_WRAP_8021_ADDRESS 0x8021 +// Type +#define D0F0xE4_WRAP_8021_TYPE TYPE_D0F0xE4 + +// **** D0F0xE4_WRAP_8022 Register Definition **** +// Address +#define D0F0xE4_WRAP_8022_ADDRESS 0x8022 +// Type +#define D0F0xE4_WRAP_8022_TYPE TYPE_D0F0xE4 + +// **** D0F0xE4_WRAP_8025 Register Definition **** +// Address +#define D0F0xE4_WRAP_8025_ADDRESS 0x8025 +// Type +#define D0F0xE4_WRAP_8025_TYPE TYPE_D0F0xE4 + +// **** D0F0xE4_WRAP_8026 Register Definition **** +// Address +#define D0F0xE4_WRAP_8026_ADDRESS 0x8026 +// Type +#define D0F0xE4_WRAP_8026_TYPE TYPE_D0F0xE4 + +// **** D0F0xF8 Register Definition **** +// Address +#define D0F0xF8_ADDRESS 0xF8 +// Type +#define D0F0xF8_TYPE TYPE_D0F0 + +// **** D0F0x64_x19 Register Definition **** +// Address +#define D0F0x64_x19_ADDRESS 0x19 +// Type +#define D0F0x64_x19_TYPE TYPE_D0F0x64 + +// **** D0F0x64_x1A Register Definition **** +// Address +#define D0F0x64_x1A_ADDRESS 0x1A +// Type +#define D0F0x64_x1A_TYPE TYPE_D0F0x64 + +// **** D0F0xBC_x20000 Register Definition **** +// Address +#define D0F0xBC_x20000_ADDRESS 0x20000 +// Type +#define D0F0xBC_x20000_TYPE TYPE_D0F0xBC + +// **** D0F0xBC_x0 Register Definition **** +// Address +#define D0F0xBC_x0_ADDRESS 0x0 +// Type +#define D0F0xBC_x0_TYPE TYPE_D0F0xBC + + + +// **** D0F0xBC_xC210003C Register Definition **** +// Address +#define D0F0xBC_xC210003C_ADDRESS 0xC210003C +// Type +#define D0F0xBC_xC210003C_TYPE TYPE_D0F0xBC + +// **** D0F0xD4_x010914C3 Register Definition **** +// Address +#define D0F0xD4_x010914C3_ADDRESS 0x010914C3 +// Type +#define D0F0xD4_x010914C3_TYPE TYPE_D0F0xD4 + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUra.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUra.h new file mode 100644 index 0000000000..2bf8952d29 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUra.h @@ -0,0 +1,204 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBURA_H_ +#define _GNBURA_H_ + +#include "GnbPcie.h" + +/// Generic device object +typedef struct { + PCI_ADDR DevPciAddress; ///< DevPciAddress + GNB_HANDLE *GnbHandle; ///< GnbHandle + AMD_CONFIG_PARAMS *StdHeader; ///< +} DEV_OBJECT; + +/// Register address 32 bit encoding +typedef struct { + UINT32 Address: 31; ///< Register address + UINT32 MultInst: 1; ///< Must equals to 0 +} URA_REGISTER_32B_ENTRY; + +/// Register address encoding that represents a group of registers that have same fields' definitions +typedef struct { + UINT32 Addr: 24; ///< Register address + UINT32 InstOffset: 7; ///< The address offset between register instances + UINT32 MultInst: 1; ///< Must equals to 1 +} URA_MULT_REG_ENTRY; + +/// 16 bit field encoding +typedef struct { + UINT16 BfOffset: 6; ///< Offset of the bit field + UINT16 BfWidth: 6; ///< Width of the bit field + UINT16 Offset: 4; ///< Number of field entries from its register address entry + ///< The first field entry of a register must be place right after its register entry and has offset 1. + ///< The second field is placed right after the first field and has offset 2 and so on. + ///< The offset field is maxed out at 15. So any entries after the 15th entries will take offset 0. +} URA_FIELD_16B_ENTRY; + +/// 32 bit field encoding +typedef struct { + UINT32 BfOffset: 6; ///< Offset of the bit field + UINT32 BfWidth: 6; ///< Width of the bit field + UINT32 RegIndex: 13; ///< Direct index to its register address entry + UINT32 Rev: 6; ///< Contains ID of the family/rev that this bit field is valid + UINT32 Reserved: 1; ///< Reserved +} URA_FIELD_32B_ENTRY; + +/// Register address 64 bit encoding +typedef struct { + UINT64 DomainAddress:32; ///< Register domain address + UINT64 DomainType: 8; ///< Register domain type + UINT64 Reserved: 24; ///< Reserved +} URA_REGISTER_64B_ENTRY; + +/// Register / Field table entry +#define URA_ENTRY UINT16 + +/// Token +typedef union { + UINT32 Encode; ///< Token value + + struct { ///< Sub structure used to parse Token + UINT32 Index: 13; ///< Index into a specific register or field entry in register/field table + UINT32 Type: 3; ///< Entry type: + ///< 000b: 16-bit field location encoding + ///< 001b: Register address encoding + ///< 010b: 32-bit field location encoding + ///< 011b: 64-bit field location encoding + ///< Others would reserved + UINT32 Selector: 6; ///< Used by unified register access to select the access method + UINT32 InstSel: 6; ///< When register/field has multiple instances, this field is used to obtain the register address of a register group. + UINT32 S3Save:1; ///< Indicate whether S3Save is needed. + UINT32 StreamSet:1; ///< Stream Set + UINT32 ParentType:1; ///< Parent token type + UINT32 Reserved: 1; ///< Reserved for device specific usage + } Parser; +} URA_TOKEN_STRUCT; + +#define URA_TOKEN UINT32 + +#define URA_TYPE_FIELD_16 0 +#define URA_TYPE_FIELD_32 1 +#define URA_TYPE_REGISTER_32 2 +#define URA_TYPE_REGISTER_64 3 + +#define URA_TOKEN_PARENT_TYPE_32 0x20000000ul +#define URA_TOKEN_PARENT_TYPE_64 0x00000000ul + +/** + TOKEN_DEF(Index, Type, Selector) + Defines a register of field token + + @param[in] Index + @param[in] Type + @param[in] Selector + @param[in] ParentType + + @return URA_TOKEN Encrypted URA_TOKEN format +--*/ +#define TOKEN_DEF(Index, Type, Selector, ParentType) ( \ + (((UINT32) (Index)) | (((UINT32) (Type)) << 13) | (((UINT32) (Selector)) << 16) | ((UINT32) (ParentType))) \ + ) + +#define _RESERVED 0xFFFFFFFFul +#define _UNUSED 0xFEFEFEFEul +#define GNB_URA_FLAG_S3SAVE 0x00000001ul +#define GNB_URA_STREAM_SET 0x20000000ul + +/// Structure used to pass token info to access methods +typedef struct { + UINT32 RegAddress; ///< Register address + UINT8 BfOffset; ///< Offset of the bit field + UINT8 BfWidth; ///< Width of the bit field + BOOLEAN WholeRegAccess; ///< Whole register access + UINT32 MethodType; ///< Index into the access method table to select access method + UINT32 Flags; ///< S3 + UINT32 StreamSet; ///< StreamSet + UINT8 RegDomainType; ///< Register Domain type +} URA_TOKEN_INFO; + +#define TYPE_GNB_INDIRECT_ACCESS 0 +#define TYPE_GNB_PROTOCOL_ACCESS 1 + +/// URA_TUPLE +typedef struct { + URA_TOKEN Token; ///< Token + UINT32 Value; ///< Token value + UINT32 StepLength; ///< Byte length to next address for stream set usage. +} URA_TUPLE; + +typedef VOID F_GNBURASERVICELOCATEREGTBL ( + IN DEV_OBJECT *Device, + IN UINT32 *UraTableAddress + ); + +typedef VOID F_GNBURASERVICEGET ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT VOID *Value + ); + +typedef VOID F_GNBURASERVICESET ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT VOID *Value + ); + +typedef VOID F_GNBURASERVICESTREAMSET ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT URA_TUPLE *UraTuple, + IN UINT32 CombinedCount + ); + +/// Register Read/Write protocol +typedef struct { + F_GNBURASERVICELOCATEREGTBL *GnbUraLocateRegTbl; ///< + F_GNBURASERVICEGET *GnbUraGet; ///< + F_GNBURASERVICESET *GnbUraSet; ///< + F_GNBURASERVICESTREAMSET *GnbUraStreamSet; ///< +} GNB_URA_SERVICE; + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUraServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUraServices.h new file mode 100644 index 0000000000..c4e51b0588 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUraServices.h @@ -0,0 +1,87 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBURASERVICES_H_ +#define _GNBURASERVICES_H_ + +#include "GnbUra.h" +#include "GnbUraToken.h" + +/*---------------------------------------------------------------------------- + * FUNCTION PROTOTYPES + * + *---------------------------------------------------------------------------- + */ + +VOID +GnbUraGet ( + IN DEV_OBJECT *Device, + IN URA_TOKEN UraToken, + IN OUT VOID *Value + ); + +VOID +GnbUraSet ( + IN DEV_OBJECT *Device, + IN URA_TOKEN UraToken, + IN VOID *Value + ); + +VOID +GnbUraCombinedGet ( + IN DEV_OBJECT *Device, + IN URA_TOKEN UraTokenRegister, + IN OUT URA_TUPLE *UraTuple, + IN UINT32 CombinedCount + ); + +VOID +GnbUraCombinedSet ( + IN DEV_OBJECT *Device, + IN URA_TOKEN UraTokenRegister, + IN OUT URA_TUPLE *UraTuple, + IN UINT32 CombinedCount + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUraToken.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUraToken.h new file mode 100644 index 0000000000..29683607ca --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Common/GnbUraToken.h @@ -0,0 +1,103 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AGESA gnb file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ +#ifndef _GNBURATOKEN_H_ +#define _GNBURATOKEN_H_ + +/// Template structure for register/field table +typedef struct { + URA_REGISTER_64B_ENTRY RxSmuIntReq;///< + URA_FIELD_16B_ENTRY BfxSmuIntToggle;///< + URA_FIELD_16B_ENTRY BfxSmuServiceIndex;///< + URA_REGISTER_64B_ENTRY RxSmuIntSts;///< + URA_FIELD_16B_ENTRY BfxSmuIntAck;///< + URA_FIELD_16B_ENTRY BfxSmuIntDone;///< + URA_REGISTER_64B_ENTRY RxSmuAuthSts;///< + URA_FIELD_16B_ENTRY BfxSmuAuthDone;///< + URA_FIELD_16B_ENTRY BfxSmuAuthPass;///< + URA_REGISTER_64B_ENTRY RxSmuFwAuth;///< + URA_FIELD_16B_ENTRY BfxSmuProtectedMode;///< + URA_REGISTER_64B_ENTRY REG_FIELD_TABLE_STRUCT_fld11;///< + URA_FIELD_16B_ENTRY BfxSmuBootSeqDone;///< + URA_REGISTER_64B_ENTRY RxSmuFwFlags;///< + URA_FIELD_16B_ENTRY BfxSmuInterruptsEnabled;///< + URA_REGISTER_64B_ENTRY RxSmuResetCntl;///< + URA_FIELD_16B_ENTRY BfxSmuRstReg;///< + URA_REGISTER_64B_ENTRY RxSmuClkCntl;///< + URA_FIELD_16B_ENTRY BfxSmuCkDisable;///< + URA_REGISTER_64B_ENTRY RxSmuAuthVector;///< + URA_REGISTER_64B_ENTRY RxSmuRamStartAddr;///< + URA_REGISTER_64B_ENTRY RxSmuRomStartAddr;///< + URA_REGISTER_64B_ENTRY RxSmuIntArgument;///< + +} REG_FIELD_TABLE_STRUCT; + +#define IDX_CALC(VarName) (offsetof (REG_FIELD_TABLE_STRUCT, VarName) / 2) /* TODO: why ## */ +#define SEL_CALC(VarName) VarName +#define FIELD_OFFSET(RegName, FieldName) ((((IDX_CALC(FieldName) - IDX_CALC(RegName) - 1) / 2) <= 15) ? ((IDX_CALC(FieldName) - IDX_CALC(RegName) - 1) / 2) : 0) + +#define TRxSmuIntReq TOKEN_DEF (IDX_CALC (RxSmuIntReq), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuIntToggle TOKEN_DEF (IDX_CALC (BfxSmuIntToggle), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuServiceIndex TOKEN_DEF (IDX_CALC (BfxSmuServiceIndex), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuIntSts TOKEN_DEF (IDX_CALC (RxSmuIntSts), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuIntAck TOKEN_DEF (IDX_CALC (BfxSmuIntAck), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuIntDone TOKEN_DEF (IDX_CALC (BfxSmuIntDone), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuAuthSts TOKEN_DEF (IDX_CALC (RxSmuAuthSts), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuAuthDone TOKEN_DEF (IDX_CALC (BfxSmuAuthDone), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuAuthPass TOKEN_DEF (IDX_CALC (BfxSmuAuthPass), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuFwAuth TOKEN_DEF (IDX_CALC (RxSmuFwAuth), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuProtectedMode TOKEN_DEF (IDX_CALC (BfxSmuProtectedMode), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuRcuUcEvents TOKEN_DEF (IDX_CALC (REG_FIELD_TABLE_STRUCT_fld11), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuBootSeqDone TOKEN_DEF (IDX_CALC (BfxSmuBootSeqDone), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuFwFlags TOKEN_DEF (IDX_CALC (RxSmuFwFlags), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_PROTOCOL_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuInterruptsEnabled TOKEN_DEF (IDX_CALC (BfxSmuInterruptsEnabled), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_PROTOCOL_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuResetCntl TOKEN_DEF (IDX_CALC (RxSmuResetCntl), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuRstReg TOKEN_DEF (IDX_CALC (BfxSmuRstReg), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuClkCntl TOKEN_DEF (IDX_CALC (RxSmuClkCntl), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TBfxSmuCkDisable TOKEN_DEF (IDX_CALC (BfxSmuCkDisable), URA_TYPE_FIELD_16, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuAuthVector TOKEN_DEF (IDX_CALC (RxSmuAuthVector), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuRamStartAddr TOKEN_DEF (IDX_CALC (RxSmuRamStartAddr), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuRomStartAddr TOKEN_DEF (IDX_CALC (RxSmuRomStartAddr), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) +#define TRxSmuIntArgument TOKEN_DEF (IDX_CALC (RxSmuIntArgument), URA_TYPE_REGISTER_64, SEL_CALC (TYPE_GNB_INDIRECT_ACCESS), URA_TOKEN_PARENT_TYPE_64) + + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtEarly.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtEarly.c new file mode 100644 index 0000000000..9b1d9084fc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtEarly.c @@ -0,0 +1,128 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB early init interface + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "OptionGnb.h" +#include "GnbLibFeatures.h" +#include "GeneralServices.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_GNBINITATEARLY_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_GNB_CONFIGURATION GnbEarlyFeatureTable[]; +extern OPTION_GNB_CONFIGURATION GnbEarlierFeatureTable[]; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +GnbInitAtEarly ( + IN OUT AMD_EARLY_PARAMS *EarlyParamsPtr + ); + +AGESA_STATUS +GnbInitAtEarlier ( + IN OUT AMD_EARLY_PARAMS *EarlyParamsPtr + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at Early + * + * + * + * @param[in,out] EarlyParamsPtr Pointer to early configuration params. + * @retval Initialization status. + */ +AGESA_STATUS +GnbInitAtEarly ( + IN OUT AMD_EARLY_PARAMS *EarlyParamsPtr + ) +{ + AGESA_STATUS Status; + Status = GnbLibDispatchFeatures (&GnbEarlyFeatureTable[0], &EarlyParamsPtr->StdHeader); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at Early before CPU + * + * + * + * @param[in,out] EarlyParamsPtr Pointer to early configuration params. + * @retval Initialization status. + */ +AGESA_STATUS +GnbInitAtEarlier ( + IN OUT AMD_EARLY_PARAMS *EarlyParamsPtr + ) +{ + AGESA_STATUS Status; + + // Only run code on BSP + if (IsBsp (&EarlyParamsPtr->StdHeader, &Status)) { + Status = GnbLibDispatchFeatures (&GnbEarlierFeatureTable[0], &EarlyParamsPtr->StdHeader); + } + + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtEnv.c new file mode 100644 index 0000000000..7b93e916ae --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtEnv.c @@ -0,0 +1,138 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB env init interface + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "OptionGnb.h" +#include "GnbLibFeatures.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_GNBINITATENV_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_GNB_CONFIGURATION GnbEnvFeatureTable[]; +extern BUILD_OPT_CFG UserOptions; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +GnbInitDataStructAtEnvDef ( + IN OUT GNB_ENV_CONFIGURATION *GnbEnvConfigPtr, + IN AMD_ENV_PARAMS *EnvParamsPtr + ); + +AGESA_STATUS +GnbInitAtEnv ( + IN AMD_ENV_PARAMS *EnvParamsPtr + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Default constructor of GNB configuration at Env + * + * + * + * @param[in] GnbEnvConfigPtr Pointer to gnb env configuration params. + * @param[in] EnvParamsPtr Pointer to env configuration params. + */ +VOID +GnbInitDataStructAtEnvDef ( + IN OUT GNB_ENV_CONFIGURATION *GnbEnvConfigPtr, + IN AMD_ENV_PARAMS *EnvParamsPtr + ) +{ + GnbEnvConfigPtr->Gnb3dStereoPinIndex = UserOptions.CfgGnb3dStereoPinIndex; + GnbEnvConfigPtr->IommuSupport = UserOptions.CfgIommuSupport; + GnbEnvConfigPtr->LvdsSpreadSpectrum = UserOptions.CfgLvdsSpreadSpectrum; + GnbEnvConfigPtr->LvdsSpreadSpectrumRate = UserOptions.CfgLvdsSpreadSpectrumRate; + GnbEnvConfigPtr->LvdsPowerOnSeqDigonToDe = UserOptions.CfgLvdsPowerOnSeqDigonToDe; + GnbEnvConfigPtr->LvdsPowerOnSeqDeToVaryBl = UserOptions.CfgLvdsPowerOnSeqDeToVaryBl; + GnbEnvConfigPtr->LvdsPowerOnSeqDeToDigon = UserOptions.CfgLvdsPowerOnSeqDeToDigon; + GnbEnvConfigPtr->LvdsPowerOnSeqVaryBlToDe = UserOptions.CfgLvdsPowerOnSeqVaryBlToDe; + GnbEnvConfigPtr->LvdsPowerOnSeqOnToOffDelay = UserOptions.CfgLvdsPowerOnSeqOnToOffDelay; + GnbEnvConfigPtr->LvdsPowerOnSeqVaryBlToBlon = UserOptions.CfgLvdsPowerOnSeqVaryBlToBlon; + GnbEnvConfigPtr->LvdsPowerOnSeqBlonToVaryBl = UserOptions.CfgLvdsPowerOnSeqBlonToVaryBl; + GnbEnvConfigPtr->LvdsMaxPixelClockFreq = UserOptions.CfgLvdsMaxPixelClockFreq; + GnbEnvConfigPtr->LcdBitDepthControlValue = UserOptions.CfgLcdBitDepthControlValue; + GnbEnvConfigPtr->Lvds24bbpPanelMode = UserOptions.CfgLvds24bbpPanelMode; + GnbEnvConfigPtr->LvdsMiscControl.Value = 0; + GnbEnvConfigPtr->LvdsMiscControl.Value = UserOptions.CfgLvdsMiscControl.Value; + GnbEnvConfigPtr->PcieRefClkSpreadSpectrum = UserOptions.CfgPcieRefClkSpreadSpectrum; + GnbEnvConfigPtr->GnbRemoteDisplaySupport = UserOptions.CfgGnbRemoteDisplaySupport; + GnbEnvConfigPtr->LvdsMiscVoltAdjustment = UserOptions.CfgLvdsMiscVoltAdjustment; + GnbEnvConfigPtr->DisplayMiscControl.Value = UserOptions.CfgDisplayMiscControl.Value; + GnbEnvConfigPtr->DpFixedVoltSwingType = UserOptions.CfgDpFixedVoltSwingType; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at Env + * + * + * + * @param[in] EnvParamsPtr Pointer to env configuration params. + * @retval Initialization status. + */ + +AGESA_STATUS +GnbInitAtEnv ( + IN AMD_ENV_PARAMS *EnvParamsPtr + ) +{ + AGESA_STATUS Status; + Status = GnbLibDispatchFeatures (&GnbEnvFeatureTable[0], &EnvParamsPtr->StdHeader); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtLate.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtLate.c new file mode 100644 index 0000000000..c45e10a1ef --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtLate.c @@ -0,0 +1,136 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB late init interface + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85198 $ @e \$Date: 2013-01-03 13:49:32 -0600 (Thu, 03 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "OptionGnb.h" +#include "GnbLibFeatures.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_GNBINITATLATE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern OPTION_GNB_CONFIGURATION GnbLateFeatureTable[]; +extern BUILD_OPT_CFG UserOptions; +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GnbInitDataStructAtLateDef ( + IN OUT GNB_LATE_CONFIGURATION *GnbLateConfigPtr, + IN AMD_LATE_PARAMS *LateParamsPtr + ); + +AGESA_STATUS +GnbInitAtLate ( + IN OUT AMD_LATE_PARAMS *LateParamsPtr + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Default constructor of GNB configuration at Late + * + * + * + * @param[in] GnbLateConfigPtr Pointer to gnb Late configuration params. + * @param[in] LateParamsPtr Pointer to Late configuration params. + */ +VOID +GnbInitDataStructAtLateDef ( + IN OUT GNB_LATE_CONFIGURATION *GnbLateConfigPtr, + IN AMD_LATE_PARAMS *LateParamsPtr + ) +{ + UINT32 Property; + + Property = TABLE_PROPERTY_DEFAULT; + Property |= GnbBuildOptions.CfgBapmSupport ? TABLE_PROPERTY_BAPM : 0; + + IDS_OPTION_HOOK (IDS_GNB_PROPERTY, &Property, + (AMD_CONFIG_PARAMS *)&LateParamsPtr->StdHeader); + + GnbLateConfigPtr->DockedTdpHeadroom = FALSE; + if ((Property & TABLE_PROPERTY_BAPM) && UserOptions.CfgDockedTdpHeadroom) { + GnbLateConfigPtr->DockedTdpHeadroom = TRUE; + } + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at Late post + * + * + * + * @param[in,out] LateParamsPtr Pointer to late configuration params. + * @retval Initialization status. + */ + +AGESA_STATUS +GnbInitAtLate ( + IN OUT AMD_LATE_PARAMS *LateParamsPtr + ) +{ + AGESA_STATUS Status; + Status = GnbLibDispatchFeatures (&GnbLateFeatureTable[0], &LateParamsPtr->StdHeader); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtMid.c new file mode 100644 index 0000000000..f786d77b92 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtMid.c @@ -0,0 +1,118 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB mid init interface + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "OptionGnb.h" +#include "GnbLibFeatures.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_GNBINITATMID_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_GNB_CONFIGURATION GnbMidFeatureTable[]; +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GnbInitDataStructAtMidDef ( + IN OUT GNB_MID_CONFIGURATION *GnbMidConfigPtr, + IN AMD_MID_PARAMS *MidParamsPtr + ); + +AGESA_STATUS +GnbInitAtMid ( + IN OUT AMD_MID_PARAMS *MidParamsPtr + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Default constructor of GNB configuration at Mid + * + * + * + * @param[in] GnbMidConfigPtr Pointer to gnb Mid configuration params. + * @param[in] MidParamsPtr Pointer to Mid configuration params. + */ +VOID +GnbInitDataStructAtMidDef ( + IN OUT GNB_MID_CONFIGURATION *GnbMidConfigPtr, + IN AMD_MID_PARAMS *MidParamsPtr + ) +{ + GnbMidConfigPtr->GnbIoapicAddress = UserOptions.CfgGnbIoapicAddress; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at Mid post + * + * + * + * @param[in,out] MidParamsPtr Pointer to mid configuration params. + * @retval Initialization status. + */ + +AGESA_STATUS +GnbInitAtMid ( + IN OUT AMD_MID_PARAMS *MidParamsPtr + ) +{ + AGESA_STATUS Status; + Status = GnbLibDispatchFeatures (&GnbMidFeatureTable[0], &MidParamsPtr->StdHeader); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtPost.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtPost.c new file mode 100644 index 0000000000..6c5c7a1cfd --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtPost.c @@ -0,0 +1,150 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB POST init interface + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "OptionGnb.h" +#include "GnbLibFeatures.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_GNBINITATPOST_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_GNB_CONFIGURATION GnbPostFeatureTable[]; +extern OPTION_GNB_CONFIGURATION GnbPostAfterDramFeatureTable[]; +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +GnbInitDataStructAtPostDef ( + IN OUT GNB_POST_CONFIGURATION *GnbPostConfigPtr, + IN AMD_POST_PARAMS *PostParamsPtr + ); + +AGESA_STATUS +GnbInitAtPost ( + IN OUT AMD_POST_PARAMS *PostParamsPtr + ); + +AGESA_STATUS +GnbInitAtPostAfterDram ( + IN OUT AMD_POST_PARAMS *PostParamsPtr + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Default constructor of GNB configuration at Env + * + * + * + * @param[in] GnbPostConfigPtr Pointer to GNB POST configuration params. + * @param[in] PostParamsPtr Pointer to POST configuration params. + */ +VOID +GnbInitDataStructAtPostDef ( + IN OUT GNB_POST_CONFIGURATION *GnbPostConfigPtr, + IN AMD_POST_PARAMS *PostParamsPtr + ) +{ + GnbPostConfigPtr->IgpuEnableDisablePolicy = UserOptions.CfgIgpuEnableDisablePolicy; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at Post + * + * + * + * @param[in] PostParamsPtr Pointer to post configuration parameters + * @retval Initialization status. + */ + +AGESA_STATUS +GnbInitAtPost ( + IN OUT AMD_POST_PARAMS *PostParamsPtr + ) +{ + AGESA_STATUS Status; + Status = GnbLibDispatchFeatures (&GnbPostFeatureTable[0], &PostParamsPtr->StdHeader); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at Post after DRAM init + * + * + * + * @param[in] PostParamsPtr Pointer to post configuration parameters + * @retval Initialization status. + */ + +AGESA_STATUS +GnbInitAtPostAfterDram ( + IN OUT AMD_POST_PARAMS *PostParamsPtr + ) +{ + AGESA_STATUS Status; + Status = GnbLibDispatchFeatures (&GnbPostAfterDramFeatureTable[0], &PostParamsPtr->StdHeader); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtReset.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtReset.c new file mode 100644 index 0000000000..e60e18b245 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtReset.c @@ -0,0 +1,93 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB reset init interface + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_GNBINITATRESET_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GnbInitAtReset ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at Reset + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GnbInitAtReset ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + Status = AGESA_SUCCESS; + + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtS3Save.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtS3Save.c new file mode 100644 index 0000000000..2201ff6d64 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/GnbInitAtS3Save.c @@ -0,0 +1,94 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB late init interface + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "OptionGnb.h" +#include "GnbLibFeatures.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_GNBINITATS3SAVE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern OPTION_GNB_CONFIGURATION GnbS3SaveFeatureTable[]; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GnbInitAtS3Save ( + IN OUT AMD_S3SAVE_PARAMS *AmdS3SaveParams + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GNB at S3 save + * + * + * + * @param[in,out] AmdS3SaveParams Pointer to AMD_S3SAVE_PARAMS. + * @retval Initialization status. + */ + +AGESA_STATUS +GnbInitAtS3Save ( + IN OUT AMD_S3SAVE_PARAMS *AmdS3SaveParams + ) +{ + AGESA_STATUS Status; + Status = GnbLibDispatchFeatures (&GnbS3SaveFeatureTable[0], &AmdS3SaveParams->StdHeader); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbCommonLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbCommonLib.h new file mode 100644 index 0000000000..af2ff525f8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbCommonLib.h @@ -0,0 +1,57 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB register access services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86079 $ @e \$Date: 2013-01-16 00:59:04 -0600 (Wed, 16 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBCOMMONLIB_H_ +#define _GNBCOMMONLIB_H_ + +#include "GnbLib.h" +#include "GnbLibCpuAcc.h" +#include "GnbLibHeap.h" +#include "GnbLibIoAcc.h" +#include "GnbLibMemAcc.h" +#include "GnbLibPci.h" +#include "GnbLibPciAcc.h" +#include "GnbTimerLib.h" + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.c new file mode 100644 index 0000000000..34990c51ed --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.c @@ -0,0 +1,530 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB register access services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "cpuFamilyTranslation.h" +#include "cpuServices.h" +#include "Gnb.h" +#include "GnbLib.h" +#include "GnbLibIoAcc.h" +#include "GnbLibPciAcc.h" +#include "GnbLibMemAcc.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_SERVICE *ServiceTable; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GnbLibPciIndirectReadField ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + OUT UINT32 *Value, + IN VOID *Config + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read GNB indirect registers + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] Width Width + * @param[out] Value Pointer to value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *Config + ) +{ + UINT32 IndexOffset; + IndexOffset = LibAmdAccessWidth (Width); + GnbLibPciWrite (Address, Width, &IndirectAddress, Config); + GnbLibPciRead (Address + IndexOffset, Width, Value, Config); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Read GNB indirect registers field + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[out] Value Pointer to value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciIndirectReadField ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + OUT UINT32 *Value, + IN VOID *Config + ) +{ + UINT32 Mask; + GnbLibPciIndirectRead (Address, IndirectAddress, AccessWidth32, Value, Config); + Mask = (1 << FieldWidth) - 1; + *Value = (*Value >> FieldOffset) & Mask; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write GNB indirect registers + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] Width Width + * @param[in] Value Pointer to value + * @param[in] Config Pointer to standard header + */ + +VOID +GnbLibPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *Config + ) +{ + UINT32 IndexOffset; + IndexOffset = LibAmdAccessWidth (Width); + GnbLibPciWrite (Address, Width, &IndirectAddress, Config); + GnbLibPciWrite (Address + IndexOffset, Width, Value, Config); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write GNB indirect registers field + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] Value Pointer to value + * @param[in] S3Save Save for S3 (TRUE/FALSE) + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciIndirectWriteField ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN VOID *Config + ) +{ + UINT32 Data; + UINT32 Mask; + GnbLibPciIndirectRead (Address, IndirectAddress, AccessWidth32, &Data, Config); + Mask = (1 << FieldWidth) - 1; + Data &= (~(Mask << FieldOffset)); + Data |= ((Value & Mask) << FieldOffset); + GnbLibPciIndirectWrite (Address, IndirectAddress, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Data, Config); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write GNB indirect registers field + * + * + * + * @param[in] Address PCI address of indirect register + * @param[in] IndirectAddress Offset of indirect register + * @param[in] Width Width + * @param[in] Mask And Mask + * @param[in] Value Or Value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciIndirectRMW ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ) +{ + UINT32 Data; + GnbLibPciIndirectRead ( + Address, + IndirectAddress, + (Width >= AccessS3SaveWidth8) ? (Width - (AccessS3SaveWidth8 - AccessWidth8)) : Width, + &Data, + Config + ); + Data = (Data & Mask) | Value; + GnbLibPciIndirectWrite (Address, IndirectAddress, Width, &Data, Config); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCI registers + * + * + * + * @param[in] Address PCI address + * @param[in] Width Access width + * @param[in] Mask AND Mask + * @param[in] Value OR Value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibPciRMW ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ) +{ + UINT32 Data; + GnbLibPciRead (Address, Width, &Data, Config); + Data = (Data & Mask) | Value; + GnbLibPciWrite (Address, Width, &Data, Config); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write I/O registers + * + * + * + * @param[in] Address I/O Port + * @param[in] Width Access width + * @param[in] Mask AND Mask + * @param[in] Value OR Mask + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibIoRMW ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ) +{ + UINT32 Data; + GnbLibIoRead (Address, Width, &Data, Config); + Data = (Data & Mask) | Value; + GnbLibIoWrite (Address, Width, &Data, Config); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Indirect IO block read + * + * + * + * @param[in] IndexPort Index Port + * @param[in] DataPort Data Port + * @param[in] Width Access width + * @param[in] IndexAddress Index Address + * @param[in] Count Count + * @param[in] Buffer Buffer + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibIndirectIoBlockRead ( + IN UINT16 IndexPort, + IN UINT16 DataPort, + IN ACCESS_WIDTH Width, + IN UINT32 IndexAddress, + IN UINT32 Count, + IN VOID *Buffer, + IN VOID *Config + ) +{ + UINT32 Index; + Index = IndexAddress; + for (; Index < (IndexAddress + Count); Index++) { + GnbLibIoWrite (IndexPort, Width, &Index, Config); + GnbLibIoRead (DataPort, Width, Buffer, Config); + Buffer = (VOID *) ((UINT8 *) Buffer + LibAmdAccessWidth (Width)); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get IOAPIC ID + * + * + * + * @param[in] IoApicBaseAddress IO APIC base address + * @param[in] Config Pointer to standard header + */ +UINT8 +GnbLiGetIoapicId ( + IN UINT64 IoApicBaseAddress, + IN VOID *Config + ) +{ + UINT32 Value; + Value = 0x0; + GnbLibMemWrite (IoApicBaseAddress, AccessWidth32, &Value, Config); + GnbLibMemRead (IoApicBaseAddress + 0x10, AccessWidth32, &Value, Config); + return (UINT8) (Value >> 24); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write MMIO registers + * + * + * + * @param[in] Address Physical address + * @param[in] Width Access width + * @param[in] Mask AND Mask + * @param[in] Value OR Value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibMemRMW ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ) +{ + UINT32 Data; + GnbLibMemRead (Address, Width, &Data, Config); + Data = (Data & Mask) | Value; + GnbLibMemWrite (Address, Width, &Data, Config); +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Calculate power of number + * + * + * + * @param[in] Value Number + * @param[in] Power Power + */ + +UINT32 +GnbLibPowerOf ( + IN UINT32 Value, + IN UINT32 Power + ) +{ + UINT32 Result; + if (Power == 0) { + return 1; + } + Result = Value; + while ((--Power) > 0) { + Result *= Value; + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Search buffer for pattern + * + * + * @param[in] Buf1 Pointer to source buffer which will be subject of search + * @param[in] Buf1Length Length of the source buffer + * @param[in] Buf2 Pointer to pattern buffer + * @param[in] Buf2Length Length of the pattern buffer + * @retval Pointer on first occurrence of Buf2 in Buf1 or NULL + */ + +VOID* +GnbLibFind ( + IN UINT8 *Buf1, + IN UINTN Buf1Length, + IN UINT8 *Buf2, + IN UINTN Buf2Length + ) +{ + UINT8 *CurrentBuf1Ptr; + CurrentBuf1Ptr = Buf1; + while (CurrentBuf1Ptr < (Buf1 + Buf1Length - Buf2Length)) { + UINT8 *SourceBufPtr; + UINT8 *PatternBufPtr; + UINTN PatternBufLength; + SourceBufPtr = CurrentBuf1Ptr; + PatternBufPtr = Buf2; + PatternBufLength = Buf2Length; + while ((*SourceBufPtr++ == *PatternBufPtr++) && (PatternBufLength-- != 0)); + if (PatternBufLength == 0) { + return CurrentBuf1Ptr; + } + CurrentBuf1Ptr++; + } + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump buffer to HDTOUT + * + * + * @param[in] Buffer Buffer pointer + * @param[in] Count Count of data elements + * @param[in] DataWidth DataWidth 1 - Byte; 2 - Word; 3 - DWORD; 4 - QWORD + * @param[in] LineWidth Number of data item per line + */ +VOID +GnbLibDebugDumpBuffer ( + IN VOID *Buffer, + IN UINT32 Count, + IN UINT8 DataWidth, + IN UINT8 LineWidth + ) +{ + UINT32 Index; + UINT32 DataItemCount; + ASSERT (LineWidth != 0); + ASSERT (DataWidth >= 1 && DataWidth <= 4); + DataItemCount = 0; + for (Index = 0; Index < Count; ) { + switch (DataWidth) { + case 1: + IDS_HDT_CONSOLE (GNB_TRACE, "%02x ", *((UINT8 *) Buffer + Index)); + Index += 1; + break; + case 2: + IDS_HDT_CONSOLE (GNB_TRACE, "%04x ", *(UINT16 *) ((UINT8 *) Buffer + Index)); + Index += 2; + break; + case 3: + IDS_HDT_CONSOLE (GNB_TRACE, "%08x ", *(UINT32 *) ((UINT8 *) Buffer + Index)); + Index += 4; + break; + case 4: + IDS_HDT_CONSOLE (GNB_TRACE, "%08x%08", *(UINT32 *) ((UINT8 *) Buffer + Index), *(UINT32 *) ((UINT8 *) Buffer + Index + 4)); + Index += 8; + break; + default: + IDS_HDT_CONSOLE (GNB_TRACE, "ERROR! Incorrect Data Width\n"); + return; + } + if (++DataItemCount >= LineWidth) { + IDS_HDT_CONSOLE (GNB_TRACE, "\n"); + DataItemCount = 0; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump buffer to HDTOUT + * + * + * @param[in] ServiceId Service ID + * @param[in] SocketId Socket ID + * @param[in] ServiceProtocol Service protocol + * @param[in] StdHeader Standard Configuration Header + */ +AGESA_STATUS +GnbLibLocateService ( + IN GNB_SERVICE_ID ServiceId, + IN UINT8 SocketId, + IN VOID **ServiceProtocol, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GNB_SERVICE *SeviceEntry; + CPU_LOGICAL_ID LogicalId; + SeviceEntry = ServiceTable; + GetLogicalIdOfSocket (SocketId, &LogicalId, StdHeader); + while (SeviceEntry != NULL) { + if (SeviceEntry->ServiceId == ServiceId && (LogicalId.Family & SeviceEntry->Family) != 0) { + *ServiceProtocol = SeviceEntry->ServiceProtocol; + return AGESA_SUCCESS; + } + SeviceEntry = SeviceEntry->NextService; + } + return AGESA_UNSUPPORTED; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.h new file mode 100644 index 0000000000..7e35615231 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLib.h @@ -0,0 +1,156 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB register access services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBLIB_H_ +#define _GNBLIB_H_ + +#define IOC_WRITE_ENABLE 0x80 + +VOID +GnbLibPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *Config + ); + +VOID +GnbLibPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *Config + ); + +VOID +GnbLibPciIndirectRMW ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ); + +VOID +GnbLibPciIndirectWriteField ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN VOID *Config + ); + + +VOID +GnbLibPciRMW ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ); + +VOID +GnbLibIoRMW ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ); + + +UINT32 +GnbLibPowerOf ( + IN UINT32 Value, + IN UINT32 Power + ); + +VOID* +GnbLibFind ( + IN UINT8 *Buf1, + IN UINTN Buf1Length, + IN UINT8 *Buf2, + IN UINTN Buf2Length + ); + +VOID +GnbLibIndirectIoBlockRead ( + IN UINT16 IndexPort, + IN UINT16 DataPort, + IN ACCESS_WIDTH Width, + IN UINT32 IndexAddress, + IN UINT32 Count, + IN VOID *Buffer, + IN VOID *Config + ); + +UINT8 +GnbLiGetIoapicId ( + IN UINT64 IoApicBaseAddress, + IN VOID *Config + ); + +VOID +GnbLibDebugDumpBuffer ( + IN VOID *Buffer, + IN UINT32 Count, + IN UINT8 DataWidth, + IN UINT8 LineWidth + ); + +AGESA_STATUS +GnbLibLocateService ( + IN GNB_SERVICE_ID ServiceId, + IN UINT8 SocketId, + IN VOID **ServiceProtocol, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.c new file mode 100644 index 0000000000..0430fba359 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.c @@ -0,0 +1,143 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access various CPU registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "Porting.h" +#include "AMD.h" +#include "GnbLibPciAcc.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBCPUACC_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GnbLibCpuPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + OUT UINT32 *Value, + IN VOID *Config + ); + +VOID +GnbLibCpuPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT32 *Value, + IN VOID *Config + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Read CPU (DCT) indirect registers + * + * + * + * @param[in] Address PCI address of DCT register + * @param[in] IndirectAddress Offset of DCT register + * @param[out] Value Pointer to value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibCpuPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + OUT UINT32 *Value, + IN VOID *Config + ) +{ + UINT32 OffsetRegisterValue; + GnbLibPciWrite (Address, AccessWidth32, &IndirectAddress, Config); + do { + GnbLibPciRead (Address , AccessWidth32, &OffsetRegisterValue, Config); + } while ((OffsetRegisterValue & BIT31) == 0); + GnbLibPciRead (Address + 4, AccessWidth32, Value, Config); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Write CPU (DCT) indirect registers + * + * + * + * @param[in] Address PCI address of DCT register + * @param[in] IndirectAddress Offset of DCT register + * @param[in] Value Pointer to value + * @param[in] Config Pointer to standard header + */ +VOID +GnbLibCpuPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT32 *Value, + IN VOID *Config + ) +{ + UINT32 OffsetRegisterValue; + OffsetRegisterValue = IndirectAddress | BIT30; + GnbLibPciWrite (Address + 4, AccessWidth32, Value, Config); + GnbLibPciWrite (Address, AccessWidth32, &IndirectAddress, Config); + do { + GnbLibPciRead (Address , AccessWidth32, &OffsetRegisterValue, Config); + } while ((OffsetRegisterValue & BIT31) == 0); +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.h new file mode 100644 index 0000000000..f560b7b12b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibCpuAcc.h @@ -0,0 +1,65 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access various CPU registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _CPUACCLIB_H_ +#define _CPUACCLIB_H_ + +VOID +GnbLibCpuPciIndirectWrite ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + IN UINT32 *Value, + IN VOID *Config + ); + +VOID +GnbLibCpuPciIndirectRead ( + IN UINT32 Address, + IN UINT32 IndirectAddress, + OUT UINT32 *Value, + IN VOID *Config + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.c new file mode 100644 index 0000000000..91af4bbbe0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.c @@ -0,0 +1,176 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access heap. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "Porting.h" +#include "AMD.h" +#include "amdlib.h" +#include "heapManager.h" +#include "GnbLibPciAcc.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBHEAP_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +VOID * +GnbAllocateHeapBuffer ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID * +GnbAllocateHeapBufferAndClear ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID * +GnbLocateHeapBuffer ( + IN UINT32 Handle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Allocates space for a new buffer in the heap + * + * + * @param[in] Handle Buffer handle + * @param[in] Length Buffer length + * @param[in] StdHeader Standard configuration header + * + * @retval NULL Buffer allocation fail + * + */ + +VOID * +GnbAllocateHeapBuffer ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + AllocHeapParams.RequestedBufferSize = (UINT32) Length; + AllocHeapParams.BufferHandle = Handle; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + Status = HeapAllocateBuffer (&AllocHeapParams, StdHeader); + if (Status != AGESA_SUCCESS) { + return NULL; + } + return AllocHeapParams.BufferPtr; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Allocates space for a new buffer in the heap and clear it + * + * + * @param[in] Handle Buffer handle + * @param[in] Length Buffer length + * @param[in] StdHeader Standard configuration header + * + * @retval NULL Buffer allocation fail + * + */ + +VOID * +GnbAllocateHeapBufferAndClear ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + VOID *Buffer; + Buffer = GnbAllocateHeapBuffer (Handle, Length, StdHeader); + if (Buffer != NULL) { + LibAmdMemFill (Buffer, 0x00, Length, StdHeader); + } + return Buffer; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Locates a previously allocated buffer on the heap. + * + * + * @param[in] Handle Buffer handle + * @param[in] StdHeader Standard configuration header + * + * @retval NULL Buffer handle not found + * + */ + +VOID * +GnbLocateHeapBuffer ( + IN UINT32 Handle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + LOCATE_HEAP_PTR LocHeapParams; + LocHeapParams.BufferHandle = Handle; + Status = HeapLocateBuffer (&LocHeapParams, StdHeader); + if (Status != AGESA_SUCCESS) { + return NULL; + } + return LocHeapParams.BufferPtr; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.h new file mode 100644 index 0000000000..a751eee938 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibHeap.h @@ -0,0 +1,69 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access heap. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBHEAPLIB_H_ +#define _GNBHEAPLIB_H_ + +VOID * +GnbAllocateHeapBuffer ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID * +GnbLocateHeapBuffer ( + IN UINT32 Handle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID * +GnbAllocateHeapBufferAndClear ( + IN UINT32 Handle, + IN UINTN Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.c new file mode 100644 index 0000000000..4e4fa7ac04 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.c @@ -0,0 +1,122 @@ +/* $NoKeywords:$ */ +/** + * @file + * +* Service procedure to access I/O registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "Porting.h" +#include "AMD.h" +#include "amdlib.h" +#include "GnbLibIoAcc.h" +#include "S3SaveState.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBIOACC_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/*----------------------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------*/ +/** + * Write I/O Port + * + * + * + * @param[in] Address Physical Address + * @param[in] Width Access width + * @param[in] Value Pointer to value + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibIoWrite ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *StdHeader + ) +{ + if (Width >= AccessS3SaveWidth8) { + S3_SAVE_IO_WRITE (StdHeader, Address, Width, Value); + } + LibAmdIoWrite (Width, Address, Value, StdHeader); +} +/** + * Read IO port + * + * + * + * @param[in] Address Physical Address + * @param[in] Width Access width + * @param[out] Value Pointer to value + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibIoRead ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *StdHeader + ) +{ + LibAmdIoRead (Width, Address, Value, StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.h new file mode 100644 index 0000000000..4521cfd616 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibIoAcc.h @@ -0,0 +1,66 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access I/O registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _IOACCLIB_H_ +#define _IOACCLIB_H_ + + +VOID +GnbLibIoWrite ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *StdHeader + ); + +VOID +GnbLibIoRead ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *StdHeader + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.c new file mode 100644 index 0000000000..ad6433bd93 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.c @@ -0,0 +1,125 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access MMIO registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "Porting.h" +#include "AMD.h" +#include "amdlib.h" +#include "GnbLibMemAcc.h" +#include "S3SaveState.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBMEMACC_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Write Memory/MMIO registers + * + * + * + * @param[in] Address Physical Address + * @param[in] Width Access width + * @param[in] Value Pointer to value + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibMemWrite ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *StdHeader + ) +{ + if (Width >= AccessS3SaveWidth8) { + S3_SAVE_MEM_WRITE (StdHeader, Address, Width, Value); + } + LibAmdMemWrite (Width, Address, Value, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read Memory/MMIO registers + * + * + * + * @param[in] Address Physical Address + * @param[in] Width Access width + * @param[out] Value Pointer to value + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibMemRead ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *StdHeader + ) +{ + LibAmdMemRead (Width, Address, Value, StdHeader); +} + + + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.h new file mode 100644 index 0000000000..908b1ec724 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibMemAcc.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access MMIO registers. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _MEMACCLIB_H_ +#define _MEMACCLIB_H_ + +VOID +GnbLibMemWrite ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *StdHeader + ); + +VOID +GnbLibMemRead ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *StdHeader + ); + +VOID +GnbLibMemRMW ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Value, + IN VOID *Config + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c new file mode 100644 index 0000000000..10ef0a3f6e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c @@ -0,0 +1,403 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various PCI service routines. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +#include "AGESA.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbLibPciAcc.h" +#include "GnbLibPci.h" +#include "GnbLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBPCI_FILECODE + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if device present + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is present + * @retval FALSE Device is not present + */ + +BOOLEAN +GnbLibPciIsDevicePresent ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 DeviceId; + GnbLibPciRead (Address, AccessWidth32, &DeviceId, StdHeader); + if (DeviceId == 0xffffffff) { + return FALSE; + } else { + return TRUE; + } +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if device is bridge + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is a bridge + * @retval FALSE Device is not a bridge + */ + +BOOLEAN +GnbLibPciIsBridgeDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Header; + GnbLibPciRead (Address | 0xe, AccessWidth8, &Header, StdHeader); + if ((Header & 0x7f) == 1) { + return TRUE; + } else { + return FALSE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if device is multifunction + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is a multifunction device. + * @retval FALSE Device is a single function device. + * + */ +BOOLEAN +GnbLibPciIsMultiFunctionDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Header; + GnbLibPciRead (Address | 0xe, AccessWidth8, &Header, StdHeader); + if ((Header & 0x80) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if device is PCIe device + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] StdHeader Standard configuration header + * @retval TRUE Device is a PCIe device + * @retval FALSE Device is not a PCIe device + * + */ + +BOOLEAN +GnbLibPciIsPcieDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + if (GnbLibFindPciCapability (Address, PCIE_CAP_ID, StdHeader) != 0 ) { + return TRUE; + } else { + return FALSE; + } +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Find PCI capability pointer + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] CapabilityId PCI capability ID + * @param[in] StdHeader Standard configuration header + * @retval Register address of capability pointer + * + */ + +UINT8 +GnbLibFindPciCapability ( + IN UINT32 Address, + IN UINT8 CapabilityId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 CapabilityPtr; + UINT8 CurrentCapabilityId; + CapabilityPtr = 0x34; + if (!GnbLibPciIsDevicePresent (Address, StdHeader)) { + return 0; + } + while (CapabilityPtr != 0) { + GnbLibPciRead (Address | CapabilityPtr, AccessWidth8 , &CapabilityPtr, StdHeader); + if (CapabilityPtr != 0) { + GnbLibPciRead (Address | CapabilityPtr , AccessWidth8 , &CurrentCapabilityId, StdHeader); + if (CurrentCapabilityId == CapabilityId) { + break; + } + CapabilityPtr++; + } + } + return CapabilityPtr; +} +/*----------------------------------------------------------------------------------------*/ +/* + * Find PCIe extended capability pointer + * + * + * + * @param[in] Address PCI address (as described in PCI_ADDR) + * @param[in] ExtendedCapabilityId Extended PCIe capability ID + * @param[in] StdHeader Standard configuration header + * @retval Register address of extended capability pointer + * + */ + + +UINT16 +GnbLibFindPcieExtendedCapability ( + IN UINT32 Address, + IN UINT16 ExtendedCapabilityId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 CapabilityPtr; + UINT32 ExtendedCapabilityIdBlock; + if (GnbLibPciIsPcieDevice (Address, StdHeader)) { + GnbLibPciRead (Address | 0x100 , AccessWidth32 , &ExtendedCapabilityIdBlock, StdHeader); + if ((ExtendedCapabilityIdBlock != 0) && ((UINT16)ExtendedCapabilityIdBlock != 0xffff)) { + do { + CapabilityPtr = (UINT16) ((ExtendedCapabilityIdBlock >> 20) & 0xfff); + if ((UINT16)ExtendedCapabilityIdBlock == ExtendedCapabilityId) { + return CapabilityPtr; + } + GnbLibPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, StdHeader); + } while (((ExtendedCapabilityIdBlock >> 20) & 0xfff) != 0); + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Scan range of device on PCI bus. + * + * + * + * @param[in] Start Start address to start scan from + * @param[in] End End address of scan + * @param[in] ScanData Supporting data + * + */ +/*----------------------------------------------------------------------------------------*/ +VOID +GnbLibPciScan ( + IN PCI_ADDR Start, + IN PCI_ADDR End, + IN GNB_PCI_SCAN_DATA *ScanData + ) +{ + UINTN Bus; + UINTN Device; + UINTN LastDevice; + UINTN Function; + UINTN LastFunction; + PCI_ADDR PciDevice; + SCAN_STATUS Status; + + for (Bus = Start.Address.Bus; Bus <= End.Address.Bus; Bus++) { + Device = (Bus == Start.Address.Bus) ? Start.Address.Device : 0x00; + LastDevice = (Bus == End.Address.Bus) ? End.Address.Device : 0x1F; + for ( ; Device <= LastDevice; Device++) { + if ((Bus == Start.Address.Bus) && (Device == Start.Address.Device)) { + Function = Start.Address.Function; + } else { + Function = 0x0; + } + PciDevice.AddressValue = MAKE_SBDFO (0, Bus, Device, Function, 0); + if (!GnbLibPciIsDevicePresent (PciDevice.AddressValue, ScanData->StdHeader)) { + continue; + } + if (GnbLibPciIsMultiFunctionDevice (PciDevice.AddressValue, ScanData->StdHeader)) { + if ((Bus == End.Address.Bus) && (Device == End.Address.Device)) { + LastFunction = Start.Address.Function; + } else { + LastFunction = 0x7; + } + } else { + LastFunction = 0x0; + } + for ( ; Function <= LastFunction; Function++) { + PciDevice.AddressValue = MAKE_SBDFO (0, Bus, Device, Function, 0); + if (GnbLibPciIsDevicePresent (PciDevice.AddressValue, ScanData->StdHeader)) { + Status = ScanData->GnbScanCallback (PciDevice, ScanData); + if ((Status & SCAN_SKIP_FUNCTIONS) != 0) { + Function = LastFunction + 1; + } + if ((Status & SCAN_SKIP_DEVICES) != 0) { + Device = LastDevice + 1; + } + if ((Status & SCAN_SKIP_BUSES) != 0) { + Bus = End.Address.Bus + 1; + } + } + } + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Scan all subordinate buses + * + * + * @param[in] Bridge PCI bridge address + * @param[in,out] ScanData Scan configuration data + * + */ +VOID +GnbLibPciScanSecondaryBus ( + IN PCI_ADDR Bridge, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + PCI_ADDR StartRange; + PCI_ADDR EndRange; + UINT8 SecondaryBus; + GnbLibPciRead (Bridge.AddressValue | 0x19, AccessWidth8, &SecondaryBus, ScanData->StdHeader); + if (SecondaryBus != 0) { + StartRange.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0); + EndRange.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0x1f, 0x7, 0); + GnbLibPciScan (StartRange, EndRange, ScanData); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get PCIe device type + * + * + * + * @param[in] Device PCI address of device. + * @param[in] StdHeader Northbridge configuration structure pointer. + * + * @retval PCIE_DEVICE_TYPE + */ + /*----------------------------------------------------------------------------------------*/ + +PCIE_DEVICE_TYPE +GnbLibGetPcieDeviceType ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PcieCapPtr; + UINT8 Value; + + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr != 0) { + GnbLibPciRead (Device.AddressValue | (PcieCapPtr + 0x2) , AccessWidth8, &Value, StdHeader); + return Value >> 4; + } + return PcieNotPcieDevice; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Save config space area + * + * + * + * @param[in] Address PCI address of device. + * @param[in] StartRegisterAddress Start register address. + * @param[in] EndRegisterAddress End register address. + * @param[in] Width Access width. + * @param[in] StdHeader Standard header. + * + */ + /*----------------------------------------------------------------------------------------*/ + +VOID +GnbLibS3SaveConfigSpace ( + IN UINT32 Address, + IN UINT16 StartRegisterAddress, + IN UINT16 EndRegisterAddress, + IN ACCESS_WIDTH Width, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 Index; + UINT16 Delta; + UINT16 Length; + Length = (StartRegisterAddress < EndRegisterAddress) ? (EndRegisterAddress - StartRegisterAddress) : (StartRegisterAddress - EndRegisterAddress); + Delta = LibAmdAccessWidth (Width); + for (Index = 0; Index <= Length; Index = Index + Delta) { + GnbLibPciRMW ( + Address | ((StartRegisterAddress < EndRegisterAddress) ? (StartRegisterAddress + Index) : (StartRegisterAddress - Index)), + Width, + 0xffffffff, + 0x0, + StdHeader + ); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.h new file mode 100644 index 0000000000..d1cf252c95 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.h @@ -0,0 +1,166 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various PCI service routines. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBLIBPCI_H_ +#define _GNBLIBPCI_H_ + +#define PCIE_CAP_ID 0x10 +#define IOMMU_CAP_ID 0x0F + +/// PCIe device type +typedef enum { + PcieDeviceEndPoint, ///< Endpoint + PcieDeviceLegacyEndPoint, ///< Legacy endpoint + PcieDeviceRootComplex = 4, ///< Root complex + PcieDeviceUpstreamPort, ///< Upstream port + PcieDeviceDownstreamPort, ///< Downstream Port + PcieDevicePcieToPcix, ///< PCIe to PCI/PCIx bridge + PcieDevicePcixToPcie, ///< PCI/PCIx to PCIe bridge + PcieNotPcieDevice = 0xff ///< unknown device +} PCIE_DEVICE_TYPE; + +typedef UINT32 SCAN_STATUS; + +#define SCAN_SKIP_FUNCTIONS 0x1 +#define SCAN_SKIP_DEVICES 0x2 +#define SCAN_SKIP_BUSES 0x4 +#define SCAN_SUCCESS 0x0 + +// Forward declaration needed for multi-structure mutual references +AGESA_FORWARD_DECLARATION (GNB_PCI_SCAN_DATA); + +typedef SCAN_STATUS (*GNB_SCAN_CALLBACK) ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +///Scan supporting data +struct _GNB_PCI_SCAN_DATA { + GNB_SCAN_CALLBACK GnbScanCallback; ///< Callback for each found device + AMD_CONFIG_PARAMS *StdHeader; ///< Standard configuration header +}; + +#define PCIE_CAP_ID 0x10 +#define PCIE_LINK_CAP_REGISTER 0x0C +#define PCIE_LINK_CTRL_REGISTER 0x10 +#define PCIE_DEVICE_CAP_REGISTER 0x04 +#define PCIE_DEVICE_CTRL_REGISTER 0x08 +#define PCIE_ASPM_L1_SUPPORT_CAP BIT11 + +#define MAX_PAYLOAD_128 0x0 ///< Max allowed payload size 128 bytes +#define MAX_PAYLOAD_256 0x1 ///< Max allowed payload size 256 bytes +#define MAX_PAYLOAD_512 0x2 ///< Max allowed payload size 512 bytes +#define MAX_PAYLOAD_1024 0x3 ///< Max allowed payload size 1024 bytes +#define MAX_PAYLOAD_2048 0x4 ///< Max allowed payload size 2048 bytes +#define MAX_PAYLOAD_4096 0x5 ///< Max allowed payload size 4096 bytes +#define MAX_PAYLOAD 0x5 ///< Max allowed payload size according to spec is 101b (4096 bytes) + +BOOLEAN +GnbLibPciIsDevicePresent ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GnbLibPciIsBridgeDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GnbLibPciIsMultiFunctionDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GnbLibPciIsPcieDevice ( + IN UINT32 Address, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLibFindPciCapability ( + IN UINT32 Address, + IN UINT8 CapabilityId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibPciScan ( + IN PCI_ADDR Start, + IN PCI_ADDR End, + IN GNB_PCI_SCAN_DATA *ScanData + ); + +VOID +GnbLibPciScanSecondaryBus ( + IN PCI_ADDR Bridge, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +PCIE_DEVICE_TYPE +GnbLibGetPcieDeviceType ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibS3SaveConfigSpace ( + IN UINT32 Address, + IN UINT16 StartRegisterAddress, + IN UINT16 EndRegisterAddress, + IN ACCESS_WIDTH Width, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT16 +GnbLibFindPcieExtendedCapability ( + IN UINT32 Address, + IN UINT16 ExtendedCapabilityId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.c new file mode 100644 index 0000000000..d9d708fa65 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.c @@ -0,0 +1,156 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "Porting.h" +#include "AMD.h" +#include "amdlib.h" +#include "GnbLibPciAcc.h" +#include "S3SaveState.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBPCIACC_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCI registers + * + * + * + * @param[in] Address PCI address (as presented in PCI_ADDR.AddressValue) + * @param[in] Width Access width + * @param[in] Value Pointer to value + * @param[in] StdHeader Pointer to standard header + */ +VOID +GnbLibPciWrite ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + PciAddress.AddressValue = Address; + if (Width >= AccessS3SaveWidth8) { + S3_SAVE_PCI_WRITE (StdHeader, PciAddress, Width, Value); + } + LibAmdPciWrite (Width, PciAddress, Value, StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCI registers + * + * + * + * @param[in] Address PCI address (as presented in PCI_ADDR.AddressValue) + * @param[in] Width Access width + * @param[out] Value Pointer to value + * @param[in] StdHeader Pointer to standard header + */ + +VOID +GnbLibPciRead ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + PciAddress.AddressValue = Address; + LibAmdPciRead (Width, PciAddress, Value, StdHeader); +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Poll PCI reg + * + * + * + * @param[in] Address PCI address (as presented in PCI_ADDR.AddressValue) + * @param[in] Width Access width + * @param[in] Data Data to compare + * @param[in] DataMask AND mask + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibPciPoll ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Data, + IN VOID *DataMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + PciAddress.AddressValue = Address; + if (Width >= AccessS3SaveWidth8) { + S3_SAVE_PCI_POLL (StdHeader, PciAddress, Width, Data, DataMask, 0xffffffff); + } + LibAmdPciPoll (Width, PciAddress, Data, DataMask, 0xffffffff, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.h new file mode 100644 index 0000000000..14808e07ff --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbLibPciAcc.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBLIBPCIACC_H_ +#define _GNBLIBPCIACC_H_ + +VOID +GnbLibPciWrite ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibPciRead ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibPciPoll ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Data, + IN VOID *DataMask, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.c new file mode 100644 index 0000000000..bbbede825d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.c @@ -0,0 +1,157 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various Timer services. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86079 $ @e \$Date: 2013-01-16 00:59:04 -0600 (Wed, 16 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +#include "AGESA.h" +#include "amdlib.h" +#include "S3SaveState.h" +#include "Gnb.h" +#include "GnbLib.h" +#include "GnbTimerLib.h" +#include "GnbFamServices.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBTIMERLIB_FILECODE + + + + +/*----------------------------------------------------------------------------------------*/ +/* + * Stall and save to script table + * + * + * + * @param[in] Microsecond Stall time + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibStallS3Save ( + IN UINT32 Microsecond, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + S3_SAVE_DISPATCH (StdHeader, GnbLibStallS3Script_ID, sizeof (Microsecond), &Microsecond); + GnbLibStall (Microsecond, StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Stall + * + * + * + * @param[in] Microsecond Stall time + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLibStall ( + IN UINT32 Microsecond, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TimeStampStart; + UINT32 TimeStampDelta; + UINT32 TimeStampCurrent; + + TimeStampStart = GnbFmTimeStamp (StdHeader); + do { + TimeStampCurrent = GnbFmTimeStamp (StdHeader); + TimeStampDelta = ((TimeStampCurrent > TimeStampStart) ? (TimeStampCurrent - TimeStampStart) : (0xffffffffull - TimeStampStart + TimeStampCurrent)); + } while (TimeStampDelta < Microsecond); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Stall S3 script + * + * + * + * @param[in] StdHeader Standard configuration header + * @param[in] ContextLength Context Length (not used) + * @param[in] Context pointer to UINT32 number of us + */ +VOID +GnbLibStallS3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID* Context + ) +{ + GnbLibStall (* ((UINT32*) Context), StdHeader); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Family specific time stamp function + * + * + * @param[in] StdHeader Standard configuration header + * @retval Count + */ +UINT32 +GnbFmTimeStamp ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + GNB_FAM_TS_SERVICES *GnbFamTsFunc; + GNB_HANDLE *GnbHandle; + + GnbHandle = GnbGetHandle (StdHeader); + + Status = GnbLibLocateService (GnbFamTsService, GnbGetSocketId (GnbHandle), (VOID **)&GnbFamTsFunc, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return GnbFamTsFunc->GnbFmTimeStamp (StdHeader); + } + return 0; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.h new file mode 100644 index 0000000000..c7796d1202 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbCommonLib/GnbTimerLib.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various Timer Services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86079 $ @e \$Date: 2013-01-16 00:59:04 -0600 (Wed, 16 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBTIMERLIB_H_ +#define _GNBTIMERLIB_H_ + +VOID +GnbLibStallS3Save ( + IN UINT32 Microsecond, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibStall ( + IN UINT32 Microsecond, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GnbFmTimeStamp ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLibStallS3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID* Context + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbFamTranslation/GnbPcieTranslation.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbFamTranslation/GnbPcieTranslation.c new file mode 100644 index 0000000000..f42e306396 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbFamTranslation/GnbPcieTranslation.c @@ -0,0 +1,515 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific function translation + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBFAMTRANSLATION_GNBPCIETRANSLATION_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] EngineType Engine Type + * @param[in] ConfigurationId Configuration ID + * @retval AGESA_SUCCESS Configuration successfully applied + * @retval AGESA_UNSUPPORTED No more configuration available for given engine type + * @retval AGESA_ERROR Requested configuration not supported + */ +AGESA_STATUS +PcieFmConfigureEnginesLaneAllocation ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIE_ENGINE_TYPE EngineType, + IN UINT8 ConfigurationId + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Wrapper->Header); + Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, (VOID **)&PcieConfigService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmConfigureEnginesLaneAllocation (Wrapper, EngineType, ConfigurationId); + } + return AGESA_ERROR; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get core configuration value + * + * + * + * @param[in] Wrapper Pointer to internal configuration data area + * @param[in] CoreId Core ID + * @param[in] ConfigurationSignature Configuration signature + * @param[out] ConfigurationValue Configuration value (for core configuration) + * @retval AGESA_SUCCESS Configuration successfully applied + * @retval AGESA_ERROR Core configuration value can not be determined + */ +AGESA_STATUS +PcieFmGetCoreConfigurationValue ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId, + IN UINT64 ConfigurationSignature, + IN UINT8 *ConfigurationValue + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_INIT_SERVICES *PcieInitService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Wrapper->Header); + Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, (VOID **)&PcieInitService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieInitService->PcieFmGetCoreConfigurationValue (Wrapper, CoreId, ConfigurationSignature, ConfigurationValue); + } + return AGESA_ERROR; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if engine can be remapped to Device/function number requested by user + * defined engine descriptor + * + * Function only called if requested device/function does not much native device/function + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieFmCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, (VOID **)&PcieConfigService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmCheckPortPciDeviceMapping (PortDescriptor, Engine); + } + return FALSE; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get core configuration string + * + * Debug function for logging configuration + * + * @param[in] Wrapper Pointer to internal configuration data area + * @param[in] ConfigurationValue Configuration value + * @retval Configuration string + */ + +CONST CHAR8* +PcieFmDebugGetCoreConfigurationString ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 ConfigurationValue + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_DEBUG_SERVICES *PcieDebugService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, (VOID **)&PcieDebugService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieDebugService->PcieFmDebugGetCoreConfigurationString (Wrapper, ConfigurationValue); + } + return " !!! Something Wrong !!!"; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get wrapper name + * + * Debug function for logging wrapper name + * + * @param[in] Wrapper Pointer to internal configuration data area + * @retval Wrapper Name string + */ + +CONST CHAR8* +PcieFmDebugGetWrapperNameString ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_DEBUG_SERVICES *PcieDebugService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, (VOID **)&PcieDebugService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieDebugService->PcieFmDebugGetWrapperNameString (Wrapper); + } + return " !!! Something Wrong !!!"; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get register address name + * + * Debug function for logging register trace + * + * @param[in] Silicon Silicon config descriptor + * @param[in] AddressFrame Address Frame + * @retval Register address name + */ +CONST CHAR8* +PcieFmDebugGetHostRegAddressSpaceString ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT16 AddressFrame + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_DEBUG_SERVICES *PcieDebugService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Silicon->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, (VOID **)&PcieDebugService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieDebugService->PcieFmDebugGetHostRegAddressSpaceString (Silicon, AddressFrame); + } + return " !!! Something Wrong !!!"; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if the lane can be muxed by link width requested by user + * defined engine descriptor + * + * Check Engine StartCoreLane could be aligned by user requested link width(x1, x2, x4, x8, x16). + * Check Engine StartCoreLane could be aligned by user requested link width x2. + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Lane can be muxed + * @retval FALSE Lane can NOT be muxed + */ + +BOOLEAN +PcieFmCheckPortPcieLaneCanBeMuxed ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, (VOID **)&PcieConfigService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmCheckPortPcieLaneCanBeMuxed (PortDescriptor, Engine); + } + return FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Map engine to specific PCI device address + * + * + * + * @param[in] Engine Pointer to engine configuration + * @retval AGESA_ERROR Fail to map PCI device address + * @retval AGESA_SUCCESS Successfully allocate PCI address + */ + +AGESA_STATUS +PcieFmMapPortPciAddress ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, (VOID **)&PcieConfigService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmMapPortPciAddress (Engine); + } + return AGESA_ERROR; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get total number of silicons/wrappers/engines for this complex + * + * + * + * @param[in] SocketId Socket ID. + * @param[out] Length Length of configuration info block + * @param[out] StdHeader Standard Configuration Header + * @retval AGESA_SUCCESS Configuration data length is correct + */ +AGESA_STATUS +PcieFmGetComplexDataLength ( + IN UINT8 SocketId, + OUT UINTN *Length, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, (VOID **)&PcieConfigService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmGetComplexDataLength (SocketId, Length, StdHeader); + } + return Status; +} + + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Build configuration + * + * + * @param[in] SocketId Socket ID. + * @param[out] Buffer Pointer to buffer to build internal complex data structure + * @param[out] StdHeader Standard configuration header. + * @retval AGESA_SUCCESS Configuration data build successfully + */ +AGESA_STATUS +PcieFmBuildComplexConfiguration ( + IN UINT8 SocketId, + OUT VOID *Buffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, (VOID **)&PcieConfigService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmBuildComplexConfiguration (SocketId, Buffer, StdHeader); + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get max link speed capability supported by this port + * + * + * + * @param[in] Flags See Flags PCIE_PORT_GEN_CAP_BOOT / PCIE_PORT_GEN_CAP_MAX + * @param[in] Engine Pointer to engine config descriptor + * @retval PcieGen1/PcieGen2 Max supported link gen capability + */ +PCIE_LINK_SPEED_CAP +PcieFmGetLinkSpeedCap ( + IN UINT32 Flags, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_INIT_SERVICES *PcieInitService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, (VOID **)&PcieInitService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieInitService->PcieFmGetLinkSpeedCap (Flags, Engine); + } + return PcieGen1; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get native PHY lane bitmap + * + * + * @param[in] PhyLaneBitmap Package PHY lane bitmap + * @param[in] Engine Standard configuration header. + * @retval Native PHY lane bitmap + */ +UINT32 +PcieFmGetNativePhyLaneBitmap ( + IN UINT32 PhyLaneBitmap, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_FAM_INIT_SERVICES *PcieInitService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, (VOID **)&PcieInitService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieInitService->PcieFmGetNativePhyLaneBitmap (PhyLaneBitmap, Engine); + } + return 0x0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set current link speed + * + * + * @param[in] LinkSpeedCapability Link Speed Capability + * @param[in] Engine Pointer to engine configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieFmSetLinkSpeedCap ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_FAM_INIT_SERVICES *PcieInitService; + + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, (VOID **)&PcieInitService, GnbLibGetHeader (Pcie)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + PcieInitService->PcieFmSetLinkSpeedCap (LinkSpeedCapability, Engine, Pcie); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get SB port info + * + * + * @param[out] SocketId Socket ID + * @param[out] SbPort Pointer to SB configuration descriptor + * @param[in] StdHeader Standard configuration header. + * @retval AGESA_SUCCESS SB configuration determined successfully + */ +AGESA_STATUS +PcieFmGetSbConfigInfo ( + IN UINT8 SocketId, + OUT PCIe_PORT_DESCRIPTOR *SbPort, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + PCIe_FAM_CONFIG_SERVICES *PcieConfigService; + Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, (VOID **)&PcieConfigService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return PcieConfigService->PcieFmGetSbConfigInfo (SocketId, SbPort, StdHeader); + } + return Status; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbFamTranslation/GnbTranslation.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbFamTranslation/GnbTranslation.c new file mode 100644 index 0000000000..1ae93d42a2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbFamTranslation/GnbTranslation.c @@ -0,0 +1,245 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific function translation + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieConfig.h" +#include "GnbFamServices.h" +#include "GnbGfxFamServices.h" +#include "GnbCommonLib.h" +#include "GnbGfx.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBFAMTRANSLATION_GNBTRANSLATION_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if IOMMU unit present and enabled + * + * + * + * + * @param[in] GnbHandle Gnb handle + * @param[in] StdHeader Standard configuration header + * + */ +BOOLEAN +GnbFmCheckIommuPresent ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + GNB_FAM_IOMMU_SERVICES *GnbIommuConfigService; + Status = GnbLibLocateService (GnbIommuService, GnbGetSocketId (GnbHandle), (VOID **)&GnbIommuConfigService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return GnbIommuConfigService->GnbFmCheckIommuPresent (GnbHandle, StdHeader); + } + return FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Create IVRS entry + * + * + * @param[in] GnbHandle Gnb handle + * @param[in] Type Entry type + * @param[in] Ivrs IVRS table pointer + * @param[in] StdHeader Standard configuration header + * + */ + +AGESA_STATUS +GnbFmCreateIvrsEntry ( + IN GNB_HANDLE *GnbHandle, + IN IVRS_BLOCK_TYPE Type, + IN VOID *Ivrs, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + GNB_FAM_IOMMU_SERVICES *GnbIommuConfigService; + Status = GnbLibLocateService (GnbIommuService, GnbGetSocketId (GnbHandle), (VOID **)&GnbIommuConfigService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return GnbIommuConfigService->GnbFmCreateIvrsEntry (GnbHandle, Type, Ivrs, StdHeader); + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Map graphics engine to display path + * + * + * + * + * @param[in] Engine Engine configuration info + * @param[out] DisplayPathList Display path list + * @param[in] Gfx Pointer to global GFX configuration + * + */ +AGESA_STATUS +GfxFmMapEngineToDisplayPath ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + AGESA_STATUS Status; + GFX_FAM_SERVICES *GfxFamilyService; + GNB_HANDLE *GnbHandle; + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + Status = GnbLibLocateService (GfxFamService, GnbGetSocketId (GnbHandle), (VOID **)&GfxFamilyService, GnbLibGetHeader (Gfx)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return GfxFamilyService->GfxMapEngineToDisplayPath (Engine, DisplayPathList, Gfx); + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Calculate COF for DFS out of Main PLL + * + * + * + * @param[in] Did Did + * @param[in] StdHeader Standard Configuration Header + * @retval COF in 10khz + */ + +UINT32 +GfxFmCalculateClock ( + IN UINT8 Did, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + GFX_FAM_SERVICES *GfxFamilyService; + GNB_HANDLE *GnbHandle; + GnbHandle = GnbGetHandle (StdHeader); + Status = GnbLibLocateService (GfxFamService, GnbGetSocketId (GnbHandle), (VOID **)&GfxFamilyService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return GfxFamilyService->GfxCalculateClock (Did, StdHeader); + } + return 200*100; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable GFX controller + * + * + * + * @param[in] StdHeader Standard configuration header + */ + +VOID +GfxFmDisableController ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + GFX_FAM_SERVICES *GfxFamilyService; + GNB_HANDLE *GnbHandle; + GnbHandle = GnbGetHandle (StdHeader); + Status = GnbLibLocateService (GfxFamService, GnbGetSocketId (GnbHandle), (VOID **)&GfxFamilyService, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + GfxFamilyService->GfxDisableController (StdHeader); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set idle voltage mode for GFX + * + * + * @param[in] Gfx Pointer to global GFX configuration + */ + +BOOLEAN +GfxFmIsVbiosPosted ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + AGESA_STATUS Status; + GFX_FAM_SERVICES *GfxFamilyService; + GNB_HANDLE *GnbHandle; + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + Status = GnbLibLocateService (GfxFamService, GnbGetSocketId (GnbHandle), (VOID **)&GfxFamilyService, GnbLibGetHeader (Gfx)); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + return GfxFamilyService->GfxIsVbiosPosted (Gfx); + } + return TRUE; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigEnv.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigEnv.c new file mode 100644 index 0000000000..96dc84121a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigEnv.c @@ -0,0 +1,135 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GnbGfxConfig.h" +#include "GfxConfigLib.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXCONFIG_GFXCONFIGENV_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GfxConfigEnvInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Update GFX config info at ENV + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS Always succeeds + */ + +AGESA_STATUS +GfxConfigEnvInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + AMD_ENV_PARAMS *EnvParamsPtr; + GFX_PLATFORM_CONFIG *Gfx; + AGESA_STATUS Status; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigEnvInterface Enter\n"); + Status = GfxLocateConfigData (StdHeader, &Gfx); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + EnvParamsPtr = (AMD_ENV_PARAMS *) StdHeader; + Gfx->Gnb3dStereoPinIndex = EnvParamsPtr->GnbEnvConfiguration.Gnb3dStereoPinIndex; + Gfx->LvdsSpreadSpectrum = EnvParamsPtr->GnbEnvConfiguration.LvdsSpreadSpectrum; + Gfx->LvdsSpreadSpectrumRate = EnvParamsPtr->GnbEnvConfiguration.LvdsSpreadSpectrumRate; + Gfx->LvdsPowerOnSeqDigonToDe = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqDigonToDe; + Gfx->LvdsPowerOnSeqDeToVaryBl = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqDeToVaryBl; + Gfx->LvdsPowerOnSeqDeToDigon = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqDeToDigon; + Gfx->LvdsPowerOnSeqVaryBlToDe = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqVaryBlToDe; + Gfx->LvdsPowerOnSeqOnToOffDelay = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqOnToOffDelay; + Gfx->LvdsPowerOnSeqVaryBlToBlon = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqVaryBlToBlon; + Gfx->LvdsPowerOnSeqBlonToVaryBl = EnvParamsPtr->GnbEnvConfiguration.LvdsPowerOnSeqBlonToVaryBl; + Gfx->LvdsMaxPixelClockFreq = EnvParamsPtr->GnbEnvConfiguration.LvdsMaxPixelClockFreq; + Gfx->LcdBitDepthControlValue = EnvParamsPtr->GnbEnvConfiguration.LcdBitDepthControlValue; + Gfx->Lvds24bbpPanelMode = EnvParamsPtr->GnbEnvConfiguration.Lvds24bbpPanelMode; + Gfx->LvdsMiscControl.Value = EnvParamsPtr->GnbEnvConfiguration.LvdsMiscControl.Value; + Gfx->PcieRefClkSpreadSpectrum = EnvParamsPtr->GnbEnvConfiguration.PcieRefClkSpreadSpectrum; + Gfx->GnbRemoteDisplaySupport = EnvParamsPtr->GnbEnvConfiguration.GnbRemoteDisplaySupport; + Gfx->LVDSVoltAdjust = EnvParamsPtr->GnbEnvConfiguration.LvdsMiscVoltAdjustment; + Gfx->DisplayMiscControl.Value = EnvParamsPtr->GnbEnvConfiguration.DisplayMiscControl.Value; + Gfx->DpFixedVoltSwingType = EnvParamsPtr->GnbEnvConfiguration.DpFixedVoltSwingType; + GfxGetUmaInfo (&Gfx->UmaInfo, StdHeader); + } + GNB_DEBUG_CODE ( + GfxConfigDebugDump (Gfx); + ); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigEnvInterface Exit [0x%x]\n", Status); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.c new file mode 100644 index 0000000000..ae0128ab7c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.c @@ -0,0 +1,264 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86877 $ @e \$Date: 2013-01-28 10:59:42 -0600 (Mon, 28 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXCONFIG_GFXCONFIGLIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +GfxEnableGmmAccess ( + IN OUT GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxGetUmaInfo ( + OUT UMA_INFO *UmaInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GfxLocateConfigData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT GFX_PLATFORM_CONFIG **Gfx + ); + +VOID +GfxConfigDebugDump ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable GMM Access + * + * + * + * @param[in,out] Gfx Pointer to GFX configuration + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GfxEnableGmmAccess ( + IN OUT GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 Value; + + if (!GnbLibPciIsDevicePresent (Gfx->GfxPciAddress.AddressValue, GnbLibGetHeader (Gfx))) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + + // Check if base address for GMM allocated + GnbLibPciIndirectRead (GNB_SBDFO | 0x60, 0x1C | IOC_WRITE_ENABLE, AccessWidth32, &Value, GnbLibGetHeader (Gfx)); + Gfx->GmmBase = 0; + + if ((Value & 0x4) != 0) { + GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x1c, AccessWidth32, &Gfx->GmmBase, GnbLibGetHeader (Gfx)); + Gfx->GmmBase = (UINT64) (Gfx->GmmBase << 32); + } + + GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x18, AccessWidth32, &Value, GnbLibGetHeader (Gfx)); + Gfx->GmmBase |= (Value & 0xfffffff0); + if (Gfx->GmmBase == 0) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + + // Check if base address for FB allocated + GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x10, AccessWidth32, &Value, GnbLibGetHeader (Gfx)); + if ((Value & 0xfffffff0) == 0) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + //Push CPU MMIO pci config to S3 script + GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 0x18, 1, 0), 0xBC, 0x80, AccessS3SaveWidth32, GnbLibGetHeader (Gfx)); + // Turn on memory decoding on APC to enable access to GMM register space + if (Gfx->GfxControllerMode == GfxControllerLegacyBridgeMode) { + GnbLibPciRMW (MAKE_SBDFO (0, 0, 1, 0, 0x4), AccessWidth32, 0xffffffff, BIT1 | BIT2, GnbLibGetHeader (Gfx)); + //Push APC pci config to S3 script + GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 1, 0, 0), 0x2C, 0x18, AccessS3SaveWidth32, GnbLibGetHeader (Gfx)); + GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 1, 0, 0), 0x4, 0x4, AccessS3SaveWidth16, GnbLibGetHeader (Gfx)); + } + // Turn on memory decoding on GFX to enable access to GMM register space + GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessWidth32, 0xffffffff, BIT1 | BIT2, GnbLibGetHeader (Gfx)); + //Push iGPU pci config to S3 script + GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x24, 0x10, AccessS3SaveWidth32, GnbLibGetHeader (Gfx)); + GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x04, 0x04, AccessS3SaveWidth16, GnbLibGetHeader (Gfx)); + return AGESA_SUCCESS; +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get UMA info + * + * UMA info stored on heap by memory module + * + * @param[out] UmaInfo Pointer to UMA info structure + * @param[in] StdHeader Standard configuration header + */ + +VOID +GfxGetUmaInfo ( + OUT UMA_INFO *UmaInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UMA_INFO *MemUmaInfo; + + MemUmaInfo = GnbLocateHeapBuffer (AMD_UMA_INFO_HANDLE, StdHeader); + if (MemUmaInfo == NULL) { + LibAmdMemFill (UmaInfo, 0x00, sizeof (UMA_INFO), StdHeader); + UmaInfo->UmaMode = UMA_NONE; + } else { + LibAmdMemCopy (UmaInfo, MemUmaInfo, sizeof (UMA_INFO), StdHeader); + if ((UmaInfo->UmaBase == 0) || (UmaInfo->UmaSize == 0)) { + UmaInfo->UmaMode = UMA_NONE; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate UMA configuration data + * + * + * + * @param[in] StdHeader Standard configuration header + * @param[in,out] Gfx Pointer to GFX configuration + * @retval AGESA_STATUS Data located + * @retval AGESA_FATA Data not found + */ + +AGESA_STATUS +GfxLocateConfigData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT GFX_PLATFORM_CONFIG **Gfx + ) +{ + *Gfx = GnbLocateHeapBuffer (AMD_GFX_PLATFORM_CONFIG_HANDLE, StdHeader); + if (*Gfx == NULL) { + IDS_ERROR_TRAP; + return AGESA_FATAL; + } + (*Gfx)->StdHeader = (PVOID) StdHeader; + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Debug dump + * + * + * + * @param[in] Gfx Pointer to GFX configuration + */ + +VOID +GfxConfigDebugDump ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + IDS_HDT_CONSOLE (GFX_MISC, "<-------------- GFX Config Start ------------->\n"); + IDS_HDT_CONSOLE (GFX_MISC, " HD Audio - %s\n", (Gfx->GnbHdAudio == 0) ? "Disabled" : "Enabled"); + IDS_HDT_CONSOLE (GFX_MISC, " DynamicRefreshRate - 0x%x\n", Gfx->DynamicRefreshRate); + IDS_HDT_CONSOLE (GFX_MISC, " LcdBackLightControl - 0x%x\n", Gfx->LcdBackLightControl); + IDS_HDT_CONSOLE (GFX_MISC, " AbmSupport - %s\n", (Gfx->AbmSupport == 0) ? "Disabled" : "Enabled"); + IDS_HDT_CONSOLE (GFX_MISC, " GmcPowerGating - %s\n", + (Gfx->GmcPowerGating == GmcPowerGatingDisabled) ? "Disabled" : ( + (Gfx->GmcPowerGating == GmcPowerGatingStutterOnly) ? "GmcPowerGatingStutterOnly" : ( + (Gfx->GmcPowerGating == GmcPowerGatingWithStutter) ? "GmcPowerGatingWithStutter" : "Unknown")) + ); + IDS_HDT_CONSOLE (GFX_MISC, " UmaSteering - %s\n", + (Gfx->UmaSteering == 0) ? "0" : ( + (Gfx->UmaSteering == SystemTrafficOnion) ? "SystemTrafficOnion" : ( + (Gfx->UmaSteering == Onion) ? "Onion" : ( + (Gfx->UmaSteering == 3) ? "Unknown" : "Unknown"))) + ); + IDS_HDT_CONSOLE (GFX_MISC, " iGpuVgaMode - %s\n", + (Gfx->iGpuVgaMode == iGpuVgaAdapter) ? "VGA" : ( + (Gfx->iGpuVgaMode == iGpuVgaNonAdapter) ? "Non VGA" : "Unknown") + ); + IDS_HDT_CONSOLE (GFX_MISC, " UmaMode - %s\n", (Gfx->UmaInfo.UmaMode == UMA_NONE) ? "No UMA" : "UMA"); + if (Gfx->UmaInfo.UmaMode != UMA_NONE) { + IDS_HDT_CONSOLE (GFX_MISC, " UmaBase - 0x%x\n", Gfx->UmaInfo.UmaBase); + IDS_HDT_CONSOLE (GFX_MISC, " UmaSize - 0x%x\n", Gfx->UmaInfo.UmaSize); + IDS_HDT_CONSOLE (GFX_MISC, " UmaAttributes - 0x%x\n", Gfx->UmaInfo.UmaAttributes); + } + IDS_HDT_CONSOLE (GFX_MISC, "<-------------- GFX Config End --------------->\n"); + +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.h new file mode 100644 index 0000000000..6c16a88752 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigLib.h @@ -0,0 +1,71 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GFXCONFIGLIB_H_ +#define _GFXCONFIGLIB_H_ + +VOID +GfxConfigDebugDump ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxGetUmaInfo ( + OUT UMA_INFO *UmaInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GfxLocateConfigData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT GFX_PLATFORM_CONFIG **Gfx + ); + +AGESA_STATUS +GfxEnableGmmAccess ( + IN OUT GFX_PLATFORM_CONFIG *Gfx + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigMid.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigMid.c new file mode 100644 index 0000000000..9cc594ea06 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigMid.c @@ -0,0 +1,113 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GnbGfxConfig.h" +#include "GfxConfigLib.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXCONFIG_GFXCONFIGMID_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GfxConfigMidInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Update GFX config info at ENV + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS Always succeeds + */ + +AGESA_STATUS +GfxConfigMidInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + AMD_MID_PARAMS *MidParamsPtr; + GFX_PLATFORM_CONFIG *Gfx; + AGESA_STATUS Status; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigMidInterface Enter\n"); + Status = GfxLocateConfigData (StdHeader, &Gfx); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + MidParamsPtr = (AMD_MID_PARAMS *) StdHeader; + Gfx->iGpuVgaMode = MidParamsPtr->GnbMidConfiguration.iGpuVgaMode; + } + GNB_DEBUG_CODE ( + GfxConfigDebugDump (Gfx); + ); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigMidInterface Exit [0x%x]\n", Status); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.c new file mode 100644 index 0000000000..d7c22074a2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GfxConfigPost.c @@ -0,0 +1,135 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86709 $ @e \$Date: 2013-01-24 17:39:09 -0600 (Thu, 24 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GfxConfigLib.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXCONFIG_GFXCONFIGPOST_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GfxConfigPostInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate UMA configuration data + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS Always succeeds + */ + +AGESA_STATUS +GfxConfigPostInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GFX_PLATFORM_CONFIG *Gfx; + AMD_POST_PARAMS *PostParamsPtr; + AGESA_STATUS Status; + PostParamsPtr = (AMD_POST_PARAMS *)StdHeader; + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigPostInterface Enter\n"); + Gfx = GnbAllocateHeapBuffer (AMD_GFX_PLATFORM_CONFIG_HANDLE, sizeof (GFX_PLATFORM_CONFIG), StdHeader); + ASSERT (Gfx != NULL); + if (Gfx != NULL) { + LibAmdMemFill (Gfx, 0x00, sizeof (GFX_PLATFORM_CONFIG), StdHeader); + if (GnbBuildOptions.IgfxModeAsPcieEp) { + Gfx->GfxControllerMode = GfxControllerPcieEndpointMode; + Gfx->GfxPciAddress.AddressValue = MAKE_SBDFO (0, 0, 1, 0, 0); + } else { + Gfx->GfxControllerMode = GfxControllerLegacyBridgeMode; + Gfx->GfxPciAddress.AddressValue = MAKE_SBDFO (0, 1, 5, 0, 0); + } + Gfx->StdHeader = (PVOID) StdHeader; + Gfx->GnbHdAudio = PostParamsPtr->PlatformConfig.GnbHdAudio; + Gfx->AbmSupport = PostParamsPtr->PlatformConfig.AbmSupport; + Gfx->DynamicRefreshRate = PostParamsPtr->PlatformConfig.DynamicRefreshRate; + Gfx->LcdBackLightControl = PostParamsPtr->PlatformConfig.LcdBackLightControl; + Gfx->AmdPlatformType = UserOptions.CfgAmdPlatformType; + Gfx->GmcPowerGating = GnbBuildOptions.GmcPowerGating; + Gfx->UmaSteering = GnbBuildOptions.CfgUmaSteering; + GNB_DEBUG_CODE ( + GfxConfigDebugDump (Gfx); + ); + } else { + Status = AGESA_ERROR; + } + IDS_OPTION_HOOK (IDS_GNB_PLATFORMCFG_OVERRIDE, Gfx, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxConfigPostInterface Exit [0x%x]\n", Status); + return Status; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GnbGfxConfig.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GnbGfxConfig.h new file mode 100644 index 0000000000..ac8535ebaf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxConfig/GnbGfxConfig.h @@ -0,0 +1,51 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize GFX configuration data structure. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBGFXCONFIG_H_ +#define _GNBGFXCONFIG_H_ + +#include "GfxConfigLib.h" + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.c new file mode 100644 index 0000000000..1c281abf79 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.c @@ -0,0 +1,184 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to collect discrete GFX card info + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GfxCardInfo.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINITLIBV1_GFXCARDINFO_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +typedef struct { + GNB_PCI_SCAN_DATA ScanData; + GFX_CARD_CARD_INFO *GfxCardInfo; + PCI_ADDR BaseBridge; + UINT8 BusNumber; +} GFX_SCAN_DATA; + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +SCAN_STATUS +GfxScanPcieDevice ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get information about all discrete GFX card in system + * + * + * + * @param[out] GfxCardInfo Pointer to GFX card info structure + * @param[in] StdHeader Standard configuration header + */ + +VOID +GfxGetDiscreteCardInfo ( + OUT GFX_CARD_CARD_INFO *GfxCardInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GFX_SCAN_DATA GfxScanData; + PCI_ADDR Start; + PCI_ADDR End; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGetDiscreteCardInfo Enter\n"); + Start.AddressValue = MAKE_SBDFO (0, 0, 2, 0, 0); + End.AddressValue = MAKE_SBDFO (0, 0, 0x1f, 7, 0); + GfxScanData.BusNumber = 5; + GfxScanData.ScanData.GnbScanCallback = GfxScanPcieDevice; + GfxScanData.ScanData.StdHeader = StdHeader; + GfxScanData.GfxCardInfo = GfxCardInfo; + GnbLibPciScan (Start, End, &GfxScanData.ScanData); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGetDiscreteCardInfo Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Evaluate device + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status of 0 + */ + +SCAN_STATUS +GfxScanPcieDevice ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + UINT8 ClassCode; + UINT32 VendorId; + + IDS_HDT_CONSOLE (GFX_MISC, " Evaluate device [%d:%d:%d]\n", + Device.Address.Bus, Device.Address.Device, Device.Address.Function + ); + + if (GnbLibPciIsBridgeDevice (Device.AddressValue, ScanData->StdHeader)) { + UINT32 SaveBusConfiguration; + UINT32 Value; + + if (Device.Address.Bus == 0) { + ((GFX_SCAN_DATA *) ScanData)->BaseBridge = Device; + } + GnbLibPciRead (Device.AddressValue | 0x18, AccessWidth32, &SaveBusConfiguration, ScanData->StdHeader); + Value = (((0xFF << 8) | ((GFX_SCAN_DATA *) ScanData)->BusNumber) << 8) | Device.Address.Bus; + GnbLibPciWrite (Device.AddressValue | 0x18, AccessWidth32, &Value, ScanData->StdHeader); + ((GFX_SCAN_DATA *) ScanData)->BusNumber++; + + GnbLibPciScanSecondaryBus (Device, ScanData); + + ((GFX_SCAN_DATA *) ScanData)->BusNumber--; + GnbLibPciWrite (Device.AddressValue | 0x18, AccessWidth32, &SaveBusConfiguration, ScanData->StdHeader); + return 0; + } + GnbLibPciRead (Device.AddressValue | 0x0b, AccessWidth8, &ClassCode, ScanData->StdHeader); + if (ClassCode == 3) { + IDS_HDT_CONSOLE (GFX_MISC, " Found GFX Card\n" + ); + + GnbLibPciRead (Device.AddressValue | 0x00, AccessWidth32, &VendorId, ScanData->StdHeader); + if (!GnbLibPciIsPcieDevice (Device.AddressValue, ScanData->StdHeader)) { + IDS_HDT_CONSOLE (GFX_MISC, " GFX Card is PCI device\n" + ); + ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->PciGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); + return 0; + } + if ((UINT16) VendorId == 0x1002) { + IDS_HDT_CONSOLE (GFX_MISC, " GFX Card is AMD PCIe device\n" + ); + ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->AmdPcieGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); + } + ((GFX_SCAN_DATA *) ScanData)->GfxCardInfo->PcieGfxCardBitmap |= (1 << ((GFX_SCAN_DATA *) ScanData)->BaseBridge.Address.Device); + } + return 0; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.h new file mode 100644 index 0000000000..7718231c21 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxCardInfo.h @@ -0,0 +1,56 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to collect discrete GFX card info + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +#ifndef _GFXCARDINFO_H_ +#define _GFXCARDINFO_H_ + +VOID +GfxGetDiscreteCardInfo ( + OUT GFX_CARD_CARD_INFO *GfxCardInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.c new file mode 100644 index 0000000000..c9c9166610 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.c @@ -0,0 +1,609 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Integrated Info Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieConfig.h" +#include "GnbGfxFamServices.h" +#include "GnbRegistersCommon.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINITLIBV1_GFXENUMCONNECTORS_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +typedef struct { + PCIE_CONNECTOR_TYPE ConnectorType; + UINT8 DisplayDeviceEnum; + UINT16 ConnectorEnum; + UINT16 EncoderEnum; + UINT8 ConnectorIndex; +} EXT_CONNECTOR_INFO; + +typedef struct { + UINT8 DisplayDeviceEnum; + UINT8 DeviceIndex; + UINT16 DeviceTag; + UINT16 DeviceAcpiEnum; +} EXT_DISPLAY_DEVICE_INFO; + +typedef struct { + AGESA_STATUS Status; + UINT8 DisplayDeviceEnum; + UINT8 RequestedPriorityIndex; + UINT8 CurrentPriorityIndex; + PCIe_ENGINE_CONFIG *Engine; +} CONNECTOR_ENUM_INFO; + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +GfxIntegratedEnumConnectorsForDevice ( + IN UINT8 DisplayDeviceEnum, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxIntegratedDebugDumpDisplayPath ( + IN EXT_DISPLAY_PATH *DisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +AGESA_STATUS +GfxIntegratedEnumerateAllConnectors ( + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxIntegratedCopyDisplayInfo ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPath, + OUT EXT_DISPLAY_PATH *SecondaryDisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +EXT_CONNECTOR_INFO ConnectorInfoTable[] = { + { + ConnectorTypeDP, + DEVICE_DFP, + CONNECTOR_DISPLAYPORT_ENUM, + ENCODER_NOT_PRESENT, + 0, + }, + { + ConnectorTypeEDP, + DEVICE_LCD, + CONNECTOR_eDP_ENUM, + ENCODER_NOT_PRESENT, + 1 + }, + { + ConnectorTypeSingleLinkDVI, + DEVICE_DFP, + CONNECTOR_SINGLE_LINK_DVI_D_ENUM, + ENCODER_NOT_PRESENT, + 2 + }, + { + ConnectorTypeDualLinkDVI, + DEVICE_DFP, + CONNECTOR_DUAL_LINK_DVI_D_ENUM, + ENCODER_NOT_PRESENT, + 3 + }, + { + ConnectorTypeHDMI, + DEVICE_DFP, + CONNECTOR_HDMI_TYPE_A_ENUM, + ENCODER_NOT_PRESENT, + 4 + }, + { + ConnectorTypeDpToVga, + DEVICE_CRT, + CONNECTOR_VGA_ENUM, + ENCODER_DP2VGA_ENUM_ID1, + 5 + }, + { + ConnectorTypeDpToLvds, + DEVICE_LCD, + CONNECTOR_LVDS_ENUM, + ENCODER_DP2LVDS_ENUM_ID2, + 6 + }, + { + ConnectorTypeStub, + DEVICE_CRT, + CONNECTOR_VGA_ENUM, + ENCODER_ALMOND_ENUM_ID1, + 5 + }, + { + ConnectorTypeSingleLinkDviI, + DEVICE_DFP, + CONNECTOR_SINGLE_LINK_DVI_I_ENUM, + ENCODER_NOT_PRESENT, + 5 + }, + { + ConnectorTypeCrt, + DEVICE_CRT, + CONNECTOR_VGA_ENUM, + ENCODER_NOT_PRESENT, + 5 + }, + { + ConnectorTypeLvds, + DEVICE_LCD, + CONNECTOR_LVDS_ENUM, + ENCODER_NOT_PRESENT, + 6 + }, + { + ConnectorTypeEDPToLvds, + DEVICE_LCD, + CONNECTOR_eDP_ENUM, + ENCODER_NOT_PRESENT, + 1 + }, + { + ConnectorTypeEDPToLvdsSwInit, + DEVICE_LCD, + CONNECTOR_eDP_ENUM, + ENCODER_NOT_PRESENT, + 1 + }, + { + ConnectorTypeAutoDetect, + DEVICE_LCD, + CONNECTOR_LVDS_eDP_ENUM, + ENCODER_DP2LVDS_ENUM_ID2, + 7 + }, +}; + +UINT8 ConnectorNumerArray[] = { +// DP eDP SDVI-D DDVI-D HDMI VGA LVDS Auto (eDP, LVDS, DP-to-LVDS) + 6, 1, 6, 6, 6, 1, 1, 2 +}; +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors for specific display device type. + * + * + * + * @param[in] ConnectorType Connector type (see PCIe_DDI_DATA::ConnectorType). + * @retval Pointer to EXT_CONNECTOR_INFO + * @retval NULL if connector type unknown. + */ +STATIC EXT_CONNECTOR_INFO* +GfxIntegratedExtConnectorInfo ( + IN UINT8 ConnectorType + ) +{ + UINTN Index; + for (Index = 0; Index < (sizeof (ConnectorInfoTable) / sizeof (EXT_CONNECTOR_INFO)); Index++) { + if (ConnectorInfoTable[Index].ConnectorType == ConnectorType) { + return &ConnectorInfoTable[Index]; + } + } + return NULL; +} + +EXT_DISPLAY_DEVICE_INFO DisplayDeviceInfoTable[] = { + { + DEVICE_CRT, + 1, + ATOM_DEVICE_CRT1_SUPPORT, + 0x100, + }, + { + DEVICE_LCD, + 1, + ATOM_DEVICE_LCD1_SUPPORT, + 0x110, + }, + { + DEVICE_DFP, + 1, + ATOM_DEVICE_DFP1_SUPPORT, + 0x210, + }, + { + DEVICE_DFP, + 2, + ATOM_DEVICE_DFP2_SUPPORT, + 0x220, + }, + { + DEVICE_DFP, + 3, + ATOM_DEVICE_DFP3_SUPPORT, + 0x230, + }, + { + DEVICE_DFP, + 4, + ATOM_DEVICE_DFP4_SUPPORT, + 0x240, + }, + { + DEVICE_DFP, + 5, + ATOM_DEVICE_DFP5_SUPPORT, + 0x250, + }, + { + DEVICE_DFP, + 6, + ATOM_DEVICE_DFP6_SUPPORT, + 0x260, + } +}; +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors for specific display device type. + * + * + * + * @param[in] DisplayDeviceEnum Display device enum + * @param[in] DisplayDeviceIndex Display device index + * @retval Pointer to EXT_DISPLAY_DEVICE_INFO + * @retval NULL if can not get display device info + */ +STATIC EXT_DISPLAY_DEVICE_INFO* +GfxIntegratedExtDisplayDeviceInfo ( + IN UINT8 DisplayDeviceEnum, + IN UINT8 DisplayDeviceIndex + ) +{ + UINT8 Index; + UINT8 LastIndex; + LastIndex = 0xff; + for (Index = 0; Index < (sizeof (DisplayDeviceInfoTable) / sizeof (EXT_DISPLAY_DEVICE_INFO)); Index++) { + if (DisplayDeviceInfoTable[Index].DisplayDeviceEnum == DisplayDeviceEnum) { + LastIndex = Index; + if (DisplayDeviceInfoTable[Index].DeviceIndex == DisplayDeviceIndex) { + return &DisplayDeviceInfoTable[Index]; + } + } + } + if (DisplayDeviceEnum == DEVICE_LCD && LastIndex != 0xff) { + return &DisplayDeviceInfoTable[LastIndex]; + } + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors + * + * + * + * @param[out] DisplayPathList Display path list + * @param[in,out] Pcie PCIe platform configuration info + * @param[in] Gfx Gfx configuration info + */ +AGESA_STATUS +GfxIntegratedEnumerateAllConnectors ( + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedEnumerateAllConnectors Enter\n"); + Status = GfxIntegratedEnumConnectorsForDevice ( + DEVICE_DFP, + DisplayPathList, + Pcie, + Gfx + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + Status = GfxIntegratedEnumConnectorsForDevice ( + DEVICE_CRT, + DisplayPathList, + Pcie, + Gfx + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + Status = GfxIntegratedEnumConnectorsForDevice ( + DEVICE_LCD, + DisplayPathList, + Pcie, + Gfx + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedEnumerateAllConnectors Exit [0x%x]\n", Status); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors for specific display device type. + * + * + * + * @param[in] Engine Engine configuration info + * @param[in,out] Buffer Buffer pointer + * @param[in] Pcie PCIe configuration info + */ +VOID +STATIC +GfxIntegratedDdiInterfaceCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + CONNECTOR_ENUM_INFO *ConnectorEnumInfo; + EXT_CONNECTOR_INFO *ExtConnectorInfo; + ConnectorEnumInfo = (CONNECTOR_ENUM_INFO*) Buffer; + ExtConnectorInfo = GfxIntegratedExtConnectorInfo (Engine->Type.Ddi.DdiData.ConnectorType); + if (ExtConnectorInfo == NULL) { + AGESA_STATUS_UPDATE (AGESA_ERROR, ConnectorEnumInfo->Status); + PcieConfigDisableEngine (Engine); + return; + } + if (ExtConnectorInfo->DisplayDeviceEnum != ConnectorEnumInfo->DisplayDeviceEnum) { + //Not device type we are looking for + return; + } + if (Engine->Type.Ddi.DisplayPriorityIndex >= ConnectorEnumInfo->RequestedPriorityIndex && + Engine->Type.Ddi.DisplayPriorityIndex < ConnectorEnumInfo->CurrentPriorityIndex) { + ConnectorEnumInfo->CurrentPriorityIndex = Engine->Type.Ddi.DisplayPriorityIndex; + ConnectorEnumInfo->Engine = Engine; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate all display connectors for specific display device type. + * + * + * + * @param[in] DisplayDeviceEnum Display device list + * @param[out] DisplayPathList Display path list + * @param[in,out] Pcie PCIe configuration info + * @param[in] Gfx Gfx configuration info + */ +AGESA_STATUS +GfxIntegratedEnumConnectorsForDevice ( + IN UINT8 DisplayDeviceEnum, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 DisplayDeviceIndex; + CONNECTOR_ENUM_INFO ConnectorEnumInfo; + EXT_CONNECTOR_INFO *ExtConnectorInfo; + EXT_DISPLAY_DEVICE_INFO *ExtDisplayDeviceInfo; + AGESA_STATUS Status; + UINT8 ConnectorIdArray[sizeof (ConnectorNumerArray)]; + ConnectorEnumInfo.Status = AGESA_SUCCESS; + DisplayDeviceIndex = 1; + ConnectorEnumInfo.RequestedPriorityIndex = 0; + ConnectorEnumInfo.DisplayDeviceEnum = DisplayDeviceEnum; + LibAmdMemFill (ConnectorIdArray, 0x00, sizeof (ConnectorIdArray), GnbLibGetHeader (Gfx)); + do { + ConnectorEnumInfo.Engine = NULL; + ConnectorEnumInfo.CurrentPriorityIndex = 0xff; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_VIRTUAL | DESCRIPTOR_DDI_ENGINE, + GfxIntegratedDdiInterfaceCallback, + &ConnectorEnumInfo, + Pcie + ); + if (ConnectorEnumInfo.Engine == NULL) { + break; // No more connector support this + } + ConnectorEnumInfo.RequestedPriorityIndex = ConnectorEnumInfo.CurrentPriorityIndex + 1; + ExtConnectorInfo = GfxIntegratedExtConnectorInfo (ConnectorEnumInfo.Engine->Type.Ddi.DdiData.ConnectorType); + ASSERT (ExtConnectorInfo != NULL); + ASSERT (ExtConnectorInfo->ConnectorIndex < sizeof (ConnectorIdArray)); + if (ConnectorIdArray[ExtConnectorInfo->ConnectorIndex] >= ConnectorNumerArray[ExtConnectorInfo->ConnectorIndex]) { + //Run out of supported connectors + AGESA_STATUS_UPDATE (AGESA_ERROR, ConnectorEnumInfo.Status); + PcieConfigDisableEngine (ConnectorEnumInfo.Engine); + continue; + } + ConnectorEnumInfo.Engine->Type.Ddi.ConnectorId = ConnectorIdArray[ExtConnectorInfo->ConnectorIndex] + 1; + ExtDisplayDeviceInfo = GfxIntegratedExtDisplayDeviceInfo (DisplayDeviceEnum, DisplayDeviceIndex); + if (ExtDisplayDeviceInfo == NULL) { + //Run out of supported display device types + AGESA_STATUS_UPDATE (AGESA_ERROR, ConnectorEnumInfo.Status); + Status = AGESA_ERROR; + PcieConfigDisableEngine (ConnectorEnumInfo.Engine); + } + + if ((Gfx->Gnb3dStereoPinIndex != 0) && (ConnectorEnumInfo.Engine->Type.Ddi.DdiData.HdpIndex == (Gfx->Gnb3dStereoPinIndex - 1))) { + AGESA_STATUS_UPDATE (AGESA_ERROR, ConnectorEnumInfo.Status); + Status = AGESA_ERROR; + PcieConfigDisableEngine (ConnectorEnumInfo.Engine); + } + + ConnectorEnumInfo.Engine->Type.Ddi.DisplayDeviceId = DisplayDeviceIndex; + + Status = GfxFmMapEngineToDisplayPath (ConnectorEnumInfo.Engine, DisplayPathList, Gfx); + AGESA_STATUS_UPDATE (Status, ConnectorEnumInfo.Status); + if (Status != AGESA_SUCCESS) { + continue; + } + ConnectorIdArray[ExtConnectorInfo->ConnectorIndex]++; + DisplayDeviceIndex++; + } while (ConnectorEnumInfo.Engine != NULL); + return ConnectorEnumInfo.Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize display path for given engine + * + * + * + * @param[in] Engine Engine configuration info + * @param[out] DisplayPath Display path list + * @param[out] SecondaryDisplayPath Secondary display path list + * @param[in] Gfx Gfx configuration info + */ + +VOID +GfxIntegratedCopyDisplayInfo ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPath, + OUT EXT_DISPLAY_PATH *SecondaryDisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + EXT_CONNECTOR_INFO *ExtConnectorInfo; + EXT_DISPLAY_DEVICE_INFO *ExtDisplayDeviceInfo; + ExtConnectorInfo = GfxIntegratedExtConnectorInfo (Engine->Type.Ddi.DdiData.ConnectorType); + ExtDisplayDeviceInfo = GfxIntegratedExtDisplayDeviceInfo (ExtConnectorInfo->DisplayDeviceEnum, Engine->Type.Ddi.DisplayDeviceId); + DisplayPath->usDeviceConnector = ExtConnectorInfo->ConnectorEnum | (Engine->Type.Ddi.ConnectorId << 8); + DisplayPath->usDeviceTag = ExtDisplayDeviceInfo->DeviceTag; + DisplayPath->usDeviceACPIEnum = ExtDisplayDeviceInfo->DeviceAcpiEnum; + DisplayPath->ucExtAUXDDCLutIndex = Engine->Type.Ddi.DdiData.AuxIndex; + DisplayPath->ucExtHPDPINLutIndex = Engine->Type.Ddi.DdiData.HdpIndex; + DisplayPath->ucChPNInvert = Engine->Type.Ddi.DdiData.LanePnInversionMask; + DisplayPath->usCaps = Engine->Type.Ddi.DdiData.Flags; + DisplayPath->usExtEncoderObjId = ExtConnectorInfo->EncoderEnum; + if (Engine->Type.Ddi.DdiData.Mapping[0].ChannelMappingValue == 0) { + DisplayPath->ChannelMapping.ucChannelMapping = (Engine->EngineData.StartLane < Engine->EngineData.EndLane) ? 0xE4 : 0x1B; + } else { + DisplayPath->ChannelMapping.ucChannelMapping = Engine->Type.Ddi.DdiData.Mapping[0].ChannelMappingValue; + } + GNB_DEBUG_CODE ( + GfxIntegratedDebugDumpDisplayPath (DisplayPath, Gfx); + ); + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDualLinkDVI) { + if (SecondaryDisplayPath != NULL) { + SecondaryDisplayPath->usDeviceConnector = DisplayPath->usDeviceConnector; + } + GNB_DEBUG_CODE ( + GfxIntegratedDebugDumpDisplayPath (DisplayPath, Gfx); + ); + + if (Engine->Type.Ddi.DdiData.Mapping[1].ChannelMappingValue == 0) { + DisplayPath->ChannelMapping.ucChannelMapping = (Engine->EngineData.StartLane < Engine->EngineData.EndLane) ? 0xE4 : 0x1B; + } else { + DisplayPath->ChannelMapping.ucChannelMapping = Engine->Type.Ddi.DdiData.Mapping[1].ChannelMappingValue; + } + } +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump display path settings + * + * + * + * @param[in] DisplayPath Display path + * @param[in] Gfx Gfx configuration + */ + +VOID +GfxIntegratedDebugDumpDisplayPath ( + IN EXT_DISPLAY_PATH *DisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + IDS_HDT_CONSOLE (GFX_MISC, " usDeviceConnector = 0x%x\n", + DisplayPath->usDeviceConnector + ); + IDS_HDT_CONSOLE (GFX_MISC, " usDeviceTag = 0x%x\n", + DisplayPath->usDeviceTag + ); + IDS_HDT_CONSOLE (GFX_MISC, " usDeviceACPIEnum = 0x%x\n", + DisplayPath->usDeviceACPIEnum + ); + IDS_HDT_CONSOLE (GFX_MISC, " usExtEncoderObjId = 0x%x\n", + DisplayPath->usExtEncoderObjId + ); + IDS_HDT_CONSOLE (GFX_MISC, " ucChannelMapping = 0x%x\n", + DisplayPath->ChannelMapping.ucChannelMapping + ); + IDS_HDT_CONSOLE (GFX_MISC, " ucChPNInvert = 0x%x\n", + DisplayPath->ucChPNInvert + ); + IDS_HDT_CONSOLE (GFX_MISC, " usCaps = 0x%x\n", + DisplayPath->usCaps + ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.h new file mode 100644 index 0000000000..20cf17e6f3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GfxEnumConnectors.h @@ -0,0 +1,64 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Integrated Info Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GFXENUMCONNECTORS_H_ +#define _GFXENUMCONNECTORS_H_ + + +VOID +GfxIntegratedCopyDisplayInfo ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPath, + OUT EXT_DISPLAY_PATH *SecondaryDisplayPath, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +AGESA_STATUS +GfxIntegratedEnumerateAllConnectors ( + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN OUT PCIe_PLATFORM_CONFIG *Pcie, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.c new file mode 100644 index 0000000000..f874e084a3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.c @@ -0,0 +1,217 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to collect discrete GFX card info + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GfxCardInfo.h" +#include "GnbRegistersCommon.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINITLIBV1_GNBGFXINITLIBV1_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +BOOLEAN +GfxLibIsControllerPresent ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GfxLibCopyMemToFb ( + IN VOID *Source, + IN UINT32 FbOffset, + IN UINT32 Length, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxLibSetiGpuVgaMode ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +AGESA_STATUS +GfxInitSsid ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * + * + * @param[in] StdHeader Standard configuration header + * @retval TRUE Gfx controller present and available + */ +BOOLEAN +GfxLibIsControllerPresent ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return GnbLibPciIsDevicePresent (MAKE_SBDFO (0, 0, 1, 0, 0), StdHeader); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Gfx SSID Registers + * + * + * + * @param[in] Gfx Pointer to global GFX configuration + * @retval AGESA_STATUS Always succeeds + */ + +AGESA_STATUS +GfxInitSsid ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + AGESA_STATUS Status; + UINT32 TempData; + PCI_ADDR IgpuAddress; + PCI_ADDR HdaudioAddress; + + Status = AGESA_SUCCESS; + TempData = 0; + + IgpuAddress = Gfx->GfxPciAddress; + HdaudioAddress = Gfx->GfxPciAddress; + HdaudioAddress.Address.Function = 1; + + // Set SSID for internal GPU + if (UserOptions.CfgGnbIGPUSSID != 0) { + GnbLibPciRMW ((IgpuAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, UserOptions.CfgGnbIGPUSSID, GnbLibGetHeader (Gfx)); + } else { + GnbLibPciRead (IgpuAddress.AddressValue, AccessS3SaveWidth32, &TempData, GnbLibGetHeader (Gfx)); + GnbLibPciRMW ((IgpuAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, TempData, GnbLibGetHeader (Gfx)); + } + + // Set SSID for internal HD Audio + if (UserOptions.CfgGnbHDAudioSSID != 0) { + GnbLibPciRMW ((HdaudioAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, UserOptions.CfgGnbHDAudioSSID, GnbLibGetHeader (Gfx)); + } else { + GnbLibPciRead (HdaudioAddress.AddressValue, AccessS3SaveWidth32, &TempData, GnbLibGetHeader (Gfx)); + GnbLibPciRMW ((HdaudioAddress.AddressValue | 0x4C), AccessS3SaveWidth32, 0, TempData, GnbLibGetHeader (Gfx)); + } + + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy memory content to FB + * + * + * @param[in] Source Pointer to source + * @param[in] FbOffset FB offset + * @param[in] Length The length to copy + * @param[in] Gfx Pointer to global GFX configuration + * + */ +VOID +GfxLibCopyMemToFb ( + IN VOID *Source, + IN UINT32 FbOffset, + IN UINT32 Length, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + GMMx00_STRUCT GMMx00; + GMMx04_STRUCT GMMx04; + UINT32 Index; + for (Index = 0; Index < Length; Index = Index + 4 ) { + GMMx00.Value = 0x80000000 | (FbOffset + Index); + GMMx04.Value = *(UINT32*) ((UINT8*)Source + Index); + GnbLibMemWrite (Gfx->GmmBase + GMMx00_ADDRESS, AccessWidth32, &GMMx00.Value, GnbLibGetHeader (Gfx)); + GnbLibMemWrite (Gfx->GmmBase + GMMx04_ADDRESS, AccessWidth32, &GMMx04.Value, GnbLibGetHeader (Gfx)); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set iGpu VGA mode + * + * + * @param[in] Gfx Pointer to global GFX configuration + * + */ +VOID +GfxLibSetiGpuVgaMode ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + GnbLibPciIndirectRMW ( + GNB_SBDFO | D0F0x60_ADDRESS, + D0F0x64_x1D_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + (UINT32) ~D0F0x64_x1D_VgaEn_MASK, + ((Gfx->iGpuVgaMode == iGpuVgaAdapter) ? 1 : 0) << D0F0x64_x1D_VgaEn_OFFSET, + GnbLibGetHeader (Gfx) + ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.h new file mode 100644 index 0000000000..cc1d782eaf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxInitLibV1/GnbGfxInitLibV1.h @@ -0,0 +1,79 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Gfx Library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +#ifndef _GNBGFXINITLIBV1_H_ +#define _GNBGFXINITLIBV1_H_ + +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GfxEnumConnectors.h" +#include "GfxCardInfo.h" + +BOOLEAN +GfxLibIsControllerPresent ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GfxInitSsid ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + + +VOID +GfxLibCopyMemToFb ( + IN VOID *Source, + IN UINT32 FbOffset, + IN UINT32 Length, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxLibSetiGpuVgaMode ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.c new file mode 100644 index 0000000000..7b5f3ef9de --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.c @@ -0,0 +1,504 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Integrated table info init + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "heapManager.h" +#include "GeneralServices.h" +#include "Gnb.h" +#include "GnbF1Table.h" +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbGfxConfig.h" +#include "GnbGfxInitLibV1.h" +#include "GnbGfxFamServices.h" +#include "GnbNbInitLibV1.h" +#include "GnbNbInitLibV5.h" +#include "GfxConfigLib.h" +#include "GfxIntegratedInfoTable.h" +#include "GfxPwrPlayTable.h" +#include "OptionGnb.h" +#include "GfxLibV3.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINTTABLEV3_GFXINTEGRATEDINFOTABLE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Init V3 Support for eDP to Lvds translators + * + * + * @param[in] Engine Engine configuration info + * @param[in,out] Buffer Buffer pointer + * @param[in] Pcie PCIe configuration info + */ +VOID +STATIC +GfxIntegrateducEDPToLVDSRxIdCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 *uceDPToLVDSRxId; + uceDPToLVDSRxId = (UINT8*) Buffer; + // APU output DP signal to a 3rd party DP translator chip (Analogix, Parade etc), + // the chip is handled by the 3rd party DP Rx firmware and it does not require the AMD SW to have a special + // initialize/enable/disable sequence to control this chip, the AMD SW just follows the eDP spec + // to enable the LVDS panel through this chip. + + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvds) { + *uceDPToLVDSRxId = eDP_TO_LVDS_COMMON_ID; + IDS_HDT_CONSOLE (GNB_TRACE, "Found 3rd party common EDPToLvds Connector\n"); + } + // APU output DP signal to a 3rd party DP translator chip which requires a AMD SW one time initialization + // to the chip based on the LVDS panel parameters ( such as power sequence time and panel SS parameter etc ). + // After that, the AMD SW does not need any specific enable/disable sequences to control this chip and just + // follows the eDP spec. to control the panel. + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvdsSwInit) { + *uceDPToLVDSRxId = eDP_TO_LVDS_SWINIT_ID; + IDS_HDT_CONSOLE (GNB_TRACE, "Found EDPToLvds Connector requiring SW init\n"); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Calculate V3 NCLK clock + * + * + * + * @param[in] NbFid NbFid + * @param[in] NbDid NbDid + * @retval Clock in 10KHz + */ + +STATIC UINT32 +GfxLibGetNclkV3 ( + IN UINT8 NbFid, + IN UINT8 NbDid + ) +{ + UINT32 Divider; + //i.e. NBCOF[0] = (100 * ([NbFid] + 4h) / (2^[NbDid])) Mhz + if (NbDid == 1) { + Divider = 2; + } else if (NbDid == 0) { + Divider = 1; + } else { + Divider = 1; + } + ASSERT (NbDid == 0 || NbDid == 1); + return ((10000 * (NbFid + 4)) / Divider); +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Init V3 Nb p-State MemclkFreq + * + * + * @param[in] IntegratedInfoTable Integrated info table pointer + * @param[in] PpF1Array pointer + * @param[in] Gfx Gfx configuration info + */ + +STATIC VOID +GfxFillNbPstateMemclkFreqV3 ( + IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN PP_F1_ARRAY_V2 *PpF1Array, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 i; + UINT8 Channel; + ULONG memps0_freq; + ULONG memps1_freq; + + Channel = 0; + if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT1) != 0) { + Channel = 1; + } else if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT2) != 0) { + Channel = 2; + } else if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT3) != 0) { + Channel = 3; + } + + + memps0_freq = 100 * GfxLibExtractDramFrequencyV3 ((UINT8) PpF1Array->MemClkFreq[Channel], GnbLibGetHeader (Gfx)); + memps1_freq = 100 * GfxLibExtractDramFrequencyV3 ((UINT8) PpF1Array->M1MemClkFreq[Channel], GnbLibGetHeader (Gfx)); + + for (i = 0; i < 4; i++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld26[i] == 1) { + IntegratedInfoTable->ulNbpStateMemclkFreq[i] = (PpF1Array->PP_FUSE_ARRAY_V2_fld29[i] == 0) ? memps0_freq : memps1_freq; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Init V3 NbPstateVid + * + * + * @param[in] PpF1Array + * @param[in] IntegratedInfoTable Integrated info table pointer + * @param[in] Gfx Gfx configuration info + */ + +STATIC VOID +GfxFillNbPStateVidV3 ( + IN PP_F1_ARRAY_V2 *PpF1Array, + IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 i; + + for (i = 0; i < 4; i++) { + IntegratedInfoTable->usNBPStateVoltage[i] = (USHORT) ((PpF1Array->PP_FUSE_ARRAY_V2_fld28[i] << 7) | (PpF1Array->PP_FUSE_ARRAY_V2_fld27[i])); + IntegratedInfoTable->ulNbpStateNClkFreq[i] = GfxLibGetNclkV3 ((UINT8) (PpF1Array->PP_FUSE_ARRAY_V2_fld30[i]), (UINT8) (PpF1Array->PP_FUSE_ARRAY_V2_fld31[i])); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy memory content to FB + * + * + * @param[in] SystemInfoTableV3Ptr Pointer to integrated info table + * @param[in] Gfx Pointer to global GFX configuration + * + */ +VOID +GfxIntInfoTablePostToFbV3 ( + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3Ptr, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 Index; + UINT32 TableOffset; + UINT32 FbAddress; + TableOffset = (UINT32) (Gfx->UmaInfo.UmaSize - sizeof (ATOM_FUSION_SYSTEM_INFO_V3)) | 0x80000000; + for (Index = 0; Index < sizeof (ATOM_FUSION_SYSTEM_INFO_V3); Index = Index + 4 ) { + FbAddress = TableOffset + Index; + GnbLibMemWrite (Gfx->GmmBase + GMMx00_ADDRESS, AccessWidth32, &FbAddress, GnbLibGetHeader (Gfx)); + GnbLibMemWrite (Gfx->GmmBase + GMMx04_ADDRESS, AccessWidth32, (UINT8*) SystemInfoTableV3Ptr + Index, GnbLibGetHeader (Gfx)); + } +} + + +STATIC VOID +GfxIntegratedInfoTable289_fun ( + IN PP_F1_ARRAY_V2 *PpF1Array, + IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINTN Index; + for (Index = 0; Index < 4; Index++) { + if (PpF1Array->excel841_fld6[Index] != 0) { + IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld4[Index].ulMaximumSupportedCLK = GfxFmCalculateClock ( + PpF1Array->excel841_fld6[Index], + GnbLibGetHeader (Gfx) + ); + IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld4[Index].ulVoltageIndex = (ULONG) Index; + } + } +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC VOID +GfxIntegratedInfoTable318_fun ( + IN PP_F1_ARRAY_V2 *PpF1Array, + IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 Index; + UINTN v1; + GnbGfx275_STRUCT *pv2; + BOOLEAN Sorting; + pv2 = &IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8[0]; + + v1 = 0; + for (Index = 0; Index < 5; Index++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index] != 0) { + pv2[v1].GnbGfx275_STRUCT_fld0 = GfxFmCalculateClock (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index], GnbLibGetHeader (Gfx)); + pv2[v1].GnbGfx275_STRUCT_fld1 = Index; + pv2[v1].GnbGfx275_STRUCT_fld2 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index]; + v1++; + } + } + if (v1 > 1) { + do { + Sorting = FALSE; + for (Index = 0; Index < (v1 - 1); Index++) { + GnbGfx275_STRUCT Temp; + BOOLEAN Exchange; + Exchange = FALSE; + if (pv2[Index].GnbGfx275_STRUCT_fld1 > pv2[Index + 1].GnbGfx275_STRUCT_fld1) { + Exchange = TRUE; + } + if ((pv2[Index].GnbGfx275_STRUCT_fld1 == pv2[Index + 1].GnbGfx275_STRUCT_fld1) && + (pv2[Index].GnbGfx275_STRUCT_fld0 > pv2[Index + 1].GnbGfx275_STRUCT_fld0)) { + Exchange = TRUE; + } + if (Exchange) { + Sorting = TRUE; + LibAmdMemCopy (&Temp, &pv2[Index], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + LibAmdMemCopy (&pv2[Index], &pv2[Index + 1], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + LibAmdMemCopy (&pv2[Index + 1], &Temp, sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + } + } + } while (Sorting); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build integrated info table + * + * + * + * @param[in] Gfx Gfx configuration info + * @param[in] SystemInfoTableV3 ATOM_FUSION_SYSTEM_INFO_V3 pointer + * @param[in] PpF1Array + * @retval AGESA_STATUS + */ +AGESA_STATUS +GfxIntInfoTableInitV3 ( + IN GFX_PLATFORM_CONFIG *Gfx, + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3, + IN PP_F1_ARRAY_V2 *PpF1Array + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + PCIe_PLATFORM_CONFIG *Pcie; + ATOM_PPLIB_POWERPLAYTABLE4 *PpTable; + UINT8 Channel; + + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableInitV3 Enter\n"); + + if (PpF1Array != NULL) { + + Channel = 0; + if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT1) != 0) { + Channel = 1; + } else if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT2) != 0) { + Channel = 2; + } else if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT3) != 0) { + Channel = 3; + } + SystemInfoTableV3->sIntegratedSysInfo.sHeader.usStructureSize = sizeof (ATOM_INTEGRATED_SYSTEM_INFO_V1_8); + ASSERT (SystemInfoTableV3->sIntegratedSysInfo.sHeader.usStructureSize == 512); + SystemInfoTableV3->sIntegratedSysInfo.sHeader.ucTableFormatRevision = 1; + SystemInfoTableV3->sIntegratedSysInfo.sHeader.ucTableContentRevision = 8; + SystemInfoTableV3->sIntegratedSysInfo.ulBootUpEngineClock = 200 * 100; //Set default engine clock to 200MhZ + SystemInfoTableV3->sIntegratedSysInfo.field2 = (PpF1Array->PP_FUSE_ARRAY_V2_fld21 + 0x10) * 10000; + SystemInfoTableV3->sIntegratedSysInfo.ulBootUpUMAClock = Gfx->UmaInfo.MemClock * 100; + + SystemInfoTableV3->sIntegratedSysInfo.usRequestedPWMFreqInHz = Gfx->LcdBackLightControl; + SystemInfoTableV3->sIntegratedSysInfo.ucUMAChannelNumber = ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_INTERLEAVE) == 0) ? 1 : 2; + SystemInfoTableV3->sIntegratedSysInfo.ucMemoryType = Gfx->UmaInfo.MemType; + SystemInfoTableV3->sIntegratedSysInfo.usBootUpNBVoltage = GnbLocateHighestVidIndexV5 (GnbLibGetHeader (Gfx)); + SystemInfoTableV3->sIntegratedSysInfo.usPanelRefreshRateRange = Gfx->DynamicRefreshRate; + SystemInfoTableV3->sIntegratedSysInfo.usLvdsSSPercentage = Gfx->LvdsSpreadSpectrum; + //Locate PCIe configuration data to get definitions of display connectors + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.sHeader.usStructureSize = sizeof (ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO); + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.sHeader.ucTableFormatRevision = 1; + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.sHeader.ucTableContentRevision = 1; + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.uc3DStereoPinId = Gfx->Gnb3dStereoPinIndex; + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.ucRemoteDisplayConfig = Gfx->GnbRemoteDisplaySupport; + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.ucFixDPVoltageSwing = (UINT8) Gfx->DpFixedVoltSwingType; + SystemInfoTableV3->sIntegratedSysInfo.usExtDispConnInfoOffset = offsetof (ATOM_INTEGRATED_SYSTEM_INFO_V1_8, sExtDispConnInfo); + + SystemInfoTableV3->sIntegratedSysInfo.usPCIEClkSSPercentage = Gfx->PcieRefClkSpreadSpectrum; + + SystemInfoTableV3->sIntegratedSysInfo.ucLvdsMisc = Gfx->LvdsMiscControl.Value; + IDS_HDT_CONSOLE (GNB_TRACE, "Lvds Misc control : %x\n", Gfx->LvdsMiscControl.Value); + if (Gfx->LvdsMiscControl.Field.LvdsVoltOverwriteEn) { + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSVoltAdjust = Gfx->LVDSVoltAdjust; + IDS_HDT_CONSOLE (GNB_TRACE, "LVDSVoltAdjust : %x\n", Gfx->LVDSVoltAdjust); + } + + SystemInfoTableV3->sIntegratedSysInfo.ulVBIOSMisc = Gfx->DisplayMiscControl.Value; + IDS_HDT_CONSOLE (GNB_TRACE, "Display Misc control : %x\n", Gfx->DisplayMiscControl.Value); + + // LVDS + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOnSeqDIGONtoDE_in4Ms = Gfx->LvdsPowerOnSeqDigonToDe; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms = Gfx->LvdsPowerOnSeqDeToVaryBl; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms = Gfx->LvdsPowerOnSeqVaryBlToDe; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOffSeqDEtoDIGON_in4Ms = Gfx->LvdsPowerOnSeqDeToDigon; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSOffToOnDelay_in4Ms = Gfx->LvdsPowerOnSeqOnToOffDelay; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms = Gfx->LvdsPowerOnSeqVaryBlToBlon; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms = Gfx->LvdsPowerOnSeqBlonToVaryBl; + SystemInfoTableV3->sIntegratedSysInfo.ulLCDBitDepthControlVal = Gfx->LcdBitDepthControlValue; + SystemInfoTableV3->sIntegratedSysInfo.usMaxLVDSPclkFreqInSingleLink = Gfx->LvdsMaxPixelClockFreq; + SystemInfoTableV3->sIntegratedSysInfo.ucMinAllowedBL_Level = Gfx->MinAllowedBLLevel; + Status = PcieLocateConfigurationData (GnbLibGetHeader (Gfx), &Pcie); + ASSERT (Status == AGESA_SUCCESS); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + Status = GfxIntegratedEnumerateAllConnectors ( + &SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.sPath[0], + Pcie, + Gfx + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.uceDPToLVDSRxId = eDP_TO_LVDS_RX_DISABLE; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_VIRTUAL | DESCRIPTOR_DDI_ENGINE, + GfxIntegrateducEDPToLVDSRxIdCallback, + &SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.uceDPToLVDSRxId, + Pcie + ); + + // Build PP table + PpTable = (ATOM_PPLIB_POWERPLAYTABLE4*) &SystemInfoTableV3->ulPowerplayTable; + // Build PP table + ///@todo + //Status = GfxPowerPlayBuildTable (PpTable, Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + // Assign usFormatID to 0x000B to represent V3 + ///@todo + PpTable->usFormatID = 0xB; + // Build Display clock info + GfxIntegratedInfoTable289_fun (PpF1Array, &SystemInfoTableV3->sIntegratedSysInfo, Gfx); + GfxIntegratedInfoTable318_fun (PpF1Array, &SystemInfoTableV3->sIntegratedSysInfo, Gfx); + ///@todo review if these parameters needed + // Fill in Nb P-state MemclkFreq Data + GfxFillNbPstateMemclkFreqV3 (&SystemInfoTableV3->sIntegratedSysInfo, PpF1Array, Gfx); + // Fill in HTC Data + if (PpF1Array->HtcEn == 1) { + SystemInfoTableV3->sIntegratedSysInfo.ucHtcTmpLmt = (UCHAR) (PpF1Array->HtcTmpLmt / 2 + 52); + SystemInfoTableV3->sIntegratedSysInfo.ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 = (UCHAR) (PpF1Array->PP_FUSE_ARRAY_V2_fld20 / 2); + } else { + SystemInfoTableV3->sIntegratedSysInfo.ucHtcTmpLmt = 0; + SystemInfoTableV3->sIntegratedSysInfo.ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 = 0; + } + // Fill in NB P states VID & NCLK info + GfxFillNbPStateVidV3 (PpF1Array, &SystemInfoTableV3->sIntegratedSysInfo, Gfx); + + // Family specific data update - store default values to be updated by family specific code + //GfxFmIntegratedInfoTableInit (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); + SystemInfoTableV3->sIntegratedSysInfo.ulDDR_DLL_PowerUpTime = 4940; + SystemInfoTableV3->sIntegratedSysInfo.ulDDR_PLL_PowerUpTime = 2000; + + if (PpF1Array->MemPhyPllPdMode[Channel] != 0) { + SystemInfoTableV3->sIntegratedSysInfo.ulSystemConfig |= BIT2; + } + if (PpF1Array->DisDllShutdownSR[Channel] == 0) { + SystemInfoTableV3->sIntegratedSysInfo.ulSystemConfig |= BIT1; + } + if (GnbBuildOptions.CfgPciePowerGatingFlags != (PCIE_POWERGATING_SKIP_CORE | PCIE_POWERGATING_SKIP_PHY)) { + SystemInfoTableV3->sIntegratedSysInfo.ulSystemConfig |= BIT0; + } + SystemInfoTableV3->sIntegratedSysInfo.ulGPUCapInfo = GPUCAPINFO_TMDS_HDMI_USE_CASCADE_PLL_MODE | GPUCAPINFO_DP_USE_SINGLE_PLL_MODE; + + IDS_HDT_CONSOLE (GNB_TRACE, "ulSystemConfig : %x\n", SystemInfoTableV3->sIntegratedSysInfo.ulSystemConfig); + + } else { + Status = AGESA_ERROR; + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableInitV3 Exit [0x%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump gfx integrated info table + * + * + * @param[in] SystemInfoTableV3Ptr Pointer to integrated info table + * @param[in] Gfx Pointer to global GFX configuration + * + */ +VOID +GfxIntInfoTableDebugDumpV3 ( + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3Ptr, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + ATOM_PPLIB_POWERPLAYTABLE4 *PpTable; + ATOM_PPLIB_EXTENDEDHEADER *ExtendedHeader; + + IDS_HDT_CONSOLE (GFX_MISC, "GfxIntInfoTableDebugDumpV3 Enter\n"); + + PpTable = (ATOM_PPLIB_POWERPLAYTABLE4*) &SystemInfoTableV3Ptr->ulPowerplayTable; + ExtendedHeader = (ATOM_PPLIB_EXTENDEDHEADER *) ((UINT8 *) (PpTable) + PpTable->usExtendendedHeaderOffset); + IDS_HDT_CONSOLE (GFX_MISC, " ExtendedHeader usSize %d\n", ExtendedHeader->usSize); + IDS_HDT_CONSOLE (GFX_MISC, " SizeOf %d\n", sizeof(ATOM_PPLIB_EXTENDEDHEADER)); + + IDS_HDT_CONSOLE (GFX_MISC, " ucHtcTmpLmt 0x%X\n", SystemInfoTableV3Ptr->sIntegratedSysInfo.ucHtcTmpLmt); + IDS_HDT_CONSOLE (GFX_MISC, " ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 0x%X\n", SystemInfoTableV3Ptr->sIntegratedSysInfo.ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11); + IDS_HDT_CONSOLE (GFX_MISC, "GfxIntInfoTableDebugDumpV3 Exit\n"); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.h new file mode 100644 index 0000000000..562f815ea2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various GfxIntegratedInfoTable definitions + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GFXINTEGRATEDINFOTABLE_H_ +#define _GFXINTEGRATEDINFOTABLE_H_ + +AGESA_STATUS +GfxIntInfoTableInitV3 ( + IN GFX_PLATFORM_CONFIG *Gfx, + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3, + IN PP_F1_ARRAY_V2 *PpF1Array + ); + +VOID +GfxIntInfoTablePostToFbV3 ( + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3Ptr, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxIntInfoTableDebugDumpV3 ( + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3Ptr, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +// GMMx00/x04 are required for copying table to frame buffer +#ifndef GMMx00_ADDRESS + #define GMMx00_ADDRESS 0x0 + #define GMMx04_ADDRESS 0x4 +#endif + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c new file mode 100644 index 0000000000..1ad00c9c5f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c @@ -0,0 +1,257 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific GFX library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "S3SaveState.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbGfx.h" +#include "GfxLibV3.h" +#include "GnbSmuInitLibV7.h" +#include "GnbCommonLib.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINTTABLEV3_GFXLIBV3_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +CONST UINT16 GfxMemClockFrequencyDefinitionTableV3 [][8] = { +{0, 0, 0, 0, 333, 0, 400, 0}, +{0, 0, 533, 0, 0, 0, 667, 0}, +{0, 0, 800, 0, 0, 0, 933, 0}, +{0, 1050, 1066, 0, 0, 0, 0, 0} +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Extract DRAM frequency + * + * + * + * @param[in] Encoding Memory Clock Frequency Value Definition + * @param[in] StdHeader Standard configuration header + * @retval Dram frequency Mhz + */ +UINT32 +GfxLibExtractDramFrequencyV3 ( + IN UINT8 Encoding, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + if (Encoding >= (sizeof (GfxMemClockFrequencyDefinitionTableV3) / sizeof (UINT16))) { + ASSERT (FALSE); + return 0; + } + return GfxMemClockFrequencyDefinitionTableV3[Encoding / 8][Encoding % 8]; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable GMM Access for gBIF BAR Arrangement + * + * + * + * @param[in,out] Gfx Pointer to GFX configuration + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GfxEnableGmmAccessV3 ( + IN OUT GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 Value; + + if (!GnbLibPciIsDevicePresent (Gfx->GfxPciAddress.AddressValue, GnbLibGetHeader (Gfx))) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + + // Check if base address for GMM allocated by reading D1F0x24 Graphics Memory Mapped Base Address + Gfx->GmmBase = 0; + GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x24, AccessWidth32, &Value, GnbLibGetHeader (Gfx)); + Gfx->GmmBase |= (Value & 0xfffffff0); + if (Gfx->GmmBase == 0) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + + // Check if base address for FB allocated + GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x10, AccessWidth32, &Value, GnbLibGetHeader (Gfx)); + if ((Value & 0xfffffff0) == 0) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + //Push CPU MMIO pci config to S3 script + GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 0x18, 1, 0), 0xBC, 0x80, AccessS3SaveWidth32, GnbLibGetHeader (Gfx)); + // Turn on memory decoding on GFX to enable access to GMM register space + GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessWidth32, 0xffffffff, BIT1 | BIT2, GnbLibGetHeader (Gfx)); + //Push iGPU pci config to S3 script + GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x24, 0x10, AccessS3SaveWidth32, GnbLibGetHeader (Gfx)); + GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x04, 0x04, AccessS3SaveWidth16, GnbLibGetHeader (Gfx)); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Power Up/Down iGPU + * + * + * + * @param[in,out] Gfx Pointer to GFX configuration + * @param[in,out] PowerControl Control power Up/Down iGPU, 0, power down iGPU, 1, power on iGPU + * @retval AGESA_STATUS + */ +AGESA_STATUS +GfxRequestGPUPowerV3 ( + IN OUT GFX_PLATFORM_CONFIG *Gfx, + IN UINT8 PowerControl + ) +{ + GNB_HANDLE *GnbHandle; + DEV_OBJECT DevObject; + + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + DevObject.DevPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + DevObject.GnbHandle = GnbHandle; + DevObject.StdHeader = GnbLibGetHeader (Gfx); + + + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Determine number of audio ports for each connector + * + * + * + * @param[in] Engine Engine configuration info + * @param[in,out] Buffer Buffer pointer + * @param[in] Pcie PCIe configuration info + */ +VOID +STATIC +GfxIntAudioEpEnumCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 *AudioCount; + AudioCount = (UINT8*) Buffer; + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeHDMI) { + IDS_HDT_CONSOLE (GNB_TRACE, "Found HDMI Connector\n"); + (*AudioCount)++; + } else if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDP) { + if ((Engine->Type.Ddi.DdiData.Flags & DDI_DATA_FLAGS_DP1_1_ONLY) == 0) { + IDS_HDT_CONSOLE (GNB_TRACE, "Found DP1.2 Connector\n"); + *AudioCount += 4; + } else { + IDS_HDT_CONSOLE (GNB_TRACE, "Found DP1.1 Connector\n"); + (*AudioCount)++; + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "New AudioCount = %d\n", *AudioCount); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate audio endpoint in all display connectors. + * + * + * + * @param[in] Gfx Gfx configuration info + * @param[in, out] AudioEPCount Total Audio endpoint number + * @retval AGESA_STATUS + */ +AGESA_STATUS +GfxIntAudioEPEnumV3 ( + IN GFX_PLATFORM_CONFIG *Gfx, + IN OUT UINT8 *AudioEPCount + ) +{ + UINT8 NumAudioEp; + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntAudioEPEnumV3 Enter\n"); + + NumAudioEp = 0; + Status = PcieLocateConfigurationData (GnbLibGetHeader (Gfx), &Pcie); + if ((Status == AGESA_SUCCESS) && (Gfx->GnbHdAudio != 0)) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL, + GfxIntAudioEpEnumCallback, + &NumAudioEp, + Pcie + ); + + if (Gfx->GnbRemoteDisplaySupport) { + NumAudioEp++; + } + } + + *AudioEPCount = NumAudioEp; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntAudioEPEnumV3 Exit\n"); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h new file mode 100644 index 0000000000..1c7938d0e9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h @@ -0,0 +1,70 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various GFX service procedures + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GFXLIBV3_H_ +#define _GFXLIBV3_H_ + +UINT32 +GfxLibExtractDramFrequencyV3 ( + IN UINT8 Encoding, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GfxEnableGmmAccessV3 ( + IN OUT GFX_PLATFORM_CONFIG *Gfx + ); + +AGESA_STATUS +GfxRequestGPUPowerV3 ( + IN OUT GFX_PLATFORM_CONFIG *Gfx, + IN UINT8 PowerControl + ); + +AGESA_STATUS +GfxIntAudioEPEnumV3 ( + IN GFX_PLATFORM_CONFIG *Gfx, + IN OUT UINT8 *AudioEPCount + ); +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c new file mode 100644 index 0000000000..4e83c44359 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c @@ -0,0 +1,1233 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Integrated Info Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 67269 $ @e \$Date: 2012-03-26 02:53:08 -0500 (Mon, 26 Mar 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbF1Table.h" +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GnbGfxFamServices.h" +#include "GnbCommonLib.h" +#include "GfxPwrPlayTable.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINTTABLEV3_GFXPWRPLAYTABLE_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/// Software state +typedef struct { + BOOLEAN Valid; ///< State valid + UINT16 Classification; ///< State classification + UINT32 CapsAndSettings; ///< State capability and settings + UINT16 Classification2; ///< State classification2 + UINT32 SW_STATE_fld4; + UINT32 SW_STATE_fld5; + UINT8 SW_STATE_fld6; + UINT8 SW_STATE_fld7[10]; +} SW_STATE; + +typedef struct { + BOOLEAN Valid; + UINT32 GfxPwrPlayTable120_STRUCT_fld1; + UINT8 Vid; + UINT16 Tdp; +} GfxPwrPlayTable120_STRUCT; + +typedef struct { + GFX_PLATFORM_CONFIG *Gfx; + ATOM_PPLIB_POWERPLAYTABLE4 *PpTable; + PP_F1_ARRAY_V2 *PpF1s; + SW_STATE SwStateArray [MAX_NUM_OF_SW_STATES]; ///< SW state array + GfxPwrPlayTable120_STRUCT PP_WORKSPACE_V2_fld4[10]; + UINT8 NumOfClockVoltageLimitEnties; /// + ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD VceClockVoltageLimitArray[MAX_NUM_OF_VCE_CLK_STATES]; + UINT8 NumOfVceClockEnties; + GfxPwrPlayTable204_STRUCT VceClockInfoArray[MAX_NUM_OF_VCE_CLK_STATES]; + UINT8 NumOfVceStateEntries; + ATOM_PPLIB_VCE_STATE_RECORD VceStateArray[MAX_NUM_OF_VCE_STATES]; ///< VCE state array + UINT8 NumOfUvdClkVoltLimitEntries; /// + ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD UvdClkVoltLimitArray[MAX_NUM_OF_UVD_CLK_STATES]; + UINT8 NumOfUvdClockEntries; + GfxPwrPlayTable261_STRUCT UvdClockInfoArray[MAX_NUM_OF_UVD_CLK_STATES]; + UINT8 PP_WORKSPACE_V2_fld15; /// + ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD PP_WORKSPACE_V2_fld16[MAX_NUM_OF_SAMCLK_STATES]; + UINT8 PP_WORKSPACE_V2_fld17; /// + GfxPwrPlayTable310_STRUCT PP_WORKSPACE_V2_fld18[5]; +} PP_WORKSPACE_V2; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +GfxIntDebugDumpPpTable ( + IN ATOM_PPLIB_POWERPLAYTABLE4 *PpTable, + IN GFX_PLATFORM_CONFIG *Gfx + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Create new software state + * + * + * @param[in, out] PpWorkspace PP workspace + * @retval Pointer to state entry in SW state array + */ + +STATIC SW_STATE * +GfxPwrPlayCreateSwState ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINTN Index; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (PpWorkspace->SwStateArray[Index].Valid == FALSE) { + PpWorkspace->SwStateArray[Index].Valid = TRUE; + return &(PpWorkspace->SwStateArray[Index]); + } + } + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC UINT8 +GfxPwrPlayTable192_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT32 fv1, + IN UINT8 Vid + ) +{ + UINT8 Index; + + for (Index = 0; Index < 10; Index++) { + if (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Valid == FALSE) { + PpWorkspace->PP_WORKSPACE_V2_fld4[Index].GfxPwrPlayTable120_STRUCT_fld1 = fv1; + PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Vid = Vid; + PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Valid = TRUE; + PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Tdp = 0; + return Index; + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC UINT8 +GfxPwrPlayTable224_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT32 fv1, + IN UINT8 Vid + ) +{ + UINT8 Index; + + for (Index = 0; Index < 10; Index++) { + if (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Valid && + fv1 == PpWorkspace->PP_WORKSPACE_V2_fld4[Index].GfxPwrPlayTable120_STRUCT_fld1 && + Vid == PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Vid) { + + return Index; + } + } + + Index = GfxPwrPlayTable192_fun (PpWorkspace, fv1, Vid); + + return Index; +} + + +STATIC VOID +GfxPwrPlayTable256_fun ( + IN OUT SW_STATE *SwStateArray, + IN UINT8 DpmStateIndex + ) +{ + SwStateArray->SW_STATE_fld7[SwStateArray->SW_STATE_fld6++] = DpmStateIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy SW state info to PPTable + * + * + * @param[in, out] PpWorkspace PP workspace + */ +STATIC VOID * +GfxPwrPlayAttachStateInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 Index; + UINT8 SwStateIndex; + STATE_ARRAY *StateArray; + ATOM_PPLIB_STATE_V2 *States; + StateArray = (STATE_ARRAY *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + States = &StateArray->States[0]; + SwStateIndex = 0; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (PpWorkspace->SwStateArray[Index].Valid && PpWorkspace->SwStateArray[Index].SW_STATE_fld6 != 0) { + States->nonClockInfoIndex = SwStateIndex; + States->ATOM_PPLIB_STATE_V2_fld0 = PpWorkspace->SwStateArray[Index].SW_STATE_fld6; + LibAmdMemCopy ( + &States->ClockInfoIndex[0], + PpWorkspace->SwStateArray[Index].SW_STATE_fld7, + PpWorkspace->SwStateArray[Index].SW_STATE_fld6, + GnbLibGetHeader (PpWorkspace->Gfx) + ); + States = (ATOM_PPLIB_STATE_V2*) ((UINT8*) States + sizeof (ATOM_PPLIB_STATE_V2) + sizeof (UINT8) * (States->ATOM_PPLIB_STATE_V2_fld0 - 1)); + SwStateIndex++; + } + } + StateArray->ucNumEntries = SwStateIndex; + PpWorkspace->PpTable->sHeader.usStructureSize = PpWorkspace->PpTable->sHeader.usStructureSize + (USHORT) ((UINT8 *) States - (UINT8 *) StateArray); + return StateArray; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Copy clock info to PPTable + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachClockInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + CLOCK_INFO_ARRAY *ClockInfoArray; + UINT8 Index; + UINT8 ClkStateIndex; + ClkStateIndex = 0; + ClockInfoArray = (CLOCK_INFO_ARRAY *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + for (Index = 0; Index < 10; Index++) { + if (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Valid == TRUE) { + ClockInfoArray->ClockInfo[ClkStateIndex].ucEngineClockHigh = (UINT8) (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].GfxPwrPlayTable120_STRUCT_fld1 >> 16); + ClockInfoArray->ClockInfo[ClkStateIndex].usEngineClockLow = (UINT16) (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].GfxPwrPlayTable120_STRUCT_fld1); + ClockInfoArray->ClockInfo[ClkStateIndex].vddcIndex = PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Vid; + ClockInfoArray->ClockInfo[ClkStateIndex].ATOM_PPLIB_SUMO_CLOCK_INFO_fld3 = PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Tdp; + ClkStateIndex++; + } + } + ClockInfoArray->ucNumEntries = ClkStateIndex; + ClockInfoArray->ucEntrySize = sizeof (GfxPwrPlayTable143_STRUCT); + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (CLOCK_INFO_ARRAY) + sizeof (GfxPwrPlayTable143_STRUCT) * ClkStateIndex - sizeof (GfxPwrPlayTable143_STRUCT); + return ClockInfoArray; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy non clock info to PPTable + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachNonClockInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + NON_CLOCK_INFO_ARRAY *NonClockInfoArray; + UINT8 Index; + UINT8 NonClkStateIndex; + + NonClockInfoArray = (NON_CLOCK_INFO_ARRAY *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + NonClkStateIndex = 0; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (PpWorkspace->SwStateArray[Index].Valid && PpWorkspace->SwStateArray[Index].SW_STATE_fld6 != 0) { + NonClockInfoArray->NonClockInfo[NonClkStateIndex].usClassification = PpWorkspace->SwStateArray[Index].Classification; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ulCapsAndSettings = PpWorkspace->SwStateArray[Index].CapsAndSettings; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].usClassification2 = PpWorkspace->SwStateArray[Index].Classification2; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ATOM_PPLIB_NONCLOCK_INFO_fld7 = PpWorkspace->SwStateArray[Index].SW_STATE_fld5; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ATOM_PPLIB_NONCLOCK_INFO_fld6 = PpWorkspace->SwStateArray[Index].SW_STATE_fld4; + NonClkStateIndex++; + } + } + NonClockInfoArray->ucNumEntries = NonClkStateIndex; + NonClockInfoArray->ucEntrySize = sizeof (ATOM_PPLIB_NONCLOCK_INFO); + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (NON_CLOCK_INFO_ARRAY) + sizeof (ATOM_PPLIB_NONCLOCK_INFO) * NonClkStateIndex - sizeof (ATOM_PPLIB_NONCLOCK_INFO); + return NonClockInfoArray; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if state valid + * + * + * @param[out] Index State index + * @param[in] PpF1s Pointer + * @param[in] Gfx Gfx configuration info + * @retval TRUE State is valid + */ +STATIC BOOLEAN +GfxPwrPlayIsF1dStateValid ( + IN UINT8 Index, + IN PP_F1_ARRAY_V2 *PpF1s, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + BOOLEAN Result; + Result = FALSE; + if ((PpF1s->PP_FUSE_ARRAY_V2_fld37 & (1 << Index)) || (PpF1s->PP_FUSE_ARRAY_V2_fld38 & (1 << Index))) { + Result = TRUE; + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC VOID +GfxPwrPlayTable437_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 ClkStateIndex; + UINT8 DpmF1Index; + UINT32 fv2; + SW_STATE *State; + PP_F1_ARRAY_V2 *PpF1s; + + PpF1s = PpWorkspace->PpF1s; + + // Create Battery state + State = GfxPwrPlayCreateSwState (PpWorkspace); + + State->Classification = ATOM_PPLIB_CLASSIFICATION_UI_BATTERY; + State->Classification2 = 0; + State->SW_STATE_fld4 = 0; + State->SW_STATE_fld5 = 0; + if (PpWorkspace->Gfx->AbmSupport != 0) { + State->CapsAndSettings |= ATOM_PPLIB_ENABLE_VARIBRIGHT; + } + if (PpWorkspace->Gfx->DynamicRefreshRate != 0) { + State->CapsAndSettings |= ATOM_PPLIB_ENABLE_DRR; + } + + for (DpmF1Index = 0; DpmF1Index < 5; DpmF1Index++) { + + if (PpF1s->PP_FUSE_ARRAY_V2_fld38 & (1 << DpmF1Index)) { + + fv2 = (PpF1s->PP_FUSE_ARRAY_V2_fld33[DpmF1Index] != 0) ? + GfxFmCalculateClock (PpF1s->PP_FUSE_ARRAY_V2_fld33[DpmF1Index], + GnbLibGetHeader (PpWorkspace->Gfx)) : 0; + + if (fv2 != 0) { + ClkStateIndex = GfxPwrPlayTable224_fun (PpWorkspace, fv2, PpF1s->PP_FUSE_ARRAY_V2_fld32[DpmF1Index]); + GfxPwrPlayTable256_fun (State, ClkStateIndex); + } + } + } + + // Create Performance state + State = GfxPwrPlayCreateSwState (PpWorkspace); + + State->Classification = ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE; + State->Classification2 = 0; + State->SW_STATE_fld4 = 0; + State->SW_STATE_fld5 = 0; + + // Loop through fused DPM states and find those that go with Performance + for (DpmF1Index = 0; DpmF1Index < 5; DpmF1Index++) { + + if (PpF1s->PP_FUSE_ARRAY_V2_fld37 & (1 << DpmF1Index)) { + + fv2 = (PpF1s->PP_FUSE_ARRAY_V2_fld33[DpmF1Index] != 0) ? + GfxFmCalculateClock (PpF1s->PP_FUSE_ARRAY_V2_fld33[DpmF1Index], + GnbLibGetHeader (PpWorkspace->Gfx)) : 0; + + if (fv2 != 0) { + ClkStateIndex = GfxPwrPlayTable224_fun (PpWorkspace, fv2, PpF1s->PP_FUSE_ARRAY_V2_fld32[DpmF1Index]); + GfxPwrPlayTable256_fun (State, ClkStateIndex); + } + } + } + + // Create Boot State + State = GfxPwrPlayCreateSwState (PpWorkspace); + State->Classification = ATOM_PPLIB_CLASSIFICATION_BOOT; + fv2 = 200 * 100; + ClkStateIndex = GfxPwrPlayTable224_fun (PpWorkspace, fv2, 0); + GfxPwrPlayTable256_fun (State, ClkStateIndex); + +} + + +/*----------------------------------------------------------------------------------------*/ + +STATIC UINT8 +GfxPwrPlayAddEclkState ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT32 Eclk + ) +{ + UINT8 Index; + USHORT EclkLow; + UCHAR EclkHigh; + EclkLow = (USHORT) (Eclk & 0xffff); + EclkHigh = (UCHAR) (Eclk >> 16); + for (Index = 0; Index < PpWorkspace->NumOfVceClockEnties; Index++) { + if (PpWorkspace->VceClockInfoArray[Index].ucECClkHigh == EclkHigh && PpWorkspace->VceClockInfoArray[Index].usECClkLow == EclkLow) { + return Index; + } + } + PpWorkspace->VceClockInfoArray[PpWorkspace->NumOfVceClockEnties].ucECClkHigh = EclkHigh; + PpWorkspace->VceClockInfoArray[PpWorkspace->NumOfVceClockEnties].usECClkLow = EclkLow; + PpWorkspace->VceClockInfoArray[PpWorkspace->NumOfVceClockEnties].GfxPwrPlayTable204_STRUCT_fld1 = EclkHigh; + PpWorkspace->VceClockInfoArray[PpWorkspace->NumOfVceClockEnties].GfxPwrPlayTable204_STRUCT_fld0 = EclkLow; + return PpWorkspace->NumOfVceClockEnties++; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Add ECLK state + * + * + * @param[in, out] PpWorkspace PP workspace + * @param[in] EclkIndex ECLK index + * @param[in] Vid Vid index + * @retval Index of state entry in Eclk Voltage record array + */ + +STATIC UINT8 +GfxPwrPlayAddEclkVoltageRecord ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT8 EclkIndex, + IN UINT8 Vid + ) +{ + UINT8 Index; + for (Index = 0; Index < PpWorkspace->NumOfClockVoltageLimitEnties; Index++) { + if (PpWorkspace->VceClockVoltageLimitArray[Index].ucVCEClockInfoIndex == EclkIndex) { + return Index; + } + } + PpWorkspace->VceClockVoltageLimitArray[PpWorkspace->NumOfClockVoltageLimitEnties].ucVCEClockInfoIndex = EclkIndex; + PpWorkspace->VceClockVoltageLimitArray[PpWorkspace->NumOfClockVoltageLimitEnties].usVoltage = Vid; + return PpWorkspace->NumOfClockVoltageLimitEnties++; +} + + +/*----------------------------------------------------------------------------------------*/ + +STATIC UINT8 +GfxPwrPlayTable588_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT32 fv1, + IN UINT32 fv2 + ) +{ + UINT8 Index; + USHORT v1; + UCHAR v2; + USHORT v3; + UCHAR v4; + v1 = (USHORT) (fv1 & 0xffff); + v2 = (UCHAR) (fv1 >> 16); + v3 = (USHORT) (fv2 & 0xffff); + v4 = (UCHAR) (fv2 >> 16); + for (Index = 0; Index < PpWorkspace->NumOfUvdClockEntries; Index++) { + if (PpWorkspace->UvdClockInfoArray[Index].GfxPwrPlayTable261_STRUCT_fld1 == v2 && + PpWorkspace->UvdClockInfoArray[Index].GfxPwrPlayTable261_STRUCT_fld0 == v1) { + return Index; + } + } + PpWorkspace->UvdClockInfoArray[PpWorkspace->NumOfUvdClockEntries].GfxPwrPlayTable261_STRUCT_fld1 = v2; + PpWorkspace->UvdClockInfoArray[PpWorkspace->NumOfUvdClockEntries].GfxPwrPlayTable261_STRUCT_fld0 = v1; + PpWorkspace->UvdClockInfoArray[PpWorkspace->NumOfUvdClockEntries].GfxPwrPlayTable261_STRUCT_fld3 = v4; + PpWorkspace->UvdClockInfoArray[PpWorkspace->NumOfUvdClockEntries].GfxPwrPlayTable261_STRUCT_fld2 = v3; + return PpWorkspace->NumOfUvdClockEntries++; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Add Uvd voltage record + * + * + * @param[in, out] PpWorkspace PP workspace + * @param[in] ClkIndex CLK index + * @param[in] Vid Vid index + * @retval Index of state entry in Eclk Voltage record array + */ + +STATIC UINT8 +GfxPwrPlayAddUvdVoltageRecord ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT8 ClkIndex, + IN UINT8 Vid + ) +{ + UINT8 Index; + for (Index = 0; Index < PpWorkspace->NumOfUvdClkVoltLimitEntries; Index++) { + if (PpWorkspace->UvdClkVoltLimitArray[Index].ucUVDClockInfoIndex == ClkIndex) { + return Index; + } + } + PpWorkspace->UvdClkVoltLimitArray[PpWorkspace->NumOfUvdClkVoltLimitEntries].ucUVDClockInfoIndex = + ClkIndex; + PpWorkspace->UvdClkVoltLimitArray[PpWorkspace->NumOfUvdClkVoltLimitEntries].usVoltage = Vid; + return PpWorkspace->NumOfUvdClkVoltLimitEntries++; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Add Samu voltage record + * + * + * @param[in, out] PpWorkspace PP workspace + * @param[in] Vid Vid + * @param[in] Samclk CLK associated with the Vid + * @retval Index of state entry in Voltage record array + */ + +STATIC UINT8 +GfxPwrPlayAddSamuVoltageRecord ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT8 Vid, + IN UINT32 Samclk + ) +{ + UINT8 Index; + USHORT SamclkLow; + UCHAR SamclkHigh; + SamclkLow = (USHORT) (Samclk & 0xffff); + SamclkHigh = (UCHAR) (Samclk >> 16); + for (Index = 0; Index < PpWorkspace->PP_WORKSPACE_V2_fld15; Index++) { + if ((PpWorkspace->PP_WORKSPACE_V2_fld16[Index].usSAMClockHigh == SamclkHigh) && + (PpWorkspace->PP_WORKSPACE_V2_fld16[Index].usSAMClockLow == SamclkLow) && + (PpWorkspace->PP_WORKSPACE_V2_fld16[Index].usVoltage == Vid) + ) { + return Index; + } + } + PpWorkspace->PP_WORKSPACE_V2_fld16[PpWorkspace->PP_WORKSPACE_V2_fld15].usSAMClockHigh = + SamclkHigh; + PpWorkspace->PP_WORKSPACE_V2_fld16[PpWorkspace->PP_WORKSPACE_V2_fld15].usSAMClockLow = + SamclkLow; + PpWorkspace->PP_WORKSPACE_V2_fld16[PpWorkspace->PP_WORKSPACE_V2_fld15].usVoltage = Vid; + return PpWorkspace->PP_WORKSPACE_V2_fld15++; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach extended header + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachExtendedHeaderBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_EXTENDEDHEADER *ExtendedHeader; + ExtendedHeader = (ATOM_PPLIB_EXTENDEDHEADER *) + ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + ExtendedHeader->usSize = sizeof (ATOM_PPLIB_EXTENDEDHEADER); + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (ATOM_PPLIB_EXTENDEDHEADER); + return ExtendedHeader; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach Vce Rev Block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachVceTableRevBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_VCE_TABLE *VceTable; + VceTable = (ATOM_PPLIB_VCE_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + VceTable->revid = 0; + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (ATOM_PPLIB_VCE_TABLE); + return VceTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach VCE clock info block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachVceClockInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + VCECLOCKINFOARRAY *VceClockInfoArray; + VceClockInfoArray = (VCECLOCKINFOARRAY *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + VceClockInfoArray->ucNumEntries = PpWorkspace->NumOfVceClockEnties; + LibAmdMemCopy ( + &VceClockInfoArray->entries[0], + &PpWorkspace->VceClockInfoArray[0], + VceClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable204_STRUCT), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (VCECLOCKINFOARRAY) + + VceClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable204_STRUCT) - + sizeof (GfxPwrPlayTable204_STRUCT); + return VceClockInfoArray; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach VCE voltage limit block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachVceVoltageLimitBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE *VceClockVoltageLimitTable; + VceClockVoltageLimitTable = (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + VceClockVoltageLimitTable->numEntries = PpWorkspace->NumOfClockVoltageLimitEnties; + LibAmdMemCopy ( + &VceClockVoltageLimitTable->entries[0], + &PpWorkspace->VceClockVoltageLimitArray[0], + VceClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = + PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE) + + VceClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD) - + sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD); + return VceClockVoltageLimitTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach VCE state block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachVceStateTableBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_VCE_STATE_TABLE *VceStateTable; + VceStateTable = (ATOM_PPLIB_VCE_STATE_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + VceStateTable->numEntries = PpWorkspace->NumOfVceStateEntries; + LibAmdMemCopy ( + &VceStateTable->entries[0], + &PpWorkspace->VceStateArray[0], + VceStateTable->numEntries * sizeof (ATOM_PPLIB_VCE_STATE_RECORD), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (ATOM_PPLIB_VCE_STATE_TABLE) + + VceStateTable->numEntries * sizeof (ATOM_PPLIB_VCE_STATE_RECORD) - + sizeof (ATOM_PPLIB_VCE_STATE_RECORD); + return VceStateTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach Uvd Rev Block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachUvdTableRevBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_UVD_TABLE *UvdTable; + UvdTable = (ATOM_PPLIB_UVD_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + UvdTable->revid = 0; + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (ATOM_PPLIB_UVD_TABLE); + return UvdTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach UVD clock info block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachUvdClockInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + GfxPwrPlayTable267_STRUCT *UvdClockInfoArray; + UvdClockInfoArray = (GfxPwrPlayTable267_STRUCT *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + UvdClockInfoArray->ucNumEntries = PpWorkspace->NumOfUvdClockEntries; + LibAmdMemCopy ( + &UvdClockInfoArray->entries[0], + &PpWorkspace->UvdClockInfoArray[0], + UvdClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable261_STRUCT), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (GfxPwrPlayTable267_STRUCT) + + UvdClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable261_STRUCT) - + sizeof (GfxPwrPlayTable261_STRUCT); + return UvdClockInfoArray; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach UVD voltage limit block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachUvdVoltageLimitBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UVD_CLK_VOLT_LIMIT_TABLE *UvdClockVoltageLimitTable; + UvdClockVoltageLimitTable = (UVD_CLK_VOLT_LIMIT_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + UvdClockVoltageLimitTable->numEntries = PpWorkspace->NumOfUvdClkVoltLimitEntries; + LibAmdMemCopy ( + &UvdClockVoltageLimitTable->entries[0], + &PpWorkspace->UvdClkVoltLimitArray[0], + UvdClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = + PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (UVD_CLK_VOLT_LIMIT_TABLE) + + UvdClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD) - + sizeof (ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD); + return UvdClockVoltageLimitTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach SAMU Rev Block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachSamuTableRevBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_SAMU_TABLE *VceTable; + VceTable = (ATOM_PPLIB_SAMU_TABLE *) ((UINT8 *) PpWorkspace->PpTable + + PpWorkspace->PpTable->sHeader.usStructureSize); + VceTable->revid = 0; + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (ATOM_PPLIB_SAMU_TABLE); + return VceTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach SAMU voltage limit block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachSamuVoltageLimitBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE *SamuClockVoltageLimitTable; + SamuClockVoltageLimitTable = (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE *) + ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + SamuClockVoltageLimitTable->numEntries = PpWorkspace->PP_WORKSPACE_V2_fld15; + LibAmdMemCopy ( + &SamuClockVoltageLimitTable->entries[0], + &PpWorkspace->PP_WORKSPACE_V2_fld16[0], + SamuClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = + PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE) + + SamuClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD) - + sizeof (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD); + return SamuClockVoltageLimitTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach Sclk Volt Dep Block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayTable956_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + GfxPwrPlayTable316_STRUCT *v0; + + v0 = (GfxPwrPlayTable316_STRUCT *) + ((UINT8 *) PpWorkspace->PpTable + + PpWorkspace->PpTable->sHeader.usStructureSize); + v0->numEntries = PpWorkspace->PP_WORKSPACE_V2_fld17; + LibAmdMemCopy ( + &v0->entries[0], + &PpWorkspace->PP_WORKSPACE_V2_fld18[0], + 5 * sizeof (GfxPwrPlayTable310_STRUCT), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = + PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (GfxPwrPlayTable316_STRUCT) + + v0->numEntries * sizeof (GfxPwrPlayTable310_STRUCT) - + sizeof (GfxPwrPlayTable310_STRUCT); + + + return v0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build VCE state info + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID +GfxPwrPlayBuildVceStateTable ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 Index; + UINT8 VceStateIndex; + UINT8 Vid; + UINT32 Eclk; + UINT32 v4; + UINT8 UsedStateBitmap; + UsedStateBitmap = 0; + // build used state + for (Index = 0; + Index < (sizeof (PpWorkspace->PpF1s->VceFlags) / + sizeof (PpWorkspace->PpF1s->VceFlags[0])) ; + Index++) { + UsedStateBitmap |= PpWorkspace->PpF1s->VceFlags[Index]; + for (VceStateIndex = 0; + VceStateIndex < (sizeof (PpWorkspace->VceStateArray) / + sizeof (PpWorkspace->VceStateArray[0])); + VceStateIndex++) { + if ((PpWorkspace->PpF1s->VceFlags[Index] & (1 << VceStateIndex)) != 0) { + v4 = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld33[PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld16[Index]], + GnbLibGetHeader (PpWorkspace->Gfx)); + Vid = PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld32[PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld16[Index]]; + PpWorkspace->VceStateArray[VceStateIndex].ucClockInfoIndex = + GfxPwrPlayTable224_fun (PpWorkspace, v4, Vid); + if (PpWorkspace->PpF1s->VceMclk) { + PpWorkspace->VceStateArray[VceStateIndex].ucClockInfoIndex |= + (PpWorkspace->PpF1s->VceMclk << 6); + } + Eclk = GfxFmCalculateClock (PpWorkspace->PpF1s->EclkDid[Index], + GnbLibGetHeader (PpWorkspace->Gfx)); + PpWorkspace->VceStateArray[VceStateIndex].ucVCEClockInfoIndex = + GfxPwrPlayAddEclkState (PpWorkspace, Eclk); + GfxPwrPlayAddEclkVoltageRecord (PpWorkspace, + PpWorkspace->VceStateArray[VceStateIndex].ucVCEClockInfoIndex, Vid); + PpWorkspace->NumOfVceStateEntries++; + } + } + } + //build unused states + for (VceStateIndex = 0; + VceStateIndex < (sizeof (PpWorkspace->VceStateArray) / sizeof (PpWorkspace->VceStateArray[0])); + VceStateIndex++) { + if ((UsedStateBitmap & (1 << VceStateIndex)) == 0) { + PpWorkspace->VceStateArray[VceStateIndex].ucClockInfoIndex = 0; + PpWorkspace->VceStateArray[VceStateIndex].ucVCEClockInfoIndex = GfxPwrPlayAddEclkState (PpWorkspace, 0); + PpWorkspace->NumOfVceStateEntries++; + } + } +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC VOID +GfxPwrPlayBuildUvdClockTable ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 Index; + UINT8 Vid; + UINT32 v2; + UINT32 v3; + UINT8 UsedStateBitmap; + UINT8 UvdIndex; + + UsedStateBitmap = 0; + // build used state + for (Index = 0; Index < MAX_NUM_OF_UVD_CLK_STATES ; Index++) { + if (GfxPwrPlayIsF1dStateValid (Index, PpWorkspace->PpF1s, PpWorkspace->Gfx)) { + Vid = PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld32[Index]; + v2 = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld1[Index], + GnbLibGetHeader (PpWorkspace->Gfx)); + v3 = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld2[Index], + GnbLibGetHeader (PpWorkspace->Gfx)); + UvdIndex = GfxPwrPlayTable588_fun (PpWorkspace, v2, v3); + GfxPwrPlayAddUvdVoltageRecord (PpWorkspace, + UvdIndex, Vid); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build SAMU info + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID +GfxPwrPlayBuildSamuTable ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 SamuIndex; + UINT8 Vid; + UINT32 Samuclk; + UINT8 UsedStateBitmap; + UsedStateBitmap = 0; + // build used state + for (SamuIndex = 0; SamuIndex < MAX_NUM_OF_SAMCLK_STATES; SamuIndex++) { + if (GfxPwrPlayIsF1dStateValid (SamuIndex, PpWorkspace->PpF1s, PpWorkspace->Gfx)) { + Vid = PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld32[SamuIndex]; + Samuclk = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld34[SamuIndex], + GnbLibGetHeader (PpWorkspace->Gfx)); + GfxPwrPlayAddSamuVoltageRecord (PpWorkspace, Vid, Samuclk); + } + } +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC VOID +GfxPwrPlayTable1122_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 v0; + UINT8 Vid; + UINT32 v2; + USHORT v3; + UCHAR v4; + + // build the table + for (v0 = 0; v0 < 5; v0++) { + Vid = PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld32[v0]; + v2 = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld33[v0], + GnbLibGetHeader (PpWorkspace->Gfx)); + ASSERT (Vid != 0) + ASSERT (v2 != 0) + v3 = (USHORT) (v2 & 0xffff); + v4 = (UCHAR) (v2 >> 16); + PpWorkspace->PP_WORKSPACE_V2_fld18[v0].GfxPwrPlayTable310_fld2 = Vid; + PpWorkspace->PP_WORKSPACE_V2_fld18[v0].GfxPwrPlayTable310_fld1 = v4; + PpWorkspace->PP_WORKSPACE_V2_fld18[v0].GfxPwrPlayTable310_fld0 = v3; + PpWorkspace->PP_WORKSPACE_V2_fld17++; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build PP table + * + * + * @param[out] Buffer Buffer to create PP table + * @param[in] Gfx Gfx configuration info + * @retval AGESA_SUCCESS + * @retval AGESA_ERROR + */ + +AGESA_STATUS +GfxPwrPlayBuildTable ( + OUT VOID *Buffer, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + PP_WORKSPACE_V2 PpWorkspace; + VOID *BlockPtr; + + LibAmdMemFill (&PpWorkspace, 0x00, sizeof (PP_WORKSPACE_V2), GnbLibGetHeader (Gfx)); + PpWorkspace.PpF1s = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, GnbLibGetHeader (Gfx)); + ASSERT (PpWorkspace.PpF1s != NULL); + if (PpWorkspace.PpF1s == NULL) { + return AGESA_ERROR; + } + + PpWorkspace.PpTable = (ATOM_PPLIB_POWERPLAYTABLE4 *) Buffer; + PpWorkspace.Gfx = Gfx; + //Fill static info + PpWorkspace.PpTable->sHeader.ucTableFormatRevision = 6; + PpWorkspace.PpTable->sHeader.ucTableContentRevision = 1; + PpWorkspace.PpTable->ucDataRevision = PpWorkspace.PpF1s->PPlayTableRev; + PpWorkspace.PpTable->sThermalController.ucType = ATOM_PP_THERMALCONTROLLER_KV; + PpWorkspace.PpTable->sThermalController.ucFanParameters = ATOM_PP_FANPARAMETERS_NOFAN; + PpWorkspace.PpTable->sHeader.usStructureSize = sizeof (ATOM_PPLIB_POWERPLAYTABLE4); + PpWorkspace.PpTable->usTableSize = sizeof (ATOM_PPLIB_POWERPLAYTABLE4); + PpWorkspace.PpTable->usFormatID = 0x13; + if ((Gfx->AmdPlatformType & AMD_PLATFORM_MOBILE) != 0) { + PpWorkspace.PpTable->ulPlatformCaps |= ATOM_PP_PLATFORM_CAP_POWERPLAY; + } + + + GfxPwrPlayTable437_fun (&PpWorkspace); + + // Fill Eclk state info + if (PpWorkspace.PpF1s->PP_FUSE_ARRAY_V2_fld13) { + GfxPwrPlayBuildVceStateTable (&PpWorkspace); + GfxPwrPlayBuildUvdClockTable (&PpWorkspace); + GfxPwrPlayBuildSamuTable (&PpWorkspace); + GfxPwrPlayTable1122_fun (&PpWorkspace); + } + + //Copy state info to actual PP table + BlockPtr = GfxPwrPlayAttachStateInfoBlock (&PpWorkspace); + PpWorkspace.PpTable->usStateArrayOffset = (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + BlockPtr = GfxPwrPlayAttachClockInfoBlock (&PpWorkspace); + PpWorkspace.PpTable->usClockInfoArrayOffset = (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + BlockPtr = GfxPwrPlayAttachNonClockInfoBlock (&PpWorkspace); + PpWorkspace.PpTable->usNonClockInfoArrayOffset = (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + + if (PpWorkspace.PpF1s->PP_FUSE_ARRAY_V2_fld13) { + ATOM_PPLIB_EXTENDEDHEADER *ExtendedHeader; + ExtendedHeader = + (ATOM_PPLIB_EXTENDEDHEADER *) GfxPwrPlayAttachExtendedHeaderBlock (&PpWorkspace); + PpWorkspace.PpTable->usExtendendedHeaderOffset = + (USHORT) ((UINT8 *) ExtendedHeader - (UINT8 *) (PpWorkspace.PpTable)); + BlockPtr = GfxPwrPlayAttachVceTableRevBlock (&PpWorkspace); + ExtendedHeader->usVCETableOffset = + (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + GfxPwrPlayAttachVceClockInfoBlock (&PpWorkspace); + GfxPwrPlayAttachVceVoltageLimitBlock (&PpWorkspace); + GfxPwrPlayAttachVceStateTableBlock (&PpWorkspace); + + BlockPtr = GfxPwrPlayAttachUvdTableRevBlock (&PpWorkspace); + ExtendedHeader->usUVDTableOffset = + (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + GfxPwrPlayAttachUvdClockInfoBlock (&PpWorkspace); + GfxPwrPlayAttachUvdVoltageLimitBlock (&PpWorkspace); + + BlockPtr = GfxPwrPlayAttachSamuTableRevBlock (&PpWorkspace); + ExtendedHeader->usSAMUTableOffset = + (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + GfxPwrPlayAttachSamuVoltageLimitBlock (&PpWorkspace); + + BlockPtr = GfxPwrPlayTable956_fun (&PpWorkspace); + PpWorkspace.PpTable->ATOM_PPLIB_POWERPLAYTABLE4_fld17 = + (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + + IDS_HDT_CONSOLE (GNB_TRACE, "ExtendedHeader \n"); + IDS_HDT_CONSOLE (GNB_TRACE, " VceTableOffset = %04x\n", ExtendedHeader->usVCETableOffset); + IDS_HDT_CONSOLE (GNB_TRACE, " UvdTableOffset = %04x\n", ExtendedHeader->usUVDTableOffset); + IDS_HDT_CONSOLE (GNB_TRACE, " SamTableOffset = %04x\n", ExtendedHeader->usSAMUTableOffset); + IDS_HDT_CONSOLE (GNB_TRACE, "\n"); + + } + GNB_DEBUG_CODE ( + GfxIntDebugDumpPpTable (PpWorkspace.PpTable, Gfx); + ); + + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump PP table + * + * + * + * @param[in] PpTable Power Play table + * @param[in] Gfx Gfx configuration info + */ + +VOID +GfxIntDebugDumpPpTable ( + IN ATOM_PPLIB_POWERPLAYTABLE4 *PpTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINTN Index; + STATE_ARRAY *StateArray; + ATOM_PPLIB_STATE_V2 *StatesPtr; + NON_CLOCK_INFO_ARRAY *NonClockInfoArrayPtr; + CLOCK_INFO_ARRAY *ClockInfoArrayPtr; + ATOM_PPLIB_EXTENDEDHEADER *ExtendedHeader; + ATOM_PPLIB_VCE_STATE_TABLE *VceStateTable; + ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE *VceClockVoltageLimitTable; + VCECLOCKINFOARRAY *VceClockInfoArray; + GfxPwrPlayTable267_STRUCT *UvdClockInfoArray; + UVD_CLK_VOLT_LIMIT_TABLE *UvdClockVoltLimitTable; + ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE *SamuClockVoltLimitTable; + UINT8 EclkIndex; + + IDS_HDT_CONSOLE (GFX_MISC, " < --- Power Play Table ------ > \n"); + IDS_HDT_CONSOLE (GFX_MISC, " Table Revision = %d\n", PpTable->ucDataRevision); + StateArray = (STATE_ARRAY *) ((UINT8 *) PpTable + PpTable->usStateArrayOffset); + StatesPtr = StateArray->States; + NonClockInfoArrayPtr = (NON_CLOCK_INFO_ARRAY *) ((UINT8 *) PpTable + PpTable->usNonClockInfoArrayOffset); + ClockInfoArrayPtr = (CLOCK_INFO_ARRAY *) ((UINT8 *) PpTable + PpTable->usClockInfoArrayOffset); + IDS_HDT_CONSOLE (GFX_MISC, " < --- SW State Table ---------> \n"); + for (Index = 0; Index < StateArray->ucNumEntries; Index++) { + IDS_HDT_CONSOLE (GFX_MISC, " State #%d\n", Index + 1 + ); + IDS_HDT_CONSOLE (GFX_MISC, " Classification 0x%x\n", + NonClockInfoArrayPtr->NonClockInfo[StatesPtr->nonClockInfoIndex].usClassification + ); + IDS_HDT_CONSOLE (GFX_MISC, " Classification2 0x%x\n", + NonClockInfoArrayPtr->NonClockInfo[StatesPtr->nonClockInfoIndex].usClassification2 + ); + IDS_HDT_CONSOLE (GFX_MISC, "\n"); + StatesPtr = (ATOM_PPLIB_STATE_V2 *) ((UINT8 *) StatesPtr + sizeof (ATOM_PPLIB_STATE_V2) + StatesPtr->ATOM_PPLIB_STATE_V2_fld0 - 1); + } + if (PpTable->usExtendendedHeaderOffset != 0) { + ExtendedHeader = (ATOM_PPLIB_EXTENDEDHEADER *) ((UINT8 *) PpTable + + PpTable->usExtendendedHeaderOffset); + + IDS_HDT_CONSOLE (GNB_TRACE, "ExtendedHeader = %08x\n", ExtendedHeader); + + VceClockInfoArray = (VCECLOCKINFOARRAY *) ((UINT8 *) PpTable + + ExtendedHeader->usVCETableOffset + sizeof (ATOM_PPLIB_VCE_TABLE)); + VceClockVoltageLimitTable = + (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE *) ((UINT8 *) VceClockInfoArray + + sizeof (VCECLOCKINFOARRAY) + + VceClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable204_STRUCT) - + sizeof (GfxPwrPlayTable204_STRUCT)); + VceStateTable = + (ATOM_PPLIB_VCE_STATE_TABLE *) ((UINT8 *) VceClockVoltageLimitTable + + sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE) + + VceClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD) - + sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD)); + UvdClockInfoArray = + (GfxPwrPlayTable267_STRUCT *) ((UINT8 *) PpTable + ExtendedHeader->usUVDTableOffset + + sizeof (ATOM_PPLIB_UVD_TABLE)); + UvdClockVoltLimitTable = + (UVD_CLK_VOLT_LIMIT_TABLE *) ((UINT8 *) UvdClockInfoArray + sizeof (GfxPwrPlayTable267_STRUCT) + + UvdClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable261_STRUCT) - + sizeof (GfxPwrPlayTable261_STRUCT)); + SamuClockVoltLimitTable = + (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE *) + ((UINT8 *) PpTable + ExtendedHeader->usSAMUTableOffset + sizeof (ATOM_PPLIB_SAMU_TABLE)); + + IDS_HDT_CONSOLE (GFX_MISC, " < --- VCE State Table [%d]--> \n", VceStateTable->numEntries); + + IDS_HDT_CONSOLE (GFX_MISC, " < --- VCE Voltage Record Table ---> \n"); + for (Index = 0; Index < VceClockVoltageLimitTable->numEntries; Index++) { + EclkIndex = VceClockVoltageLimitTable->entries[Index].ucVCEClockInfoIndex; + IDS_HDT_CONSOLE (GFX_MISC, " VCE Voltage Record #%d\n", Index + ); + IDS_HDT_CONSOLE (GFX_MISC, " ECLK = %d\n", + VceClockInfoArray->entries[EclkIndex].usECClkLow | (VceClockInfoArray->entries[EclkIndex].ucECClkHigh << 16) + ); + IDS_HDT_CONSOLE (GFX_MISC, " VID index = %d\n", + VceClockVoltageLimitTable->entries[Index].usVoltage + ); + } + + + IDS_HDT_CONSOLE (GFX_MISC, " < --- SAMU Voltage Record Table ---> \n"); + for (Index = 0; Index < SamuClockVoltLimitTable->numEntries; Index++) { + IDS_HDT_CONSOLE (GFX_MISC, " SAMU Voltage Record #%d\n", Index + ); + IDS_HDT_CONSOLE (GFX_MISC, " SAMCLK = %d\n", + SamuClockVoltLimitTable->entries[Index].usSAMClockLow | + (SamuClockVoltLimitTable->entries[Index].usSAMClockHigh << 16) + ); + IDS_HDT_CONSOLE (GFX_MISC, " VID index = %d\n", + SamuClockVoltLimitTable->entries[Index].usVoltage + ); + } + } + + IDS_HDT_CONSOLE (GFX_MISC, " PplayDumpExit\n"); + +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h new file mode 100644 index 0000000000..05895ced55 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h @@ -0,0 +1,321 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Power Play Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 63366 $ @e \$Date: 2011-12-21 14:49:48 -0600 (Wed, 21 Dec 2011) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GFXPWRPLAYTABLE_H_ +#define _GFXPWRPLAYTABLE_H_ + +#pragma pack (push, 1) + +#define POLICY_LABEL_BATTERY 0x1 +#define POLICY_LABEL_PERFORMANCE 0x2 + +#define MAX_NUM_OF_SW_STATES 3 +#define MAX_NUM_OF_VCE_CLK_STATES 5 +#define MAX_NUM_OF_VCE_STATES 6 +#define MAX_NUM_OF_UVD_CLK_STATES 5 +#define MAX_NUM_OF_SAMCLK_STATES 5 +/// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps +#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1 +#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2 +#define ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 4 +#define ATOM_PP_PLATFORM_CAP_ASPM_L0s 8 +#define ATOM_PP_PLATFORM_CAP_ASPM_L1 16 +#define ATOM_PP_PLATFORM_CAP_HARDWAREDC 32 +#define ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY 64 +#define ATOM_PP_PLATFORM_CAP_STEPVDDC 128 +#define ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL 256 +#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512 +#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024 +#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048 +#define ATOM_PP_PLATFORM_CAP_MVDDCONTROL 4096 +#define ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT 0x2000 // Go to boot state on alerts, e.g. on an AC->DC transition. +#define ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT 0x4000 // Do NOT wait for VBLANK during an alert (e.g. AC->DC transition). +#define ATOM_PP_PLATFORM_CAP_VDDCI_CONTROL 0x8000 // Does +#define ATOM_PP_PLATFORM_CAP_REGULATOR_HOT 0x00010000ul // Enable the 'regulator hot' feature. +#define ATOM_PP_PLATFORM_CAP_BACO 0x00020000ul // Does the driver supports BACO state. + + +#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY 1 +#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED 3 +#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE 5 + +#define ATOM_PPLIB_CLASSIFICATION_BOOT 0x0008 +#define ATOM_PPLIB_CLASSIFICATION_THERMAL 0x0010 +#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE 0x0020 +#define ATOM_PPLIB_CLASSIFICATION_REST 0x0040 +#define ATOM_PPLIB_CLASSIFICATION_FORCED 0x0080 +#define ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE 0x0100 +#define ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE 0x0200 +#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE 0x0400 +#define ATOM_PPLIB_CLASSIFICATION_3DLOW 0x0800 +#define ATOM_PPLIB_CLASSIFICATION_ACPI 0x1000 +#define ATOM_PPLIB_CLASSIFICATION_HD2STATE 0x2000 +#define ATOM_PPLIB_CLASSIFICATION_HDSTATE 0x4000 +#define ATOM_PPLIB_CLASSIFICATION_SDSTATE 0x8000 +#define ATOM_PPLIB_CLASSIFICATION_NONUVDSTATE 0x0000 + +#define ATOM_PPLIB_CLASSIFICATION2_MVC 0x0004 //Multi-View + +#define ATOM_PPLIB_ENABLE_VARIBRIGHT 0x00008000ul +#define ATOM_PPLIB_ENABLE_DRR 0x00080000ul + +#define ATOM_PP_FANPARAMETERS_NOFAN 0x80 +#define ATOM_PP_THERMALCONTROLLER_KV 0x13 + +typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO { + USHORT usEngineClockLow; + UCHAR ucEngineClockHigh; + UCHAR vddcIndex; + USHORT ATOM_PPLIB_SUMO_CLOCK_INFO_fld3; + USHORT rsv1; + ULONG rsv2[2]; +} GfxPwrPlayTable143_STRUCT; + +/// Non clock info +typedef struct _ATOM_PPLIB_NONCLOCK_INFO { + USHORT usClassification; ///< State classification see ATOM_PPLIB_CLASSIFICATION_* + UCHAR ucMinTemperature; ///< Reserved + UCHAR ucMaxTemperature; ///< Reserved + ULONG ulCapsAndSettings; ///< Capability Setting (ATOM_PPLIB_ENABLE_DRR or ATOM_PPLIB_ENABLE_VARIBRIGHT or 0) + UCHAR ucRequiredPower; ///< Reserved + USHORT usClassification2; ///< Reserved + ULONG ATOM_PPLIB_NONCLOCK_INFO_fld6; + ULONG ATOM_PPLIB_NONCLOCK_INFO_fld7; + UCHAR ucUnused[5]; ///< Reserved +} ATOM_PPLIB_NONCLOCK_INFO; + +/// Thermal controller info stub +typedef struct _ATOM_PPLIB_THERMALCONTROLLER { + UCHAR ucType; ///< Reserved. Should be set 0xE + UCHAR ucI2cLine; ///< Reserved. Should be set 0 + UCHAR ucI2cAddress; ///< Reserved. Should be set 0 + UCHAR ucFanParameters; ///< Reserved. Should be set 0x80 + UCHAR ucFanMinRPM; ///< Reserved. Should be set 0 + UCHAR ucFanMaxRPM; ///< Reserved. Should be set 0 + UCHAR ucReserved; ///< Reserved. Should be set 0 + UCHAR ucFlags; ///< Reserved. Should be set 0 +} ATOM_PPLIB_THERMALCONTROLLER; + +/// SW state info +typedef struct _ATOM_PPLIB_STATE_V2 { + UCHAR ATOM_PPLIB_STATE_V2_fld0; + UCHAR nonClockInfoIndex; ///< Index to the array of NonClockInfos + UCHAR ClockInfoIndex[1]; ///< Array of DPM states. Actual number calculated during state enumeration +} ATOM_PPLIB_STATE_V2; + +/// SW state Array +typedef struct { + UCHAR ucNumEntries; ///< Number of SW states + ATOM_PPLIB_STATE_V2 States[1]; ///< SW state info. Actual number calculated during state enumeration +} STATE_ARRAY; + +/// Clock info Array +typedef struct { + UCHAR ucNumEntries; ///< Number of ClockInfo entries + UCHAR ucEntrySize; + GfxPwrPlayTable143_STRUCT ClockInfo[1]; +} CLOCK_INFO_ARRAY; + +/// Non clock info Array +typedef struct { + + UCHAR ucNumEntries; ///< Number of Entries; + UCHAR ucEntrySize; ///< Size of NonClockInfo + ATOM_PPLIB_NONCLOCK_INFO NonClockInfo[1]; ///< Non clock info array +} NON_CLOCK_INFO_ARRAY; + +/// VCE clock info +typedef struct { + USHORT GfxPwrPlayTable204_STRUCT_fld0; + UCHAR GfxPwrPlayTable204_STRUCT_fld1; + USHORT usECClkLow; + UCHAR ucECClkHigh; +} GfxPwrPlayTable204_STRUCT; + +/// VCE clock info array +typedef struct { + UCHAR ucNumEntries; + GfxPwrPlayTable204_STRUCT entries[1]; +} VCECLOCKINFOARRAY; + +/// VCE voltage limit record +typedef struct { + USHORT usVoltage; ///< Voltage index + UCHAR ucVCEClockInfoIndex; ///< Index of VCE clock state +} ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD; + +/// VCE voltage limit table +typedef struct { + UCHAR numEntries; ///< Number of entries + ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD entries[1]; ///< Voltage limit state array +} ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE; + +/// VCE state record +typedef struct { + UCHAR ucVCEClockInfoIndex; ///< Index of VCE clock state + UCHAR ucClockInfoIndex; +} ATOM_PPLIB_VCE_STATE_RECORD; + +/// VCE state table +typedef struct { + UCHAR numEntries; ///< Number of state entries + ATOM_PPLIB_VCE_STATE_RECORD entries[1]; ///< State entries +} ATOM_PPLIB_VCE_STATE_TABLE; + +/// Extended header +typedef struct { + USHORT usSize; ///< size of header + ULONG rsv15; ///< reserved + ULONG rsv16; ///< reserved + USHORT usVCETableOffset; ///< offset of ATOM_PPLIB_VCE_TABLE + USHORT usUVDTableOffset; ///< offset of ATOM_PPLIB_UVD_TABLE + USHORT usSAMUTableOffset; ///< offset of ATOM_PPLIB_SAMU_TABLE + USHORT usPPMTableOffset; ///< offset of ATOM_PPLIB_PPM_TABLE + USHORT usACPTableOffset; ///< offset of ATOM_PPLIB_ACP_TABLE + USHORT usCACTDPTableOffset; ///< offset of ATOM_PPLIB_CACTDP_TABLE +} ATOM_PPLIB_EXTENDEDHEADER; + +/// VCE table +typedef struct { + UCHAR revid; ///< revision ID +} ATOM_PPLIB_VCE_TABLE; + + +typedef struct { + USHORT GfxPwrPlayTable261_STRUCT_fld0; + UCHAR GfxPwrPlayTable261_STRUCT_fld1; + USHORT GfxPwrPlayTable261_STRUCT_fld2; + UCHAR GfxPwrPlayTable261_STRUCT_fld3; +} GfxPwrPlayTable261_STRUCT; + +/// UVD clock info array +typedef struct { + UCHAR ucNumEntries; + GfxPwrPlayTable261_STRUCT entries[1]; +} GfxPwrPlayTable267_STRUCT; + +/// VCE voltage limit record +typedef struct { + USHORT usVoltage; ///< Voltage index + UCHAR ucUVDClockInfoIndex; ///< Index of VCE clock state +} ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD; + +/// VCE voltage limit table +typedef struct { + UCHAR numEntries; ///< Number of entries + ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD entries[1]; ///< Voltage limit state array +} UVD_CLK_VOLT_LIMIT_TABLE; + +/// UVD table +typedef struct { + UCHAR revid; ///< revision ID +} ATOM_PPLIB_UVD_TABLE; + +/// SAMU voltage limit record +typedef struct { + USHORT usVoltage; ///< voltage + USHORT usSAMClockLow; ///< SamClk low + UCHAR usSAMClockHigh; ///< SamClk high +} ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD; + +/// SAMU voltage limit table +typedef struct { + UCHAR numEntries; ///< number of entries + ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD entries[1]; ///< array of entries +} ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE; + +/// SAMU table +typedef struct { + UCHAR revid; ///< table revision id +// ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE limits; ///< offset of table +} ATOM_PPLIB_SAMU_TABLE; + +typedef struct { + USHORT GfxPwrPlayTable310_fld0; + UCHAR GfxPwrPlayTable310_fld1; + USHORT GfxPwrPlayTable310_fld2; +} GfxPwrPlayTable310_STRUCT; + +typedef struct { + UCHAR numEntries; + GfxPwrPlayTable310_STRUCT entries[1]; +} GfxPwrPlayTable316_STRUCT; + +#define ATOM_PPM_A_A 1 +#define ATOM_PPM_A_I 2 + +/// Power Play table +typedef struct _ATOM_PPLIB_POWERPLAYTABLE4 { + ATOM_COMMON_TABLE_HEADER sHeader; ///< Common header + UCHAR ucDataRevision; ///< Revision of PP table + UCHAR Reserved1[4]; ///< Reserved + USHORT usStateArrayOffset; ///< Offset from start of this table to array of ucNumStates ATOM_PPLIB_STATE structures + USHORT usClockInfoArrayOffset; ///< Offset from start of the table to ClockInfoArray + USHORT usNonClockInfoArrayOffset; ///< Offset from Start of the table to NonClockInfoArray + USHORT Reserved2[2]; ///< Reserved + USHORT usTableSize; ///< the size of this structure, or the extended structure + ULONG ulPlatformCaps; ///< See ATOM_PPLIB_CAPS_* + ATOM_PPLIB_THERMALCONTROLLER sThermalController; ///< Thermal controller stub. + USHORT Reserved4[2]; ///< Reserved + UCHAR Reserved5; ///< Reserved + USHORT Reserved6; ///< Reserved + USHORT usFormatID; ///< Format ID + USHORT Reserved7[1]; ///< Reserved + USHORT usExtendendedHeaderOffset; ///< Extended header offset + ULONG Reserved8[2]; ///< Reserved + USHORT ATOM_PPLIB_POWERPLAYTABLE4_fld17; + USHORT Reserved9[5]; ///< Reserved +} ATOM_PPLIB_POWERPLAYTABLE4; + +#pragma pack (pop) + + +AGESA_STATUS +GfxPwrPlayBuildTable ( + OUT VOID *Buffer, + IN GFX_PLATFORM_CONFIG *Gfx + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibKB.c new file mode 100644 index 0000000000..30ec1b368a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibKB.c @@ -0,0 +1,92 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "Ids.h" +#include "AlibSsdtKB.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_ALIBKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID * +PcieAlibGetBaseTableKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Get base SSDT table + * + * + * + * @param[in] StdHeader Standard Configuration Header + * @retval pointer to SSTD table + */ +VOID * +PcieAlibGetBaseTableKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return &AlibSsdtKB[0]; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibSsdtKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibSsdtKB.h new file mode 100644 index 0000000000..eb3c21f80d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibSsdtKB.h @@ -0,0 +1,3230 @@ +/** + * @file + * + * ALIB SSDT table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87932 $ @e \$Date: 2013-02-13 13:53:55 -0600 (Wed, 13 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _ALIBSSDTKB_H_ +#define _ALIBSSDTKB_H_ + +UINT8 AlibSsdtKB[] = { + 0x53, 0x53, 0x44, 0x54, 0x52, 0x63, 0x00, 0x00, + 0x02, 0x82, 0x41, 0x4D, 0x44, 0x00, 0x00, 0x00, + 0x41, 0x4C, 0x49, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x4D, 0x53, 0x46, 0x54, + 0x00, 0x00, 0x00, 0x04, 0x10, 0x8D, 0x32, 0x06, + 0x5C, 0x5F, 0x53, 0x42, 0x5F, 0x08, 0x41, 0x47, + 0x52, 0x42, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, + 0x41, 0x44, 0x42, 0x47, 0x11, 0x04, 0x0B, 0x00, + 0x01, 0x08, 0x41, 0x44, 0x41, 0x54, 0x11, 0x45, + 0x20, 0x0B, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x41, 0x17, 0x41, + 0x4C, 0x49, 0x42, 0x02, 0xA0, 0x40, 0x09, 0x93, + 0x68, 0x0A, 0x00, 0x70, 0x11, 0x04, 0x0B, 0x00, + 0x01, 0x60, 0x8B, 0x60, 0x0A, 0x00, 0x41, 0x30, + 0x32, 0x35, 0x70, 0x0A, 0x08, 0x41, 0x30, 0x32, + 0x35, 0x8B, 0x60, 0x0A, 0x02, 0x41, 0x30, 0x32, + 0x36, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x32, 0x36, + 0x8A, 0x60, 0x0A, 0x04, 0x41, 0x30, 0x32, 0x37, + 0xA0, 0x36, 0x94, 0x83, 0x88, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x0A, + 0x00, 0x00, 0x0A, 0x00, 0x70, 0x0D, 0x3D, 0x3D, + 0x3D, 0x20, 0x41, 0x4C, 0x49, 0x42, 0x20, 0x30, + 0x20, 0x2D, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, + 0x3D, 0x3D, 0x3D, 0x00, 0x5B, 0x31, 0x70, 0x0A, + 0x0F, 0x41, 0x30, 0x32, 0x37, 0xA4, 0x60, 0xA1, + 0x25, 0x70, 0x0D, 0x3D, 0x3D, 0x3D, 0x20, 0x41, + 0x4C, 0x49, 0x42, 0x20, 0x30, 0x20, 0x2D, 0x20, + 0x66, 0x61, 0x6C, 0x73, 0x65, 0x20, 0x3D, 0x3D, + 0x3D, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x01, 0x41, + 0x30, 0x32, 0x37, 0xA4, 0x60, 0xA0, 0x13, 0x93, + 0x68, 0x0A, 0x01, 0x70, 0x83, 0x88, 0x69, 0x0A, + 0x02, 0x00, 0x60, 0xA4, 0x41, 0x30, 0x32, 0x38, + 0x60, 0xA0, 0x26, 0x93, 0x68, 0x0A, 0x02, 0x70, + 0x0D, 0x3D, 0x3D, 0x3D, 0x20, 0x41, 0x4C, 0x49, + 0x42, 0x20, 0x32, 0x20, 0x2D, 0x20, 0x65, 0x6E, + 0x74, 0x65, 0x72, 0x20, 0x3D, 0x3D, 0x3D, 0x00, + 0x5B, 0x31, 0xA4, 0x41, 0x30, 0x32, 0x39, 0x69, + 0xA0, 0x2E, 0x93, 0x68, 0x0A, 0x03, 0x70, 0x83, + 0x88, 0x69, 0x0A, 0x02, 0x00, 0x60, 0x70, 0x0D, + 0x3D, 0x3D, 0x3D, 0x20, 0x41, 0x4C, 0x49, 0x42, + 0x20, 0x33, 0x20, 0x2D, 0x20, 0x65, 0x6E, 0x74, + 0x65, 0x72, 0x20, 0x3D, 0x3D, 0x3D, 0x00, 0x5B, + 0x31, 0xA4, 0x41, 0x30, 0x33, 0x30, 0x60, 0xA0, + 0x1C, 0x93, 0x68, 0x0A, 0x06, 0x70, 0x83, 0x88, + 0x69, 0x0A, 0x04, 0x00, 0x60, 0x70, 0x83, 0x88, + 0x69, 0x0A, 0x02, 0x00, 0x61, 0xA4, 0x41, 0x30, + 0x33, 0x33, 0x60, 0x61, 0xA0, 0x27, 0x93, 0x68, + 0x0A, 0x08, 0x70, 0x83, 0x88, 0x69, 0x0A, 0x02, + 0x00, 0x60, 0x70, 0x83, 0x88, 0x69, 0x0A, 0x03, + 0x00, 0x61, 0xA0, 0x0A, 0x93, 0x60, 0x0A, 0x01, + 0x41, 0x50, 0x54, 0x53, 0x61, 0xA1, 0x06, 0x41, + 0x57, 0x41, 0x4B, 0x61, 0xA0, 0x12, 0x93, 0x68, + 0x0A, 0x09, 0x70, 0x83, 0x88, 0x69, 0x0A, 0x02, + 0x00, 0x60, 0x41, 0x30, 0x33, 0x34, 0x60, 0xA0, + 0x13, 0x93, 0x68, 0x0A, 0x0A, 0x70, 0x83, 0x88, + 0x69, 0x0A, 0x02, 0x00, 0x60, 0xA4, 0x41, 0x30, + 0x33, 0x35, 0x60, 0xA4, 0x0A, 0x00, 0x14, 0x44, + 0x08, 0x41, 0x30, 0x33, 0x33, 0x02, 0x70, 0x0D, + 0x20, 0x48, 0x6F, 0x74, 0x70, 0x6C, 0x75, 0x67, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, 0x00, + 0x5B, 0x31, 0x70, 0x0A, 0x00, 0x60, 0xA2, 0x1E, + 0x95, 0x60, 0x0A, 0x05, 0x70, 0x41, 0x30, 0x39, + 0x36, 0x60, 0x69, 0x61, 0xA0, 0x0E, 0x93, 0x61, + 0x0A, 0x01, 0x70, 0x41, 0x30, 0x39, 0x37, 0x60, + 0x68, 0x61, 0xA5, 0x75, 0x60, 0x70, 0x11, 0x03, + 0x0A, 0x0A, 0x67, 0x8B, 0x67, 0x0A, 0x00, 0x41, + 0x30, 0x32, 0x35, 0x8C, 0x67, 0x0A, 0x02, 0x41, + 0x30, 0x33, 0x36, 0x8C, 0x67, 0x0A, 0x03, 0x41, + 0x30, 0x39, 0x38, 0x70, 0x0A, 0x04, 0x41, 0x30, + 0x32, 0x35, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x33, + 0x36, 0x70, 0x61, 0x41, 0x30, 0x39, 0x38, 0x70, + 0x0D, 0x20, 0x48, 0x6F, 0x74, 0x70, 0x6C, 0x75, + 0x67, 0x20, 0x45, 0x78, 0x69, 0x74, 0x00, 0x5B, + 0x31, 0xA4, 0x67, 0x14, 0x43, 0x0B, 0x41, 0x30, + 0x39, 0x36, 0x02, 0x70, 0x73, 0x0D, 0x20, 0x48, + 0x6F, 0x74, 0x70, 0x6C, 0x75, 0x67, 0x43, 0x68, + 0x65, 0x63, 0x6B, 0x50, 0x6F, 0x72, 0x74, 0x20, + 0x50, 0x6F, 0x72, 0x74, 0x20, 0x20, 0x00, 0x98, + 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, + 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x00, 0xA4, 0x5C, + 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, + 0x52, 0x30, 0x41, 0x42, 0x52, 0x30, 0x41, 0x30, + 0x38, 0x39, 0x69, 0xA0, 0x1A, 0x93, 0x68, 0x0A, + 0x01, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, + 0x31, 0x41, 0x30, 0x38, 0x39, 0x69, 0xA0, 0x1A, + 0x93, 0x68, 0x0A, 0x02, 0xA4, 0x5C, 0x2F, 0x04, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, + 0x41, 0x42, 0x52, 0x32, 0x41, 0x30, 0x38, 0x39, + 0x69, 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x03, 0xA4, + 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x33, 0x41, + 0x30, 0x38, 0x39, 0x69, 0xA0, 0x1A, 0x93, 0x68, + 0x0A, 0x04, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, + 0x52, 0x34, 0x41, 0x30, 0x38, 0x39, 0x69, 0x14, + 0x43, 0x0B, 0x41, 0x30, 0x39, 0x37, 0x02, 0x70, + 0x73, 0x0D, 0x20, 0x48, 0x6F, 0x74, 0x70, 0x6C, + 0x75, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6B, 0x50, + 0x6F, 0x72, 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, + 0x20, 0x20, 0x00, 0x98, 0x68, 0x00, 0x41, 0x44, + 0x42, 0x47, 0x5B, 0x31, 0xA0, 0x1A, 0x93, 0x68, + 0x0A, 0x00, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, + 0x52, 0x30, 0x41, 0x30, 0x39, 0x30, 0x69, 0xA0, + 0x1A, 0x93, 0x68, 0x0A, 0x01, 0xA4, 0x5C, 0x2F, + 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, + 0x30, 0x41, 0x42, 0x52, 0x31, 0x41, 0x30, 0x39, + 0x30, 0x69, 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x02, + 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x32, + 0x41, 0x30, 0x39, 0x30, 0x69, 0xA0, 0x1A, 0x93, + 0x68, 0x0A, 0x03, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x33, 0x41, 0x30, 0x39, 0x30, 0x69, + 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x04, 0xA4, 0x5C, + 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, + 0x52, 0x30, 0x41, 0x42, 0x52, 0x34, 0x41, 0x30, + 0x39, 0x30, 0x69, 0x08, 0x41, 0x44, 0x30, 0x30, + 0x0A, 0x00, 0x08, 0x44, 0x4B, 0x30, 0x30, 0x0A, + 0x00, 0x14, 0x42, 0x04, 0x41, 0x30, 0x32, 0x38, + 0x01, 0xA0, 0x0A, 0x93, 0x41, 0x44, 0x30, 0x30, + 0x68, 0xA4, 0x0A, 0x00, 0x70, 0x68, 0x41, 0x44, + 0x30, 0x30, 0x70, 0x73, 0x0D, 0x20, 0x41, 0x63, + 0x2F, 0x44, 0x63, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, + 0x64, 0x20, 0x74, 0x6F, 0x3A, 0x20, 0x00, 0x98, + 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, + 0x41, 0x30, 0x31, 0x31, 0x14, 0x35, 0x41, 0x30, + 0x33, 0x35, 0x01, 0x70, 0x68, 0x44, 0x4B, 0x30, + 0x30, 0x70, 0x73, 0x0D, 0x20, 0x44, 0x6F, 0x63, + 0x6B, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x64, 0x20, + 0x74, 0x6F, 0x3A, 0x20, 0x00, 0x98, 0x68, 0x00, + 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x41, 0x30, + 0x31, 0x36, 0x08, 0x41, 0x50, 0x30, 0x31, 0x0A, + 0x00, 0x08, 0x41, 0x50, 0x30, 0x32, 0x0A, 0x00, + 0x08, 0x41, 0x50, 0x30, 0x33, 0x0A, 0x00, 0x08, + 0x41, 0x50, 0x30, 0x35, 0x0A, 0x00, 0x08, 0x41, + 0x50, 0x30, 0x42, 0x0A, 0xFF, 0x08, 0x41, 0x50, + 0x31, 0x30, 0x0A, 0x00, 0x14, 0x41, 0x0B, 0x41, + 0x30, 0x32, 0x39, 0x01, 0x70, 0x11, 0x04, 0x0B, + 0x00, 0x01, 0x67, 0x8B, 0x67, 0x0A, 0x00, 0x41, + 0x30, 0x32, 0x35, 0x70, 0x0A, 0x03, 0x41, 0x30, + 0x32, 0x35, 0x8C, 0x67, 0x0A, 0x02, 0x41, 0x30, + 0x33, 0x36, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x33, + 0x36, 0xA0, 0x33, 0x93, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x0A, 0x00, 0x00, 0x0A, 0x01, 0x70, 0x0D, 0x70, + 0x73, 0x70, 0x70, 0x20, 0x70, 0x65, 0x72, 0x66, + 0x20, 0x30, 0x20, 0x2D, 0x20, 0x65, 0x78, 0x69, + 0x74, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x02, 0x41, + 0x30, 0x33, 0x36, 0xA4, 0x67, 0xA0, 0x32, 0x93, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x0A, 0x00, 0x00, 0x0A, + 0x00, 0x70, 0x0D, 0x70, 0x73, 0x70, 0x70, 0x20, + 0x6F, 0x66, 0x66, 0x20, 0x30, 0x20, 0x2D, 0x20, + 0x65, 0x78, 0x69, 0x74, 0x00, 0x5B, 0x31, 0x70, + 0x0A, 0x01, 0x41, 0x30, 0x33, 0x36, 0xA4, 0x67, + 0x41, 0x30, 0x33, 0x37, 0x68, 0xA0, 0x0B, 0x92, + 0x93, 0x41, 0x50, 0x30, 0x35, 0x0A, 0x01, 0xA4, + 0x67, 0x41, 0x30, 0x33, 0x38, 0x70, 0x0A, 0x02, + 0x41, 0x30, 0x33, 0x36, 0xA4, 0x67, 0x14, 0x2F, + 0x41, 0x30, 0x31, 0x32, 0x00, 0xA0, 0x17, 0x92, + 0x94, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x44, 0x41, 0x54, 0x0A, 0x00, 0x00, + 0x0A, 0x01, 0xA4, 0x0A, 0x00, 0xA0, 0x0C, 0x92, + 0x93, 0x41, 0x50, 0x30, 0x35, 0x0A, 0x01, 0xA4, + 0x0A, 0x00, 0x41, 0x30, 0x33, 0x38, 0x14, 0x13, + 0x41, 0x30, 0x33, 0x39, 0x01, 0xA0, 0x0C, 0x93, + 0x68, 0x0A, 0x03, 0x70, 0x0A, 0x00, 0x41, 0x50, + 0x30, 0x31, 0x14, 0x0D, 0x41, 0x30, 0x31, 0x30, + 0x01, 0x70, 0x0A, 0x01, 0x41, 0x50, 0x31, 0x30, + 0x14, 0x49, 0x09, 0x41, 0x30, 0x33, 0x30, 0x01, + 0x70, 0x73, 0x0D, 0x20, 0x50, 0x73, 0x70, 0x70, + 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x20, 0x5B, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5D, 0x20, + 0x00, 0x98, 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, + 0x5B, 0x31, 0x70, 0x68, 0x41, 0x50, 0x30, 0x35, + 0xA0, 0x17, 0x92, 0x94, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x0A, 0x00, 0x00, 0x0A, 0x01, 0xA4, 0x0A, 0x00, + 0x70, 0x41, 0x50, 0x30, 0x42, 0x61, 0xA0, 0x20, + 0x93, 0x41, 0x50, 0x30, 0x35, 0x0A, 0x00, 0x70, + 0x0A, 0x00, 0x60, 0xA2, 0x0C, 0x95, 0x60, 0x0A, + 0x05, 0x41, 0x30, 0x34, 0x30, 0x60, 0x75, 0x60, + 0x70, 0x0A, 0x00, 0x41, 0x50, 0x30, 0x42, 0x41, + 0x30, 0x33, 0x38, 0x70, 0x61, 0x41, 0x50, 0x30, + 0x42, 0x70, 0x11, 0x04, 0x0B, 0x00, 0x01, 0x67, + 0x70, 0x0A, 0x03, 0x88, 0x67, 0x0A, 0x00, 0x00, + 0x70, 0x0A, 0x00, 0x88, 0x67, 0x0A, 0x01, 0x00, + 0x70, 0x0A, 0x00, 0x88, 0x67, 0x0A, 0x02, 0x00, + 0xA4, 0x67, 0x14, 0x1A, 0x41, 0x30, 0x34, 0x31, + 0x00, 0xA0, 0x0E, 0x92, 0x93, 0x41, 0x50, 0x30, + 0x42, 0x0A, 0xFF, 0xA4, 0x41, 0x50, 0x30, 0x42, + 0xA4, 0x41, 0x44, 0x30, 0x30, 0x14, 0x47, 0x0D, + 0x41, 0x30, 0x33, 0x37, 0x01, 0x8B, 0x68, 0x0A, + 0x02, 0x41, 0x50, 0x30, 0x36, 0x8B, 0x68, 0x0A, + 0x04, 0x41, 0x50, 0x30, 0x37, 0x8B, 0x68, 0x0A, + 0x06, 0x41, 0x50, 0x30, 0x38, 0x8C, 0x68, 0x0A, + 0x08, 0x41, 0x50, 0x30, 0x39, 0x8C, 0x68, 0x0A, + 0x09, 0x41, 0x50, 0x30, 0x41, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x65, 0x72, 0x66, 0x52, 0x65, 0x71, + 0x20, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x49, + 0x64, 0x3A, 0x00, 0x98, 0x41, 0x50, 0x30, 0x36, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x65, 0x72, 0x66, 0x52, + 0x65, 0x71, 0x20, 0x54, 0x79, 0x70, 0x65, 0x3A, + 0x20, 0x20, 0x20, 0x20, 0x00, 0x98, 0x41, 0x50, + 0x30, 0x39, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x65, 0x72, + 0x66, 0x52, 0x65, 0x71, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x00, 0x98, + 0x41, 0x50, 0x30, 0x41, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x0A, 0x00, 0x60, 0xA2, + 0x3D, 0x95, 0x60, 0x0A, 0x05, 0xA0, 0x35, 0x93, + 0x41, 0x30, 0x34, 0x32, 0x60, 0x41, 0x50, 0x30, + 0x36, 0x0A, 0x01, 0xA0, 0x1B, 0x93, 0x7B, 0x41, + 0x50, 0x30, 0x37, 0x41, 0x50, 0x30, 0x38, 0x00, + 0x0A, 0x01, 0x70, 0x41, 0x30, 0x34, 0x33, 0x60, + 0x61, 0x41, 0x30, 0x34, 0x34, 0x60, 0x61, 0xA1, + 0x0A, 0x41, 0x30, 0x34, 0x34, 0x60, 0x41, 0x50, + 0x30, 0x41, 0xA5, 0x75, 0x60, 0x14, 0x2E, 0x41, + 0x30, 0x34, 0x35, 0x00, 0x70, 0x0A, 0x01, 0x41, + 0x50, 0x30, 0x32, 0x70, 0x0A, 0x00, 0x60, 0xA2, + 0x1C, 0x95, 0x60, 0x0A, 0x05, 0x70, 0x41, 0x30, + 0x34, 0x36, 0x60, 0x61, 0xA0, 0x0D, 0x94, 0x61, + 0x41, 0x50, 0x30, 0x32, 0x70, 0x61, 0x41, 0x50, + 0x30, 0x32, 0x75, 0x60, 0x14, 0x2E, 0x41, 0x30, + 0x34, 0x37, 0x00, 0x70, 0x0A, 0x00, 0x41, 0x50, + 0x30, 0x33, 0x70, 0x0A, 0x00, 0x60, 0xA2, 0x1C, + 0x95, 0x60, 0x0A, 0x05, 0x70, 0x41, 0x30, 0x34, + 0x38, 0x60, 0x61, 0xA0, 0x0D, 0x94, 0x61, 0x41, + 0x50, 0x30, 0x33, 0x70, 0x61, 0x41, 0x50, 0x30, + 0x33, 0x75, 0x60, 0x14, 0x46, 0x19, 0x41, 0x30, + 0x33, 0x38, 0x00, 0x70, 0x0D, 0x50, 0x73, 0x70, + 0x70, 0x50, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x45, 0x6E, + 0x74, 0x65, 0x72, 0x00, 0x5B, 0x31, 0x41, 0x30, + 0x34, 0x37, 0x70, 0x73, 0x0D, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x4F, 0x76, 0x65, + 0x72, 0x72, 0x69, 0x64, 0x65, 0x20, 0x20, 0x00, + 0x98, 0x41, 0x50, 0x30, 0x33, 0x00, 0x41, 0x44, + 0x42, 0x47, 0x5B, 0x31, 0x41, 0x30, 0x34, 0x35, + 0x70, 0x73, 0x0D, 0x20, 0x41, 0x67, 0x67, 0x72, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x20, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x20, 0x20, 0x53, + 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, 0x00, 0x98, + 0x41, 0x50, 0x30, 0x32, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x41, + 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, + 0x74, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, + 0x20, 0x00, 0x98, 0x41, 0x50, 0x30, 0x31, 0x00, + 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0xA0, 0x17, + 0x92, 0x93, 0x41, 0x50, 0x30, 0x32, 0x41, 0x50, + 0x30, 0x31, 0x41, 0x30, 0x31, 0x37, 0x41, 0x50, + 0x30, 0x32, 0x41, 0x50, 0x30, 0x31, 0xA0, 0x21, + 0x94, 0x41, 0x50, 0x30, 0x32, 0x41, 0x50, 0x30, + 0x31, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x30, 0x34, 0x39, 0x41, 0x50, 0x30, 0x32, 0x70, + 0x41, 0x50, 0x30, 0x32, 0x41, 0x50, 0x30, 0x31, + 0x70, 0x0A, 0x00, 0x60, 0xA2, 0x40, 0x05, 0x95, + 0x60, 0x0A, 0x05, 0x70, 0x41, 0x30, 0x34, 0x36, + 0x60, 0x61, 0x70, 0x41, 0x30, 0x35, 0x30, 0x60, + 0x62, 0xA0, 0x0B, 0x92, 0x93, 0x61, 0x62, 0x41, + 0x30, 0x35, 0x31, 0x60, 0x61, 0xA1, 0x2D, 0xA0, + 0x2B, 0x93, 0x41, 0x50, 0x31, 0x30, 0x0A, 0x01, + 0x70, 0x0D, 0x50, 0x6F, 0x72, 0x74, 0x20, 0x73, + 0x70, 0x65, 0x65, 0x64, 0x20, 0x63, 0x68, 0x61, + 0x6E, 0x67, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x63, + 0x65, 0x64, 0x00, 0x5B, 0x31, 0x41, 0x30, 0x35, + 0x31, 0x60, 0x61, 0x75, 0x60, 0xA0, 0x21, 0x95, + 0x41, 0x50, 0x30, 0x32, 0x41, 0x50, 0x30, 0x31, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, + 0x34, 0x39, 0x41, 0x50, 0x30, 0x32, 0x70, 0x41, + 0x50, 0x30, 0x32, 0x41, 0x50, 0x30, 0x31, 0xA1, + 0x21, 0xA0, 0x1F, 0x93, 0x41, 0x50, 0x31, 0x30, + 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x30, 0x34, 0x39, 0x41, 0x50, 0x30, 0x32, + 0x70, 0x41, 0x50, 0x30, 0x32, 0x41, 0x50, 0x30, + 0x31, 0x70, 0x0A, 0x00, 0x41, 0x50, 0x31, 0x30, + 0x70, 0x0D, 0x50, 0x73, 0x70, 0x70, 0x50, 0x72, + 0x6F, 0x63, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x20, 0x45, 0x78, 0x69, 0x74, 0x00, + 0x5B, 0x31, 0x14, 0x40, 0x0E, 0x41, 0x30, 0x35, + 0x31, 0x02, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x73, + 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x50, 0x6F, 0x72, 0x74, 0x53, 0x70, 0x65, + 0x65, 0x64, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x20, + 0x20, 0x00, 0x98, 0x68, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x65, 0x64, + 0x20, 0x20, 0x00, 0x98, 0x69, 0x00, 0x41, 0x44, + 0x42, 0x47, 0x5B, 0x31, 0xA0, 0x1A, 0x93, 0x68, + 0x0A, 0x00, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, + 0x52, 0x30, 0x41, 0x30, 0x35, 0x32, 0x69, 0xA0, + 0x1A, 0x93, 0x68, 0x0A, 0x01, 0xA4, 0x5C, 0x2F, + 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, + 0x30, 0x41, 0x42, 0x52, 0x31, 0x41, 0x30, 0x35, + 0x32, 0x69, 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x02, + 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x32, + 0x41, 0x30, 0x35, 0x32, 0x69, 0xA0, 0x1A, 0x93, + 0x68, 0x0A, 0x03, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x33, 0x41, 0x30, 0x35, 0x32, 0x69, + 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x04, 0xA4, 0x5C, + 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, + 0x52, 0x30, 0x41, 0x42, 0x52, 0x34, 0x41, 0x30, + 0x35, 0x32, 0x69, 0x14, 0x49, 0x08, 0x41, 0x30, + 0x35, 0x30, 0x01, 0xA0, 0x19, 0x93, 0x68, 0x0A, + 0x00, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, + 0x30, 0x41, 0x30, 0x35, 0x33, 0xA0, 0x19, 0x93, + 0x68, 0x0A, 0x01, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x31, 0x41, 0x30, 0x35, 0x33, 0xA0, + 0x19, 0x93, 0x68, 0x0A, 0x02, 0xA4, 0x5C, 0x2F, + 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, + 0x30, 0x41, 0x42, 0x52, 0x32, 0x41, 0x30, 0x35, + 0x33, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x03, 0xA4, + 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x33, 0x41, + 0x30, 0x35, 0x33, 0xA0, 0x19, 0x93, 0x68, 0x0A, + 0x04, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, + 0x34, 0x41, 0x30, 0x35, 0x33, 0x14, 0x49, 0x08, + 0x41, 0x30, 0x34, 0x36, 0x01, 0xA0, 0x19, 0x93, + 0x68, 0x0A, 0x00, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x30, 0x41, 0x30, 0x35, 0x34, 0xA0, + 0x19, 0x93, 0x68, 0x0A, 0x01, 0xA4, 0x5C, 0x2F, + 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, + 0x30, 0x41, 0x42, 0x52, 0x31, 0x41, 0x30, 0x35, + 0x34, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x02, 0xA4, + 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x32, 0x41, + 0x30, 0x35, 0x34, 0xA0, 0x19, 0x93, 0x68, 0x0A, + 0x03, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, + 0x33, 0x41, 0x30, 0x35, 0x34, 0xA0, 0x19, 0x93, + 0x68, 0x0A, 0x04, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x34, 0x41, 0x30, 0x35, 0x34, 0x14, + 0x49, 0x08, 0x41, 0x30, 0x34, 0x38, 0x01, 0xA0, + 0x19, 0x93, 0x68, 0x0A, 0x00, 0xA4, 0x5C, 0x2F, + 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, + 0x30, 0x41, 0x42, 0x52, 0x30, 0x41, 0x30, 0x35, + 0x35, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x01, 0xA4, + 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x31, 0x41, + 0x30, 0x35, 0x35, 0xA0, 0x19, 0x93, 0x68, 0x0A, + 0x02, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, + 0x32, 0x41, 0x30, 0x35, 0x35, 0xA0, 0x19, 0x93, + 0x68, 0x0A, 0x03, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x33, 0x41, 0x30, 0x35, 0x35, 0xA0, + 0x19, 0x93, 0x68, 0x0A, 0x04, 0xA4, 0x5C, 0x2F, + 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, + 0x30, 0x41, 0x42, 0x52, 0x34, 0x41, 0x30, 0x35, + 0x35, 0x14, 0x49, 0x08, 0x41, 0x30, 0x34, 0x33, + 0x01, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x00, 0xA4, + 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x30, 0x41, + 0x30, 0x35, 0x36, 0xA0, 0x19, 0x93, 0x68, 0x0A, + 0x01, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, + 0x31, 0x41, 0x30, 0x35, 0x36, 0xA0, 0x19, 0x93, + 0x68, 0x0A, 0x02, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x32, 0x41, 0x30, 0x35, 0x36, 0xA0, + 0x19, 0x93, 0x68, 0x0A, 0x03, 0xA4, 0x5C, 0x2F, + 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, + 0x30, 0x41, 0x42, 0x52, 0x33, 0x41, 0x30, 0x35, + 0x36, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x04, 0xA4, + 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x34, 0x41, + 0x30, 0x35, 0x36, 0x14, 0x45, 0x0B, 0x41, 0x30, + 0x34, 0x34, 0x02, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x73, 0x70, 0x70, 0x53, 0x65, 0x74, 0x50, 0x6F, + 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x20, 0x20, + 0x00, 0x98, 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, + 0x5B, 0x31, 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x00, + 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x30, + 0x41, 0x30, 0x35, 0x37, 0x69, 0xA0, 0x1A, 0x93, + 0x68, 0x0A, 0x01, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x31, 0x41, 0x30, 0x35, 0x37, 0x69, + 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x02, 0xA4, 0x5C, + 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, + 0x52, 0x30, 0x41, 0x42, 0x52, 0x32, 0x41, 0x30, + 0x35, 0x37, 0x69, 0xA0, 0x1A, 0x93, 0x68, 0x0A, + 0x03, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, + 0x33, 0x41, 0x30, 0x35, 0x37, 0x69, 0xA0, 0x1A, + 0x93, 0x68, 0x0A, 0x04, 0xA4, 0x5C, 0x2F, 0x04, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, + 0x41, 0x42, 0x52, 0x34, 0x41, 0x30, 0x35, 0x37, + 0x69, 0x14, 0x4E, 0x08, 0x41, 0x30, 0x34, 0x32, + 0x02, 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x00, 0xA4, + 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x30, 0x41, + 0x30, 0x35, 0x38, 0x69, 0xA0, 0x1A, 0x93, 0x68, + 0x0A, 0x01, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, + 0x52, 0x31, 0x41, 0x30, 0x35, 0x38, 0x69, 0xA0, + 0x1A, 0x93, 0x68, 0x0A, 0x02, 0xA4, 0x5C, 0x2F, + 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, + 0x30, 0x41, 0x42, 0x52, 0x32, 0x41, 0x30, 0x35, + 0x38, 0x69, 0xA0, 0x1A, 0x93, 0x68, 0x0A, 0x03, + 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x33, + 0x41, 0x30, 0x35, 0x38, 0x69, 0xA0, 0x1A, 0x93, + 0x68, 0x0A, 0x04, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, + 0x42, 0x52, 0x34, 0x41, 0x30, 0x35, 0x38, 0x69, + 0x14, 0x49, 0x08, 0x41, 0x30, 0x34, 0x30, 0x01, + 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x00, 0xA4, 0x5C, + 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, + 0x52, 0x30, 0x41, 0x42, 0x52, 0x30, 0x41, 0x30, + 0x35, 0x39, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x01, + 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x31, + 0x41, 0x30, 0x35, 0x39, 0xA0, 0x19, 0x93, 0x68, + 0x0A, 0x02, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, + 0x52, 0x32, 0x41, 0x30, 0x35, 0x39, 0xA0, 0x19, + 0x93, 0x68, 0x0A, 0x03, 0xA4, 0x5C, 0x2F, 0x04, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, + 0x41, 0x42, 0x52, 0x33, 0x41, 0x30, 0x35, 0x39, + 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x04, 0xA4, 0x5C, + 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, + 0x52, 0x30, 0x41, 0x42, 0x52, 0x34, 0x41, 0x30, + 0x35, 0x39, 0x14, 0x49, 0x08, 0x41, 0x30, 0x33, + 0x34, 0x01, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x00, + 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x30, + 0x41, 0x30, 0x36, 0x30, 0xA0, 0x19, 0x93, 0x68, + 0x0A, 0x01, 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, + 0x52, 0x31, 0x41, 0x30, 0x36, 0x30, 0xA0, 0x19, + 0x93, 0x68, 0x0A, 0x02, 0xA4, 0x5C, 0x2F, 0x04, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, 0x52, 0x30, + 0x41, 0x42, 0x52, 0x32, 0x41, 0x30, 0x36, 0x30, + 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x03, 0xA4, 0x5C, + 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x57, + 0x52, 0x30, 0x41, 0x42, 0x52, 0x33, 0x41, 0x30, + 0x36, 0x30, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x04, + 0xA4, 0x5C, 0x2F, 0x04, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x57, 0x52, 0x30, 0x41, 0x42, 0x52, 0x34, + 0x41, 0x30, 0x36, 0x30, 0x5B, 0x80, 0x41, 0x31, + 0x32, 0x30, 0x00, 0x72, 0x41, 0x47, 0x52, 0x42, + 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x0B, 0x00, + 0x10, 0x5B, 0x81, 0x18, 0x41, 0x31, 0x32, 0x30, + 0x01, 0x00, 0x40, 0x6E, 0x00, 0x13, 0x41, 0x30, + 0x32, 0x33, 0x07, 0x00, 0x46, 0x8E, 0x41, 0x30, + 0x30, 0x38, 0x01, 0x5B, 0x80, 0x41, 0x31, 0x32, + 0x31, 0x00, 0x72, 0x41, 0x47, 0x52, 0x42, 0x0C, + 0x00, 0x40, 0x0C, 0x00, 0x00, 0x0B, 0x00, 0x10, + 0x5B, 0x81, 0x2F, 0x41, 0x31, 0x32, 0x31, 0x01, + 0x00, 0x40, 0x92, 0x00, 0x16, 0x41, 0x30, 0x32, + 0x34, 0x01, 0x41, 0x31, 0x32, 0x32, 0x04, 0x00, + 0x05, 0x00, 0x05, 0x41, 0x30, 0x32, 0x30, 0x07, + 0x00, 0x44, 0x73, 0x00, 0x08, 0x41, 0x30, 0x32, + 0x32, 0x03, 0x00, 0x03, 0x41, 0x30, 0x32, 0x31, + 0x02, 0x5B, 0x81, 0x21, 0x41, 0x31, 0x32, 0x31, + 0x01, 0x00, 0x40, 0xAE, 0x00, 0x02, 0x41, 0x31, + 0x32, 0x33, 0x03, 0x00, 0x02, 0x41, 0x31, 0x32, + 0x34, 0x01, 0x00, 0x48, 0x07, 0x00, 0x03, 0x41, + 0x31, 0x32, 0x35, 0x01, 0x5B, 0x80, 0x41, 0x31, + 0x32, 0x36, 0x00, 0x72, 0x41, 0x47, 0x52, 0x42, + 0x0C, 0x00, 0x50, 0x0C, 0x00, 0x00, 0x0B, 0x00, + 0x10, 0x5B, 0x81, 0x10, 0x41, 0x31, 0x32, 0x36, + 0x01, 0x00, 0x40, 0xB8, 0x00, 0x0E, 0x41, 0x31, + 0x32, 0x37, 0x01, 0x5B, 0x80, 0x41, 0x31, 0x30, + 0x33, 0x00, 0x41, 0x47, 0x52, 0x42, 0x0B, 0x00, + 0x10, 0x5B, 0x81, 0x26, 0x41, 0x31, 0x30, 0x33, + 0x01, 0x00, 0x40, 0x30, 0x41, 0x31, 0x30, 0x34, + 0x20, 0x00, 0x40, 0x2A, 0x41, 0x31, 0x30, 0x35, + 0x20, 0x00, 0x40, 0x06, 0x41, 0x31, 0x30, 0x36, + 0x20, 0x00, 0x40, 0x16, 0x41, 0x31, 0x30, 0x37, + 0x20, 0x5B, 0x87, 0x17, 0x41, 0x31, 0x30, 0x33, + 0x41, 0x31, 0x30, 0x36, 0x0C, 0x01, 0x00, 0x21, + 0x00, 0x03, 0x00, 0x40, 0x36, 0x41, 0x31, 0x30, + 0x38, 0x01, 0x5B, 0x87, 0x1C, 0x41, 0x31, 0x30, + 0x33, 0x41, 0x31, 0x30, 0x35, 0x0C, 0x00, 0x00, + 0x10, 0xC2, 0x03, 0x00, 0x40, 0x5E, 0x41, 0x31, + 0x30, 0x39, 0x01, 0x41, 0x31, 0x31, 0x30, 0x10, + 0x5B, 0x87, 0x1C, 0x41, 0x31, 0x30, 0x33, 0x41, + 0x31, 0x30, 0x35, 0x0C, 0x04, 0x00, 0x10, 0xC2, + 0x03, 0x00, 0x40, 0x5E, 0x41, 0x31, 0x31, 0x31, + 0x01, 0x41, 0x31, 0x31, 0x32, 0x01, 0x5B, 0x87, + 0x17, 0x41, 0x31, 0x30, 0x33, 0x41, 0x31, 0x30, + 0x35, 0x0C, 0x3C, 0x00, 0x10, 0xC2, 0x03, 0x00, + 0x40, 0x5E, 0x41, 0x31, 0x31, 0x33, 0x20, 0x5B, + 0x87, 0x23, 0x41, 0x31, 0x30, 0x33, 0x41, 0x31, + 0x30, 0x35, 0x0C, 0xD8, 0xF9, 0x03, 0x00, 0x03, + 0x00, 0x40, 0x5E, 0x41, 0x31, 0x31, 0x34, 0x01, + 0x41, 0x31, 0x31, 0x35, 0x01, 0x00, 0x03, 0x41, + 0x31, 0x31, 0x36, 0x01, 0x5B, 0x87, 0x16, 0x41, + 0x31, 0x30, 0x33, 0x41, 0x31, 0x30, 0x37, 0x0A, + 0x00, 0x03, 0x00, 0x40, 0x7E, 0x00, 0x04, 0x41, + 0x31, 0x31, 0x37, 0x01, 0x5B, 0x80, 0x41, 0x31, + 0x31, 0x38, 0x00, 0x72, 0x41, 0x47, 0x52, 0x42, + 0x0B, 0x00, 0x80, 0x00, 0x0B, 0x00, 0x10, 0x5B, + 0x81, 0x0B, 0x41, 0x31, 0x31, 0x38, 0x03, 0x41, + 0x31, 0x31, 0x39, 0x20, 0x14, 0x48, 0x07, 0x41, + 0x30, 0x34, 0x39, 0x01, 0x70, 0x73, 0x0D, 0x20, + 0x50, 0x43, 0x49, 0x65, 0x20, 0x56, 0x49, 0x44, + 0x20, 0x3A, 0x00, 0x98, 0x68, 0x00, 0x41, 0x44, + 0x42, 0x47, 0x5B, 0x31, 0xA0, 0x16, 0x93, 0x68, + 0x0A, 0x01, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x0A, + 0x01, 0x00, 0x60, 0xA0, 0x16, 0x93, 0x68, 0x0A, + 0x02, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x0A, 0x02, + 0x00, 0x60, 0xA0, 0x09, 0x94, 0x60, 0x0A, 0xF7, + 0x70, 0x0A, 0xF7, 0x60, 0x70, 0x77, 0x0B, 0x71, + 0x02, 0x72, 0x74, 0x0A, 0xF7, 0x60, 0x61, 0x0A, + 0x01, 0x00, 0x00, 0x62, 0x78, 0x77, 0x62, 0x0A, + 0x04, 0x62, 0x0A, 0x64, 0x63, 0x64, 0x41, 0x31, + 0x32, 0x38, 0x0A, 0x3A, 0x64, 0x14, 0x06, 0x41, + 0x30, 0x39, 0x31, 0x03, 0x14, 0x42, 0x10, 0x41, + 0x31, 0x32, 0x38, 0x0A, 0x70, 0x0D, 0x20, 0x47, + 0x6E, 0x62, 0x53, 0x6D, 0x75, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x20, + 0x45, 0x6E, 0x74, 0x65, 0x72, 0x00, 0x5B, 0x31, + 0x70, 0x73, 0x0D, 0x20, 0x20, 0x53, 0x6D, 0x75, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x20, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x00, 0x98, + 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, + 0x70, 0x73, 0x0D, 0x20, 0x20, 0x53, 0x6D, 0x75, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, + 0x74, 0x20, 0x3D, 0x20, 0x00, 0x98, 0x69, 0x00, + 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0xA2, 0x20, + 0x92, 0x93, 0x41, 0x31, 0x31, 0x32, 0x0A, 0x01, + 0x70, 0x0D, 0x2D, 0x2D, 0x57, 0x61, 0x69, 0x74, + 0x20, 0x49, 0x6E, 0x69, 0x74, 0x20, 0x44, 0x6F, + 0x6E, 0x65, 0x2D, 0x2D, 0x00, 0x5B, 0x31, 0x70, + 0x69, 0x41, 0x31, 0x31, 0x33, 0x70, 0x68, 0x41, + 0x31, 0x31, 0x30, 0x80, 0x41, 0x31, 0x30, 0x39, + 0x41, 0x31, 0x30, 0x39, 0xA2, 0x1F, 0x92, 0x93, + 0x41, 0x31, 0x31, 0x31, 0x0A, 0x01, 0x70, 0x0D, + 0x2D, 0x2D, 0x57, 0x61, 0x69, 0x74, 0x20, 0x49, + 0x6E, 0x69, 0x74, 0x20, 0x41, 0x63, 0x6B, 0x2D, + 0x2D, 0x00, 0x5B, 0x31, 0xA2, 0x20, 0x92, 0x93, + 0x41, 0x31, 0x31, 0x32, 0x0A, 0x01, 0x70, 0x0D, + 0x2D, 0x2D, 0x57, 0x61, 0x69, 0x74, 0x20, 0x49, + 0x6E, 0x69, 0x74, 0x20, 0x44, 0x6F, 0x6E, 0x65, + 0x2D, 0x2D, 0x00, 0x5B, 0x31, 0x70, 0x41, 0x31, + 0x31, 0x33, 0x60, 0x70, 0x0D, 0x47, 0x6E, 0x62, + 0x53, 0x6D, 0x75, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x20, 0x45, 0x78, + 0x69, 0x74, 0x00, 0x5B, 0x31, 0xA4, 0x60, 0x14, + 0x1C, 0x41, 0x30, 0x36, 0x33, 0x01, 0xA0, 0x0C, + 0x93, 0x68, 0x0A, 0x01, 0x70, 0x0A, 0x00, 0x41, + 0x31, 0x30, 0x38, 0xA1, 0x08, 0x70, 0x0A, 0x01, + 0x41, 0x31, 0x30, 0x38, 0x14, 0x4A, 0x04, 0x41, + 0x30, 0x30, 0x36, 0x01, 0x70, 0x41, 0x31, 0x32, + 0x37, 0x60, 0xA0, 0x1F, 0x93, 0x68, 0x0A, 0x00, + 0x70, 0x0A, 0x01, 0x41, 0x31, 0x32, 0x37, 0x70, + 0x0D, 0x20, 0x4D, 0x65, 0x6D, 0x20, 0x50, 0x53, + 0x20, 0x4F, 0x46, 0x46, 0x21, 0x21, 0x21, 0x00, + 0x5B, 0x31, 0xA1, 0x1A, 0x70, 0x0A, 0x00, 0x41, + 0x31, 0x32, 0x37, 0x70, 0x0D, 0x20, 0x4D, 0x65, + 0x6D, 0x20, 0x50, 0x53, 0x20, 0x4F, 0x4E, 0x21, + 0x21, 0x21, 0x00, 0x5B, 0x31, 0xA4, 0x60, 0x08, + 0x41, 0x31, 0x32, 0x39, 0x0A, 0x00, 0x08, 0x41, + 0x31, 0x33, 0x30, 0x0A, 0x00, 0x14, 0x4A, 0x0B, + 0x41, 0x30, 0x30, 0x35, 0x01, 0xA0, 0x25, 0x93, + 0x41, 0x31, 0x32, 0x39, 0x0A, 0x00, 0xA0, 0x15, + 0x92, 0x93, 0x41, 0x31, 0x31, 0x39, 0x0C, 0xFF, + 0xFF, 0xFF, 0xFF, 0x70, 0x41, 0x31, 0x31, 0x35, + 0x41, 0x31, 0x33, 0x30, 0x70, 0x0A, 0x01, 0x41, + 0x31, 0x32, 0x39, 0xA0, 0x4C, 0x08, 0x93, 0x41, + 0x31, 0x33, 0x30, 0x0A, 0x01, 0xA0, 0x40, 0x06, + 0x93, 0x68, 0x0A, 0x00, 0xA0, 0x30, 0x93, 0x44, + 0x4B, 0x30, 0x30, 0x0A, 0x01, 0x70, 0x0D, 0x20, + 0x41, 0x43, 0x2F, 0x55, 0x6E, 0x64, 0x6F, 0x63, + 0x6B, 0x65, 0x64, 0x20, 0x73, 0x6F, 0x20, 0x65, + 0x6E, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x42, 0x41, + 0x50, 0x4D, 0x00, 0x5B, 0x31, 0x41, 0x31, 0x32, + 0x38, 0x0A, 0x30, 0x0A, 0x00, 0xA1, 0x28, 0x70, + 0x0D, 0x20, 0x41, 0x43, 0x2F, 0x44, 0x6F, 0x63, + 0x6B, 0x65, 0x64, 0x20, 0x73, 0x6F, 0x20, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x42, + 0x41, 0x50, 0x4D, 0x00, 0x5B, 0x31, 0x41, 0x31, + 0x32, 0x38, 0x0A, 0x31, 0x0A, 0x00, 0xA1, 0x21, + 0x70, 0x0D, 0x20, 0x44, 0x43, 0x20, 0x73, 0x6F, + 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, + 0x20, 0x42, 0x41, 0x50, 0x4D, 0x00, 0x5B, 0x31, + 0x41, 0x31, 0x32, 0x38, 0x0A, 0x31, 0x0A, 0x00, + 0x14, 0x39, 0x41, 0x31, 0x33, 0x31, 0x01, 0xA0, + 0x1A, 0x93, 0x68, 0x0A, 0x01, 0x70, 0x0D, 0x20, + 0x54, 0x44, 0x43, 0x3A, 0x20, 0x4F, 0x6E, 0x00, + 0x5B, 0x31, 0x41, 0x31, 0x32, 0x38, 0x0A, 0x2E, + 0x0A, 0x00, 0xA1, 0x17, 0x70, 0x0D, 0x20, 0x54, + 0x44, 0x43, 0x3A, 0x20, 0x4F, 0x66, 0x66, 0x00, + 0x5B, 0x31, 0x41, 0x31, 0x32, 0x38, 0x0A, 0x2F, + 0x0A, 0x00, 0x14, 0x3F, 0x41, 0x31, 0x33, 0x32, + 0x01, 0xA0, 0x1D, 0x93, 0x68, 0x0A, 0x01, 0x70, + 0x0D, 0x20, 0x50, 0x6B, 0x67, 0x50, 0x77, 0x72, + 0x3A, 0x20, 0x4F, 0x6E, 0x00, 0x5B, 0x31, 0x41, + 0x31, 0x32, 0x38, 0x0A, 0x51, 0x0A, 0x00, 0xA1, + 0x1A, 0x70, 0x0D, 0x20, 0x50, 0x6B, 0x67, 0x50, + 0x77, 0x72, 0x3A, 0x20, 0x4F, 0x66, 0x66, 0x00, + 0x5B, 0x31, 0x41, 0x31, 0x32, 0x38, 0x0A, 0x52, + 0x0A, 0x00, 0x14, 0x3F, 0x41, 0x31, 0x33, 0x33, + 0x01, 0xA0, 0x19, 0x93, 0x68, 0x0A, 0x01, 0x70, + 0x0D, 0x20, 0x56, 0x50, 0x43, 0x3A, 0x20, 0x4F, + 0x6E, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x01, 0x41, + 0x31, 0x31, 0x34, 0xA1, 0x16, 0x70, 0x0D, 0x20, + 0x56, 0x50, 0x43, 0x3A, 0x20, 0x4F, 0x66, 0x66, + 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x00, 0x41, 0x31, + 0x31, 0x34, 0x41, 0x31, 0x32, 0x38, 0x0A, 0x0C, + 0x0A, 0x00, 0x14, 0x46, 0x0D, 0x41, 0x30, 0x30, + 0x39, 0x01, 0xA0, 0x46, 0x05, 0x93, 0x68, 0x0A, + 0x01, 0x70, 0x0D, 0x20, 0x44, 0x50, 0x4D, 0x3A, + 0x20, 0x6E, 0x6F, 0x20, 0x6D, 0x61, 0x73, 0x6B, + 0x00, 0x5B, 0x31, 0x41, 0x31, 0x32, 0x38, 0x0A, + 0x58, 0x0A, 0x00, 0x70, 0x0D, 0x20, 0x43, 0x6C, + 0x72, 0x20, 0x54, 0x64, 0x70, 0x4C, 0x69, 0x6D, + 0x69, 0x74, 0x44, 0x69, 0x73, 0x00, 0x5B, 0x31, + 0x70, 0x0A, 0x00, 0x41, 0x31, 0x32, 0x35, 0x41, + 0x31, 0x33, 0x33, 0x0A, 0x01, 0x41, 0x31, 0x33, + 0x32, 0x0A, 0x01, 0x41, 0x31, 0x33, 0x31, 0x0A, + 0x01, 0x41, 0x30, 0x30, 0x35, 0x41, 0x44, 0x30, + 0x30, 0xA1, 0x4A, 0x06, 0x41, 0x30, 0x30, 0x35, + 0x41, 0x44, 0x30, 0x30, 0x41, 0x31, 0x33, 0x31, + 0x0A, 0x00, 0x41, 0x31, 0x33, 0x32, 0x0A, 0x00, + 0x41, 0x31, 0x33, 0x33, 0x0A, 0x00, 0x70, 0x0D, + 0x20, 0x53, 0x65, 0x74, 0x20, 0x54, 0x64, 0x70, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x44, 0x69, 0x73, + 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x01, 0x41, 0x31, + 0x32, 0x35, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x0A, + 0x04, 0x00, 0x60, 0x70, 0x73, 0x0D, 0x20, 0x20, + 0x44, 0x50, 0x4D, 0x20, 0x6D, 0x61, 0x73, 0x6B, + 0x20, 0x3D, 0x20, 0x00, 0x98, 0x60, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x41, 0x31, 0x32, + 0x38, 0x0A, 0x58, 0x60, 0x70, 0x0D, 0x20, 0x20, + 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x00, 0x5B, + 0x31, 0x14, 0x24, 0x41, 0x30, 0x30, 0x37, 0x01, + 0x70, 0x41, 0x31, 0x31, 0x37, 0x60, 0xA0, 0x0C, + 0x93, 0x68, 0x0A, 0x00, 0x70, 0x0A, 0x00, 0x41, + 0x31, 0x31, 0x37, 0xA1, 0x08, 0x70, 0x0A, 0x01, + 0x41, 0x31, 0x31, 0x37, 0xA4, 0x60, 0x5B, 0x80, + 0x50, 0x4D, 0x49, 0x4F, 0x01, 0x0B, 0xD6, 0x0C, + 0x0A, 0x02, 0x5B, 0x81, 0x10, 0x50, 0x4D, 0x49, + 0x4F, 0x01, 0x41, 0x30, 0x39, 0x39, 0x08, 0x41, + 0x31, 0x30, 0x30, 0x08, 0x5B, 0x86, 0x12, 0x41, + 0x30, 0x39, 0x39, 0x41, 0x31, 0x30, 0x30, 0x01, + 0x00, 0x40, 0x70, 0x41, 0x31, 0x30, 0x31, 0x20, + 0x5B, 0x80, 0x41, 0x43, 0x46, 0x47, 0x01, 0x41, + 0x31, 0x30, 0x31, 0x0A, 0x08, 0x5B, 0x81, 0x0B, + 0x41, 0x43, 0x46, 0x47, 0x03, 0x41, 0x31, 0x30, + 0x32, 0x20, 0x5B, 0x87, 0x16, 0x41, 0x43, 0x46, + 0x47, 0x41, 0x31, 0x30, 0x32, 0x0C, 0x68, 0x00, + 0x00, 0x80, 0x03, 0x00, 0x20, 0x41, 0x30, 0x37, + 0x30, 0x02, 0x08, 0x41, 0x42, 0x53, 0x4D, 0x0A, + 0x00, 0x14, 0x27, 0x41, 0x30, 0x36, 0x37, 0x01, + 0xA0, 0x15, 0x93, 0x68, 0x0A, 0x00, 0x70, 0x41, + 0x30, 0x37, 0x30, 0x41, 0x42, 0x53, 0x4D, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x30, 0xA1, 0x0A, + 0x70, 0x41, 0x42, 0x53, 0x4D, 0x41, 0x30, 0x37, + 0x30, 0x5B, 0x82, 0x8C, 0x83, 0x04, 0x41, 0x57, + 0x52, 0x30, 0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, + 0x41, 0xD0, 0x0C, 0x02, 0x08, 0x5F, 0x55, 0x49, + 0x44, 0x0A, 0x90, 0x08, 0x57, 0x52, 0x42, 0x53, + 0x0B, 0x30, 0x01, 0x5B, 0x82, 0x4A, 0xE6, 0x41, + 0x42, 0x52, 0x30, 0x08, 0x5F, 0x48, 0x49, 0x44, + 0x0C, 0x41, 0xD0, 0x0C, 0x02, 0x08, 0x5F, 0x55, + 0x49, 0x44, 0x0A, 0x80, 0x08, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x20, 0x08, 0x41, 0x42, 0x30, 0x30, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x31, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x45, 0x0A, 0x00, + 0x08, 0x41, 0x42, 0x30, 0x32, 0x0A, 0x00, 0x08, + 0x41, 0x42, 0x30, 0x33, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x34, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x35, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, + 0x36, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x37, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x38, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x39, 0x0A, 0x00, + 0x08, 0x41, 0x42, 0x30, 0x41, 0x0A, 0x00, 0x08, + 0x41, 0x42, 0x30, 0x42, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x43, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x44, 0x0A, 0x00, 0x5B, 0x80, 0x41, 0x30, + 0x38, 0x33, 0x00, 0x72, 0x41, 0x47, 0x52, 0x42, + 0x7D, 0x79, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x0D, 0x00, 0x00, 0x0A, + 0x0F, 0x00, 0x79, 0x83, 0x88, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, + 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0E, 0x00, 0x00, + 0x0A, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x10, + 0x5B, 0x81, 0x45, 0x04, 0x41, 0x30, 0x38, 0x33, + 0x01, 0x00, 0x40, 0x0C, 0x00, 0x08, 0x41, 0x30, + 0x37, 0x34, 0x08, 0x41, 0x30, 0x37, 0x35, 0x08, + 0x00, 0x48, 0x26, 0x41, 0x30, 0x37, 0x30, 0x02, + 0x00, 0x03, 0x41, 0x30, 0x37, 0x31, 0x01, 0x00, + 0x0A, 0x00, 0x0B, 0x41, 0x30, 0x37, 0x32, 0x01, + 0x00, 0x44, 0x0E, 0x41, 0x30, 0x38, 0x32, 0x04, + 0x00, 0x01, 0x41, 0x30, 0x37, 0x39, 0x01, 0x00, + 0x4A, 0x2B, 0x41, 0x30, 0x38, 0x34, 0x20, 0x5B, + 0x87, 0x16, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA1, 0x03, 0x00, 0x40, 0x72, + 0x00, 0x0C, 0x41, 0x30, 0x36, 0x36, 0x01, 0x5B, + 0x87, 0x16, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA2, 0x03, 0x00, 0x40, 0x72, + 0x00, 0x0D, 0x41, 0x30, 0x38, 0x31, 0x01, 0x5B, + 0x87, 0x27, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA4, 0x03, 0x00, 0x40, 0x72, + 0x41, 0x30, 0x37, 0x37, 0x01, 0x41, 0x30, 0x37, + 0x38, 0x01, 0x00, 0x0B, 0x41, 0x30, 0x37, 0x33, + 0x02, 0x00, 0x0E, 0x41, 0x30, 0x38, 0x30, 0x01, + 0x5B, 0x87, 0x14, 0x41, 0x30, 0x38, 0x33, 0x41, + 0x30, 0x38, 0x34, 0x0A, 0xA5, 0x03, 0x00, 0x40, + 0x72, 0x41, 0x30, 0x36, 0x35, 0x06, 0x5B, 0x80, + 0x41, 0x30, 0x38, 0x35, 0x00, 0x41, 0x47, 0x52, + 0x42, 0x0B, 0x00, 0x10, 0x5B, 0x81, 0x0E, 0x41, + 0x30, 0x38, 0x35, 0x01, 0x00, 0x40, 0x70, 0x41, + 0x30, 0x38, 0x36, 0x20, 0x5B, 0x87, 0x3C, 0x41, + 0x30, 0x38, 0x35, 0x41, 0x30, 0x38, 0x36, 0x7D, + 0x79, 0x5E, 0x57, 0x52, 0x42, 0x53, 0x0A, 0x10, + 0x00, 0x72, 0x0B, 0x00, 0x08, 0x77, 0x0B, 0x00, + 0x01, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, + 0x31, 0x32, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x40, 0x72, 0x41, 0x30, 0x38, + 0x37, 0x01, 0x5B, 0x87, 0x20, 0x41, 0x30, 0x38, + 0x35, 0x41, 0x30, 0x38, 0x36, 0x7D, 0x79, 0x5E, + 0x57, 0x52, 0x42, 0x53, 0x0A, 0x10, 0x00, 0x0B, + 0x29, 0x80, 0x00, 0x03, 0x00, 0x40, 0x72, 0x41, + 0x30, 0x38, 0x38, 0x10, 0x08, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x00, 0x14, 0x4D, 0x18, 0x5F, 0x49, + 0x4E, 0x49, 0x00, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x00, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x30, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x01, 0x00, 0x00, 0x41, 0x42, 0x30, 0x45, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x02, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x31, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x03, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x32, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x04, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x33, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x05, 0x00, 0x00, 0x41, 0x42, 0x30, 0x34, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x06, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x35, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x07, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x36, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x08, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x37, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x09, 0x00, 0x00, 0x41, 0x42, 0x30, 0x38, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x0A, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x39, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x0B, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x41, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0C, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x42, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x0D, 0x00, 0x00, 0x41, 0x42, 0x30, 0x43, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x0E, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x44, 0x14, 0x22, 0x41, 0x30, 0x36, 0x31, 0x00, + 0x70, 0x41, 0x30, 0x34, 0x31, 0x60, 0xA0, 0x0A, + 0x93, 0x60, 0x0A, 0x01, 0xA4, 0x41, 0x42, 0x30, + 0x31, 0xA0, 0x0A, 0x93, 0x60, 0x0A, 0x00, 0xA4, + 0x41, 0x42, 0x30, 0x45, 0x14, 0x1F, 0x41, 0x30, + 0x35, 0x35, 0x00, 0xA0, 0x15, 0x92, 0x93, 0x41, + 0x42, 0x31, 0x30, 0x0A, 0x00, 0xA0, 0x0B, 0x93, + 0x41, 0x42, 0x31, 0x30, 0x0A, 0x01, 0xA4, 0x0A, + 0x01, 0xA4, 0x0A, 0x00, 0x14, 0x2A, 0x41, 0x30, + 0x36, 0x32, 0x00, 0xA0, 0x0E, 0x92, 0x93, 0x41, + 0x42, 0x30, 0x35, 0x0A, 0x00, 0xA4, 0x41, 0x42, + 0x30, 0x35, 0xA0, 0x11, 0x94, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x01, 0xA4, 0x74, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x01, 0x00, 0xA4, 0x0A, 0x00, 0x14, + 0x49, 0x07, 0x41, 0x30, 0x35, 0x34, 0x00, 0xA0, + 0x22, 0x93, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x50, 0x30, 0x35, 0x0A, 0x00, 0xA0, 0x0E, + 0x92, 0x93, 0x41, 0x42, 0x30, 0x35, 0x0A, 0x00, + 0xA4, 0x41, 0x42, 0x30, 0x35, 0xA4, 0x41, 0x42, + 0x30, 0x45, 0x70, 0x41, 0x30, 0x36, 0x32, 0x60, + 0xA0, 0x17, 0x92, 0x93, 0x60, 0x0A, 0x00, 0xA0, + 0x0C, 0x94, 0x60, 0x41, 0x42, 0x30, 0x30, 0xA4, + 0x41, 0x42, 0x30, 0x30, 0xA1, 0x03, 0xA4, 0x60, + 0x70, 0x41, 0x30, 0x36, 0x31, 0x60, 0xA0, 0x28, + 0x92, 0x93, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x50, 0x30, 0x33, 0x0A, 0x00, 0xA0, 0x18, + 0x95, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x50, 0x30, 0x33, 0x60, 0xA4, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x33, 0xA4, + 0x60, 0x14, 0x0B, 0x41, 0x30, 0x35, 0x33, 0x00, + 0xA4, 0x41, 0x42, 0x30, 0x32, 0x14, 0x0B, 0x41, + 0x30, 0x35, 0x36, 0x00, 0xA4, 0x41, 0x42, 0x30, + 0x30, 0x14, 0x4B, 0x13, 0x41, 0x30, 0x35, 0x32, + 0x01, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x50, 0x6F, 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x00, + 0x98, 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x68, 0x41, 0x42, 0x30, 0x32, 0xA0, + 0x14, 0x93, 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, + 0x36, 0x33, 0x0A, 0x01, 0x41, 0x30, 0x36, 0x34, + 0x68, 0xA0, 0x40, 0x0B, 0x92, 0x95, 0x41, 0x30, + 0x36, 0x35, 0x0A, 0x10, 0xA0, 0x10, 0x92, 0x93, + 0x41, 0x42, 0x31, 0x30, 0x0A, 0x00, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x36, 0x36, 0xA1, 0x08, 0x70, + 0x0A, 0x01, 0x41, 0x30, 0x36, 0x36, 0xA0, 0x14, + 0x93, 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x36, + 0x37, 0x0A, 0x00, 0xA1, 0x07, 0x41, 0x30, 0x36, + 0x38, 0x0A, 0x00, 0x08, 0x41, 0x30, 0x36, 0x39, + 0x0A, 0x00, 0x70, 0x41, 0x30, 0x37, 0x30, 0x41, + 0x30, 0x36, 0x39, 0x70, 0x0A, 0x00, 0x41, 0x30, + 0x37, 0x30, 0x70, 0x0A, 0x01, 0x60, 0xA2, 0x2D, + 0x60, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, 0x31, + 0x5B, 0x22, 0x0A, 0x1E, 0xA2, 0x0C, 0x93, 0x41, + 0x30, 0x37, 0x32, 0x0A, 0x01, 0x5B, 0x22, 0x0A, + 0x0A, 0xA0, 0x0F, 0x93, 0x68, 0x0A, 0x01, 0xA0, + 0x09, 0x93, 0x41, 0x30, 0x37, 0x33, 0x0A, 0x00, + 0xA5, 0xA1, 0x02, 0xA5, 0x70, 0x41, 0x30, 0x36, + 0x39, 0x41, 0x30, 0x37, 0x30, 0xA0, 0x14, 0x93, + 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x36, 0x37, + 0x0A, 0x01, 0xA1, 0x07, 0x41, 0x30, 0x36, 0x38, + 0x0A, 0x01, 0xA0, 0x14, 0x93, 0x41, 0x42, 0x30, + 0x33, 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x30, 0x36, 0x33, 0x0A, 0x00, 0x70, + 0x0D, 0x50, 0x63, 0x69, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x50, 0x6F, 0x72, 0x74, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x45, 0x78, + 0x69, 0x74, 0x00, 0x5B, 0x31, 0x14, 0x28, 0x41, + 0x30, 0x35, 0x37, 0x01, 0x70, 0x73, 0x0D, 0x20, + 0x53, 0x65, 0x74, 0x20, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, + 0x70, 0x68, 0x41, 0x42, 0x31, 0x30, 0x14, 0x22, + 0x41, 0x30, 0x35, 0x38, 0x01, 0x7A, 0x68, 0x0A, + 0x08, 0x60, 0xA0, 0x13, 0x90, 0x92, 0x95, 0x60, + 0x41, 0x30, 0x37, 0x34, 0x92, 0x94, 0x60, 0x41, + 0x30, 0x37, 0x35, 0xA4, 0x0A, 0x01, 0xA4, 0x0A, + 0x00, 0x14, 0x1F, 0x41, 0x30, 0x37, 0x36, 0x01, + 0x7D, 0x41, 0x42, 0x30, 0x44, 0x79, 0x41, 0x42, + 0x30, 0x43, 0x0A, 0x03, 0x00, 0x60, 0xA0, 0x07, + 0x93, 0x68, 0x60, 0xA4, 0x0A, 0x01, 0xA4, 0x0A, + 0x00, 0x14, 0x0D, 0x41, 0x30, 0x35, 0x39, 0x00, + 0x70, 0x0A, 0x00, 0x41, 0x42, 0x31, 0x30, 0x14, + 0x42, 0x07, 0x41, 0x30, 0x36, 0x34, 0x01, 0xA0, + 0x0D, 0x92, 0x95, 0x68, 0x0A, 0x02, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x37, 0x37, 0xA0, 0x0D, 0x92, + 0x95, 0x68, 0x0A, 0x03, 0x70, 0x0A, 0x01, 0x41, + 0x30, 0x37, 0x38, 0xA0, 0x31, 0x93, 0x68, 0x0A, + 0x01, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, 0x39, + 0x70, 0x0A, 0x00, 0x41, 0x30, 0x37, 0x37, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x38, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x38, 0x30, 0xA0, 0x0F, 0x93, + 0x41, 0x42, 0x30, 0x34, 0x0A, 0x01, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x38, 0x31, 0xA1, 0x16, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x39, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x38, 0x30, 0x70, 0x0A, 0x00, + 0x41, 0x30, 0x38, 0x31, 0x70, 0x68, 0x41, 0x30, + 0x38, 0x32, 0x14, 0x41, 0x32, 0x41, 0x30, 0x36, + 0x30, 0x00, 0x70, 0x0D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x00, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x43, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x46, 0x75, 0x6E, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x44, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, 0x74, 0x41, + 0x63, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x45, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, + 0x74, 0x4D, 0x61, 0x78, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x30, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, + 0x6F, 0x72, 0x74, 0x41, 0x63, 0x53, 0x70, 0x65, + 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x45, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x50, 0x6F, 0x72, 0x74, 0x44, 0x63, 0x53, + 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x31, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, 0x74, 0x43, + 0x75, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x32, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x53, 0x62, 0x50, + 0x6F, 0x72, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x33, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x4C, + 0x69, 0x6E, 0x6B, 0x53, 0x61, 0x66, 0x65, 0x4D, + 0x6F, 0x64, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x34, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x4F, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x35, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x50, 0x68, 0x79, 0x4C, + 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x36, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x45, 0x6E, 0x64, 0x50, 0x68, 0x79, 0x4C, + 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x37, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x43, 0x6F, 0x72, 0x65, 0x4C, 0x61, 0x6E, 0x65, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x38, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x45, 0x6E, 0x64, + 0x43, 0x6F, 0x72, 0x65, 0x4C, 0x61, 0x6E, 0x65, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x39, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x6F, 0x72, 0x74, 0x49, 0x64, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x41, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x4C, 0x69, 0x6E, 0x6B, 0x48, 0x6F, 0x74, + 0x70, 0x6C, 0x75, 0x67, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x42, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x0D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x00, 0x5B, 0x31, 0x14, 0x42, 0x05, 0x41, + 0x30, 0x39, 0x34, 0x02, 0xA0, 0x11, 0x93, 0x41, + 0x30, 0x39, 0x33, 0x68, 0x0A, 0x00, 0x0C, 0xFF, + 0xFF, 0xFF, 0xFF, 0xA4, 0x0A, 0x00, 0x70, 0x41, + 0x30, 0x39, 0x33, 0x68, 0x0A, 0x34, 0x60, 0xA2, + 0x2F, 0x0A, 0x01, 0x70, 0x41, 0x30, 0x39, 0x33, + 0x68, 0x7B, 0x60, 0x0A, 0xFF, 0x00, 0x61, 0xA0, + 0x0E, 0x93, 0x7B, 0x61, 0x0A, 0xFF, 0x00, 0x69, + 0xA4, 0x7B, 0x60, 0x0A, 0xFF, 0x00, 0x7B, 0x7A, + 0x61, 0x0A, 0x08, 0x00, 0x0A, 0xFF, 0x60, 0xA0, + 0x07, 0x93, 0x60, 0x0A, 0x00, 0xA4, 0x60, 0x08, + 0x41, 0x45, 0x53, 0x50, 0x12, 0x12, 0x08, 0x0A, + 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, + 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x14, + 0x49, 0x0D, 0x41, 0x30, 0x36, 0x38, 0x01, 0x70, + 0x0D, 0x50, 0x63, 0x69, 0x65, 0x45, 0x70, 0x41, + 0x73, 0x70, 0x6D, 0x20, 0x45, 0x6E, 0x74, 0x65, + 0x72, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x00, 0x60, + 0xA0, 0x49, 0x08, 0x92, 0x93, 0x41, 0x30, 0x39, + 0x33, 0x60, 0x0A, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, + 0xFF, 0x7B, 0x41, 0x30, 0x39, 0x33, 0x60, 0x0A, + 0x08, 0x0A, 0x80, 0x61, 0xA0, 0x09, 0x93, 0x61, + 0x0A, 0x80, 0x70, 0x0A, 0x07, 0x67, 0xA1, 0x05, + 0x70, 0x0A, 0x00, 0x67, 0xA2, 0x4D, 0x05, 0x92, + 0x94, 0x60, 0x67, 0x70, 0x41, 0x30, 0x39, 0x34, + 0x60, 0x0A, 0x10, 0x61, 0xA0, 0x08, 0x93, 0x61, + 0x0A, 0x00, 0x75, 0x60, 0x9F, 0xA0, 0x2B, 0x93, + 0x68, 0x0A, 0x00, 0x70, 0x41, 0x30, 0x39, 0x33, + 0x60, 0x72, 0x61, 0x0A, 0x10, 0x00, 0x62, 0x41, + 0x30, 0x39, 0x35, 0x60, 0x72, 0x61, 0x0A, 0x10, + 0x00, 0x7B, 0x62, 0x80, 0x0A, 0x03, 0x00, 0x00, + 0x70, 0x62, 0x88, 0x41, 0x45, 0x53, 0x50, 0x60, + 0x00, 0xA1, 0x16, 0x70, 0x83, 0x88, 0x41, 0x45, + 0x53, 0x50, 0x60, 0x00, 0x62, 0x41, 0x30, 0x39, + 0x35, 0x60, 0x72, 0x61, 0x0A, 0x10, 0x00, 0x62, + 0x75, 0x60, 0xA1, 0x1A, 0x70, 0x0D, 0x45, 0x6E, + 0x64, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x6E, + 0x6F, 0x74, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6E, 0x74, 0x00, 0x5B, 0x31, 0x70, 0x0D, 0x50, + 0x63, 0x69, 0x65, 0x45, 0x70, 0x41, 0x73, 0x70, + 0x6D, 0x20, 0x45, 0x78, 0x69, 0x74, 0x00, 0x5B, + 0x31, 0x14, 0x3D, 0x41, 0x30, 0x39, 0x35, 0x0B, + 0x72, 0x41, 0x47, 0x52, 0x42, 0x79, 0x41, 0x30, + 0x37, 0x34, 0x0A, 0x14, 0x00, 0x60, 0x72, 0x60, + 0x79, 0x68, 0x0A, 0x0C, 0x00, 0x60, 0x72, 0x60, + 0x69, 0x60, 0x5B, 0x80, 0x41, 0x44, 0x52, 0x42, + 0x00, 0x60, 0x0A, 0x04, 0x5B, 0x81, 0x0B, 0x41, + 0x44, 0x52, 0x42, 0x03, 0x41, 0x44, 0x52, 0x52, + 0x20, 0x70, 0x6A, 0x41, 0x44, 0x52, 0x52, 0x14, + 0x3C, 0x41, 0x30, 0x39, 0x33, 0x0A, 0x72, 0x41, + 0x47, 0x52, 0x42, 0x79, 0x41, 0x30, 0x37, 0x34, + 0x0A, 0x14, 0x00, 0x60, 0x72, 0x60, 0x79, 0x68, + 0x0A, 0x0C, 0x00, 0x60, 0x72, 0x60, 0x69, 0x60, + 0x5B, 0x80, 0x41, 0x44, 0x52, 0x42, 0x00, 0x60, + 0x0A, 0x04, 0x5B, 0x81, 0x0B, 0x41, 0x44, 0x52, + 0x42, 0x03, 0x41, 0x44, 0x52, 0x52, 0x20, 0xA4, + 0x41, 0x44, 0x52, 0x52, 0x14, 0x19, 0x41, 0x30, + 0x38, 0x39, 0x01, 0xA0, 0x0C, 0x92, 0x93, 0x41, + 0x42, 0x30, 0x42, 0x0A, 0x01, 0xA4, 0x0A, 0x00, + 0xA4, 0x41, 0x30, 0x37, 0x36, 0x68, 0x14, 0x49, + 0x25, 0x41, 0x30, 0x39, 0x30, 0x01, 0x08, 0x41, + 0x30, 0x36, 0x39, 0x0A, 0x00, 0x70, 0x41, 0x30, + 0x37, 0x30, 0x41, 0x30, 0x36, 0x39, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x37, 0x30, 0xA0, 0x09, 0x93, + 0x68, 0x0A, 0x01, 0x70, 0x0A, 0x01, 0x60, 0xA1, + 0x05, 0x70, 0x0A, 0x05, 0x60, 0xA2, 0x46, 0x1E, + 0x92, 0x93, 0x60, 0x0A, 0x08, 0xA0, 0x41, 0x04, + 0x93, 0x60, 0x0A, 0x01, 0xA0, 0x15, 0x94, 0x41, + 0x42, 0x30, 0x45, 0x0A, 0x01, 0x70, 0x41, 0x42, + 0x30, 0x45, 0x41, 0x42, 0x30, 0x35, 0x41, 0x30, + 0x33, 0x38, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x30, 0x39, 0x31, 0x0A, 0x01, 0x41, 0x42, + 0x30, 0x36, 0x41, 0x42, 0x30, 0x37, 0x41, 0x30, + 0x39, 0x32, 0x0A, 0x01, 0x70, 0x0A, 0x00, 0x41, + 0x30, 0x38, 0x37, 0x70, 0x0A, 0x03, 0x60, 0xA0, + 0x4D, 0x04, 0x93, 0x60, 0x0A, 0x03, 0x70, 0x0A, + 0x00, 0x61, 0x70, 0x0A, 0x00, 0x62, 0xA2, 0x2E, + 0x95, 0x61, 0x0A, 0x3C, 0xA0, 0x22, 0x94, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x04, 0x70, 0x0D, 0x20, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x64, + 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x00, + 0x5B, 0x31, 0x70, 0x0A, 0x01, 0x62, 0xA5, 0x5B, + 0x22, 0x0A, 0x01, 0x75, 0x61, 0xA0, 0x09, 0x93, + 0x62, 0x0A, 0x01, 0x70, 0x0A, 0x04, 0x60, 0xA1, + 0x05, 0x70, 0x0A, 0x05, 0x60, 0xA0, 0x45, 0x06, + 0x93, 0x60, 0x0A, 0x04, 0x70, 0x0A, 0x00, 0x61, + 0x70, 0x0A, 0x00, 0x62, 0xA2, 0x37, 0x95, 0x61, + 0x0A, 0x50, 0xA0, 0x2B, 0x90, 0x92, 0x95, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x10, 0x92, 0x94, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x13, 0x70, 0x0D, 0x20, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x50, + 0x72, 0x65, 0x73, 0x65, 0x6E, 0x74, 0x00, 0x5B, + 0x31, 0x70, 0x0A, 0x01, 0x62, 0xA5, 0x5B, 0x22, + 0x0A, 0x01, 0x75, 0x61, 0xA0, 0x09, 0x93, 0x62, + 0x0A, 0x01, 0x70, 0x0A, 0x07, 0x60, 0xA1, 0x14, + 0xA0, 0x0C, 0x93, 0x41, 0x42, 0x30, 0x34, 0x0A, + 0x01, 0x70, 0x0A, 0x05, 0x60, 0xA1, 0x05, 0x70, + 0x0A, 0x06, 0x60, 0xA0, 0x45, 0x07, 0x93, 0x60, + 0x0A, 0x06, 0x70, 0x0A, 0x01, 0x41, 0x42, 0x30, + 0x34, 0x70, 0x0A, 0x01, 0x41, 0x42, 0x30, 0x35, + 0x41, 0x30, 0x36, 0x34, 0x0A, 0x01, 0xA0, 0x46, + 0x05, 0x5B, 0x12, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x4C, 0x49, 0x43, 0x66, 0x70, 0x0D, + 0x20, 0x43, 0x61, 0x6C, 0x6C, 0x20, 0x41, 0x4C, + 0x49, 0x43, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, + 0x64, 0x00, 0x5B, 0x31, 0x7D, 0x79, 0x41, 0x42, + 0x30, 0x43, 0x0A, 0x03, 0x00, 0x41, 0x42, 0x30, + 0x44, 0x61, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x4C, 0x49, 0x43, 0x61, 0x0A, 0x00, 0x5B, + 0x22, 0x0A, 0x02, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x4C, 0x49, 0x43, 0x61, 0x0A, 0x01, + 0x70, 0x0A, 0x03, 0x60, 0x9F, 0x70, 0x0A, 0x05, + 0x60, 0xA0, 0x44, 0x06, 0x93, 0x60, 0x0A, 0x05, + 0x70, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x50, 0x72, + 0x65, 0x73, 0x65, 0x6E, 0x74, 0x00, 0x5B, 0x31, + 0x41, 0x30, 0x39, 0x33, 0x0A, 0x00, 0x0A, 0x00, + 0x70, 0x0A, 0x01, 0x41, 0x30, 0x38, 0x37, 0x41, + 0x30, 0x39, 0x32, 0x0A, 0x00, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x30, 0x39, 0x31, 0x0A, + 0x00, 0x41, 0x42, 0x30, 0x36, 0x41, 0x42, 0x30, + 0x37, 0x70, 0x0A, 0x00, 0x41, 0x42, 0x30, 0x35, + 0x70, 0x0A, 0x00, 0x41, 0x42, 0x30, 0x34, 0x70, + 0x0A, 0x00, 0x41, 0x42, 0x31, 0x30, 0x70, 0x0A, + 0x00, 0x62, 0x70, 0x0A, 0x08, 0x60, 0xA0, 0x0D, + 0x93, 0x60, 0x0A, 0x07, 0x70, 0x0A, 0x01, 0x62, + 0x70, 0x0A, 0x08, 0x60, 0xA0, 0x0F, 0x93, 0x41, + 0x42, 0x30, 0x34, 0x0A, 0x00, 0x70, 0x0A, 0x00, + 0x41, 0x42, 0x30, 0x35, 0xA0, 0x28, 0x91, 0x94, + 0x41, 0x42, 0x30, 0x45, 0x0A, 0x01, 0x93, 0x41, + 0x50, 0x30, 0x35, 0x0A, 0x01, 0xA0, 0x17, 0x94, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x0A, 0x00, 0x00, 0x0A, + 0x01, 0x41, 0x30, 0x33, 0x38, 0x70, 0x41, 0x30, + 0x36, 0x39, 0x41, 0x30, 0x37, 0x30, 0xA4, 0x62, + 0x14, 0x46, 0x05, 0x41, 0x30, 0x39, 0x32, 0x01, + 0xA0, 0x14, 0x94, 0x41, 0x42, 0x30, 0x36, 0x41, + 0x42, 0x30, 0x37, 0x74, 0x41, 0x42, 0x30, 0x36, + 0x41, 0x42, 0x30, 0x37, 0x60, 0xA1, 0x0B, 0x74, + 0x41, 0x42, 0x30, 0x37, 0x41, 0x42, 0x30, 0x36, + 0x60, 0x75, 0x60, 0x79, 0x0A, 0x01, 0x60, 0x60, + 0x76, 0x60, 0x79, 0x60, 0x41, 0x42, 0x30, 0x38, + 0x60, 0xA0, 0x0F, 0x93, 0x68, 0x0A, 0x01, 0x7D, + 0x41, 0x30, 0x38, 0x38, 0x60, 0x41, 0x30, 0x38, + 0x38, 0xA1, 0x0D, 0x7B, 0x41, 0x30, 0x38, 0x38, + 0x80, 0x60, 0x00, 0x41, 0x30, 0x38, 0x38, 0x5B, + 0x82, 0x4A, 0xE6, 0x41, 0x42, 0x52, 0x31, 0x08, + 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0C, + 0x02, 0x08, 0x5F, 0x55, 0x49, 0x44, 0x0A, 0x81, + 0x08, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x34, 0x08, + 0x41, 0x42, 0x30, 0x30, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x31, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x45, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, + 0x32, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x33, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x34, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x35, 0x0A, 0x00, + 0x08, 0x41, 0x42, 0x30, 0x36, 0x0A, 0x00, 0x08, + 0x41, 0x42, 0x30, 0x37, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x38, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x39, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, + 0x41, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x42, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x43, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x44, 0x0A, 0x00, + 0x5B, 0x80, 0x41, 0x30, 0x38, 0x33, 0x00, 0x72, + 0x41, 0x47, 0x52, 0x42, 0x7D, 0x79, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x0D, 0x00, 0x00, 0x0A, 0x0F, 0x00, 0x79, 0x83, + 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, + 0x0A, 0x0E, 0x00, 0x00, 0x0A, 0x0C, 0x00, 0x00, + 0x00, 0x0B, 0x00, 0x10, 0x5B, 0x81, 0x45, 0x04, + 0x41, 0x30, 0x38, 0x33, 0x01, 0x00, 0x40, 0x0C, + 0x00, 0x08, 0x41, 0x30, 0x37, 0x34, 0x08, 0x41, + 0x30, 0x37, 0x35, 0x08, 0x00, 0x48, 0x26, 0x41, + 0x30, 0x37, 0x30, 0x02, 0x00, 0x03, 0x41, 0x30, + 0x37, 0x31, 0x01, 0x00, 0x0A, 0x00, 0x0B, 0x41, + 0x30, 0x37, 0x32, 0x01, 0x00, 0x44, 0x0E, 0x41, + 0x30, 0x38, 0x32, 0x04, 0x00, 0x01, 0x41, 0x30, + 0x37, 0x39, 0x01, 0x00, 0x4A, 0x2B, 0x41, 0x30, + 0x38, 0x34, 0x20, 0x5B, 0x87, 0x16, 0x41, 0x30, + 0x38, 0x33, 0x41, 0x30, 0x38, 0x34, 0x0A, 0xA1, + 0x03, 0x00, 0x40, 0x72, 0x00, 0x0C, 0x41, 0x30, + 0x36, 0x36, 0x01, 0x5B, 0x87, 0x16, 0x41, 0x30, + 0x38, 0x33, 0x41, 0x30, 0x38, 0x34, 0x0A, 0xA2, + 0x03, 0x00, 0x40, 0x72, 0x00, 0x0D, 0x41, 0x30, + 0x38, 0x31, 0x01, 0x5B, 0x87, 0x27, 0x41, 0x30, + 0x38, 0x33, 0x41, 0x30, 0x38, 0x34, 0x0A, 0xA4, + 0x03, 0x00, 0x40, 0x72, 0x41, 0x30, 0x37, 0x37, + 0x01, 0x41, 0x30, 0x37, 0x38, 0x01, 0x00, 0x0B, + 0x41, 0x30, 0x37, 0x33, 0x02, 0x00, 0x0E, 0x41, + 0x30, 0x38, 0x30, 0x01, 0x5B, 0x87, 0x14, 0x41, + 0x30, 0x38, 0x33, 0x41, 0x30, 0x38, 0x34, 0x0A, + 0xA5, 0x03, 0x00, 0x40, 0x72, 0x41, 0x30, 0x36, + 0x35, 0x06, 0x5B, 0x80, 0x41, 0x30, 0x38, 0x35, + 0x00, 0x41, 0x47, 0x52, 0x42, 0x0B, 0x00, 0x10, + 0x5B, 0x81, 0x0E, 0x41, 0x30, 0x38, 0x35, 0x01, + 0x00, 0x40, 0x70, 0x41, 0x30, 0x38, 0x36, 0x20, + 0x5B, 0x87, 0x3C, 0x41, 0x30, 0x38, 0x35, 0x41, + 0x30, 0x38, 0x36, 0x7D, 0x79, 0x5E, 0x57, 0x52, + 0x42, 0x53, 0x0A, 0x10, 0x00, 0x72, 0x0B, 0x00, + 0x08, 0x77, 0x0B, 0x00, 0x01, 0x83, 0x88, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, + 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, + 0x72, 0x41, 0x30, 0x38, 0x37, 0x01, 0x5B, 0x87, + 0x20, 0x41, 0x30, 0x38, 0x35, 0x41, 0x30, 0x38, + 0x36, 0x7D, 0x79, 0x5E, 0x57, 0x52, 0x42, 0x53, + 0x0A, 0x10, 0x00, 0x0B, 0x29, 0x80, 0x00, 0x03, + 0x00, 0x40, 0x72, 0x41, 0x30, 0x38, 0x38, 0x10, + 0x08, 0x41, 0x42, 0x31, 0x30, 0x0A, 0x00, 0x14, + 0x4D, 0x18, 0x5F, 0x49, 0x4E, 0x49, 0x00, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x00, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x30, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x01, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x45, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x02, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x31, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x03, 0x00, 0x00, 0x41, 0x42, 0x30, 0x32, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x04, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x33, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x05, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x34, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x06, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x35, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x07, 0x00, 0x00, 0x41, 0x42, 0x30, 0x36, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x08, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x37, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x09, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x38, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0A, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x39, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x0B, 0x00, 0x00, 0x41, 0x42, 0x30, 0x41, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x0C, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x42, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x0D, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x43, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0E, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x44, 0x14, 0x22, 0x41, + 0x30, 0x36, 0x31, 0x00, 0x70, 0x41, 0x30, 0x34, + 0x31, 0x60, 0xA0, 0x0A, 0x93, 0x60, 0x0A, 0x01, + 0xA4, 0x41, 0x42, 0x30, 0x31, 0xA0, 0x0A, 0x93, + 0x60, 0x0A, 0x00, 0xA4, 0x41, 0x42, 0x30, 0x45, + 0x14, 0x1F, 0x41, 0x30, 0x35, 0x35, 0x00, 0xA0, + 0x15, 0x92, 0x93, 0x41, 0x42, 0x31, 0x30, 0x0A, + 0x00, 0xA0, 0x0B, 0x93, 0x41, 0x42, 0x31, 0x30, + 0x0A, 0x01, 0xA4, 0x0A, 0x01, 0xA4, 0x0A, 0x00, + 0x14, 0x2A, 0x41, 0x30, 0x36, 0x32, 0x00, 0xA0, + 0x0E, 0x92, 0x93, 0x41, 0x42, 0x30, 0x35, 0x0A, + 0x00, 0xA4, 0x41, 0x42, 0x30, 0x35, 0xA0, 0x11, + 0x94, 0x41, 0x42, 0x31, 0x30, 0x0A, 0x01, 0xA4, + 0x74, 0x41, 0x42, 0x31, 0x30, 0x0A, 0x01, 0x00, + 0xA4, 0x0A, 0x00, 0x14, 0x49, 0x07, 0x41, 0x30, + 0x35, 0x34, 0x00, 0xA0, 0x22, 0x93, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x35, + 0x0A, 0x00, 0xA0, 0x0E, 0x92, 0x93, 0x41, 0x42, + 0x30, 0x35, 0x0A, 0x00, 0xA4, 0x41, 0x42, 0x30, + 0x35, 0xA4, 0x41, 0x42, 0x30, 0x45, 0x70, 0x41, + 0x30, 0x36, 0x32, 0x60, 0xA0, 0x17, 0x92, 0x93, + 0x60, 0x0A, 0x00, 0xA0, 0x0C, 0x94, 0x60, 0x41, + 0x42, 0x30, 0x30, 0xA4, 0x41, 0x42, 0x30, 0x30, + 0xA1, 0x03, 0xA4, 0x60, 0x70, 0x41, 0x30, 0x36, + 0x31, 0x60, 0xA0, 0x28, 0x92, 0x93, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x33, + 0x0A, 0x00, 0xA0, 0x18, 0x95, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x33, 0x60, + 0xA4, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x50, 0x30, 0x33, 0xA4, 0x60, 0x14, 0x0B, 0x41, + 0x30, 0x35, 0x33, 0x00, 0xA4, 0x41, 0x42, 0x30, + 0x32, 0x14, 0x0B, 0x41, 0x30, 0x35, 0x36, 0x00, + 0xA4, 0x41, 0x42, 0x30, 0x30, 0x14, 0x4B, 0x13, + 0x41, 0x30, 0x35, 0x32, 0x01, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x50, 0x6F, 0x72, 0x74, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x45, 0x6E, + 0x74, 0x65, 0x72, 0x20, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x3A, 0x20, 0x00, 0x98, 0x68, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x68, 0x41, + 0x42, 0x30, 0x32, 0xA0, 0x14, 0x93, 0x41, 0x42, + 0x30, 0x33, 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x30, 0x36, 0x33, 0x0A, 0x01, + 0x41, 0x30, 0x36, 0x34, 0x68, 0xA0, 0x40, 0x0B, + 0x92, 0x95, 0x41, 0x30, 0x36, 0x35, 0x0A, 0x10, + 0xA0, 0x10, 0x92, 0x93, 0x41, 0x42, 0x31, 0x30, + 0x0A, 0x00, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x36, + 0x36, 0xA1, 0x08, 0x70, 0x0A, 0x01, 0x41, 0x30, + 0x36, 0x36, 0xA0, 0x14, 0x93, 0x41, 0x42, 0x30, + 0x33, 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x30, 0x36, 0x37, 0x0A, 0x00, 0xA1, + 0x07, 0x41, 0x30, 0x36, 0x38, 0x0A, 0x00, 0x08, + 0x41, 0x30, 0x36, 0x39, 0x0A, 0x00, 0x70, 0x41, + 0x30, 0x37, 0x30, 0x41, 0x30, 0x36, 0x39, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x30, 0x70, 0x0A, + 0x01, 0x60, 0xA2, 0x2D, 0x60, 0x70, 0x0A, 0x01, + 0x41, 0x30, 0x37, 0x31, 0x5B, 0x22, 0x0A, 0x1E, + 0xA2, 0x0C, 0x93, 0x41, 0x30, 0x37, 0x32, 0x0A, + 0x01, 0x5B, 0x22, 0x0A, 0x0A, 0xA0, 0x0F, 0x93, + 0x68, 0x0A, 0x01, 0xA0, 0x09, 0x93, 0x41, 0x30, + 0x37, 0x33, 0x0A, 0x00, 0xA5, 0xA1, 0x02, 0xA5, + 0x70, 0x41, 0x30, 0x36, 0x39, 0x41, 0x30, 0x37, + 0x30, 0xA0, 0x14, 0x93, 0x41, 0x42, 0x30, 0x33, + 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x30, 0x36, 0x37, 0x0A, 0x01, 0xA1, 0x07, + 0x41, 0x30, 0x36, 0x38, 0x0A, 0x01, 0xA0, 0x14, + 0x93, 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x36, + 0x33, 0x0A, 0x00, 0x70, 0x0D, 0x50, 0x63, 0x69, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x50, 0x6F, 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x20, 0x45, 0x78, 0x69, 0x74, 0x00, 0x5B, + 0x31, 0x14, 0x28, 0x41, 0x30, 0x35, 0x37, 0x01, + 0x70, 0x73, 0x0D, 0x20, 0x53, 0x65, 0x74, 0x20, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x68, 0x00, 0x41, 0x44, + 0x42, 0x47, 0x5B, 0x31, 0x70, 0x68, 0x41, 0x42, + 0x31, 0x30, 0x14, 0x22, 0x41, 0x30, 0x35, 0x38, + 0x01, 0x7A, 0x68, 0x0A, 0x08, 0x60, 0xA0, 0x13, + 0x90, 0x92, 0x95, 0x60, 0x41, 0x30, 0x37, 0x34, + 0x92, 0x94, 0x60, 0x41, 0x30, 0x37, 0x35, 0xA4, + 0x0A, 0x01, 0xA4, 0x0A, 0x00, 0x14, 0x1F, 0x41, + 0x30, 0x37, 0x36, 0x01, 0x7D, 0x41, 0x42, 0x30, + 0x44, 0x79, 0x41, 0x42, 0x30, 0x43, 0x0A, 0x03, + 0x00, 0x60, 0xA0, 0x07, 0x93, 0x68, 0x60, 0xA4, + 0x0A, 0x01, 0xA4, 0x0A, 0x00, 0x14, 0x0D, 0x41, + 0x30, 0x35, 0x39, 0x00, 0x70, 0x0A, 0x00, 0x41, + 0x42, 0x31, 0x30, 0x14, 0x42, 0x07, 0x41, 0x30, + 0x36, 0x34, 0x01, 0xA0, 0x0D, 0x92, 0x95, 0x68, + 0x0A, 0x02, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, + 0x37, 0xA0, 0x0D, 0x92, 0x95, 0x68, 0x0A, 0x03, + 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, 0x38, 0xA0, + 0x31, 0x93, 0x68, 0x0A, 0x01, 0x70, 0x0A, 0x01, + 0x41, 0x30, 0x37, 0x39, 0x70, 0x0A, 0x00, 0x41, + 0x30, 0x37, 0x37, 0x70, 0x0A, 0x00, 0x41, 0x30, + 0x37, 0x38, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x38, + 0x30, 0xA0, 0x0F, 0x93, 0x41, 0x42, 0x30, 0x34, + 0x0A, 0x01, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x38, + 0x31, 0xA1, 0x16, 0x70, 0x0A, 0x00, 0x41, 0x30, + 0x37, 0x39, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x38, + 0x30, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x38, 0x31, + 0x70, 0x68, 0x41, 0x30, 0x38, 0x32, 0x14, 0x41, + 0x32, 0x41, 0x30, 0x36, 0x30, 0x00, 0x70, 0x0D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x00, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x43, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x44, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, + 0x6F, 0x72, 0x74, 0x41, 0x63, 0x53, 0x70, 0x65, + 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x45, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x50, 0x6F, 0x72, 0x74, 0x4D, 0x61, 0x78, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x30, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, 0x74, 0x41, + 0x63, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x45, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, + 0x74, 0x44, 0x63, 0x53, 0x70, 0x65, 0x65, 0x64, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x31, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, + 0x6F, 0x72, 0x74, 0x43, 0x75, 0x72, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x32, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x53, 0x62, 0x50, 0x6F, 0x72, 0x74, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x33, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x4C, 0x69, 0x6E, 0x6B, 0x53, + 0x61, 0x66, 0x65, 0x4D, 0x6F, 0x64, 0x65, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x34, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x4C, 0x6F, 0x63, + 0x61, 0x6C, 0x4F, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x35, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x50, 0x68, 0x79, 0x4C, 0x61, 0x6E, 0x65, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x36, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x45, 0x6E, 0x64, + 0x50, 0x68, 0x79, 0x4C, 0x61, 0x6E, 0x65, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x37, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x72, 0x65, + 0x4C, 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x38, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x45, 0x6E, 0x64, 0x43, 0x6F, 0x72, 0x65, + 0x4C, 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x39, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x49, + 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x41, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x4C, 0x69, 0x6E, + 0x6B, 0x48, 0x6F, 0x74, 0x70, 0x6C, 0x75, 0x67, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x42, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x0D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x00, 0x5B, 0x31, + 0x14, 0x42, 0x05, 0x41, 0x30, 0x39, 0x34, 0x02, + 0xA0, 0x11, 0x93, 0x41, 0x30, 0x39, 0x33, 0x68, + 0x0A, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, + 0x0A, 0x00, 0x70, 0x41, 0x30, 0x39, 0x33, 0x68, + 0x0A, 0x34, 0x60, 0xA2, 0x2F, 0x0A, 0x01, 0x70, + 0x41, 0x30, 0x39, 0x33, 0x68, 0x7B, 0x60, 0x0A, + 0xFF, 0x00, 0x61, 0xA0, 0x0E, 0x93, 0x7B, 0x61, + 0x0A, 0xFF, 0x00, 0x69, 0xA4, 0x7B, 0x60, 0x0A, + 0xFF, 0x00, 0x7B, 0x7A, 0x61, 0x0A, 0x08, 0x00, + 0x0A, 0xFF, 0x60, 0xA0, 0x07, 0x93, 0x60, 0x0A, + 0x00, 0xA4, 0x60, 0x08, 0x41, 0x45, 0x53, 0x50, + 0x12, 0x12, 0x08, 0x0A, 0x00, 0x0A, 0x00, 0x0A, + 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, + 0x00, 0x0A, 0x00, 0x14, 0x49, 0x0D, 0x41, 0x30, + 0x36, 0x38, 0x01, 0x70, 0x0D, 0x50, 0x63, 0x69, + 0x65, 0x45, 0x70, 0x41, 0x73, 0x70, 0x6D, 0x20, + 0x45, 0x6E, 0x74, 0x65, 0x72, 0x00, 0x5B, 0x31, + 0x70, 0x0A, 0x00, 0x60, 0xA0, 0x49, 0x08, 0x92, + 0x93, 0x41, 0x30, 0x39, 0x33, 0x60, 0x0A, 0x00, + 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0x7B, 0x41, 0x30, + 0x39, 0x33, 0x60, 0x0A, 0x08, 0x0A, 0x80, 0x61, + 0xA0, 0x09, 0x93, 0x61, 0x0A, 0x80, 0x70, 0x0A, + 0x07, 0x67, 0xA1, 0x05, 0x70, 0x0A, 0x00, 0x67, + 0xA2, 0x4D, 0x05, 0x92, 0x94, 0x60, 0x67, 0x70, + 0x41, 0x30, 0x39, 0x34, 0x60, 0x0A, 0x10, 0x61, + 0xA0, 0x08, 0x93, 0x61, 0x0A, 0x00, 0x75, 0x60, + 0x9F, 0xA0, 0x2B, 0x93, 0x68, 0x0A, 0x00, 0x70, + 0x41, 0x30, 0x39, 0x33, 0x60, 0x72, 0x61, 0x0A, + 0x10, 0x00, 0x62, 0x41, 0x30, 0x39, 0x35, 0x60, + 0x72, 0x61, 0x0A, 0x10, 0x00, 0x7B, 0x62, 0x80, + 0x0A, 0x03, 0x00, 0x00, 0x70, 0x62, 0x88, 0x41, + 0x45, 0x53, 0x50, 0x60, 0x00, 0xA1, 0x16, 0x70, + 0x83, 0x88, 0x41, 0x45, 0x53, 0x50, 0x60, 0x00, + 0x62, 0x41, 0x30, 0x39, 0x35, 0x60, 0x72, 0x61, + 0x0A, 0x10, 0x00, 0x62, 0x75, 0x60, 0xA1, 0x1A, + 0x70, 0x0D, 0x45, 0x6E, 0x64, 0x70, 0x6F, 0x69, + 0x6E, 0x74, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6E, 0x74, 0x00, 0x5B, + 0x31, 0x70, 0x0D, 0x50, 0x63, 0x69, 0x65, 0x45, + 0x70, 0x41, 0x73, 0x70, 0x6D, 0x20, 0x45, 0x78, + 0x69, 0x74, 0x00, 0x5B, 0x31, 0x14, 0x3D, 0x41, + 0x30, 0x39, 0x35, 0x0B, 0x72, 0x41, 0x47, 0x52, + 0x42, 0x79, 0x41, 0x30, 0x37, 0x34, 0x0A, 0x14, + 0x00, 0x60, 0x72, 0x60, 0x79, 0x68, 0x0A, 0x0C, + 0x00, 0x60, 0x72, 0x60, 0x69, 0x60, 0x5B, 0x80, + 0x41, 0x44, 0x52, 0x42, 0x00, 0x60, 0x0A, 0x04, + 0x5B, 0x81, 0x0B, 0x41, 0x44, 0x52, 0x42, 0x03, + 0x41, 0x44, 0x52, 0x52, 0x20, 0x70, 0x6A, 0x41, + 0x44, 0x52, 0x52, 0x14, 0x3C, 0x41, 0x30, 0x39, + 0x33, 0x0A, 0x72, 0x41, 0x47, 0x52, 0x42, 0x79, + 0x41, 0x30, 0x37, 0x34, 0x0A, 0x14, 0x00, 0x60, + 0x72, 0x60, 0x79, 0x68, 0x0A, 0x0C, 0x00, 0x60, + 0x72, 0x60, 0x69, 0x60, 0x5B, 0x80, 0x41, 0x44, + 0x52, 0x42, 0x00, 0x60, 0x0A, 0x04, 0x5B, 0x81, + 0x0B, 0x41, 0x44, 0x52, 0x42, 0x03, 0x41, 0x44, + 0x52, 0x52, 0x20, 0xA4, 0x41, 0x44, 0x52, 0x52, + 0x14, 0x19, 0x41, 0x30, 0x38, 0x39, 0x01, 0xA0, + 0x0C, 0x92, 0x93, 0x41, 0x42, 0x30, 0x42, 0x0A, + 0x01, 0xA4, 0x0A, 0x00, 0xA4, 0x41, 0x30, 0x37, + 0x36, 0x68, 0x14, 0x49, 0x25, 0x41, 0x30, 0x39, + 0x30, 0x01, 0x08, 0x41, 0x30, 0x36, 0x39, 0x0A, + 0x00, 0x70, 0x41, 0x30, 0x37, 0x30, 0x41, 0x30, + 0x36, 0x39, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x37, + 0x30, 0xA0, 0x09, 0x93, 0x68, 0x0A, 0x01, 0x70, + 0x0A, 0x01, 0x60, 0xA1, 0x05, 0x70, 0x0A, 0x05, + 0x60, 0xA2, 0x46, 0x1E, 0x92, 0x93, 0x60, 0x0A, + 0x08, 0xA0, 0x41, 0x04, 0x93, 0x60, 0x0A, 0x01, + 0xA0, 0x15, 0x94, 0x41, 0x42, 0x30, 0x45, 0x0A, + 0x01, 0x70, 0x41, 0x42, 0x30, 0x45, 0x41, 0x42, + 0x30, 0x35, 0x41, 0x30, 0x33, 0x38, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x39, 0x31, + 0x0A, 0x01, 0x41, 0x42, 0x30, 0x36, 0x41, 0x42, + 0x30, 0x37, 0x41, 0x30, 0x39, 0x32, 0x0A, 0x01, + 0x70, 0x0A, 0x00, 0x41, 0x30, 0x38, 0x37, 0x70, + 0x0A, 0x03, 0x60, 0xA0, 0x4D, 0x04, 0x93, 0x60, + 0x0A, 0x03, 0x70, 0x0A, 0x00, 0x61, 0x70, 0x0A, + 0x00, 0x62, 0xA2, 0x2E, 0x95, 0x61, 0x0A, 0x3C, + 0xA0, 0x22, 0x94, 0x41, 0x30, 0x36, 0x35, 0x0A, + 0x04, 0x70, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x20, 0x64, 0x65, 0x74, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x00, 0x5B, 0x31, 0x70, 0x0A, + 0x01, 0x62, 0xA5, 0x5B, 0x22, 0x0A, 0x01, 0x75, + 0x61, 0xA0, 0x09, 0x93, 0x62, 0x0A, 0x01, 0x70, + 0x0A, 0x04, 0x60, 0xA1, 0x05, 0x70, 0x0A, 0x05, + 0x60, 0xA0, 0x45, 0x06, 0x93, 0x60, 0x0A, 0x04, + 0x70, 0x0A, 0x00, 0x61, 0x70, 0x0A, 0x00, 0x62, + 0xA2, 0x37, 0x95, 0x61, 0x0A, 0x50, 0xA0, 0x2B, + 0x90, 0x92, 0x95, 0x41, 0x30, 0x36, 0x35, 0x0A, + 0x10, 0x92, 0x94, 0x41, 0x30, 0x36, 0x35, 0x0A, + 0x13, 0x70, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x20, 0x50, 0x72, 0x65, 0x73, 0x65, + 0x6E, 0x74, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x01, + 0x62, 0xA5, 0x5B, 0x22, 0x0A, 0x01, 0x75, 0x61, + 0xA0, 0x09, 0x93, 0x62, 0x0A, 0x01, 0x70, 0x0A, + 0x07, 0x60, 0xA1, 0x14, 0xA0, 0x0C, 0x93, 0x41, + 0x42, 0x30, 0x34, 0x0A, 0x01, 0x70, 0x0A, 0x05, + 0x60, 0xA1, 0x05, 0x70, 0x0A, 0x06, 0x60, 0xA0, + 0x45, 0x07, 0x93, 0x60, 0x0A, 0x06, 0x70, 0x0A, + 0x01, 0x41, 0x42, 0x30, 0x34, 0x70, 0x0A, 0x01, + 0x41, 0x42, 0x30, 0x35, 0x41, 0x30, 0x36, 0x34, + 0x0A, 0x01, 0xA0, 0x46, 0x05, 0x5B, 0x12, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x4C, 0x49, + 0x43, 0x66, 0x70, 0x0D, 0x20, 0x43, 0x61, 0x6C, + 0x6C, 0x20, 0x41, 0x4C, 0x49, 0x43, 0x20, 0x6D, + 0x65, 0x74, 0x68, 0x6F, 0x64, 0x00, 0x5B, 0x31, + 0x7D, 0x79, 0x41, 0x42, 0x30, 0x43, 0x0A, 0x03, + 0x00, 0x41, 0x42, 0x30, 0x44, 0x61, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x4C, 0x49, 0x43, + 0x61, 0x0A, 0x00, 0x5B, 0x22, 0x0A, 0x02, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x4C, 0x49, + 0x43, 0x61, 0x0A, 0x01, 0x70, 0x0A, 0x03, 0x60, + 0x9F, 0x70, 0x0A, 0x05, 0x60, 0xA0, 0x44, 0x06, + 0x93, 0x60, 0x0A, 0x05, 0x70, 0x0D, 0x20, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x6E, 0x6F, + 0x74, 0x20, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6E, + 0x74, 0x00, 0x5B, 0x31, 0x41, 0x30, 0x39, 0x33, + 0x0A, 0x00, 0x0A, 0x00, 0x70, 0x0A, 0x01, 0x41, + 0x30, 0x38, 0x37, 0x41, 0x30, 0x39, 0x32, 0x0A, + 0x00, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x30, 0x39, 0x31, 0x0A, 0x00, 0x41, 0x42, 0x30, + 0x36, 0x41, 0x42, 0x30, 0x37, 0x70, 0x0A, 0x00, + 0x41, 0x42, 0x30, 0x35, 0x70, 0x0A, 0x00, 0x41, + 0x42, 0x30, 0x34, 0x70, 0x0A, 0x00, 0x41, 0x42, + 0x31, 0x30, 0x70, 0x0A, 0x00, 0x62, 0x70, 0x0A, + 0x08, 0x60, 0xA0, 0x0D, 0x93, 0x60, 0x0A, 0x07, + 0x70, 0x0A, 0x01, 0x62, 0x70, 0x0A, 0x08, 0x60, + 0xA0, 0x0F, 0x93, 0x41, 0x42, 0x30, 0x34, 0x0A, + 0x00, 0x70, 0x0A, 0x00, 0x41, 0x42, 0x30, 0x35, + 0xA0, 0x28, 0x91, 0x94, 0x41, 0x42, 0x30, 0x45, + 0x0A, 0x01, 0x93, 0x41, 0x50, 0x30, 0x35, 0x0A, + 0x01, 0xA0, 0x17, 0x94, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x0A, 0x00, 0x00, 0x0A, 0x01, 0x41, 0x30, 0x33, + 0x38, 0x70, 0x41, 0x30, 0x36, 0x39, 0x41, 0x30, + 0x37, 0x30, 0xA4, 0x62, 0x14, 0x46, 0x05, 0x41, + 0x30, 0x39, 0x32, 0x01, 0xA0, 0x14, 0x94, 0x41, + 0x42, 0x30, 0x36, 0x41, 0x42, 0x30, 0x37, 0x74, + 0x41, 0x42, 0x30, 0x36, 0x41, 0x42, 0x30, 0x37, + 0x60, 0xA1, 0x0B, 0x74, 0x41, 0x42, 0x30, 0x37, + 0x41, 0x42, 0x30, 0x36, 0x60, 0x75, 0x60, 0x79, + 0x0A, 0x01, 0x60, 0x60, 0x76, 0x60, 0x79, 0x60, + 0x41, 0x42, 0x30, 0x38, 0x60, 0xA0, 0x0F, 0x93, + 0x68, 0x0A, 0x01, 0x7D, 0x41, 0x30, 0x38, 0x38, + 0x60, 0x41, 0x30, 0x38, 0x38, 0xA1, 0x0D, 0x7B, + 0x41, 0x30, 0x38, 0x38, 0x80, 0x60, 0x00, 0x41, + 0x30, 0x38, 0x38, 0x5B, 0x82, 0x4A, 0xE6, 0x41, + 0x42, 0x52, 0x32, 0x08, 0x5F, 0x48, 0x49, 0x44, + 0x0C, 0x41, 0xD0, 0x0C, 0x02, 0x08, 0x5F, 0x55, + 0x49, 0x44, 0x0A, 0x82, 0x08, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x48, 0x08, 0x41, 0x42, 0x30, 0x30, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x31, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x45, 0x0A, 0x00, + 0x08, 0x41, 0x42, 0x30, 0x32, 0x0A, 0x00, 0x08, + 0x41, 0x42, 0x30, 0x33, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x34, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x35, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, + 0x36, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x37, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x38, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x39, 0x0A, 0x00, + 0x08, 0x41, 0x42, 0x30, 0x41, 0x0A, 0x00, 0x08, + 0x41, 0x42, 0x30, 0x42, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x43, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x44, 0x0A, 0x00, 0x5B, 0x80, 0x41, 0x30, + 0x38, 0x33, 0x00, 0x72, 0x41, 0x47, 0x52, 0x42, + 0x7D, 0x79, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x0D, 0x00, 0x00, 0x0A, + 0x0F, 0x00, 0x79, 0x83, 0x88, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, + 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0E, 0x00, 0x00, + 0x0A, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x10, + 0x5B, 0x81, 0x45, 0x04, 0x41, 0x30, 0x38, 0x33, + 0x01, 0x00, 0x40, 0x0C, 0x00, 0x08, 0x41, 0x30, + 0x37, 0x34, 0x08, 0x41, 0x30, 0x37, 0x35, 0x08, + 0x00, 0x48, 0x26, 0x41, 0x30, 0x37, 0x30, 0x02, + 0x00, 0x03, 0x41, 0x30, 0x37, 0x31, 0x01, 0x00, + 0x0A, 0x00, 0x0B, 0x41, 0x30, 0x37, 0x32, 0x01, + 0x00, 0x44, 0x0E, 0x41, 0x30, 0x38, 0x32, 0x04, + 0x00, 0x01, 0x41, 0x30, 0x37, 0x39, 0x01, 0x00, + 0x4A, 0x2B, 0x41, 0x30, 0x38, 0x34, 0x20, 0x5B, + 0x87, 0x16, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA1, 0x03, 0x00, 0x40, 0x72, + 0x00, 0x0C, 0x41, 0x30, 0x36, 0x36, 0x01, 0x5B, + 0x87, 0x16, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA2, 0x03, 0x00, 0x40, 0x72, + 0x00, 0x0D, 0x41, 0x30, 0x38, 0x31, 0x01, 0x5B, + 0x87, 0x27, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA4, 0x03, 0x00, 0x40, 0x72, + 0x41, 0x30, 0x37, 0x37, 0x01, 0x41, 0x30, 0x37, + 0x38, 0x01, 0x00, 0x0B, 0x41, 0x30, 0x37, 0x33, + 0x02, 0x00, 0x0E, 0x41, 0x30, 0x38, 0x30, 0x01, + 0x5B, 0x87, 0x14, 0x41, 0x30, 0x38, 0x33, 0x41, + 0x30, 0x38, 0x34, 0x0A, 0xA5, 0x03, 0x00, 0x40, + 0x72, 0x41, 0x30, 0x36, 0x35, 0x06, 0x5B, 0x80, + 0x41, 0x30, 0x38, 0x35, 0x00, 0x41, 0x47, 0x52, + 0x42, 0x0B, 0x00, 0x10, 0x5B, 0x81, 0x0E, 0x41, + 0x30, 0x38, 0x35, 0x01, 0x00, 0x40, 0x70, 0x41, + 0x30, 0x38, 0x36, 0x20, 0x5B, 0x87, 0x3C, 0x41, + 0x30, 0x38, 0x35, 0x41, 0x30, 0x38, 0x36, 0x7D, + 0x79, 0x5E, 0x57, 0x52, 0x42, 0x53, 0x0A, 0x10, + 0x00, 0x72, 0x0B, 0x00, 0x08, 0x77, 0x0B, 0x00, + 0x01, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, + 0x31, 0x32, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x40, 0x72, 0x41, 0x30, 0x38, + 0x37, 0x01, 0x5B, 0x87, 0x20, 0x41, 0x30, 0x38, + 0x35, 0x41, 0x30, 0x38, 0x36, 0x7D, 0x79, 0x5E, + 0x57, 0x52, 0x42, 0x53, 0x0A, 0x10, 0x00, 0x0B, + 0x29, 0x80, 0x00, 0x03, 0x00, 0x40, 0x72, 0x41, + 0x30, 0x38, 0x38, 0x10, 0x08, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x00, 0x14, 0x4D, 0x18, 0x5F, 0x49, + 0x4E, 0x49, 0x00, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x00, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x30, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x01, 0x00, 0x00, 0x41, 0x42, 0x30, 0x45, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x02, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x31, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x03, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x32, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x04, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x33, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x05, 0x00, 0x00, 0x41, 0x42, 0x30, 0x34, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x06, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x35, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x07, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x36, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x08, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x37, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x09, 0x00, 0x00, 0x41, 0x42, 0x30, 0x38, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x0A, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x39, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x0B, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x41, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0C, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x42, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x0D, 0x00, 0x00, 0x41, 0x42, 0x30, 0x43, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x0E, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x44, 0x14, 0x22, 0x41, 0x30, 0x36, 0x31, 0x00, + 0x70, 0x41, 0x30, 0x34, 0x31, 0x60, 0xA0, 0x0A, + 0x93, 0x60, 0x0A, 0x01, 0xA4, 0x41, 0x42, 0x30, + 0x31, 0xA0, 0x0A, 0x93, 0x60, 0x0A, 0x00, 0xA4, + 0x41, 0x42, 0x30, 0x45, 0x14, 0x1F, 0x41, 0x30, + 0x35, 0x35, 0x00, 0xA0, 0x15, 0x92, 0x93, 0x41, + 0x42, 0x31, 0x30, 0x0A, 0x00, 0xA0, 0x0B, 0x93, + 0x41, 0x42, 0x31, 0x30, 0x0A, 0x01, 0xA4, 0x0A, + 0x01, 0xA4, 0x0A, 0x00, 0x14, 0x2A, 0x41, 0x30, + 0x36, 0x32, 0x00, 0xA0, 0x0E, 0x92, 0x93, 0x41, + 0x42, 0x30, 0x35, 0x0A, 0x00, 0xA4, 0x41, 0x42, + 0x30, 0x35, 0xA0, 0x11, 0x94, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x01, 0xA4, 0x74, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x01, 0x00, 0xA4, 0x0A, 0x00, 0x14, + 0x49, 0x07, 0x41, 0x30, 0x35, 0x34, 0x00, 0xA0, + 0x22, 0x93, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x50, 0x30, 0x35, 0x0A, 0x00, 0xA0, 0x0E, + 0x92, 0x93, 0x41, 0x42, 0x30, 0x35, 0x0A, 0x00, + 0xA4, 0x41, 0x42, 0x30, 0x35, 0xA4, 0x41, 0x42, + 0x30, 0x45, 0x70, 0x41, 0x30, 0x36, 0x32, 0x60, + 0xA0, 0x17, 0x92, 0x93, 0x60, 0x0A, 0x00, 0xA0, + 0x0C, 0x94, 0x60, 0x41, 0x42, 0x30, 0x30, 0xA4, + 0x41, 0x42, 0x30, 0x30, 0xA1, 0x03, 0xA4, 0x60, + 0x70, 0x41, 0x30, 0x36, 0x31, 0x60, 0xA0, 0x28, + 0x92, 0x93, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x50, 0x30, 0x33, 0x0A, 0x00, 0xA0, 0x18, + 0x95, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x50, 0x30, 0x33, 0x60, 0xA4, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x33, 0xA4, + 0x60, 0x14, 0x0B, 0x41, 0x30, 0x35, 0x33, 0x00, + 0xA4, 0x41, 0x42, 0x30, 0x32, 0x14, 0x0B, 0x41, + 0x30, 0x35, 0x36, 0x00, 0xA4, 0x41, 0x42, 0x30, + 0x30, 0x14, 0x4B, 0x13, 0x41, 0x30, 0x35, 0x32, + 0x01, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x50, 0x6F, 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x00, + 0x98, 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x68, 0x41, 0x42, 0x30, 0x32, 0xA0, + 0x14, 0x93, 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, + 0x36, 0x33, 0x0A, 0x01, 0x41, 0x30, 0x36, 0x34, + 0x68, 0xA0, 0x40, 0x0B, 0x92, 0x95, 0x41, 0x30, + 0x36, 0x35, 0x0A, 0x10, 0xA0, 0x10, 0x92, 0x93, + 0x41, 0x42, 0x31, 0x30, 0x0A, 0x00, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x36, 0x36, 0xA1, 0x08, 0x70, + 0x0A, 0x01, 0x41, 0x30, 0x36, 0x36, 0xA0, 0x14, + 0x93, 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x36, + 0x37, 0x0A, 0x00, 0xA1, 0x07, 0x41, 0x30, 0x36, + 0x38, 0x0A, 0x00, 0x08, 0x41, 0x30, 0x36, 0x39, + 0x0A, 0x00, 0x70, 0x41, 0x30, 0x37, 0x30, 0x41, + 0x30, 0x36, 0x39, 0x70, 0x0A, 0x00, 0x41, 0x30, + 0x37, 0x30, 0x70, 0x0A, 0x01, 0x60, 0xA2, 0x2D, + 0x60, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, 0x31, + 0x5B, 0x22, 0x0A, 0x1E, 0xA2, 0x0C, 0x93, 0x41, + 0x30, 0x37, 0x32, 0x0A, 0x01, 0x5B, 0x22, 0x0A, + 0x0A, 0xA0, 0x0F, 0x93, 0x68, 0x0A, 0x01, 0xA0, + 0x09, 0x93, 0x41, 0x30, 0x37, 0x33, 0x0A, 0x00, + 0xA5, 0xA1, 0x02, 0xA5, 0x70, 0x41, 0x30, 0x36, + 0x39, 0x41, 0x30, 0x37, 0x30, 0xA0, 0x14, 0x93, + 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x36, 0x37, + 0x0A, 0x01, 0xA1, 0x07, 0x41, 0x30, 0x36, 0x38, + 0x0A, 0x01, 0xA0, 0x14, 0x93, 0x41, 0x42, 0x30, + 0x33, 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x30, 0x36, 0x33, 0x0A, 0x00, 0x70, + 0x0D, 0x50, 0x63, 0x69, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x50, 0x6F, 0x72, 0x74, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x45, 0x78, + 0x69, 0x74, 0x00, 0x5B, 0x31, 0x14, 0x28, 0x41, + 0x30, 0x35, 0x37, 0x01, 0x70, 0x73, 0x0D, 0x20, + 0x53, 0x65, 0x74, 0x20, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, + 0x70, 0x68, 0x41, 0x42, 0x31, 0x30, 0x14, 0x22, + 0x41, 0x30, 0x35, 0x38, 0x01, 0x7A, 0x68, 0x0A, + 0x08, 0x60, 0xA0, 0x13, 0x90, 0x92, 0x95, 0x60, + 0x41, 0x30, 0x37, 0x34, 0x92, 0x94, 0x60, 0x41, + 0x30, 0x37, 0x35, 0xA4, 0x0A, 0x01, 0xA4, 0x0A, + 0x00, 0x14, 0x1F, 0x41, 0x30, 0x37, 0x36, 0x01, + 0x7D, 0x41, 0x42, 0x30, 0x44, 0x79, 0x41, 0x42, + 0x30, 0x43, 0x0A, 0x03, 0x00, 0x60, 0xA0, 0x07, + 0x93, 0x68, 0x60, 0xA4, 0x0A, 0x01, 0xA4, 0x0A, + 0x00, 0x14, 0x0D, 0x41, 0x30, 0x35, 0x39, 0x00, + 0x70, 0x0A, 0x00, 0x41, 0x42, 0x31, 0x30, 0x14, + 0x42, 0x07, 0x41, 0x30, 0x36, 0x34, 0x01, 0xA0, + 0x0D, 0x92, 0x95, 0x68, 0x0A, 0x02, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x37, 0x37, 0xA0, 0x0D, 0x92, + 0x95, 0x68, 0x0A, 0x03, 0x70, 0x0A, 0x01, 0x41, + 0x30, 0x37, 0x38, 0xA0, 0x31, 0x93, 0x68, 0x0A, + 0x01, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, 0x39, + 0x70, 0x0A, 0x00, 0x41, 0x30, 0x37, 0x37, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x38, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x38, 0x30, 0xA0, 0x0F, 0x93, + 0x41, 0x42, 0x30, 0x34, 0x0A, 0x01, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x38, 0x31, 0xA1, 0x16, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x39, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x38, 0x30, 0x70, 0x0A, 0x00, + 0x41, 0x30, 0x38, 0x31, 0x70, 0x68, 0x41, 0x30, + 0x38, 0x32, 0x14, 0x41, 0x32, 0x41, 0x30, 0x36, + 0x30, 0x00, 0x70, 0x0D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x00, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x43, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x46, 0x75, 0x6E, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x44, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, 0x74, 0x41, + 0x63, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x45, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, + 0x74, 0x4D, 0x61, 0x78, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x30, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, + 0x6F, 0x72, 0x74, 0x41, 0x63, 0x53, 0x70, 0x65, + 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x45, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x50, 0x6F, 0x72, 0x74, 0x44, 0x63, 0x53, + 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x31, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, 0x74, 0x43, + 0x75, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x32, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x53, 0x62, 0x50, + 0x6F, 0x72, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x33, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x4C, + 0x69, 0x6E, 0x6B, 0x53, 0x61, 0x66, 0x65, 0x4D, + 0x6F, 0x64, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x34, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x4F, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x35, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x50, 0x68, 0x79, 0x4C, + 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x36, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x45, 0x6E, 0x64, 0x50, 0x68, 0x79, 0x4C, + 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x37, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x43, 0x6F, 0x72, 0x65, 0x4C, 0x61, 0x6E, 0x65, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x38, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x45, 0x6E, 0x64, + 0x43, 0x6F, 0x72, 0x65, 0x4C, 0x61, 0x6E, 0x65, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x39, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x6F, 0x72, 0x74, 0x49, 0x64, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x41, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x4C, 0x69, 0x6E, 0x6B, 0x48, 0x6F, 0x74, + 0x70, 0x6C, 0x75, 0x67, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x42, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x0D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x00, 0x5B, 0x31, 0x14, 0x42, 0x05, 0x41, + 0x30, 0x39, 0x34, 0x02, 0xA0, 0x11, 0x93, 0x41, + 0x30, 0x39, 0x33, 0x68, 0x0A, 0x00, 0x0C, 0xFF, + 0xFF, 0xFF, 0xFF, 0xA4, 0x0A, 0x00, 0x70, 0x41, + 0x30, 0x39, 0x33, 0x68, 0x0A, 0x34, 0x60, 0xA2, + 0x2F, 0x0A, 0x01, 0x70, 0x41, 0x30, 0x39, 0x33, + 0x68, 0x7B, 0x60, 0x0A, 0xFF, 0x00, 0x61, 0xA0, + 0x0E, 0x93, 0x7B, 0x61, 0x0A, 0xFF, 0x00, 0x69, + 0xA4, 0x7B, 0x60, 0x0A, 0xFF, 0x00, 0x7B, 0x7A, + 0x61, 0x0A, 0x08, 0x00, 0x0A, 0xFF, 0x60, 0xA0, + 0x07, 0x93, 0x60, 0x0A, 0x00, 0xA4, 0x60, 0x08, + 0x41, 0x45, 0x53, 0x50, 0x12, 0x12, 0x08, 0x0A, + 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, + 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x14, + 0x49, 0x0D, 0x41, 0x30, 0x36, 0x38, 0x01, 0x70, + 0x0D, 0x50, 0x63, 0x69, 0x65, 0x45, 0x70, 0x41, + 0x73, 0x70, 0x6D, 0x20, 0x45, 0x6E, 0x74, 0x65, + 0x72, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x00, 0x60, + 0xA0, 0x49, 0x08, 0x92, 0x93, 0x41, 0x30, 0x39, + 0x33, 0x60, 0x0A, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, + 0xFF, 0x7B, 0x41, 0x30, 0x39, 0x33, 0x60, 0x0A, + 0x08, 0x0A, 0x80, 0x61, 0xA0, 0x09, 0x93, 0x61, + 0x0A, 0x80, 0x70, 0x0A, 0x07, 0x67, 0xA1, 0x05, + 0x70, 0x0A, 0x00, 0x67, 0xA2, 0x4D, 0x05, 0x92, + 0x94, 0x60, 0x67, 0x70, 0x41, 0x30, 0x39, 0x34, + 0x60, 0x0A, 0x10, 0x61, 0xA0, 0x08, 0x93, 0x61, + 0x0A, 0x00, 0x75, 0x60, 0x9F, 0xA0, 0x2B, 0x93, + 0x68, 0x0A, 0x00, 0x70, 0x41, 0x30, 0x39, 0x33, + 0x60, 0x72, 0x61, 0x0A, 0x10, 0x00, 0x62, 0x41, + 0x30, 0x39, 0x35, 0x60, 0x72, 0x61, 0x0A, 0x10, + 0x00, 0x7B, 0x62, 0x80, 0x0A, 0x03, 0x00, 0x00, + 0x70, 0x62, 0x88, 0x41, 0x45, 0x53, 0x50, 0x60, + 0x00, 0xA1, 0x16, 0x70, 0x83, 0x88, 0x41, 0x45, + 0x53, 0x50, 0x60, 0x00, 0x62, 0x41, 0x30, 0x39, + 0x35, 0x60, 0x72, 0x61, 0x0A, 0x10, 0x00, 0x62, + 0x75, 0x60, 0xA1, 0x1A, 0x70, 0x0D, 0x45, 0x6E, + 0x64, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x6E, + 0x6F, 0x74, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6E, 0x74, 0x00, 0x5B, 0x31, 0x70, 0x0D, 0x50, + 0x63, 0x69, 0x65, 0x45, 0x70, 0x41, 0x73, 0x70, + 0x6D, 0x20, 0x45, 0x78, 0x69, 0x74, 0x00, 0x5B, + 0x31, 0x14, 0x3D, 0x41, 0x30, 0x39, 0x35, 0x0B, + 0x72, 0x41, 0x47, 0x52, 0x42, 0x79, 0x41, 0x30, + 0x37, 0x34, 0x0A, 0x14, 0x00, 0x60, 0x72, 0x60, + 0x79, 0x68, 0x0A, 0x0C, 0x00, 0x60, 0x72, 0x60, + 0x69, 0x60, 0x5B, 0x80, 0x41, 0x44, 0x52, 0x42, + 0x00, 0x60, 0x0A, 0x04, 0x5B, 0x81, 0x0B, 0x41, + 0x44, 0x52, 0x42, 0x03, 0x41, 0x44, 0x52, 0x52, + 0x20, 0x70, 0x6A, 0x41, 0x44, 0x52, 0x52, 0x14, + 0x3C, 0x41, 0x30, 0x39, 0x33, 0x0A, 0x72, 0x41, + 0x47, 0x52, 0x42, 0x79, 0x41, 0x30, 0x37, 0x34, + 0x0A, 0x14, 0x00, 0x60, 0x72, 0x60, 0x79, 0x68, + 0x0A, 0x0C, 0x00, 0x60, 0x72, 0x60, 0x69, 0x60, + 0x5B, 0x80, 0x41, 0x44, 0x52, 0x42, 0x00, 0x60, + 0x0A, 0x04, 0x5B, 0x81, 0x0B, 0x41, 0x44, 0x52, + 0x42, 0x03, 0x41, 0x44, 0x52, 0x52, 0x20, 0xA4, + 0x41, 0x44, 0x52, 0x52, 0x14, 0x19, 0x41, 0x30, + 0x38, 0x39, 0x01, 0xA0, 0x0C, 0x92, 0x93, 0x41, + 0x42, 0x30, 0x42, 0x0A, 0x01, 0xA4, 0x0A, 0x00, + 0xA4, 0x41, 0x30, 0x37, 0x36, 0x68, 0x14, 0x49, + 0x25, 0x41, 0x30, 0x39, 0x30, 0x01, 0x08, 0x41, + 0x30, 0x36, 0x39, 0x0A, 0x00, 0x70, 0x41, 0x30, + 0x37, 0x30, 0x41, 0x30, 0x36, 0x39, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x37, 0x30, 0xA0, 0x09, 0x93, + 0x68, 0x0A, 0x01, 0x70, 0x0A, 0x01, 0x60, 0xA1, + 0x05, 0x70, 0x0A, 0x05, 0x60, 0xA2, 0x46, 0x1E, + 0x92, 0x93, 0x60, 0x0A, 0x08, 0xA0, 0x41, 0x04, + 0x93, 0x60, 0x0A, 0x01, 0xA0, 0x15, 0x94, 0x41, + 0x42, 0x30, 0x45, 0x0A, 0x01, 0x70, 0x41, 0x42, + 0x30, 0x45, 0x41, 0x42, 0x30, 0x35, 0x41, 0x30, + 0x33, 0x38, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x30, 0x39, 0x31, 0x0A, 0x01, 0x41, 0x42, + 0x30, 0x36, 0x41, 0x42, 0x30, 0x37, 0x41, 0x30, + 0x39, 0x32, 0x0A, 0x01, 0x70, 0x0A, 0x00, 0x41, + 0x30, 0x38, 0x37, 0x70, 0x0A, 0x03, 0x60, 0xA0, + 0x4D, 0x04, 0x93, 0x60, 0x0A, 0x03, 0x70, 0x0A, + 0x00, 0x61, 0x70, 0x0A, 0x00, 0x62, 0xA2, 0x2E, + 0x95, 0x61, 0x0A, 0x3C, 0xA0, 0x22, 0x94, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x04, 0x70, 0x0D, 0x20, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x64, + 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x00, + 0x5B, 0x31, 0x70, 0x0A, 0x01, 0x62, 0xA5, 0x5B, + 0x22, 0x0A, 0x01, 0x75, 0x61, 0xA0, 0x09, 0x93, + 0x62, 0x0A, 0x01, 0x70, 0x0A, 0x04, 0x60, 0xA1, + 0x05, 0x70, 0x0A, 0x05, 0x60, 0xA0, 0x45, 0x06, + 0x93, 0x60, 0x0A, 0x04, 0x70, 0x0A, 0x00, 0x61, + 0x70, 0x0A, 0x00, 0x62, 0xA2, 0x37, 0x95, 0x61, + 0x0A, 0x50, 0xA0, 0x2B, 0x90, 0x92, 0x95, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x10, 0x92, 0x94, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x13, 0x70, 0x0D, 0x20, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x50, + 0x72, 0x65, 0x73, 0x65, 0x6E, 0x74, 0x00, 0x5B, + 0x31, 0x70, 0x0A, 0x01, 0x62, 0xA5, 0x5B, 0x22, + 0x0A, 0x01, 0x75, 0x61, 0xA0, 0x09, 0x93, 0x62, + 0x0A, 0x01, 0x70, 0x0A, 0x07, 0x60, 0xA1, 0x14, + 0xA0, 0x0C, 0x93, 0x41, 0x42, 0x30, 0x34, 0x0A, + 0x01, 0x70, 0x0A, 0x05, 0x60, 0xA1, 0x05, 0x70, + 0x0A, 0x06, 0x60, 0xA0, 0x45, 0x07, 0x93, 0x60, + 0x0A, 0x06, 0x70, 0x0A, 0x01, 0x41, 0x42, 0x30, + 0x34, 0x70, 0x0A, 0x01, 0x41, 0x42, 0x30, 0x35, + 0x41, 0x30, 0x36, 0x34, 0x0A, 0x01, 0xA0, 0x46, + 0x05, 0x5B, 0x12, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x4C, 0x49, 0x43, 0x66, 0x70, 0x0D, + 0x20, 0x43, 0x61, 0x6C, 0x6C, 0x20, 0x41, 0x4C, + 0x49, 0x43, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, + 0x64, 0x00, 0x5B, 0x31, 0x7D, 0x79, 0x41, 0x42, + 0x30, 0x43, 0x0A, 0x03, 0x00, 0x41, 0x42, 0x30, + 0x44, 0x61, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x4C, 0x49, 0x43, 0x61, 0x0A, 0x00, 0x5B, + 0x22, 0x0A, 0x02, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x4C, 0x49, 0x43, 0x61, 0x0A, 0x01, + 0x70, 0x0A, 0x03, 0x60, 0x9F, 0x70, 0x0A, 0x05, + 0x60, 0xA0, 0x44, 0x06, 0x93, 0x60, 0x0A, 0x05, + 0x70, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x50, 0x72, + 0x65, 0x73, 0x65, 0x6E, 0x74, 0x00, 0x5B, 0x31, + 0x41, 0x30, 0x39, 0x33, 0x0A, 0x00, 0x0A, 0x00, + 0x70, 0x0A, 0x01, 0x41, 0x30, 0x38, 0x37, 0x41, + 0x30, 0x39, 0x32, 0x0A, 0x00, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x30, 0x39, 0x31, 0x0A, + 0x00, 0x41, 0x42, 0x30, 0x36, 0x41, 0x42, 0x30, + 0x37, 0x70, 0x0A, 0x00, 0x41, 0x42, 0x30, 0x35, + 0x70, 0x0A, 0x00, 0x41, 0x42, 0x30, 0x34, 0x70, + 0x0A, 0x00, 0x41, 0x42, 0x31, 0x30, 0x70, 0x0A, + 0x00, 0x62, 0x70, 0x0A, 0x08, 0x60, 0xA0, 0x0D, + 0x93, 0x60, 0x0A, 0x07, 0x70, 0x0A, 0x01, 0x62, + 0x70, 0x0A, 0x08, 0x60, 0xA0, 0x0F, 0x93, 0x41, + 0x42, 0x30, 0x34, 0x0A, 0x00, 0x70, 0x0A, 0x00, + 0x41, 0x42, 0x30, 0x35, 0xA0, 0x28, 0x91, 0x94, + 0x41, 0x42, 0x30, 0x45, 0x0A, 0x01, 0x93, 0x41, + 0x50, 0x30, 0x35, 0x0A, 0x01, 0xA0, 0x17, 0x94, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x0A, 0x00, 0x00, 0x0A, + 0x01, 0x41, 0x30, 0x33, 0x38, 0x70, 0x41, 0x30, + 0x36, 0x39, 0x41, 0x30, 0x37, 0x30, 0xA4, 0x62, + 0x14, 0x46, 0x05, 0x41, 0x30, 0x39, 0x32, 0x01, + 0xA0, 0x14, 0x94, 0x41, 0x42, 0x30, 0x36, 0x41, + 0x42, 0x30, 0x37, 0x74, 0x41, 0x42, 0x30, 0x36, + 0x41, 0x42, 0x30, 0x37, 0x60, 0xA1, 0x0B, 0x74, + 0x41, 0x42, 0x30, 0x37, 0x41, 0x42, 0x30, 0x36, + 0x60, 0x75, 0x60, 0x79, 0x0A, 0x01, 0x60, 0x60, + 0x76, 0x60, 0x79, 0x60, 0x41, 0x42, 0x30, 0x38, + 0x60, 0xA0, 0x0F, 0x93, 0x68, 0x0A, 0x01, 0x7D, + 0x41, 0x30, 0x38, 0x38, 0x60, 0x41, 0x30, 0x38, + 0x38, 0xA1, 0x0D, 0x7B, 0x41, 0x30, 0x38, 0x38, + 0x80, 0x60, 0x00, 0x41, 0x30, 0x38, 0x38, 0x5B, + 0x82, 0x4A, 0xE6, 0x41, 0x42, 0x52, 0x33, 0x08, + 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0C, + 0x02, 0x08, 0x5F, 0x55, 0x49, 0x44, 0x0A, 0x83, + 0x08, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x5C, 0x08, + 0x41, 0x42, 0x30, 0x30, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x31, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x45, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, + 0x32, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x33, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x34, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x35, 0x0A, 0x00, + 0x08, 0x41, 0x42, 0x30, 0x36, 0x0A, 0x00, 0x08, + 0x41, 0x42, 0x30, 0x37, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x38, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x39, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, + 0x41, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x42, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x43, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x44, 0x0A, 0x00, + 0x5B, 0x80, 0x41, 0x30, 0x38, 0x33, 0x00, 0x72, + 0x41, 0x47, 0x52, 0x42, 0x7D, 0x79, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x0D, 0x00, 0x00, 0x0A, 0x0F, 0x00, 0x79, 0x83, + 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, + 0x0A, 0x0E, 0x00, 0x00, 0x0A, 0x0C, 0x00, 0x00, + 0x00, 0x0B, 0x00, 0x10, 0x5B, 0x81, 0x45, 0x04, + 0x41, 0x30, 0x38, 0x33, 0x01, 0x00, 0x40, 0x0C, + 0x00, 0x08, 0x41, 0x30, 0x37, 0x34, 0x08, 0x41, + 0x30, 0x37, 0x35, 0x08, 0x00, 0x48, 0x26, 0x41, + 0x30, 0x37, 0x30, 0x02, 0x00, 0x03, 0x41, 0x30, + 0x37, 0x31, 0x01, 0x00, 0x0A, 0x00, 0x0B, 0x41, + 0x30, 0x37, 0x32, 0x01, 0x00, 0x44, 0x0E, 0x41, + 0x30, 0x38, 0x32, 0x04, 0x00, 0x01, 0x41, 0x30, + 0x37, 0x39, 0x01, 0x00, 0x4A, 0x2B, 0x41, 0x30, + 0x38, 0x34, 0x20, 0x5B, 0x87, 0x16, 0x41, 0x30, + 0x38, 0x33, 0x41, 0x30, 0x38, 0x34, 0x0A, 0xA1, + 0x03, 0x00, 0x40, 0x72, 0x00, 0x0C, 0x41, 0x30, + 0x36, 0x36, 0x01, 0x5B, 0x87, 0x16, 0x41, 0x30, + 0x38, 0x33, 0x41, 0x30, 0x38, 0x34, 0x0A, 0xA2, + 0x03, 0x00, 0x40, 0x72, 0x00, 0x0D, 0x41, 0x30, + 0x38, 0x31, 0x01, 0x5B, 0x87, 0x27, 0x41, 0x30, + 0x38, 0x33, 0x41, 0x30, 0x38, 0x34, 0x0A, 0xA4, + 0x03, 0x00, 0x40, 0x72, 0x41, 0x30, 0x37, 0x37, + 0x01, 0x41, 0x30, 0x37, 0x38, 0x01, 0x00, 0x0B, + 0x41, 0x30, 0x37, 0x33, 0x02, 0x00, 0x0E, 0x41, + 0x30, 0x38, 0x30, 0x01, 0x5B, 0x87, 0x14, 0x41, + 0x30, 0x38, 0x33, 0x41, 0x30, 0x38, 0x34, 0x0A, + 0xA5, 0x03, 0x00, 0x40, 0x72, 0x41, 0x30, 0x36, + 0x35, 0x06, 0x5B, 0x80, 0x41, 0x30, 0x38, 0x35, + 0x00, 0x41, 0x47, 0x52, 0x42, 0x0B, 0x00, 0x10, + 0x5B, 0x81, 0x0E, 0x41, 0x30, 0x38, 0x35, 0x01, + 0x00, 0x40, 0x70, 0x41, 0x30, 0x38, 0x36, 0x20, + 0x5B, 0x87, 0x3C, 0x41, 0x30, 0x38, 0x35, 0x41, + 0x30, 0x38, 0x36, 0x7D, 0x79, 0x5E, 0x57, 0x52, + 0x42, 0x53, 0x0A, 0x10, 0x00, 0x72, 0x0B, 0x00, + 0x08, 0x77, 0x0B, 0x00, 0x01, 0x83, 0x88, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, + 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0B, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, + 0x72, 0x41, 0x30, 0x38, 0x37, 0x01, 0x5B, 0x87, + 0x20, 0x41, 0x30, 0x38, 0x35, 0x41, 0x30, 0x38, + 0x36, 0x7D, 0x79, 0x5E, 0x57, 0x52, 0x42, 0x53, + 0x0A, 0x10, 0x00, 0x0B, 0x29, 0x80, 0x00, 0x03, + 0x00, 0x40, 0x72, 0x41, 0x30, 0x38, 0x38, 0x10, + 0x08, 0x41, 0x42, 0x31, 0x30, 0x0A, 0x00, 0x14, + 0x4D, 0x18, 0x5F, 0x49, 0x4E, 0x49, 0x00, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x00, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x30, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x01, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x45, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x02, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x31, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x03, 0x00, 0x00, 0x41, 0x42, 0x30, 0x32, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x04, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x33, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x05, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x34, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x06, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x35, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x07, 0x00, 0x00, 0x41, 0x42, 0x30, 0x36, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x08, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x37, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x09, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x38, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0A, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x39, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x0B, 0x00, 0x00, 0x41, 0x42, 0x30, 0x41, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x0C, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x42, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x0D, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x43, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0E, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x44, 0x14, 0x22, 0x41, + 0x30, 0x36, 0x31, 0x00, 0x70, 0x41, 0x30, 0x34, + 0x31, 0x60, 0xA0, 0x0A, 0x93, 0x60, 0x0A, 0x01, + 0xA4, 0x41, 0x42, 0x30, 0x31, 0xA0, 0x0A, 0x93, + 0x60, 0x0A, 0x00, 0xA4, 0x41, 0x42, 0x30, 0x45, + 0x14, 0x1F, 0x41, 0x30, 0x35, 0x35, 0x00, 0xA0, + 0x15, 0x92, 0x93, 0x41, 0x42, 0x31, 0x30, 0x0A, + 0x00, 0xA0, 0x0B, 0x93, 0x41, 0x42, 0x31, 0x30, + 0x0A, 0x01, 0xA4, 0x0A, 0x01, 0xA4, 0x0A, 0x00, + 0x14, 0x2A, 0x41, 0x30, 0x36, 0x32, 0x00, 0xA0, + 0x0E, 0x92, 0x93, 0x41, 0x42, 0x30, 0x35, 0x0A, + 0x00, 0xA4, 0x41, 0x42, 0x30, 0x35, 0xA0, 0x11, + 0x94, 0x41, 0x42, 0x31, 0x30, 0x0A, 0x01, 0xA4, + 0x74, 0x41, 0x42, 0x31, 0x30, 0x0A, 0x01, 0x00, + 0xA4, 0x0A, 0x00, 0x14, 0x49, 0x07, 0x41, 0x30, + 0x35, 0x34, 0x00, 0xA0, 0x22, 0x93, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x35, + 0x0A, 0x00, 0xA0, 0x0E, 0x92, 0x93, 0x41, 0x42, + 0x30, 0x35, 0x0A, 0x00, 0xA4, 0x41, 0x42, 0x30, + 0x35, 0xA4, 0x41, 0x42, 0x30, 0x45, 0x70, 0x41, + 0x30, 0x36, 0x32, 0x60, 0xA0, 0x17, 0x92, 0x93, + 0x60, 0x0A, 0x00, 0xA0, 0x0C, 0x94, 0x60, 0x41, + 0x42, 0x30, 0x30, 0xA4, 0x41, 0x42, 0x30, 0x30, + 0xA1, 0x03, 0xA4, 0x60, 0x70, 0x41, 0x30, 0x36, + 0x31, 0x60, 0xA0, 0x28, 0x92, 0x93, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x33, + 0x0A, 0x00, 0xA0, 0x18, 0x95, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x33, 0x60, + 0xA4, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x50, 0x30, 0x33, 0xA4, 0x60, 0x14, 0x0B, 0x41, + 0x30, 0x35, 0x33, 0x00, 0xA4, 0x41, 0x42, 0x30, + 0x32, 0x14, 0x0B, 0x41, 0x30, 0x35, 0x36, 0x00, + 0xA4, 0x41, 0x42, 0x30, 0x30, 0x14, 0x4B, 0x13, + 0x41, 0x30, 0x35, 0x32, 0x01, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x50, 0x6F, 0x72, 0x74, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x45, 0x6E, + 0x74, 0x65, 0x72, 0x20, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x3A, 0x20, 0x00, 0x98, 0x68, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x68, 0x41, + 0x42, 0x30, 0x32, 0xA0, 0x14, 0x93, 0x41, 0x42, + 0x30, 0x33, 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x30, 0x36, 0x33, 0x0A, 0x01, + 0x41, 0x30, 0x36, 0x34, 0x68, 0xA0, 0x40, 0x0B, + 0x92, 0x95, 0x41, 0x30, 0x36, 0x35, 0x0A, 0x10, + 0xA0, 0x10, 0x92, 0x93, 0x41, 0x42, 0x31, 0x30, + 0x0A, 0x00, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x36, + 0x36, 0xA1, 0x08, 0x70, 0x0A, 0x01, 0x41, 0x30, + 0x36, 0x36, 0xA0, 0x14, 0x93, 0x41, 0x42, 0x30, + 0x33, 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x30, 0x36, 0x37, 0x0A, 0x00, 0xA1, + 0x07, 0x41, 0x30, 0x36, 0x38, 0x0A, 0x00, 0x08, + 0x41, 0x30, 0x36, 0x39, 0x0A, 0x00, 0x70, 0x41, + 0x30, 0x37, 0x30, 0x41, 0x30, 0x36, 0x39, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x30, 0x70, 0x0A, + 0x01, 0x60, 0xA2, 0x2D, 0x60, 0x70, 0x0A, 0x01, + 0x41, 0x30, 0x37, 0x31, 0x5B, 0x22, 0x0A, 0x1E, + 0xA2, 0x0C, 0x93, 0x41, 0x30, 0x37, 0x32, 0x0A, + 0x01, 0x5B, 0x22, 0x0A, 0x0A, 0xA0, 0x0F, 0x93, + 0x68, 0x0A, 0x01, 0xA0, 0x09, 0x93, 0x41, 0x30, + 0x37, 0x33, 0x0A, 0x00, 0xA5, 0xA1, 0x02, 0xA5, + 0x70, 0x41, 0x30, 0x36, 0x39, 0x41, 0x30, 0x37, + 0x30, 0xA0, 0x14, 0x93, 0x41, 0x42, 0x30, 0x33, + 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x30, 0x36, 0x37, 0x0A, 0x01, 0xA1, 0x07, + 0x41, 0x30, 0x36, 0x38, 0x0A, 0x01, 0xA0, 0x14, + 0x93, 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x36, + 0x33, 0x0A, 0x00, 0x70, 0x0D, 0x50, 0x63, 0x69, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x50, 0x6F, 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x20, 0x45, 0x78, 0x69, 0x74, 0x00, 0x5B, + 0x31, 0x14, 0x28, 0x41, 0x30, 0x35, 0x37, 0x01, + 0x70, 0x73, 0x0D, 0x20, 0x53, 0x65, 0x74, 0x20, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x68, 0x00, 0x41, 0x44, + 0x42, 0x47, 0x5B, 0x31, 0x70, 0x68, 0x41, 0x42, + 0x31, 0x30, 0x14, 0x22, 0x41, 0x30, 0x35, 0x38, + 0x01, 0x7A, 0x68, 0x0A, 0x08, 0x60, 0xA0, 0x13, + 0x90, 0x92, 0x95, 0x60, 0x41, 0x30, 0x37, 0x34, + 0x92, 0x94, 0x60, 0x41, 0x30, 0x37, 0x35, 0xA4, + 0x0A, 0x01, 0xA4, 0x0A, 0x00, 0x14, 0x1F, 0x41, + 0x30, 0x37, 0x36, 0x01, 0x7D, 0x41, 0x42, 0x30, + 0x44, 0x79, 0x41, 0x42, 0x30, 0x43, 0x0A, 0x03, + 0x00, 0x60, 0xA0, 0x07, 0x93, 0x68, 0x60, 0xA4, + 0x0A, 0x01, 0xA4, 0x0A, 0x00, 0x14, 0x0D, 0x41, + 0x30, 0x35, 0x39, 0x00, 0x70, 0x0A, 0x00, 0x41, + 0x42, 0x31, 0x30, 0x14, 0x42, 0x07, 0x41, 0x30, + 0x36, 0x34, 0x01, 0xA0, 0x0D, 0x92, 0x95, 0x68, + 0x0A, 0x02, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, + 0x37, 0xA0, 0x0D, 0x92, 0x95, 0x68, 0x0A, 0x03, + 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, 0x38, 0xA0, + 0x31, 0x93, 0x68, 0x0A, 0x01, 0x70, 0x0A, 0x01, + 0x41, 0x30, 0x37, 0x39, 0x70, 0x0A, 0x00, 0x41, + 0x30, 0x37, 0x37, 0x70, 0x0A, 0x00, 0x41, 0x30, + 0x37, 0x38, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x38, + 0x30, 0xA0, 0x0F, 0x93, 0x41, 0x42, 0x30, 0x34, + 0x0A, 0x01, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x38, + 0x31, 0xA1, 0x16, 0x70, 0x0A, 0x00, 0x41, 0x30, + 0x37, 0x39, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x38, + 0x30, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x38, 0x31, + 0x70, 0x68, 0x41, 0x30, 0x38, 0x32, 0x14, 0x41, + 0x32, 0x41, 0x30, 0x36, 0x30, 0x00, 0x70, 0x0D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x00, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x43, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x44, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, + 0x6F, 0x72, 0x74, 0x41, 0x63, 0x53, 0x70, 0x65, + 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x45, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x50, 0x6F, 0x72, 0x74, 0x4D, 0x61, 0x78, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x30, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, 0x74, 0x41, + 0x63, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x45, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, + 0x74, 0x44, 0x63, 0x53, 0x70, 0x65, 0x65, 0x64, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x31, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, + 0x6F, 0x72, 0x74, 0x43, 0x75, 0x72, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x32, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x53, 0x62, 0x50, 0x6F, 0x72, 0x74, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x33, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x4C, 0x69, 0x6E, 0x6B, 0x53, + 0x61, 0x66, 0x65, 0x4D, 0x6F, 0x64, 0x65, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x34, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x4C, 0x6F, 0x63, + 0x61, 0x6C, 0x4F, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x35, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x50, 0x68, 0x79, 0x4C, 0x61, 0x6E, 0x65, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x36, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x45, 0x6E, 0x64, + 0x50, 0x68, 0x79, 0x4C, 0x61, 0x6E, 0x65, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x37, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x72, 0x65, + 0x4C, 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x38, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x45, 0x6E, 0x64, 0x43, 0x6F, 0x72, 0x65, + 0x4C, 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x39, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x6F, 0x72, 0x74, 0x49, + 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x41, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x4C, 0x69, 0x6E, + 0x6B, 0x48, 0x6F, 0x74, 0x70, 0x6C, 0x75, 0x67, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x42, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x0D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x00, 0x5B, 0x31, + 0x14, 0x42, 0x05, 0x41, 0x30, 0x39, 0x34, 0x02, + 0xA0, 0x11, 0x93, 0x41, 0x30, 0x39, 0x33, 0x68, + 0x0A, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, + 0x0A, 0x00, 0x70, 0x41, 0x30, 0x39, 0x33, 0x68, + 0x0A, 0x34, 0x60, 0xA2, 0x2F, 0x0A, 0x01, 0x70, + 0x41, 0x30, 0x39, 0x33, 0x68, 0x7B, 0x60, 0x0A, + 0xFF, 0x00, 0x61, 0xA0, 0x0E, 0x93, 0x7B, 0x61, + 0x0A, 0xFF, 0x00, 0x69, 0xA4, 0x7B, 0x60, 0x0A, + 0xFF, 0x00, 0x7B, 0x7A, 0x61, 0x0A, 0x08, 0x00, + 0x0A, 0xFF, 0x60, 0xA0, 0x07, 0x93, 0x60, 0x0A, + 0x00, 0xA4, 0x60, 0x08, 0x41, 0x45, 0x53, 0x50, + 0x12, 0x12, 0x08, 0x0A, 0x00, 0x0A, 0x00, 0x0A, + 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, + 0x00, 0x0A, 0x00, 0x14, 0x49, 0x0D, 0x41, 0x30, + 0x36, 0x38, 0x01, 0x70, 0x0D, 0x50, 0x63, 0x69, + 0x65, 0x45, 0x70, 0x41, 0x73, 0x70, 0x6D, 0x20, + 0x45, 0x6E, 0x74, 0x65, 0x72, 0x00, 0x5B, 0x31, + 0x70, 0x0A, 0x00, 0x60, 0xA0, 0x49, 0x08, 0x92, + 0x93, 0x41, 0x30, 0x39, 0x33, 0x60, 0x0A, 0x00, + 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0x7B, 0x41, 0x30, + 0x39, 0x33, 0x60, 0x0A, 0x08, 0x0A, 0x80, 0x61, + 0xA0, 0x09, 0x93, 0x61, 0x0A, 0x80, 0x70, 0x0A, + 0x07, 0x67, 0xA1, 0x05, 0x70, 0x0A, 0x00, 0x67, + 0xA2, 0x4D, 0x05, 0x92, 0x94, 0x60, 0x67, 0x70, + 0x41, 0x30, 0x39, 0x34, 0x60, 0x0A, 0x10, 0x61, + 0xA0, 0x08, 0x93, 0x61, 0x0A, 0x00, 0x75, 0x60, + 0x9F, 0xA0, 0x2B, 0x93, 0x68, 0x0A, 0x00, 0x70, + 0x41, 0x30, 0x39, 0x33, 0x60, 0x72, 0x61, 0x0A, + 0x10, 0x00, 0x62, 0x41, 0x30, 0x39, 0x35, 0x60, + 0x72, 0x61, 0x0A, 0x10, 0x00, 0x7B, 0x62, 0x80, + 0x0A, 0x03, 0x00, 0x00, 0x70, 0x62, 0x88, 0x41, + 0x45, 0x53, 0x50, 0x60, 0x00, 0xA1, 0x16, 0x70, + 0x83, 0x88, 0x41, 0x45, 0x53, 0x50, 0x60, 0x00, + 0x62, 0x41, 0x30, 0x39, 0x35, 0x60, 0x72, 0x61, + 0x0A, 0x10, 0x00, 0x62, 0x75, 0x60, 0xA1, 0x1A, + 0x70, 0x0D, 0x45, 0x6E, 0x64, 0x70, 0x6F, 0x69, + 0x6E, 0x74, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6E, 0x74, 0x00, 0x5B, + 0x31, 0x70, 0x0D, 0x50, 0x63, 0x69, 0x65, 0x45, + 0x70, 0x41, 0x73, 0x70, 0x6D, 0x20, 0x45, 0x78, + 0x69, 0x74, 0x00, 0x5B, 0x31, 0x14, 0x3D, 0x41, + 0x30, 0x39, 0x35, 0x0B, 0x72, 0x41, 0x47, 0x52, + 0x42, 0x79, 0x41, 0x30, 0x37, 0x34, 0x0A, 0x14, + 0x00, 0x60, 0x72, 0x60, 0x79, 0x68, 0x0A, 0x0C, + 0x00, 0x60, 0x72, 0x60, 0x69, 0x60, 0x5B, 0x80, + 0x41, 0x44, 0x52, 0x42, 0x00, 0x60, 0x0A, 0x04, + 0x5B, 0x81, 0x0B, 0x41, 0x44, 0x52, 0x42, 0x03, + 0x41, 0x44, 0x52, 0x52, 0x20, 0x70, 0x6A, 0x41, + 0x44, 0x52, 0x52, 0x14, 0x3C, 0x41, 0x30, 0x39, + 0x33, 0x0A, 0x72, 0x41, 0x47, 0x52, 0x42, 0x79, + 0x41, 0x30, 0x37, 0x34, 0x0A, 0x14, 0x00, 0x60, + 0x72, 0x60, 0x79, 0x68, 0x0A, 0x0C, 0x00, 0x60, + 0x72, 0x60, 0x69, 0x60, 0x5B, 0x80, 0x41, 0x44, + 0x52, 0x42, 0x00, 0x60, 0x0A, 0x04, 0x5B, 0x81, + 0x0B, 0x41, 0x44, 0x52, 0x42, 0x03, 0x41, 0x44, + 0x52, 0x52, 0x20, 0xA4, 0x41, 0x44, 0x52, 0x52, + 0x14, 0x19, 0x41, 0x30, 0x38, 0x39, 0x01, 0xA0, + 0x0C, 0x92, 0x93, 0x41, 0x42, 0x30, 0x42, 0x0A, + 0x01, 0xA4, 0x0A, 0x00, 0xA4, 0x41, 0x30, 0x37, + 0x36, 0x68, 0x14, 0x49, 0x25, 0x41, 0x30, 0x39, + 0x30, 0x01, 0x08, 0x41, 0x30, 0x36, 0x39, 0x0A, + 0x00, 0x70, 0x41, 0x30, 0x37, 0x30, 0x41, 0x30, + 0x36, 0x39, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x37, + 0x30, 0xA0, 0x09, 0x93, 0x68, 0x0A, 0x01, 0x70, + 0x0A, 0x01, 0x60, 0xA1, 0x05, 0x70, 0x0A, 0x05, + 0x60, 0xA2, 0x46, 0x1E, 0x92, 0x93, 0x60, 0x0A, + 0x08, 0xA0, 0x41, 0x04, 0x93, 0x60, 0x0A, 0x01, + 0xA0, 0x15, 0x94, 0x41, 0x42, 0x30, 0x45, 0x0A, + 0x01, 0x70, 0x41, 0x42, 0x30, 0x45, 0x41, 0x42, + 0x30, 0x35, 0x41, 0x30, 0x33, 0x38, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x39, 0x31, + 0x0A, 0x01, 0x41, 0x42, 0x30, 0x36, 0x41, 0x42, + 0x30, 0x37, 0x41, 0x30, 0x39, 0x32, 0x0A, 0x01, + 0x70, 0x0A, 0x00, 0x41, 0x30, 0x38, 0x37, 0x70, + 0x0A, 0x03, 0x60, 0xA0, 0x4D, 0x04, 0x93, 0x60, + 0x0A, 0x03, 0x70, 0x0A, 0x00, 0x61, 0x70, 0x0A, + 0x00, 0x62, 0xA2, 0x2E, 0x95, 0x61, 0x0A, 0x3C, + 0xA0, 0x22, 0x94, 0x41, 0x30, 0x36, 0x35, 0x0A, + 0x04, 0x70, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x20, 0x64, 0x65, 0x74, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x00, 0x5B, 0x31, 0x70, 0x0A, + 0x01, 0x62, 0xA5, 0x5B, 0x22, 0x0A, 0x01, 0x75, + 0x61, 0xA0, 0x09, 0x93, 0x62, 0x0A, 0x01, 0x70, + 0x0A, 0x04, 0x60, 0xA1, 0x05, 0x70, 0x0A, 0x05, + 0x60, 0xA0, 0x45, 0x06, 0x93, 0x60, 0x0A, 0x04, + 0x70, 0x0A, 0x00, 0x61, 0x70, 0x0A, 0x00, 0x62, + 0xA2, 0x37, 0x95, 0x61, 0x0A, 0x50, 0xA0, 0x2B, + 0x90, 0x92, 0x95, 0x41, 0x30, 0x36, 0x35, 0x0A, + 0x10, 0x92, 0x94, 0x41, 0x30, 0x36, 0x35, 0x0A, + 0x13, 0x70, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x20, 0x50, 0x72, 0x65, 0x73, 0x65, + 0x6E, 0x74, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x01, + 0x62, 0xA5, 0x5B, 0x22, 0x0A, 0x01, 0x75, 0x61, + 0xA0, 0x09, 0x93, 0x62, 0x0A, 0x01, 0x70, 0x0A, + 0x07, 0x60, 0xA1, 0x14, 0xA0, 0x0C, 0x93, 0x41, + 0x42, 0x30, 0x34, 0x0A, 0x01, 0x70, 0x0A, 0x05, + 0x60, 0xA1, 0x05, 0x70, 0x0A, 0x06, 0x60, 0xA0, + 0x45, 0x07, 0x93, 0x60, 0x0A, 0x06, 0x70, 0x0A, + 0x01, 0x41, 0x42, 0x30, 0x34, 0x70, 0x0A, 0x01, + 0x41, 0x42, 0x30, 0x35, 0x41, 0x30, 0x36, 0x34, + 0x0A, 0x01, 0xA0, 0x46, 0x05, 0x5B, 0x12, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x4C, 0x49, + 0x43, 0x66, 0x70, 0x0D, 0x20, 0x43, 0x61, 0x6C, + 0x6C, 0x20, 0x41, 0x4C, 0x49, 0x43, 0x20, 0x6D, + 0x65, 0x74, 0x68, 0x6F, 0x64, 0x00, 0x5B, 0x31, + 0x7D, 0x79, 0x41, 0x42, 0x30, 0x43, 0x0A, 0x03, + 0x00, 0x41, 0x42, 0x30, 0x44, 0x61, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x4C, 0x49, 0x43, + 0x61, 0x0A, 0x00, 0x5B, 0x22, 0x0A, 0x02, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x4C, 0x49, + 0x43, 0x61, 0x0A, 0x01, 0x70, 0x0A, 0x03, 0x60, + 0x9F, 0x70, 0x0A, 0x05, 0x60, 0xA0, 0x44, 0x06, + 0x93, 0x60, 0x0A, 0x05, 0x70, 0x0D, 0x20, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x6E, 0x6F, + 0x74, 0x20, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6E, + 0x74, 0x00, 0x5B, 0x31, 0x41, 0x30, 0x39, 0x33, + 0x0A, 0x00, 0x0A, 0x00, 0x70, 0x0A, 0x01, 0x41, + 0x30, 0x38, 0x37, 0x41, 0x30, 0x39, 0x32, 0x0A, + 0x00, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x30, 0x39, 0x31, 0x0A, 0x00, 0x41, 0x42, 0x30, + 0x36, 0x41, 0x42, 0x30, 0x37, 0x70, 0x0A, 0x00, + 0x41, 0x42, 0x30, 0x35, 0x70, 0x0A, 0x00, 0x41, + 0x42, 0x30, 0x34, 0x70, 0x0A, 0x00, 0x41, 0x42, + 0x31, 0x30, 0x70, 0x0A, 0x00, 0x62, 0x70, 0x0A, + 0x08, 0x60, 0xA0, 0x0D, 0x93, 0x60, 0x0A, 0x07, + 0x70, 0x0A, 0x01, 0x62, 0x70, 0x0A, 0x08, 0x60, + 0xA0, 0x0F, 0x93, 0x41, 0x42, 0x30, 0x34, 0x0A, + 0x00, 0x70, 0x0A, 0x00, 0x41, 0x42, 0x30, 0x35, + 0xA0, 0x28, 0x91, 0x94, 0x41, 0x42, 0x30, 0x45, + 0x0A, 0x01, 0x93, 0x41, 0x50, 0x30, 0x35, 0x0A, + 0x01, 0xA0, 0x17, 0x94, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x0A, 0x00, 0x00, 0x0A, 0x01, 0x41, 0x30, 0x33, + 0x38, 0x70, 0x41, 0x30, 0x36, 0x39, 0x41, 0x30, + 0x37, 0x30, 0xA4, 0x62, 0x14, 0x46, 0x05, 0x41, + 0x30, 0x39, 0x32, 0x01, 0xA0, 0x14, 0x94, 0x41, + 0x42, 0x30, 0x36, 0x41, 0x42, 0x30, 0x37, 0x74, + 0x41, 0x42, 0x30, 0x36, 0x41, 0x42, 0x30, 0x37, + 0x60, 0xA1, 0x0B, 0x74, 0x41, 0x42, 0x30, 0x37, + 0x41, 0x42, 0x30, 0x36, 0x60, 0x75, 0x60, 0x79, + 0x0A, 0x01, 0x60, 0x60, 0x76, 0x60, 0x79, 0x60, + 0x41, 0x42, 0x30, 0x38, 0x60, 0xA0, 0x0F, 0x93, + 0x68, 0x0A, 0x01, 0x7D, 0x41, 0x30, 0x38, 0x38, + 0x60, 0x41, 0x30, 0x38, 0x38, 0xA1, 0x0D, 0x7B, + 0x41, 0x30, 0x38, 0x38, 0x80, 0x60, 0x00, 0x41, + 0x30, 0x38, 0x38, 0x5B, 0x82, 0x4A, 0xE6, 0x41, + 0x42, 0x52, 0x34, 0x08, 0x5F, 0x48, 0x49, 0x44, + 0x0C, 0x41, 0xD0, 0x0C, 0x02, 0x08, 0x5F, 0x55, + 0x49, 0x44, 0x0A, 0x84, 0x08, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x70, 0x08, 0x41, 0x42, 0x30, 0x30, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x31, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x45, 0x0A, 0x00, + 0x08, 0x41, 0x42, 0x30, 0x32, 0x0A, 0x00, 0x08, + 0x41, 0x42, 0x30, 0x33, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x34, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x35, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, + 0x36, 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x37, + 0x0A, 0x00, 0x08, 0x41, 0x42, 0x30, 0x38, 0x0A, + 0x00, 0x08, 0x41, 0x42, 0x30, 0x39, 0x0A, 0x00, + 0x08, 0x41, 0x42, 0x30, 0x41, 0x0A, 0x00, 0x08, + 0x41, 0x42, 0x30, 0x42, 0x0A, 0x00, 0x08, 0x41, + 0x42, 0x30, 0x43, 0x0A, 0x00, 0x08, 0x41, 0x42, + 0x30, 0x44, 0x0A, 0x00, 0x5B, 0x80, 0x41, 0x30, + 0x38, 0x33, 0x00, 0x72, 0x41, 0x47, 0x52, 0x42, + 0x7D, 0x79, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x0D, 0x00, 0x00, 0x0A, + 0x0F, 0x00, 0x79, 0x83, 0x88, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, + 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0E, 0x00, 0x00, + 0x0A, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x10, + 0x5B, 0x81, 0x45, 0x04, 0x41, 0x30, 0x38, 0x33, + 0x01, 0x00, 0x40, 0x0C, 0x00, 0x08, 0x41, 0x30, + 0x37, 0x34, 0x08, 0x41, 0x30, 0x37, 0x35, 0x08, + 0x00, 0x48, 0x26, 0x41, 0x30, 0x37, 0x30, 0x02, + 0x00, 0x03, 0x41, 0x30, 0x37, 0x31, 0x01, 0x00, + 0x0A, 0x00, 0x0B, 0x41, 0x30, 0x37, 0x32, 0x01, + 0x00, 0x44, 0x0E, 0x41, 0x30, 0x38, 0x32, 0x04, + 0x00, 0x01, 0x41, 0x30, 0x37, 0x39, 0x01, 0x00, + 0x4A, 0x2B, 0x41, 0x30, 0x38, 0x34, 0x20, 0x5B, + 0x87, 0x16, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA1, 0x03, 0x00, 0x40, 0x72, + 0x00, 0x0C, 0x41, 0x30, 0x36, 0x36, 0x01, 0x5B, + 0x87, 0x16, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA2, 0x03, 0x00, 0x40, 0x72, + 0x00, 0x0D, 0x41, 0x30, 0x38, 0x31, 0x01, 0x5B, + 0x87, 0x27, 0x41, 0x30, 0x38, 0x33, 0x41, 0x30, + 0x38, 0x34, 0x0A, 0xA4, 0x03, 0x00, 0x40, 0x72, + 0x41, 0x30, 0x37, 0x37, 0x01, 0x41, 0x30, 0x37, + 0x38, 0x01, 0x00, 0x0B, 0x41, 0x30, 0x37, 0x33, + 0x02, 0x00, 0x0E, 0x41, 0x30, 0x38, 0x30, 0x01, + 0x5B, 0x87, 0x14, 0x41, 0x30, 0x38, 0x33, 0x41, + 0x30, 0x38, 0x34, 0x0A, 0xA5, 0x03, 0x00, 0x40, + 0x72, 0x41, 0x30, 0x36, 0x35, 0x06, 0x5B, 0x80, + 0x41, 0x30, 0x38, 0x35, 0x00, 0x41, 0x47, 0x52, + 0x42, 0x0B, 0x00, 0x10, 0x5B, 0x81, 0x0E, 0x41, + 0x30, 0x38, 0x35, 0x01, 0x00, 0x40, 0x70, 0x41, + 0x30, 0x38, 0x36, 0x20, 0x5B, 0x87, 0x3C, 0x41, + 0x30, 0x38, 0x35, 0x41, 0x30, 0x38, 0x36, 0x7D, + 0x79, 0x5E, 0x57, 0x52, 0x42, 0x53, 0x0A, 0x10, + 0x00, 0x72, 0x0B, 0x00, 0x08, 0x77, 0x0B, 0x00, + 0x01, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, + 0x31, 0x32, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x40, 0x72, 0x41, 0x30, 0x38, + 0x37, 0x01, 0x5B, 0x87, 0x20, 0x41, 0x30, 0x38, + 0x35, 0x41, 0x30, 0x38, 0x36, 0x7D, 0x79, 0x5E, + 0x57, 0x52, 0x42, 0x53, 0x0A, 0x10, 0x00, 0x0B, + 0x29, 0x80, 0x00, 0x03, 0x00, 0x40, 0x72, 0x41, + 0x30, 0x38, 0x38, 0x10, 0x08, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x00, 0x14, 0x4D, 0x18, 0x5F, 0x49, + 0x4E, 0x49, 0x00, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x00, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x30, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x01, 0x00, 0x00, 0x41, 0x42, 0x30, 0x45, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x02, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x31, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x03, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x32, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x04, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x33, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x05, 0x00, 0x00, 0x41, 0x42, 0x30, 0x34, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x06, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x35, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x07, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x36, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x08, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x37, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x09, 0x00, 0x00, 0x41, 0x42, 0x30, 0x38, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x0A, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x39, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, + 0x42, 0x31, 0x32, 0x0A, 0x0B, 0x00, 0x00, 0x41, + 0x42, 0x30, 0x41, 0x70, 0x83, 0x88, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, + 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, 0x0C, 0x00, + 0x00, 0x41, 0x42, 0x30, 0x42, 0x70, 0x83, 0x88, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x44, + 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, 0x32, 0x0A, + 0x0D, 0x00, 0x00, 0x41, 0x42, 0x30, 0x43, 0x70, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x72, 0x41, 0x42, 0x31, + 0x32, 0x0A, 0x0E, 0x00, 0x00, 0x41, 0x42, 0x30, + 0x44, 0x14, 0x22, 0x41, 0x30, 0x36, 0x31, 0x00, + 0x70, 0x41, 0x30, 0x34, 0x31, 0x60, 0xA0, 0x0A, + 0x93, 0x60, 0x0A, 0x01, 0xA4, 0x41, 0x42, 0x30, + 0x31, 0xA0, 0x0A, 0x93, 0x60, 0x0A, 0x00, 0xA4, + 0x41, 0x42, 0x30, 0x45, 0x14, 0x1F, 0x41, 0x30, + 0x35, 0x35, 0x00, 0xA0, 0x15, 0x92, 0x93, 0x41, + 0x42, 0x31, 0x30, 0x0A, 0x00, 0xA0, 0x0B, 0x93, + 0x41, 0x42, 0x31, 0x30, 0x0A, 0x01, 0xA4, 0x0A, + 0x01, 0xA4, 0x0A, 0x00, 0x14, 0x2A, 0x41, 0x30, + 0x36, 0x32, 0x00, 0xA0, 0x0E, 0x92, 0x93, 0x41, + 0x42, 0x30, 0x35, 0x0A, 0x00, 0xA4, 0x41, 0x42, + 0x30, 0x35, 0xA0, 0x11, 0x94, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x01, 0xA4, 0x74, 0x41, 0x42, 0x31, + 0x30, 0x0A, 0x01, 0x00, 0xA4, 0x0A, 0x00, 0x14, + 0x49, 0x07, 0x41, 0x30, 0x35, 0x34, 0x00, 0xA0, + 0x22, 0x93, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x50, 0x30, 0x35, 0x0A, 0x00, 0xA0, 0x0E, + 0x92, 0x93, 0x41, 0x42, 0x30, 0x35, 0x0A, 0x00, + 0xA4, 0x41, 0x42, 0x30, 0x35, 0xA4, 0x41, 0x42, + 0x30, 0x45, 0x70, 0x41, 0x30, 0x36, 0x32, 0x60, + 0xA0, 0x17, 0x92, 0x93, 0x60, 0x0A, 0x00, 0xA0, + 0x0C, 0x94, 0x60, 0x41, 0x42, 0x30, 0x30, 0xA4, + 0x41, 0x42, 0x30, 0x30, 0xA1, 0x03, 0xA4, 0x60, + 0x70, 0x41, 0x30, 0x36, 0x31, 0x60, 0xA0, 0x28, + 0x92, 0x93, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x50, 0x30, 0x33, 0x0A, 0x00, 0xA0, 0x18, + 0x95, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, + 0x50, 0x30, 0x33, 0x60, 0xA4, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x50, 0x30, 0x33, 0xA4, + 0x60, 0x14, 0x0B, 0x41, 0x30, 0x35, 0x33, 0x00, + 0xA4, 0x41, 0x42, 0x30, 0x32, 0x14, 0x0B, 0x41, + 0x30, 0x35, 0x36, 0x00, 0xA4, 0x41, 0x42, 0x30, + 0x30, 0x14, 0x4B, 0x13, 0x41, 0x30, 0x35, 0x32, + 0x01, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x50, 0x6F, 0x72, 0x74, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x20, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x00, + 0x98, 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x68, 0x41, 0x42, 0x30, 0x32, 0xA0, + 0x14, 0x93, 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, + 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, + 0x36, 0x33, 0x0A, 0x01, 0x41, 0x30, 0x36, 0x34, + 0x68, 0xA0, 0x40, 0x0B, 0x92, 0x95, 0x41, 0x30, + 0x36, 0x35, 0x0A, 0x10, 0xA0, 0x10, 0x92, 0x93, + 0x41, 0x42, 0x31, 0x30, 0x0A, 0x00, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x36, 0x36, 0xA1, 0x08, 0x70, + 0x0A, 0x01, 0x41, 0x30, 0x36, 0x36, 0xA0, 0x14, + 0x93, 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, 0x5C, + 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x36, + 0x37, 0x0A, 0x00, 0xA1, 0x07, 0x41, 0x30, 0x36, + 0x38, 0x0A, 0x00, 0x08, 0x41, 0x30, 0x36, 0x39, + 0x0A, 0x00, 0x70, 0x41, 0x30, 0x37, 0x30, 0x41, + 0x30, 0x36, 0x39, 0x70, 0x0A, 0x00, 0x41, 0x30, + 0x37, 0x30, 0x70, 0x0A, 0x01, 0x60, 0xA2, 0x2D, + 0x60, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, 0x31, + 0x5B, 0x22, 0x0A, 0x1E, 0xA2, 0x0C, 0x93, 0x41, + 0x30, 0x37, 0x32, 0x0A, 0x01, 0x5B, 0x22, 0x0A, + 0x0A, 0xA0, 0x0F, 0x93, 0x68, 0x0A, 0x01, 0xA0, + 0x09, 0x93, 0x41, 0x30, 0x37, 0x33, 0x0A, 0x00, + 0xA5, 0xA1, 0x02, 0xA5, 0x70, 0x41, 0x30, 0x36, + 0x39, 0x41, 0x30, 0x37, 0x30, 0xA0, 0x14, 0x93, + 0x41, 0x42, 0x30, 0x33, 0x0A, 0x01, 0x5C, 0x2E, + 0x5F, 0x53, 0x42, 0x5F, 0x41, 0x30, 0x36, 0x37, + 0x0A, 0x01, 0xA1, 0x07, 0x41, 0x30, 0x36, 0x38, + 0x0A, 0x01, 0xA0, 0x14, 0x93, 0x41, 0x42, 0x30, + 0x33, 0x0A, 0x01, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x30, 0x36, 0x33, 0x0A, 0x00, 0x70, + 0x0D, 0x50, 0x63, 0x69, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x50, 0x6F, 0x72, 0x74, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x45, 0x78, + 0x69, 0x74, 0x00, 0x5B, 0x31, 0x14, 0x28, 0x41, + 0x30, 0x35, 0x37, 0x01, 0x70, 0x73, 0x0D, 0x20, + 0x53, 0x65, 0x74, 0x20, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x68, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, + 0x70, 0x68, 0x41, 0x42, 0x31, 0x30, 0x14, 0x22, + 0x41, 0x30, 0x35, 0x38, 0x01, 0x7A, 0x68, 0x0A, + 0x08, 0x60, 0xA0, 0x13, 0x90, 0x92, 0x95, 0x60, + 0x41, 0x30, 0x37, 0x34, 0x92, 0x94, 0x60, 0x41, + 0x30, 0x37, 0x35, 0xA4, 0x0A, 0x01, 0xA4, 0x0A, + 0x00, 0x14, 0x1F, 0x41, 0x30, 0x37, 0x36, 0x01, + 0x7D, 0x41, 0x42, 0x30, 0x44, 0x79, 0x41, 0x42, + 0x30, 0x43, 0x0A, 0x03, 0x00, 0x60, 0xA0, 0x07, + 0x93, 0x68, 0x60, 0xA4, 0x0A, 0x01, 0xA4, 0x0A, + 0x00, 0x14, 0x0D, 0x41, 0x30, 0x35, 0x39, 0x00, + 0x70, 0x0A, 0x00, 0x41, 0x42, 0x31, 0x30, 0x14, + 0x42, 0x07, 0x41, 0x30, 0x36, 0x34, 0x01, 0xA0, + 0x0D, 0x92, 0x95, 0x68, 0x0A, 0x02, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x37, 0x37, 0xA0, 0x0D, 0x92, + 0x95, 0x68, 0x0A, 0x03, 0x70, 0x0A, 0x01, 0x41, + 0x30, 0x37, 0x38, 0xA0, 0x31, 0x93, 0x68, 0x0A, + 0x01, 0x70, 0x0A, 0x01, 0x41, 0x30, 0x37, 0x39, + 0x70, 0x0A, 0x00, 0x41, 0x30, 0x37, 0x37, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x38, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x38, 0x30, 0xA0, 0x0F, 0x93, + 0x41, 0x42, 0x30, 0x34, 0x0A, 0x01, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x38, 0x31, 0xA1, 0x16, 0x70, + 0x0A, 0x00, 0x41, 0x30, 0x37, 0x39, 0x70, 0x0A, + 0x01, 0x41, 0x30, 0x38, 0x30, 0x70, 0x0A, 0x00, + 0x41, 0x30, 0x38, 0x31, 0x70, 0x68, 0x41, 0x30, + 0x38, 0x32, 0x14, 0x41, 0x32, 0x41, 0x30, 0x36, + 0x30, 0x00, 0x70, 0x0D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x00, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x43, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x46, 0x75, 0x6E, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x44, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, 0x74, 0x41, + 0x63, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x45, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, + 0x74, 0x4D, 0x61, 0x78, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x30, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x50, + 0x6F, 0x72, 0x74, 0x41, 0x63, 0x53, 0x70, 0x65, + 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x45, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x50, 0x6F, 0x72, 0x74, 0x44, 0x63, 0x53, + 0x70, 0x65, 0x65, 0x64, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x31, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x63, 0x69, 0x65, 0x50, 0x6F, 0x72, 0x74, 0x43, + 0x75, 0x72, 0x53, 0x70, 0x65, 0x65, 0x64, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x32, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x50, 0x63, 0x69, 0x65, 0x53, 0x62, 0x50, + 0x6F, 0x72, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x33, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, 0x65, 0x4C, + 0x69, 0x6E, 0x6B, 0x53, 0x61, 0x66, 0x65, 0x4D, + 0x6F, 0x64, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x34, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, 0x63, 0x69, + 0x65, 0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x4F, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x35, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x50, 0x68, 0x79, 0x4C, + 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x36, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x45, 0x6E, 0x64, 0x50, 0x68, 0x79, 0x4C, + 0x61, 0x6E, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x37, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x73, 0x0D, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x43, 0x6F, 0x72, 0x65, 0x4C, 0x61, 0x6E, 0x65, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, + 0x30, 0x38, 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, + 0x31, 0x70, 0x73, 0x0D, 0x20, 0x45, 0x6E, 0x64, + 0x43, 0x6F, 0x72, 0x65, 0x4C, 0x61, 0x6E, 0x65, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, 0x00, 0x98, + 0x41, 0x42, 0x30, 0x39, 0x00, 0x41, 0x44, 0x42, + 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, 0x20, 0x50, + 0x6F, 0x72, 0x74, 0x49, 0x64, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0x20, + 0x00, 0x98, 0x41, 0x42, 0x30, 0x41, 0x00, 0x41, + 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, 0x73, 0x0D, + 0x20, 0x4C, 0x69, 0x6E, 0x6B, 0x48, 0x6F, 0x74, + 0x70, 0x6C, 0x75, 0x67, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3A, 0x20, 0x00, 0x98, 0x41, 0x42, 0x30, 0x42, + 0x00, 0x41, 0x44, 0x42, 0x47, 0x5B, 0x31, 0x70, + 0x0D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x00, 0x5B, 0x31, 0x14, 0x42, 0x05, 0x41, + 0x30, 0x39, 0x34, 0x02, 0xA0, 0x11, 0x93, 0x41, + 0x30, 0x39, 0x33, 0x68, 0x0A, 0x00, 0x0C, 0xFF, + 0xFF, 0xFF, 0xFF, 0xA4, 0x0A, 0x00, 0x70, 0x41, + 0x30, 0x39, 0x33, 0x68, 0x0A, 0x34, 0x60, 0xA2, + 0x2F, 0x0A, 0x01, 0x70, 0x41, 0x30, 0x39, 0x33, + 0x68, 0x7B, 0x60, 0x0A, 0xFF, 0x00, 0x61, 0xA0, + 0x0E, 0x93, 0x7B, 0x61, 0x0A, 0xFF, 0x00, 0x69, + 0xA4, 0x7B, 0x60, 0x0A, 0xFF, 0x00, 0x7B, 0x7A, + 0x61, 0x0A, 0x08, 0x00, 0x0A, 0xFF, 0x60, 0xA0, + 0x07, 0x93, 0x60, 0x0A, 0x00, 0xA4, 0x60, 0x08, + 0x41, 0x45, 0x53, 0x50, 0x12, 0x12, 0x08, 0x0A, + 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, + 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x14, + 0x49, 0x0D, 0x41, 0x30, 0x36, 0x38, 0x01, 0x70, + 0x0D, 0x50, 0x63, 0x69, 0x65, 0x45, 0x70, 0x41, + 0x73, 0x70, 0x6D, 0x20, 0x45, 0x6E, 0x74, 0x65, + 0x72, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x00, 0x60, + 0xA0, 0x49, 0x08, 0x92, 0x93, 0x41, 0x30, 0x39, + 0x33, 0x60, 0x0A, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, + 0xFF, 0x7B, 0x41, 0x30, 0x39, 0x33, 0x60, 0x0A, + 0x08, 0x0A, 0x80, 0x61, 0xA0, 0x09, 0x93, 0x61, + 0x0A, 0x80, 0x70, 0x0A, 0x07, 0x67, 0xA1, 0x05, + 0x70, 0x0A, 0x00, 0x67, 0xA2, 0x4D, 0x05, 0x92, + 0x94, 0x60, 0x67, 0x70, 0x41, 0x30, 0x39, 0x34, + 0x60, 0x0A, 0x10, 0x61, 0xA0, 0x08, 0x93, 0x61, + 0x0A, 0x00, 0x75, 0x60, 0x9F, 0xA0, 0x2B, 0x93, + 0x68, 0x0A, 0x00, 0x70, 0x41, 0x30, 0x39, 0x33, + 0x60, 0x72, 0x61, 0x0A, 0x10, 0x00, 0x62, 0x41, + 0x30, 0x39, 0x35, 0x60, 0x72, 0x61, 0x0A, 0x10, + 0x00, 0x7B, 0x62, 0x80, 0x0A, 0x03, 0x00, 0x00, + 0x70, 0x62, 0x88, 0x41, 0x45, 0x53, 0x50, 0x60, + 0x00, 0xA1, 0x16, 0x70, 0x83, 0x88, 0x41, 0x45, + 0x53, 0x50, 0x60, 0x00, 0x62, 0x41, 0x30, 0x39, + 0x35, 0x60, 0x72, 0x61, 0x0A, 0x10, 0x00, 0x62, + 0x75, 0x60, 0xA1, 0x1A, 0x70, 0x0D, 0x45, 0x6E, + 0x64, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x6E, + 0x6F, 0x74, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6E, 0x74, 0x00, 0x5B, 0x31, 0x70, 0x0D, 0x50, + 0x63, 0x69, 0x65, 0x45, 0x70, 0x41, 0x73, 0x70, + 0x6D, 0x20, 0x45, 0x78, 0x69, 0x74, 0x00, 0x5B, + 0x31, 0x14, 0x3D, 0x41, 0x30, 0x39, 0x35, 0x0B, + 0x72, 0x41, 0x47, 0x52, 0x42, 0x79, 0x41, 0x30, + 0x37, 0x34, 0x0A, 0x14, 0x00, 0x60, 0x72, 0x60, + 0x79, 0x68, 0x0A, 0x0C, 0x00, 0x60, 0x72, 0x60, + 0x69, 0x60, 0x5B, 0x80, 0x41, 0x44, 0x52, 0x42, + 0x00, 0x60, 0x0A, 0x04, 0x5B, 0x81, 0x0B, 0x41, + 0x44, 0x52, 0x42, 0x03, 0x41, 0x44, 0x52, 0x52, + 0x20, 0x70, 0x6A, 0x41, 0x44, 0x52, 0x52, 0x14, + 0x3C, 0x41, 0x30, 0x39, 0x33, 0x0A, 0x72, 0x41, + 0x47, 0x52, 0x42, 0x79, 0x41, 0x30, 0x37, 0x34, + 0x0A, 0x14, 0x00, 0x60, 0x72, 0x60, 0x79, 0x68, + 0x0A, 0x0C, 0x00, 0x60, 0x72, 0x60, 0x69, 0x60, + 0x5B, 0x80, 0x41, 0x44, 0x52, 0x42, 0x00, 0x60, + 0x0A, 0x04, 0x5B, 0x81, 0x0B, 0x41, 0x44, 0x52, + 0x42, 0x03, 0x41, 0x44, 0x52, 0x52, 0x20, 0xA4, + 0x41, 0x44, 0x52, 0x52, 0x14, 0x19, 0x41, 0x30, + 0x38, 0x39, 0x01, 0xA0, 0x0C, 0x92, 0x93, 0x41, + 0x42, 0x30, 0x42, 0x0A, 0x01, 0xA4, 0x0A, 0x00, + 0xA4, 0x41, 0x30, 0x37, 0x36, 0x68, 0x14, 0x49, + 0x25, 0x41, 0x30, 0x39, 0x30, 0x01, 0x08, 0x41, + 0x30, 0x36, 0x39, 0x0A, 0x00, 0x70, 0x41, 0x30, + 0x37, 0x30, 0x41, 0x30, 0x36, 0x39, 0x70, 0x0A, + 0x00, 0x41, 0x30, 0x37, 0x30, 0xA0, 0x09, 0x93, + 0x68, 0x0A, 0x01, 0x70, 0x0A, 0x01, 0x60, 0xA1, + 0x05, 0x70, 0x0A, 0x05, 0x60, 0xA2, 0x46, 0x1E, + 0x92, 0x93, 0x60, 0x0A, 0x08, 0xA0, 0x41, 0x04, + 0x93, 0x60, 0x0A, 0x01, 0xA0, 0x15, 0x94, 0x41, + 0x42, 0x30, 0x45, 0x0A, 0x01, 0x70, 0x41, 0x42, + 0x30, 0x45, 0x41, 0x42, 0x30, 0x35, 0x41, 0x30, + 0x33, 0x38, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x30, 0x39, 0x31, 0x0A, 0x01, 0x41, 0x42, + 0x30, 0x36, 0x41, 0x42, 0x30, 0x37, 0x41, 0x30, + 0x39, 0x32, 0x0A, 0x01, 0x70, 0x0A, 0x00, 0x41, + 0x30, 0x38, 0x37, 0x70, 0x0A, 0x03, 0x60, 0xA0, + 0x4D, 0x04, 0x93, 0x60, 0x0A, 0x03, 0x70, 0x0A, + 0x00, 0x61, 0x70, 0x0A, 0x00, 0x62, 0xA2, 0x2E, + 0x95, 0x61, 0x0A, 0x3C, 0xA0, 0x22, 0x94, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x04, 0x70, 0x0D, 0x20, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x64, + 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x00, + 0x5B, 0x31, 0x70, 0x0A, 0x01, 0x62, 0xA5, 0x5B, + 0x22, 0x0A, 0x01, 0x75, 0x61, 0xA0, 0x09, 0x93, + 0x62, 0x0A, 0x01, 0x70, 0x0A, 0x04, 0x60, 0xA1, + 0x05, 0x70, 0x0A, 0x05, 0x60, 0xA0, 0x45, 0x06, + 0x93, 0x60, 0x0A, 0x04, 0x70, 0x0A, 0x00, 0x61, + 0x70, 0x0A, 0x00, 0x62, 0xA2, 0x37, 0x95, 0x61, + 0x0A, 0x50, 0xA0, 0x2B, 0x90, 0x92, 0x95, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x10, 0x92, 0x94, 0x41, + 0x30, 0x36, 0x35, 0x0A, 0x13, 0x70, 0x0D, 0x20, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x50, + 0x72, 0x65, 0x73, 0x65, 0x6E, 0x74, 0x00, 0x5B, + 0x31, 0x70, 0x0A, 0x01, 0x62, 0xA5, 0x5B, 0x22, + 0x0A, 0x01, 0x75, 0x61, 0xA0, 0x09, 0x93, 0x62, + 0x0A, 0x01, 0x70, 0x0A, 0x07, 0x60, 0xA1, 0x14, + 0xA0, 0x0C, 0x93, 0x41, 0x42, 0x30, 0x34, 0x0A, + 0x01, 0x70, 0x0A, 0x05, 0x60, 0xA1, 0x05, 0x70, + 0x0A, 0x06, 0x60, 0xA0, 0x45, 0x07, 0x93, 0x60, + 0x0A, 0x06, 0x70, 0x0A, 0x01, 0x41, 0x42, 0x30, + 0x34, 0x70, 0x0A, 0x01, 0x41, 0x42, 0x30, 0x35, + 0x41, 0x30, 0x36, 0x34, 0x0A, 0x01, 0xA0, 0x46, + 0x05, 0x5B, 0x12, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x4C, 0x49, 0x43, 0x66, 0x70, 0x0D, + 0x20, 0x43, 0x61, 0x6C, 0x6C, 0x20, 0x41, 0x4C, + 0x49, 0x43, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, + 0x64, 0x00, 0x5B, 0x31, 0x7D, 0x79, 0x41, 0x42, + 0x30, 0x43, 0x0A, 0x03, 0x00, 0x41, 0x42, 0x30, + 0x44, 0x61, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x4C, 0x49, 0x43, 0x61, 0x0A, 0x00, 0x5B, + 0x22, 0x0A, 0x02, 0x5C, 0x2E, 0x5F, 0x53, 0x42, + 0x5F, 0x41, 0x4C, 0x49, 0x43, 0x61, 0x0A, 0x01, + 0x70, 0x0A, 0x03, 0x60, 0x9F, 0x70, 0x0A, 0x05, + 0x60, 0xA0, 0x44, 0x06, 0x93, 0x60, 0x0A, 0x05, + 0x70, 0x0D, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x50, 0x72, + 0x65, 0x73, 0x65, 0x6E, 0x74, 0x00, 0x5B, 0x31, + 0x41, 0x30, 0x39, 0x33, 0x0A, 0x00, 0x0A, 0x00, + 0x70, 0x0A, 0x01, 0x41, 0x30, 0x38, 0x37, 0x41, + 0x30, 0x39, 0x32, 0x0A, 0x00, 0x5C, 0x2E, 0x5F, + 0x53, 0x42, 0x5F, 0x41, 0x30, 0x39, 0x31, 0x0A, + 0x00, 0x41, 0x42, 0x30, 0x36, 0x41, 0x42, 0x30, + 0x37, 0x70, 0x0A, 0x00, 0x41, 0x42, 0x30, 0x35, + 0x70, 0x0A, 0x00, 0x41, 0x42, 0x30, 0x34, 0x70, + 0x0A, 0x00, 0x41, 0x42, 0x31, 0x30, 0x70, 0x0A, + 0x00, 0x62, 0x70, 0x0A, 0x08, 0x60, 0xA0, 0x0D, + 0x93, 0x60, 0x0A, 0x07, 0x70, 0x0A, 0x01, 0x62, + 0x70, 0x0A, 0x08, 0x60, 0xA0, 0x0F, 0x93, 0x41, + 0x42, 0x30, 0x34, 0x0A, 0x00, 0x70, 0x0A, 0x00, + 0x41, 0x42, 0x30, 0x35, 0xA0, 0x28, 0x91, 0x94, + 0x41, 0x42, 0x30, 0x45, 0x0A, 0x01, 0x93, 0x41, + 0x50, 0x30, 0x35, 0x0A, 0x01, 0xA0, 0x17, 0x94, + 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, 0x42, 0x5F, + 0x41, 0x44, 0x41, 0x54, 0x0A, 0x00, 0x00, 0x0A, + 0x01, 0x41, 0x30, 0x33, 0x38, 0x70, 0x41, 0x30, + 0x36, 0x39, 0x41, 0x30, 0x37, 0x30, 0xA4, 0x62, + 0x14, 0x46, 0x05, 0x41, 0x30, 0x39, 0x32, 0x01, + 0xA0, 0x14, 0x94, 0x41, 0x42, 0x30, 0x36, 0x41, + 0x42, 0x30, 0x37, 0x74, 0x41, 0x42, 0x30, 0x36, + 0x41, 0x42, 0x30, 0x37, 0x60, 0xA1, 0x0B, 0x74, + 0x41, 0x42, 0x30, 0x37, 0x41, 0x42, 0x30, 0x36, + 0x60, 0x75, 0x60, 0x79, 0x0A, 0x01, 0x60, 0x60, + 0x76, 0x60, 0x79, 0x60, 0x41, 0x42, 0x30, 0x38, + 0x60, 0xA0, 0x0F, 0x93, 0x68, 0x0A, 0x01, 0x7D, + 0x41, 0x30, 0x38, 0x38, 0x60, 0x41, 0x30, 0x38, + 0x38, 0xA1, 0x0D, 0x7B, 0x41, 0x30, 0x38, 0x38, + 0x80, 0x60, 0x00, 0x41, 0x30, 0x38, 0x38, 0x08, + 0x41, 0x30, 0x30, 0x31, 0x0A, 0x01, 0x08, 0x41, + 0x30, 0x30, 0x32, 0x0A, 0x01, 0x08, 0x41, 0x30, + 0x30, 0x33, 0x0A, 0x00, 0x08, 0x41, 0x30, 0x30, + 0x34, 0x0A, 0x00, 0x14, 0x28, 0x41, 0x50, 0x54, + 0x53, 0x01, 0xA0, 0x21, 0x93, 0x68, 0x0A, 0x03, + 0x41, 0x30, 0x30, 0x35, 0x0A, 0x01, 0x70, 0x41, + 0x30, 0x30, 0x36, 0x0A, 0x00, 0x41, 0x30, 0x30, + 0x33, 0x70, 0x41, 0x30, 0x30, 0x37, 0x0A, 0x00, + 0x41, 0x30, 0x30, 0x34, 0x14, 0x4F, 0x09, 0x41, + 0x57, 0x41, 0x4B, 0x01, 0xA0, 0x47, 0x08, 0x93, + 0x68, 0x0A, 0x03, 0x70, 0x41, 0x30, 0x30, 0x38, + 0x60, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x0A, 0x06, + 0x00, 0x61, 0xA0, 0x31, 0x90, 0x93, 0x60, 0x0A, + 0x01, 0x93, 0x61, 0x0A, 0x01, 0x70, 0x0D, 0x20, + 0x44, 0x63, 0x54, 0x44, 0x50, 0x20, 0x63, 0x61, + 0x70, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x61, 0x6E, + 0x64, 0x20, 0x65, 0x6E, 0x61, 0x62, 0x6C, 0x65, + 0x64, 0x00, 0x5B, 0x31, 0x41, 0x30, 0x30, 0x39, + 0x44, 0x4B, 0x30, 0x30, 0xA1, 0x09, 0x41, 0x30, + 0x30, 0x35, 0x41, 0x44, 0x30, 0x30, 0xA0, 0x0E, + 0x93, 0x41, 0x30, 0x30, 0x33, 0x0A, 0x00, 0x41, + 0x30, 0x30, 0x36, 0x0A, 0x01, 0xA1, 0x07, 0x41, + 0x30, 0x30, 0x36, 0x0A, 0x00, 0xA0, 0x0E, 0x93, + 0x41, 0x30, 0x30, 0x34, 0x0A, 0x01, 0x41, 0x30, + 0x30, 0x37, 0x0A, 0x01, 0xA1, 0x07, 0x41, 0x30, + 0x30, 0x37, 0x0A, 0x00, 0xA0, 0x0F, 0x91, 0x93, + 0x68, 0x0A, 0x03, 0x93, 0x68, 0x0A, 0x04, 0x41, + 0x30, 0x31, 0x30, 0x68, 0x14, 0x2E, 0x41, 0x30, + 0x31, 0x31, 0x00, 0x41, 0x30, 0x31, 0x32, 0x41, + 0x30, 0x31, 0x33, 0x41, 0x50, 0x30, 0x31, 0x41, + 0x44, 0x30, 0x30, 0x41, 0x30, 0x31, 0x34, 0x41, + 0x44, 0x30, 0x30, 0x41, 0x30, 0x31, 0x35, 0x41, + 0x44, 0x30, 0x30, 0x41, 0x30, 0x30, 0x35, 0x41, + 0x44, 0x30, 0x30, 0x14, 0x40, 0x05, 0x41, 0x30, + 0x31, 0x36, 0x00, 0x70, 0x41, 0x30, 0x30, 0x38, + 0x60, 0x70, 0x83, 0x88, 0x5C, 0x2E, 0x5F, 0x53, + 0x42, 0x5F, 0x41, 0x44, 0x41, 0x54, 0x0A, 0x06, + 0x00, 0x61, 0xA0, 0x31, 0x90, 0x93, 0x60, 0x0A, + 0x01, 0x93, 0x61, 0x0A, 0x01, 0x70, 0x0D, 0x20, + 0x44, 0x63, 0x54, 0x44, 0x50, 0x20, 0x63, 0x61, + 0x70, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x61, 0x6E, + 0x64, 0x20, 0x65, 0x6E, 0x61, 0x62, 0x6C, 0x65, + 0x64, 0x00, 0x5B, 0x31, 0x41, 0x30, 0x30, 0x39, + 0x44, 0x4B, 0x30, 0x30, 0x14, 0x0F, 0x41, 0x30, + 0x31, 0x37, 0x02, 0x41, 0x30, 0x31, 0x33, 0x68, + 0x41, 0x44, 0x30, 0x30, 0x08, 0x41, 0x30, 0x31, + 0x38, 0x0A, 0x00, 0x08, 0x41, 0x30, 0x31, 0x39, + 0x0A, 0x00, 0x14, 0x4F, 0x16, 0x41, 0x30, 0x31, + 0x34, 0x01, 0xA0, 0x45, 0x0B, 0x93, 0x68, 0x0A, + 0x00, 0x70, 0x0A, 0x7F, 0x41, 0x30, 0x32, 0x30, + 0x70, 0x0D, 0x20, 0x46, 0x34, 0x78, 0x31, 0x32, + 0x38, 0x5B, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, + 0x6C, 0x75, 0x73, 0x68, 0x54, 0x6D, 0x72, 0x5D, + 0x20, 0x3D, 0x20, 0x30, 0x78, 0x37, 0x46, 0x00, + 0x5B, 0x31, 0x70, 0x0A, 0x02, 0x41, 0x30, 0x32, + 0x31, 0x70, 0x0D, 0x20, 0x46, 0x34, 0x78, 0x32, + 0x31, 0x30, 0x5B, 0x58, 0x43, 0x36, 0x4D, 0x6F, + 0x6E, 0x4D, 0x69, 0x73, 0x70, 0x72, 0x65, 0x64, + 0x69, 0x63, 0x74, 0x41, 0x63, 0x74, 0x5D, 0x20, + 0x3D, 0x20, 0x30, 0x78, 0x32, 0x00, 0x5B, 0x31, + 0x70, 0x0A, 0x04, 0x41, 0x30, 0x32, 0x32, 0x70, + 0x0D, 0x20, 0x46, 0x34, 0x78, 0x32, 0x31, 0x30, + 0x5B, 0x58, 0x43, 0x36, 0x4D, 0x6F, 0x6E, 0x69, + 0x74, 0x6F, 0x72, 0x54, 0x68, 0x72, 0x65, 0x73, + 0x68, 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x34, + 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x0F, 0x41, 0x30, + 0x32, 0x33, 0x70, 0x0D, 0x20, 0x46, 0x33, 0x78, + 0x44, 0x43, 0x5B, 0x43, 0x61, 0x63, 0x68, 0x65, + 0x46, 0x6C, 0x75, 0x73, 0x68, 0x4F, 0x6E, 0x48, + 0x61, 0x6C, 0x74, 0x54, 0x6D, 0x72, 0x5D, 0x20, + 0x3D, 0x20, 0x30, 0x78, 0x46, 0x00, 0x5B, 0x31, + 0xA1, 0x41, 0x0B, 0x70, 0x0A, 0x3C, 0x41, 0x30, + 0x32, 0x30, 0x70, 0x0D, 0x20, 0x46, 0x34, 0x78, + 0x31, 0x32, 0x38, 0x5B, 0x43, 0x61, 0x63, 0x68, + 0x65, 0x46, 0x6C, 0x75, 0x73, 0x68, 0x54, 0x6D, + 0x72, 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x33, + 0x43, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x01, 0x41, + 0x30, 0x32, 0x31, 0x70, 0x0D, 0x20, 0x46, 0x34, + 0x78, 0x32, 0x31, 0x30, 0x5B, 0x58, 0x43, 0x36, + 0x4D, 0x6F, 0x6E, 0x4D, 0x69, 0x73, 0x70, 0x72, + 0x65, 0x64, 0x69, 0x63, 0x74, 0x41, 0x63, 0x74, + 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x31, 0x00, + 0x5B, 0x31, 0x70, 0x0A, 0x02, 0x41, 0x30, 0x32, + 0x32, 0x70, 0x0D, 0x20, 0x46, 0x34, 0x78, 0x32, + 0x31, 0x30, 0x5B, 0x58, 0x43, 0x36, 0x4D, 0x6F, + 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x54, 0x68, 0x72, + 0x65, 0x73, 0x68, 0x5D, 0x20, 0x3D, 0x20, 0x30, + 0x78, 0x32, 0x00, 0x5B, 0x31, 0x70, 0x0A, 0x04, + 0x41, 0x30, 0x32, 0x33, 0x70, 0x0D, 0x20, 0x46, + 0x33, 0x78, 0x44, 0x43, 0x5B, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x46, 0x6C, 0x75, 0x73, 0x68, 0x4F, + 0x6E, 0x48, 0x61, 0x6C, 0x74, 0x54, 0x6D, 0x72, + 0x5D, 0x20, 0x3D, 0x20, 0x30, 0x78, 0x34, 0x00, + 0x5B, 0x31, 0x14, 0x4E, 0x05, 0x41, 0x30, 0x31, + 0x35, 0x01, 0xA0, 0x18, 0x93, 0x41, 0x30, 0x31, + 0x38, 0x0A, 0x00, 0x70, 0x41, 0x30, 0x32, 0x34, + 0x41, 0x30, 0x31, 0x39, 0x70, 0x0A, 0x01, 0x41, + 0x30, 0x31, 0x38, 0xA0, 0x3D, 0x93, 0x41, 0x30, + 0x31, 0x39, 0x0A, 0x01, 0xA0, 0x1C, 0x93, 0x68, + 0x0A, 0x00, 0x70, 0x0A, 0x00, 0x41, 0x30, 0x32, + 0x34, 0x70, 0x0D, 0x20, 0x41, 0x50, 0x4D, 0x20, + 0x4F, 0x46, 0x46, 0x21, 0x21, 0x21, 0x00, 0x5B, + 0x31, 0xA1, 0x17, 0x70, 0x0A, 0x01, 0x41, 0x30, + 0x32, 0x34, 0x70, 0x0D, 0x20, 0x41, 0x50, 0x4D, + 0x20, 0x4F, 0x4E, 0x21, 0x21, 0x21, 0x00, 0x5B, + 0x31, 0x14, 0x40, 0x0C, 0x41, 0x30, 0x31, 0x33, + 0x02, 0xA0, 0x3D, 0x93, 0x69, 0x0A, 0x00, 0x70, + 0x0D, 0x20, 0x4C, 0x43, 0x4C, 0x4B, 0x20, 0x44, + 0x50, 0x4D, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x20, 0x30, 0x20, 0x5B, 0x4F, 0x46, 0x46, 0x5D, + 0x2C, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x35, 0x20, 0x5B, 0x4F, 0x4E, 0x5D, 0x2C, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x36, 0x20, + 0x5B, 0x4F, 0x4E, 0x5D, 0x00, 0x5B, 0x31, 0xA1, + 0x4A, 0x07, 0xA0, 0x3D, 0x93, 0x68, 0x0A, 0x01, + 0x70, 0x0D, 0x20, 0x4C, 0x43, 0x4C, 0x4B, 0x20, + 0x44, 0x50, 0x4D, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x30, 0x20, 0x5B, 0x4F, 0x4E, 0x5D, + 0x2C, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, + 0x35, 0x20, 0x5B, 0x4F, 0x4E, 0x5D, 0x2C, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x36, 0x20, + 0x5B, 0x4F, 0x46, 0x46, 0x5D, 0x00, 0x5B, 0x31, + 0xA1, 0x39, 0x70, 0x0D, 0x20, 0x4C, 0x43, 0x4C, + 0x4B, 0x20, 0x44, 0x50, 0x4D, 0x20, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x20, 0x30, 0x20, 0x5B, 0x4F, + 0x4E, 0x5D, 0x2C, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x35, 0x20, 0x5B, 0x4F, 0x46, 0x46, + 0x5D, 0x2C, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x20, 0x36, 0x20, 0x5B, 0x4F, 0x4E, 0x5D, 0x00, + 0x5B, 0x31 +}; + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxEnvInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxEnvInitKB.c new file mode 100644 index 0000000000..f0cbd18965 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxEnvInitKB.c @@ -0,0 +1,229 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GFX env post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86586 $ @e \$Date: 2013-01-23 12:45:26 -0600 (Wed, 23 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbTable.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbGfxInitLibV1.h" +#include "GnbGfxConfig.h" +#include "GnbGfxFamServices.h" +#include "GfxLibKB.h" +#include "GfxLibV3.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "GnbHandleLib.h" +#include "cpuFamilyTranslation.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GFXENVINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_TABLE ROMDATA GfxEnvInitTableKB[]; +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +GfxEnvInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize GFX straps. + * + * + * @param[in] Gfx Pointer to global GFX configuration + * @retval AGESA_STATUS + */ + +STATIC AGESA_STATUS +GfxStrapsEnvInitKB ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + D0F0xD4_x010914E1_STRUCT D0F0xD4_x10914E1; + D0F0xD4_x010914E2_STRUCT D0F0xD4_x10914E2; + D0F0xD4_x01091507_STRUCT D0F0xD4_x1091507; + D0F0x64_x1D_STRUCT D0F0x64_x1D; + UINT32 D0F0xD4_x010914C3; + GNB_HANDLE *GnbHandle; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxStrapsEnvInitKB Enter\n"); + + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + + GnbRegisterReadKB (GnbHandle, D0F0xD4_x010914E1_TYPE, D0F0xD4_x010914E1_ADDRESS, &D0F0xD4_x10914E1.Value, 0, GnbLibGetHeader (Gfx)); + GnbRegisterReadKB (GnbHandle, D0F0xD4_x010914E2_TYPE, D0F0xD4_x010914E2_ADDRESS, &D0F0xD4_x10914E2.Value, 0, GnbLibGetHeader (Gfx)); + GnbRegisterReadKB (GnbHandle, D0F0xD4_x01091507_TYPE, D0F0xD4_x01091507_ADDRESS, &D0F0xD4_x1091507.Value, 0, GnbLibGetHeader (Gfx)); + GnbRegisterReadKB (GnbHandle, D0F0xD4_x010914C3_TYPE, D0F0xD4_x010914C3_ADDRESS, &D0F0xD4_x010914C3, 0, GnbLibGetHeader (Gfx)); + + GnbLibPciIndirectRead ( + GNB_SBDFO | D0F0x60_ADDRESS, + D0F0x64_x1D_ADDRESS | IOC_WRITE_ENABLE, + AccessWidth32, + &D0F0x64_x1D.Value, + GnbLibGetHeader (Gfx) + ); + + D0F0x64_x1D.Field.VgaEn = 0x1; + + D0F0xD4_x10914E2.Field.bita = 0x0; + D0F0xD4_x10914E2.Field.bita = 0x0; + D0F0xD4_x1091507.Field.bit16 = Gfx->GnbHdAudio; + D0F0xD4_x10914E2.Field.bit13 = Gfx->GnbHdAudio; + + D0F0xD4_x10914E1.Field.StrapBifRegApSize = 0x2; + D0F0xD4_x10914E1.Field.StrapBifDoorbellBarDis = 0x0; + D0F0xD4_x10914E1.Field.Bitfield_13_13 = 0x0; + D0F0xD4_x10914E1.Field.Bitfield_15_14 = 0x3; + + if (Gfx->UmaInfo.UmaSize > 128 * 0x100000) { + D0F0xD4_x10914E1.Field.StrapBifMemApSize = 0x1; + D0F0xD4_x1091507.Field.StrapBifMemApSizePin = 0x1; + } else if (Gfx->UmaInfo.UmaSize > 64 * 0x100000) { + D0F0xD4_x10914E1.Field.StrapBifMemApSize = 0x0; + D0F0xD4_x1091507.Field.StrapBifMemApSizePin = 0x0; + } else { + D0F0xD4_x10914E1.Field.StrapBifMemApSize = 0x2; + D0F0xD4_x1091507.Field.StrapBifMemApSizePin = 0x2; + } + + GnbLibPciIndirectWrite ( + GNB_SBDFO | D0F0x60_ADDRESS, + D0F0x64_x1D_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + &D0F0x64_x1D.Value, + GnbLibGetHeader (Gfx) + ); + + D0F0xD4_x010914C3 |= BIT0; + GnbRegisterWriteKB (GnbHandle, D0F0xD4_x010914E1_TYPE, D0F0xD4_x010914E1_ADDRESS, &D0F0xD4_x10914E1.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, D0F0xD4_x010914E2_TYPE, D0F0xD4_x010914E2_ADDRESS, &D0F0xD4_x10914E2.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, D0F0xD4_x01091507_TYPE, D0F0xD4_x01091507_ADDRESS, &D0F0xD4_x1091507.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, D0F0xD4_x010914C3_TYPE, D0F0xD4_x010914C3_ADDRESS, &D0F0xD4_x010914C3, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxStrapsEnvInitKB Exit\n"); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GFX at Env Post. + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + + +AGESA_STATUS +GfxEnvInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + GFX_PLATFORM_CONFIG *Gfx; + GNB_HANDLE *GnbHandle; + UINT32 Property; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxEnvInterfaceKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + Property = TABLE_PROPERTY_DEFAULT; + + Status = GfxLocateConfigData (StdHeader, &Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + if (Gfx->UmaInfo.UmaMode != UMA_NONE) { + // Power up iGPU + GfxRequestGPUPowerV3 (Gfx, 1); + Status = GfxStrapsEnvInitKB (Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + } else { + GfxFmDisableController (StdHeader); + Property |= TABLE_PROPERTY_IGFX_DISABLED; + } + } else { + GfxFmDisableController (StdHeader); + Property |= TABLE_PROPERTY_IGFX_DISABLED; + } + + GnbHandle = GnbGetHandle (StdHeader); + ASSERT (GnbHandle != NULL); + Status = GnbProcessTable ( + GnbHandle, + GfxEnvInitTableKB, + Property, + GNB_TABLE_FLAGS_FORCE_S3_SAVE, + StdHeader + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxEnvInterfaceKB Exit [0x%x]\n", AgesaStatus); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.c new file mode 100644 index 0000000000..234592bfb3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.c @@ -0,0 +1,375 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe late post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87849 $ @e \$Date: 2013-02-11 15:37:58 -0600 (Mon, 11 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GnbTable.h" +#include "GnbPcieConfig.h" +#include "GnbRegisterAccKB.h" +#include "cpuFamilyTranslation.h" +#include "GnbRegistersKB.h" +#include "GfxLibKB.h" +#include "GfxGmcInitKB.h" +#include "Filecode.h" + +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GFXGMCINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern GNB_TABLE ROMDATA GfxGmcFeature1DisableKB []; +extern GNB_TABLE ROMDATA GfxGmcInitTableKB []; +extern GNB_TABLE ROMDATA GfxGmcFeature1EnableKB []; + + +#define GNB_GFX_DRAM_CH_0_PRESENT 1 +#define GNB_GFX_DRAM_CH_1_PRESENT 2 + +#define DRAMTYPE_DDR3 1 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize Fb location + * + * + * + * @param[in] GnbHandle Pointer to GNB_HANDLE + * @param[in] Gfx Pointer to global GFX configuration + * + */ +STATIC VOID +GfxGmcInitializeFbLocationKB ( + IN GNB_HANDLE *GnbHandle, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 GMMx2024; + UINT32 GMMx2068; + UINT32 GMMx2C04; + UINT32 GMMx5428; + UINT64 FBBase; + UINT64 FBTop; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGmcInitializeFbLocationKB Enter\n"); + + FBBase = 0x0F00000000; + FBTop = FBBase + Gfx->UmaInfo.UmaSize - 1; + GMMx2024 = 0; + GMMx2C04 = 0; + GMMx2024 |= (UINT16) (FBBase >> 24); + GMMx2024 |= (UINT32) ((FBTop >> 24) << 16); + GMMx2068 = (UINT32) (Gfx->UmaInfo.UmaBase >> 22); + GMMx2C04 = (UINT32) (FBBase >> 8); + GMMx5428 = Gfx->UmaInfo.UmaSize >> 20; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2024, &GMMx2024, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2068, &GMMx2068, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2C04, &GMMx2C04, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x5428, &GMMx5428, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGmcInitializeFbLocationKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize sequencer model + * + * + * + * @param[in] GnbHandle Pointer to GNB_HANDLE + * @param[in] Gfx Pointer to global GFX configuration + * + */ +STATIC VOID +GfxGmcInitializeHubAndCitfSteeringKB ( + IN GNB_HANDLE *GnbHandle, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 GMMx2004; + UINT32 GMMx2008; + + GMMx2004 = 0x2210; + GMMx2008 = 0; + + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2004, &GMMx2004, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2008, &GMMx2008, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable Stutter Mode with/without power-gating + * + * + * + * @param[in] GnbHandle Pointer to GNB_HANDLE + * @param[in] Gfx Pointer to global GFX configuration + * + */ +STATIC VOID +GfxGmcEnableStutterModePowerGatingKB ( + IN GNB_HANDLE *GnbHandle, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 GMMx3508; + UINT32 GMMx350C; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGmcEnableStutterModePowerGatingKB Enter\n"); + + GnbRegisterReadKB (GnbHandle, 0x12, 0x3508, &GMMx3508, 0, GnbLibGetHeader (Gfx)); + GnbRegisterReadKB (GnbHandle, 0x12, 0x350C, &GMMx350C, 0, GnbLibGetHeader (Gfx)); + if (Gfx->GmcPowerGating != GmcPowerGatingDisabled) { + // Enabling power gating + if (Gfx->GmcPowerGating == GmcPowerGatingWithStutter) { + GMMx3508 |= 1; + GMMx350C |= 1 << 11; + GMMx350C &= ~(1 << 16); + } else { + GMMx3508 &= ~1; + GMMx350C &= ~(1 << 11); + GMMx350C |= 1 << 16; + } + GnbRegisterWriteKB (GnbHandle, 0x12, 0x3508, &GMMx3508, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x350C, &GMMx350C, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + } else { + // Disabling power gating + GMMx3508 &= ~1; + GMMx350C &= ~(1 << 11); + GMMx350C &= ~(1 << 16); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x3508, &GMMx3508, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x350C, &GMMx350C, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + } + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGmcEnableStutterModePowerGatingKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * + * + * + * + * @param[in] GnbHandle Pointer to GNB_HANDLE + * @param[in] Gfx Pointer to global GFX configuration + */ + +STATIC VOID +GfxGmcSecureGarlicAccessKB ( + IN GNB_HANDLE *GnbHandle, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 v1; + UINT32 v2; + UINT32 v3; + + v1 = (UINT32) (Gfx->UmaInfo.UmaBase >> 20); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2868, &v1, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + v2 = (UINT32) (((Gfx->UmaInfo.UmaBase + Gfx->UmaInfo.UmaSize) >> 20) - 1); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x286C, &v2, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + // Area FB - 32K reserved by VBIOS for SBIOS to use + v3 = (UINT32) ((Gfx->UmaInfo.UmaBase + Gfx->UmaInfo.UmaSize - 32 * 1024) >> 12); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2878, &v3, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize C6 aperture location + * + * + * + * @param[in] GnbHandle Pointer to GNB_HANDLE + * @param[in] Gfx Pointer to global GFX configuration + * + */ +STATIC VOID +GfxGmcInitializeC6LocationKB ( + IN GNB_HANDLE *GnbHandle, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + D18F2x118_STRUCT D18F2x118; + D18F1x44_STRUCT D18F1x44; + UINT32 GMMx2870; + UINT32 GMMx2874; + + // Check C6 enable, D18F2x118[CC6SaveEn] + GnbRegisterReadKB (GnbHandle, D18F2x118_TYPE, D18F2x118_ADDRESS, &D18F2x118.Value, 0, GnbLibGetHeader (Gfx)); + + if (D18F2x118.Field.CC6SaveEn) { + // From D18F1x[144:140,44:40] DRAM Base/Limit, + // {DramBase[47:24], 00_0000h} <= address[47:0] <= {DramLimit[47:24], FF_FFFFh}. + GnbRegisterReadKB (GnbHandle, D18F1x44_TYPE, D18F1x44_ADDRESS, &D18F1x44.Value, 0, GnbLibGetHeader (Gfx)); + // + // base 39:20, base = Dram Limit + 1 + // ex: system 256 MB on Node 0, D18F1x44.Field.DramLimit_39_24_ = 0xE (240MB -1) + // Node DRAM D18F1x[144:140,44:40] CC6DRAMRange D18F4x128 D18F1x120 D18F1x124 + // 0 256MB 0MB ~ 240 MB - 1 240 MB ~ 256 MB - 1 0 0 MB, 256 MB - 1 + // + + // base 39:20 + GMMx2870 = ((D18F1x44.Field.DramLimit_39_24 + 1) << 4); + // top 39:20 + GMMx2874 = (((D18F1x44.Field.DramLimit_39_24 + 1) << 24) + (16 * 0x100000) - 1) >> 20; + + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2870, &GMMx2870, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2874, &GMMx2874, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize GMC + * + * + * + * @param[in] Gfx Pointer to global GFX configuration + * + */ + +AGESA_STATUS +GfxGmcInitKB ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 v1; + UINT32 GMMx25E8; + D18F3x44_STRUCT D18F3x44; + GNB_HANDLE *GnbHandle; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGmcInitKB Enter\n"); +//2.1 Disable clock-gating + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + ASSERT (GnbHandle != NULL); + GnbProcessTable ( + GnbHandle, + GfxGmcFeature1DisableKB, + 0, + GNB_TABLE_FLAGS_FORCE_S3_SAVE, + GnbLibGetHeader (Gfx) + ); +//2.3 HUB & CITF channel steering + GfxGmcInitializeHubAndCitfSteeringKB (GnbHandle, Gfx); +//2.6 Frame buffer location + GfxGmcInitializeFbLocationKB (GnbHandle, Gfx); +//2.8 Securing GARLIC access +//2.8.1 GARLIC request disable + GfxGmcSecureGarlicAccessKB (GnbHandle, Gfx); +//2.8.2 C6 save aperture + GfxGmcInitializeC6LocationKB (GnbHandle, Gfx); +//2.2 System memory address translation +//2.4 Sequencer model programming +//2.5 Power Gating - PGFSM and RENG init +//2.7 Performance tuning +//2.10 Display latency +//2.11 Remove blackout + GnbProcessTable ( + GnbHandle, + GfxGmcInitTableKB, + 0, + GNB_TABLE_FLAGS_FORCE_S3_SAVE, + GnbLibGetHeader (Gfx) + ); +//4. Power management + GnbProcessTable ( + GnbHandle, + GfxGmcFeature1EnableKB, + 0, + GNB_TABLE_FLAGS_FORCE_S3_SAVE, + GnbLibGetHeader (Gfx) + ); + +// SETUP or BLDCFG may override. + switch (Gfx->UmaSteering) { + case 0: + v1 = 0; + GnbRegisterReadKB (GnbHandle, D18F3x44_TYPE, D18F3x44_ADDRESS, &D18F3x44.Value, 0, GnbLibGetHeader (Gfx)); + if (D18F3x44.Field.DramEccEn == 1) { + v1 = SystemTrafficOnion; + } + break; + case SystemTrafficOnion: + v1 = SystemTrafficOnion; + break; + case Onion: + v1 = Onion; + break; + case 3: + v1 = 3; + break; + default: + v1 = 0; + ASSERT (FALSE); + break; + } + GnbRegisterWriteKB (GnbHandle, 0x12, 0x206C, &v1, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_GMM_REGISTER_OVERRIDE, Gfx, GnbLibGetHeader (Gfx)); + + GnbRegisterReadKB (GnbHandle, 0x12, 0x25E8, &GMMx25E8, 0, GnbLibGetHeader (Gfx)); + GMMx25E8 |= BIT14; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x25E8, &GMMx25E8, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Gfx)); + + if (Gfx->GmcPowerGating != GmcPowerGatingDisabled) { + //4.2 Enabling stutter mode with or without power-gating + GfxGmcEnableStutterModePowerGatingKB (GnbHandle, Gfx); + } + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGmcInitKB Exit\n"); + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.h new file mode 100644 index 0000000000..a6b63cafcf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxGmcInitKB.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * various service procedures + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GFXGMCINITKB_H_ +#define _GFXGMCINITKB_H_ + +#include "GnbRegistersKB.h" + +AGESA_STATUS +GfxGmcInitKB ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c new file mode 100644 index 0000000000..c81fd5ee3f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c @@ -0,0 +1,526 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Integrated table info init + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87902 $ @e \$Date: 2013-02-12 15:59:48 -0600 (Tue, 12 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "heapManager.h" +#include "GeneralServices.h" +#include "Gnb.h" +#include "GnbF1Table.h" +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbGfxConfig.h" +#include "GnbGfxInitLibV1.h" +#include "GnbGfxFamServices.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "GnbNbInitLibV1.h" +#include "GfxConfigLib.h" +#include "GfxIntegratedInfoTable.h" +#include "GfxPwrPlayTable.h" +#include "GfxLibKB.h" +#include "GfxLibV3.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GFXINTEGRATEDINFOTABLEKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +#define GFX_REFCLK 100 // (in MHz) Reference clock is 100 MHz + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GfxMapEngineToDisplayPathKB ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +AGESA_STATUS +GfxIntInfoTableInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +CONST UINT8 DdiLaneConfigArrayKB [][4] = { + {8, 11, 0, 0}, + {12, 15, 1, 1}, + {11, 8, 0, 0}, + {15, 12, 1, 1}, + {16, 19, 6, 6}, + {19, 16, 6, 6} +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize display path for given engine + * + * + * + * @param[in] Engine Engine configuration info + * @param[out] DisplayPathList Display path list + * @param[in] Gfx Pointer to global GFX configuration + */ + +AGESA_STATUS +GfxMapEngineToDisplayPathKB ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT EXT_DISPLAY_PATH *DisplayPathList, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + AGESA_STATUS Status; + UINT8 PrimaryDisplayPathId; + UINT8 SecondaryDisplayPathId; + UINTN DisplayPathIndex; + PrimaryDisplayPathId = 0xff; + SecondaryDisplayPathId = 0xff; + for (DisplayPathIndex = 0; DisplayPathIndex < (sizeof (DdiLaneConfigArrayKB) / 4); DisplayPathIndex++) { + if (DdiLaneConfigArrayKB[DisplayPathIndex][0] == Engine->EngineData.StartLane && + DdiLaneConfigArrayKB[DisplayPathIndex][1] == Engine->EngineData.EndLane) { + PrimaryDisplayPathId = DdiLaneConfigArrayKB[DisplayPathIndex][2]; + SecondaryDisplayPathId = DdiLaneConfigArrayKB[DisplayPathIndex][3]; + break; + } + } + + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDualLinkDVI || + (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeLvds && PrimaryDisplayPathId != 0)) { + // Display config invalid for KB + PrimaryDisplayPathId = 0xff; + } + + if (PrimaryDisplayPathId != 0xff) { + ASSERT (Engine->Type.Ddi.DdiData.AuxIndex <= Aux3); + IDS_HDT_CONSOLE (GFX_MISC, " Allocate Display Connector at Primary sPath[%d]\n", PrimaryDisplayPathId); + Engine->InitStatus |= INIT_STATUS_DDI_ACTIVE; + GfxIntegratedCopyDisplayInfo ( + Engine, + &DisplayPathList[PrimaryDisplayPathId], + (PrimaryDisplayPathId != SecondaryDisplayPathId) ? &DisplayPathList[SecondaryDisplayPathId] : NULL, + Gfx + ); + + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeSingleLinkDviI) { + LibAmdMemCopy (&DisplayPathList[6], &DisplayPathList[PrimaryDisplayPathId], sizeof (EXT_DISPLAY_PATH), GnbLibGetHeader (Gfx)); + DisplayPathList[6].usDeviceACPIEnum = 0x100; + DisplayPathList[6].usDeviceTag = ATOM_DEVICE_CRT1_SUPPORT; + } + + Status = AGESA_SUCCESS; + } else { + IDS_HDT_CONSOLE (GFX_MISC, " Error!!! Map DDI lanes %d - %d to display path failed\n", + Engine->EngineData.StartLane, + Engine->EngineData.EndLane + ); + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_DDI_LINK_CONFIGURATION, + Engine->EngineData.StartLane, + Engine->EngineData.EndLane, + 0, + 0, + GnbLibGetHeader (Gfx) + ); + Status = AGESA_ERROR; + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Init KB Nb p-State MemclkFreq + * + * + * @param[in] IntegratedInfoTable Integrated info table pointer + * @param[in] Gfx Gfx configuration info + */ + +STATIC VOID +GfxFillNbPstateMemclkFreqKB ( + IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + D18F2x94_dct0_STRUCT D18F2x94; + D18F2x2E0_dct0_STRUCT D18F2x2E0; + D18F5x160_STRUCT NbPstate; + UINT8 i; + ULONG memps0_freq; + ULONG memps1_freq; + UINT8 last_valid_pstate; + GNB_HANDLE *GnbHandle; + + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + ASSERT (GnbHandle != NULL); + + GnbRegisterReadKB ( + GnbHandle, + D18F2x94_dct0_TYPE, + D18F2x94_dct0_ADDRESS, + &D18F2x94.Value, + 0, + GnbLibGetHeader (Gfx) + ); + + GnbRegisterReadKB ( + GnbHandle, + D18F2x2E0_dct0_TYPE, + D18F2x2E0_dct0_ADDRESS, + &D18F2x2E0.Value, + 0, + GnbLibGetHeader (Gfx) + ); + + memps0_freq = 100 * GfxLibExtractDramFrequencyV3 ((UINT8) D18F2x94.Field.MemClkFreq, GnbLibGetHeader (Gfx)); + memps1_freq = 100 * GfxLibExtractDramFrequencyV3 ((UINT8) D18F2x2E0.Field.M1MemClkFreq, GnbLibGetHeader (Gfx)); + + last_valid_pstate = 0; + for (i = 0; i < 4; i++) { + NbPstate.Value = 0; + GnbRegisterReadKB ( + GnbHandle, + TYPE_D18F5, + (D18F5x160_ADDRESS + (i * 4)), + &NbPstate.Value, + 0, + GnbLibGetHeader (Gfx) + ); + if (NbPstate.Field.NbPstateEn == 1) { + last_valid_pstate = i; + IntegratedInfoTable->ulNbpStateMemclkFreq[i] = (NbPstate.Field.MemPstate == 0) ? memps0_freq : memps1_freq; + } else { + IntegratedInfoTable->ulNbpStateMemclkFreq[i] = + IntegratedInfoTable->ulNbpStateMemclkFreq[last_valid_pstate]; + } + } + + for (i = 0; i < 4; i++) { + IDS_HDT_CONSOLE (GNB_TRACE, " Nclk[%d] = %08x\n", i, IntegratedInfoTable->ulNbpStateNClkFreq[i]); + IDS_HDT_CONSOLE (GNB_TRACE, " Mclk[%d] = %08x\n", i, IntegratedInfoTable->ulNbpStateMemclkFreq[i]); + } + +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Calculate ulGMCRestoreResetTime + * + * + * @param[in] IntegratedInfoTable Integrated info table pointer + * @param[in] Gfx Gfx configuration info + * @param[in] PpF1Array + * @retval AGESA_STATUS + */ +///@todo - this is currently based on TN +STATIC AGESA_STATUS +GfxCalculateRestoreResetTimeKB ( + IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx, + IN PP_F1_ARRAY_V2 *PpF1Array + ) +{ + UINT8 MaxDid; + ULONG FreqSclk; + UINTN Index; + UINT32 TSclk; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxCalculateRestoreResetTimeKB Enter\n"); + MaxDid = PpF1Array->PP_FUSE_ARRAY_V2_fld3; + for (Index = 0; Index < 4; Index++) { + MaxDid = MAX (MaxDid, PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index]); + } + IDS_HDT_CONSOLE (GNB_TRACE, "MaxDid = %d\n", MaxDid); + FreqSclk = GfxFmCalculateClock (MaxDid, GnbLibGetHeader (Gfx)); + // FreqSclk is in 10KHz units - need calculations in nS + // For accuracy, do calculations in .01nS, then convert at the end + TSclk = (100 * (1000000000 / 10000)) / FreqSclk; + + IntegratedInfoTable->ulGMCRestoreResetTime = ((TSclk * 662) + 99) / 100; + IDS_HDT_CONSOLE (GNB_TRACE, "ulGMCRestoreResetTime = %d\n", IntegratedInfoTable->ulGMCRestoreResetTime); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxCalculateRestoreResetTimeKB Exit\n"); + + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Init KB HTC Data + * + * + * @param[in] IntegratedInfoTable Integrated info table pointer + * @param[in] Gfx Gfx configuration info + */ + +STATIC VOID +GfxFillHtcDataKB ( + IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + D18F3x64_STRUCT D18F3x64; + GNB_HANDLE *GnbHandle; + + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + ASSERT (GnbHandle != NULL); + + GnbRegisterReadKB ( + GnbHandle, + D18F3x64_TYPE, + D18F3x64_ADDRESS, + &D18F3x64.Value, + 0, + GnbLibGetHeader (Gfx) + ); + + if (D18F3x64.Field.HtcEn == 1) { + IntegratedInfoTable->ucHtcTmpLmt = (UCHAR) (D18F3x64.Field.HtcTmpLmt / 2 + 52); + IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 = (UCHAR) (D18F3x64.Field.HtcHystLmt / 2); + } else { + IntegratedInfoTable->ucHtcTmpLmt = 0; + IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 = 0; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Init Sclk <-> VID table + * + * + * @param[in] PpF1Array + * @param[in] IntegratedInfoTable Integrated info table pointer + * @param[in] Gfx Gfx configuration info + */ + +STATIC VOID +GfxIntInfoTableInitSclkTableKB ( + IN PP_F1_ARRAY_V2 *PpF1Array, + IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 Index; + UINTN AvailSclkIndex; + GnbGfx275_STRUCT *AvailSclkList; + BOOLEAN Sorting; + AvailSclkList = &IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8[0]; + + AvailSclkIndex = 0; + for (Index = 0; Index < 5; Index++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index] != 0) { + AvailSclkList[AvailSclkIndex].GnbGfx275_STRUCT_fld0 = GfxFmCalculateClock (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index], GnbLibGetHeader (Gfx)); + AvailSclkList[AvailSclkIndex].GnbGfx275_STRUCT_fld1 = Index; + AvailSclkList[AvailSclkIndex].GnbGfx275_STRUCT_fld2 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index]; + AvailSclkIndex++; + } + } + //Sort by VoltageIndex & GnbGfx275_STRUCT_fld0 + if (AvailSclkIndex > 1) { + do { + Sorting = FALSE; + for (Index = 0; Index < (AvailSclkIndex - 1); Index++) { + GnbGfx275_STRUCT Temp; + BOOLEAN Exchange; + Exchange = FALSE; + if (AvailSclkList[Index].GnbGfx275_STRUCT_fld1 > AvailSclkList[Index + 1].GnbGfx275_STRUCT_fld1) { + Exchange = TRUE; + } + if ((AvailSclkList[Index].GnbGfx275_STRUCT_fld1 == AvailSclkList[Index + 1].GnbGfx275_STRUCT_fld1) && + (AvailSclkList[Index].GnbGfx275_STRUCT_fld0 > AvailSclkList[Index + 1].GnbGfx275_STRUCT_fld0)) { + Exchange = TRUE; + } + if (Exchange) { + Sorting = TRUE; + LibAmdMemCopy (&Temp, &AvailSclkList[Index], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + LibAmdMemCopy (&AvailSclkList[Index], &AvailSclkList[Index + 1], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + LibAmdMemCopy (&AvailSclkList[Index + 1], &Temp, sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + } + } + } while (Sorting); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build integrated info table + * + * + * + * @param[in] Gfx Gfx configuration info + * @retval AGESA_STATUS + */ +AGESA_STATUS +STATIC +GfxIntInfoTableInitKB ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + ATOM_FUSION_SYSTEM_INFO_V3 SystemInfoTableV3; + PP_F1_ARRAY_V2 *PpF1Array; + ATOM_PPLIB_POWERPLAYTABLE4 *PpTable; + D18F5x170_STRUCT D18F5x170; + GNB_HANDLE *GnbHandle; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntInfoTableInitKB Enter\n"); + + AgesaStatus = AGESA_SUCCESS; + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + ASSERT (GnbHandle != NULL); + PpF1Array = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, GnbLibGetHeader (Gfx)); + if (PpF1Array != NULL) { + LibAmdMemFill (&SystemInfoTableV3, 0x00, sizeof (ATOM_FUSION_SYSTEM_INFO_V3), GnbLibGetHeader (Gfx)); + + // Use common initialization first + Status = GfxIntInfoTableInitV3 (Gfx, &SystemInfoTableV3, PpF1Array); + // Complete table with KB-specific fields + + // Build PP table + PpTable = (ATOM_PPLIB_POWERPLAYTABLE4*) &SystemInfoTableV3.ulPowerplayTable; + Status = GfxPwrPlayBuildTable (PpTable, Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + IDS_HDT_CONSOLE (GNB_TRACE, "KB Pplay done\n"); + + // Assign usFormatID to 0x0013 to represent Kabini + PpTable->usFormatID = 0x13; + + // Build Sclk info table + GfxIntInfoTableInitSclkTableKB (PpF1Array, &SystemInfoTableV3.sIntegratedSysInfo, Gfx); + + // Fill in Nb P-state MemclkFreq Data + GfxFillNbPstateMemclkFreqKB (&SystemInfoTableV3.sIntegratedSysInfo, Gfx); + // Fill in HTC Data + GfxFillHtcDataKB (&SystemInfoTableV3.sIntegratedSysInfo, Gfx); + + // Family specific data update + // Determine ulGMCRestoreResetTime + Status = GfxCalculateRestoreResetTimeKB (&SystemInfoTableV3.sIntegratedSysInfo, Gfx, PpF1Array); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + //GfxFmIntegratedInfoTableInit (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); + SystemInfoTableV3.sIntegratedSysInfo.ulDDR_DLL_PowerUpTime = 4940; + SystemInfoTableV3.sIntegratedSysInfo.ulDDR_PLL_PowerUpTime = 2000; + + SystemInfoTableV3.sIntegratedSysInfo.ulGPUCapInfo = + GPUCAPINFO_TMDS_HDMI_USE_SINGLE_PLL_MODE | + GPUCAPINFO_DP_USE_SINGLE_PLL_MODE | + GPUCAPINFO_DFS_BYPASS_DISABLE; + + // GPUCAPINFO_DFS_BYPASS_ENABLE should be enabled by default for MOBILE systems + if ((Gfx->AmdPlatformType & AMD_PLATFORM_MOBILE) != 0) { + SystemInfoTableV3.sIntegratedSysInfo.ulGPUCapInfo |= GPUCAPINFO_DFS_BYPASS_ENABLE; + } + + // Check if NbPstate enable + GnbRegisterReadKB (GnbHandle, TYPE_D18F5, D18F5x170_ADDRESS, &D18F5x170.Value, 0, GnbLibGetHeader (Gfx)); + if ((D18F5x170.Field.SwNbPstateLoDis != 1) && (D18F5x170.Field.NbPstateMaxVal != 0)) { + // If NbPstate enable, then enable NBDPM for driver + SystemInfoTableV3.sIntegratedSysInfo.ulSystemConfig |= BIT3; + } + + IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_INTEGRATED_TABLE_CONFIG, &SystemInfoTableV3.sIntegratedSysInfo, GnbLibGetHeader (Gfx)); + //Copy integrated info table to Frame Buffer. (Do not use LibAmdMemCopy, routine not guaranteed access to above 4G memory in 32 bit mode.) + GfxIntInfoTablePostToFbV3 (&SystemInfoTableV3, Gfx); + + GNB_DEBUG_CODE ( + GfxIntInfoTableDebugDumpV3 (&SystemInfoTableV3, Gfx); + ); + } else { + Status = AGESA_ERROR; + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntInfoTableInitKB Exit [0x%x]\n", Status); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build integrated info table + * GMC FB access requred + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ +AGESA_STATUS +GfxIntInfoTableInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + GFX_PLATFORM_CONFIG *Gfx; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntInfoTableInterfaceKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + if (GfxLibIsControllerPresent (StdHeader)) { + Status = GfxLocateConfigData (StdHeader, &Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status != AGESA_FATAL) { + Status = GfxIntInfoTableInitKB (Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntInfoTableInterfaceKB Exit[0x%x]\n", AgesaStatus); + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.c new file mode 100644 index 0000000000..7523736eb3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.c @@ -0,0 +1,192 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific GFX library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "S3SaveState.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbGfx.h" +#include "GfxLibKB.h" +#include "GnbCommonLib.h" +#include "GnbRegisterAccKB.h" +#include "GnbRegistersKB.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GFXLIBKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GfxDisableControllerKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GfxCalculateClockKB ( + IN UINT8 Did, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GfxIsVbiosPostedKB ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable GFX controller + * + * + * + * @param[in] StdHeader Standard configuration header + */ + +VOID +GfxDisableControllerKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GnbLibPciRMW ( + MAKE_SBDFO (0, 0, 0, 0,D0F0x7C_ADDRESS), + AccessS3SaveWidth32, + 0xffffffff, + 1 << D0F0x7C_ForceIntGfxDisable_OFFSET, + StdHeader + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get system PLL COF + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval System PLL COF + */ +UINT32 +GfxLibGetSystemPllCofKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 v0; + GnbRegisterReadKB (GnbGetHandle (StdHeader), 0x4, 0xC0500000, &v0, 0, StdHeader); + return 100 * (((v0 >> 1) & 0x3F) + 0x10); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Calculate COF for DFS out of Main PLL + * + * + * + * @param[in] Did Did + * @param[in] StdHeader Standard Configuration Header + * @retval COF in 10khz + */ + +UINT32 +GfxCalculateClockKB ( + IN UINT8 Did, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Divider; + UINT32 SystemPllCof; + SystemPllCof = GfxLibGetSystemPllCofKB (StdHeader) * 100; + if (Did >= 8 && Did <= 0x3F) { + Divider = Did * 25; + } else if (Did > 0x3F && Did <= 0x5F) { + Divider = (Did - 64) * 50 + 1600; + } else if (Did > 0x5F && Did <= 0x7E) { + Divider = (Did - 96) * 100 + 3200; + } else if (Did == 0x7f) { + Divider = 128 * 100; + } else { + ASSERT (FALSE); + return 200 * 100; + } + ASSERT (Divider != 0); + return (((SystemPllCof * 100) + (Divider - 1)) / Divider); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if Video BIOS has posted or not + * + * + * @param[in] Gfx Pointer to global GFX configuration + */ + +BOOLEAN +GfxIsVbiosPostedKB ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 D0F0xBC_xC0200000; + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Gfx)), 0x4, 0xC0200000, &D0F0xBC_xC0200000, 0, GnbLibGetHeader (Gfx)); + + return (((D0F0xBC_xC0200000 >> 16) & 1) == 0) ? TRUE : FALSE; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.h new file mode 100644 index 0000000000..117a794fef --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxLibKB.h @@ -0,0 +1,53 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various GFX service procedures + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GFXLIBKB_H_ +#define _GFXLIBKB_H_ + +UINT32 +GfxLibGetSystemPllCofKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxMidInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxMidInitKB.c new file mode 100644 index 0000000000..b6cfe666a3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxMidInitKB.c @@ -0,0 +1,161 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GFX mid post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 88282 $ @e \$Date: 2013-02-19 11:20:56 -0600 (Tue, 19 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbGfxConfig.h" +#include "GnbGfxInitLibV1.h" +#include "GnbNbInitLibV1.h" +#include "GnbNbInitLibV5.h" +#include "GnbGfxFamServices.h" +#include "GfxGmcInitKB.h" +#include "GfxLibKB.h" +#include "GfxLibV3.h" +#include "GnbRegisterAccKB.h" +#include "GnbRegistersKB.h" +#include "PcieConfigData.h" +#include "PcieConfigLib.h" +#include "cpuFamilyTranslation.h" +#include "GfxSamuInitKB.h" +#include "GnbHandleLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GFXMIDINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GfxMidInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GFX at Mid Post. + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GfxMidInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + GFX_PLATFORM_CONFIG *Gfx; + UINT8 AudioEPCount; + UINT32 GMMx5F50; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxMidInterfaceKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + Status = GfxLocateConfigData (StdHeader, &Gfx); + ASSERT (Status == AGESA_SUCCESS); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_FATAL) { + GfxFmDisableController (StdHeader); + } else { + if (Gfx->UmaInfo.UmaMode != UMA_NONE) { + Status = GfxEnableGmmAccessV3 (Gfx); + ASSERT (Status == AGESA_SUCCESS); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status != AGESA_SUCCESS) { + // Can not initialize GMM registers going to disable GFX controller + IDS_HDT_CONSOLE (GNB_TRACE, " Fail to establish GMM access\n"); + Gfx->UmaInfo.UmaMode = UMA_NONE; + GfxFmDisableController (StdHeader); + } else { + Status = GfxGmcInitKB (Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + //Status = GfxSamuInit (Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + Status = GfxInitSsid (Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + AudioEPCount = 0; + Status = GfxIntAudioEPEnumV3 (Gfx, &AudioEPCount); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + if (AudioEPCount > 2) { + AudioEPCount = 2; + } + + AudioEPCount = 7 - AudioEPCount; + GnbRegisterReadKB (GnbGetHandle (StdHeader), 0x12, 0x5F50, &GMMx5F50, 0, StdHeader); + GMMx5F50 &= ~7; GMMx5F50 |= AudioEPCount & 7; + GMMx5F50 |= 1 << 4; + GnbRegisterWriteKB (GnbGetHandle (StdHeader), 0x12, 0x5F50, &GMMx5F50, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + } + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "GfxMidInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxPostInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxPostInitKB.c new file mode 100644 index 0000000000..fa70f375fb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxPostInitKB.c @@ -0,0 +1,153 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe late post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbGfx.h" +#include "GnbGfxConfig.h" +#include "GnbF1Table.h" +#include "GnbGfxInitLibV1.h" +#include "GnbRegisterAccKB.h" +#include "GnbRegistersKB.h" +#include "GnbHandleLib.h" +#include "GfxLibV3.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GFXPOSTINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GfxPostInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Init GFX at Post. + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + + +AGESA_STATUS +GfxPostInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_POST_PARAMS *PostParamsPtr; + GFX_CARD_CARD_INFO GfxDiscreteCardInfo; + AGESA_STATUS Status; + GFX_PLATFORM_CONFIG *Gfx; + UINT32 D0F0xBC_xC00C0000; + GnbRegistersKB7269_STRUCT var5; + GnbRegistersKB7314_STRUCT var6; + GNB_HANDLE *GnbHandle; + + PostParamsPtr = (AMD_POST_PARAMS *)StdHeader; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxPostInterfaceKB Enter\n"); + GnbHandle = GnbGetHandle (StdHeader); + ASSERT (GnbHandle != NULL); + GnbRegisterReadKB (GnbHandle, 0x4, + 0xc00c0000, &D0F0xBC_xC00C0000, 0, StdHeader); + Status = GfxLocateConfigData (StdHeader, &Gfx); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + if (((D0F0xBC_xC00C0000 >> 1) & 1) != 1) { + if (PostParamsPtr->MemConfig.UmaMode != UMA_NONE) { + LibAmdMemFill (&GfxDiscreteCardInfo, 0x0, sizeof (GfxDiscreteCardInfo), StdHeader); + GfxGetDiscreteCardInfo (&GfxDiscreteCardInfo, StdHeader); + if (((GfxDiscreteCardInfo.PciGfxCardBitmap != 0) || + (GfxDiscreteCardInfo.AmdPcieGfxCardBitmap != GfxDiscreteCardInfo.PcieGfxCardBitmap)) || + ((PostParamsPtr->GnbPostConfig.IgpuEnableDisablePolicy == IGPU_DISABLE_ANY_PCIE) && + ((GfxDiscreteCardInfo.PciGfxCardBitmap != 0) || (GfxDiscreteCardInfo.PcieGfxCardBitmap != 0)))) { + PostParamsPtr->MemConfig.UmaMode = UMA_NONE; + IDS_HDT_CONSOLE (GFX_MISC, " GfxDisabled due dGPU policy\n"); + } + } + + if (PostParamsPtr->MemConfig.UmaMode == UMA_NONE) { + GnbRegisterReadKB (GnbHandle, TYPE_D0F0xD4, 0x13014AC, &var5.Value, 0, StdHeader); + GnbRegisterReadKB (GnbHandle, TYPE_D0F0xD4, 0x13014B6, &var6.Value, 0, StdHeader); + var5.Field.bit16 = FALSE; + var6.Field.bit13 = FALSE; + GnbRegisterWriteKB (GnbHandle, TYPE_D0F0xD4, 0x13014AC, &var5.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + GnbRegisterWriteKB (GnbHandle, TYPE_D0F0xD4, 0x13014B6, &var6.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + } + + // Power down iGPU + GfxRequestGPUPowerV3 (Gfx, 0); + } else { + PostParamsPtr->MemConfig.UmaMode = UMA_NONE; + } + } else { + PostParamsPtr->MemConfig.UmaMode = UMA_NONE; + } + IDS_HDT_CONSOLE (GNB_TRACE, "GfxPostInterfaceKB Exit [0x%x]\n", Status); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.c new file mode 100644 index 0000000000..66cf992243 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.c @@ -0,0 +1,253 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe late post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86584 $ @e \$Date: 2013-01-23 12:34:28 -0600 (Wed, 23 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbCommonLib.h" +#include "GnbTable.h" +#include "GnbPcieConfig.h" +#include "GnbRegisterAccKB.h" +#include "cpuFamilyTranslation.h" +#include "GnbRegistersKB.h" +#include "GfxLibKB.h" +#include "GfxSamuInitKB.h" +#include "GnbSamuPatchKB.h" +#include "OptionGnb.h" +#include "Filecode.h" + +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GFXSAMUINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +#define LENGTH_1MBYTE 0x0100000ul +#define MASK_1MBYTE 0x0FFFFFul + +#define SAM_IND_INDEX 0x22000ul +#define SAM_IND_DATA 0x22004ul + +#define SAM_SAB_IND_INDEX 0x22008ul +#define SAM_SAB_IND_DATA 0x2200Cul + +#define SMU_TOOLS_INDEX 0x238ul +#define SMU_TOOLS_DATA 0x23Cul + +typedef struct { + UINT32 BootControl; ///< + UINT32 KeySelect; ///< + UINT32 KernelAddrLo; ///< + UINT32 KernelAddrHi; ///< + UINT32 TweakSelect; ///< +} SAMU_BOOT_CONTROL; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize GMC + * + * + * + * @param[in] Gfx Pointer to global GFX configuration + * + */ + +AGESA_STATUS +GfxSamuInit ( + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 D0F0xBC_xC00C0000; + GNB_HANDLE *GnbHandle; + VOID *ControlXBuffer; + VOID *AlignedControlXBuffer; + VOID *PatchYBuffer; + VOID *AlignedPatchYBuffer; + SAMU_BOOT_CONTROL *SamuBootControl; + + UINT32 D0F0xBC_x800000A4; + UINT32 GMMx22000; + UINT32 GMMx22004; + UINT32 GMMx22008; + UINT32 GMMx2200C; + UINT32 LoopCount; + BOOLEAN SamuUseF1dPatch; + BOOLEAN SamuPatchEnabled; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbSamuInit Enter\n"); + + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + ASSERT (GnbHandle != NULL); + GnbRegisterReadKB (GnbHandle, 0x4, 0xc00c0000, + &D0F0xBC_xC00C0000, 0, GnbLibGetHeader (Gfx)); + + SamuPatchEnabled = GnbBuildOptions.CfgSamuPatchEnabled; + IDS_OPTION_HOOK (IDS_GNB_LOAD_SAMU_PATCH, &SamuPatchEnabled, GnbLibGetHeader (Gfx)); + + if ((((D0F0xBC_xC00C0000) & BIT24) == 0) && + (SamuPatchEnabled == TRUE)) { + + // Decide which version of the patch to use + SamuUseF1dPatch = TRUE; + + GMMx22008 = 0x29; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22008, + &GMMx22008, 0, GnbLibGetHeader (Gfx)); + GnbRegisterReadKB (GnbHandle, 0x12, 0x2200C, + &GMMx2200C, 0, GnbLibGetHeader (Gfx)); + IDS_HDT_CONSOLE (GNB_TRACE, " SAMSAB:29=%08x\n", GMMx2200C); + + if (GMMx2200C == 0x80000001) { + SamuUseF1dPatch = FALSE; + } + + ControlXBuffer = GnbAllocateHeapBufferAndClear (AMD_GNB_SAMU_BOOT_CONTROL_HANDLE, 2 * LENGTH_1MBYTE, GnbLibGetHeader (Gfx)); + ASSERT (ControlXBuffer != NULL); + if (ControlXBuffer == NULL) { + return AGESA_ERROR; + } + AlignedControlXBuffer = (VOID *) (((UINTN)ControlXBuffer + LENGTH_1MBYTE) & (~MASK_1MBYTE)); + PatchYBuffer = GnbAllocateHeapBuffer (AMD_GNB_SAMU_PATCH_HANDLE, 2 * LENGTH_1MBYTE, GnbLibGetHeader (Gfx)); + ASSERT (PatchYBuffer != NULL); + if (PatchYBuffer == NULL) { + return AGESA_ERROR; + } + AlignedPatchYBuffer = (VOID *) (((UINTN)PatchYBuffer + LENGTH_1MBYTE) & (~MASK_1MBYTE)); + + // Copy samu firmware patch to PatchYBuffer + if (SamuUseF1dPatch == TRUE) { + LibAmdMemCopy (AlignedPatchYBuffer, &SamuPatchKB[0], + SamuPatchKBHeader[1], GnbLibGetHeader (Gfx)); + } else { + LibAmdMemCopy (AlignedPatchYBuffer, &SamuPatchKBUnf1[0], + SamuPatchKBHeaderUnf1[1], GnbLibGetHeader (Gfx)); + } + + // WBINVD + LibAmdWriteBackInvalidateCache (); + + // Load boot control structure + SamuBootControl = (SAMU_BOOT_CONTROL *)AlignedControlXBuffer; + SamuBootControl->BootControl = 0x3; + SamuBootControl->KernelAddrLo = (UINT32) (AlignedPatchYBuffer); + SamuBootControl->KernelAddrHi = 0; //(UINT32) ((((UINT64) AlignedPatchYBuffer) >> 32) & 0xFF); + if (SamuUseF1dPatch == TRUE) { + SamuBootControl->TweakSelect = 0xBB027E1F; + SamuBootControl->KeySelect = 0x8E174F83; + } else { + SamuBootControl->TweakSelect = 0x0; + SamuBootControl->KeySelect = 0x0; + } + + + // Write 0x0 to SAM_CGC_HOST_CTRL to release the clock-gating of SAMU + GMMx22000 = 0x3; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22000, &GMMx22000, 0, GnbLibGetHeader (Gfx)); + GMMx22004 = 0x0; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22004, &GMMx22004, 0, GnbLibGetHeader (Gfx)); + + // Write (physical address of boot control structure)>>8 into SAM_SAB_INIT_TLB_CONFIG (Location X >> 8) + GMMx22008 = 0x4; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22008, &GMMx22008, 0, GnbLibGetHeader (Gfx)); + GMMx2200C = ((UINT32) ((UINT32) AlignedControlXBuffer)) >> 8; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x2200C, &GMMx2200C, 0, GnbLibGetHeader (Gfx)); + + // Write 0x0 to SAM_RST_HOST_SOFT_RESET + GMMx22000 = 0x1; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22000, &GMMx22000, 0, GnbLibGetHeader (Gfx)); + GMMx22004 = 0x0; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22004, &GMMx22004, 0, GnbLibGetHeader (Gfx)); + + // Write 0x2 to SAM_SCRATCH_0 to start the firmware boot + GMMx22000 = 0x38; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22000, &GMMx22000, 0, GnbLibGetHeader (Gfx)); + GMMx22004 = 0x2; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22004, &GMMx22004, 0, GnbLibGetHeader (Gfx)); + + // Poll SAM_RST_HOST_SOFT_RST_RDY and wait for HOST_RDY + do { + // Write 0x2 to SAM_SCRATCH_0 to start the firmware boot + GMMx22000 = 0x51; + GnbRegisterWriteKB (GnbHandle, 0x12, 0x22000, &GMMx22000, 0, GnbLibGetHeader (Gfx)); + GnbRegisterReadKB (GnbHandle, 0x12, 0x22004, &GMMx22004, 0, GnbLibGetHeader (Gfx)); + } while ((GMMx22004 & BIT0) == 0); + + // Clear the allocated memory ranges, locations X and Y (write 0), issue WBINVD + LibAmdMemFill (ControlXBuffer, 0, 2 * LENGTH_1MBYTE, GnbLibGetHeader (Gfx)); + LibAmdMemFill (PatchYBuffer, 0, 2 * LENGTH_1MBYTE, GnbLibGetHeader (Gfx)); + LibAmdWriteBackInvalidateCache (); + + // Confirm read of SMC_DRAM_ACCESS_CNTL is 0x1 + D0F0xBC_x800000A4 = 0; + for (LoopCount = 0; LoopCount < 0x00FFFFFF; LoopCount++) { + GnbRegisterReadKB (GnbHandle, 0x4, 0x800000A4, &D0F0xBC_x800000A4, 0, GnbLibGetHeader (Gfx)); + if ((D0F0xBC_x800000A4 & BIT0) != 0) { + break; + } + } + ASSERT ((D0F0xBC_x800000A4 & BIT0) != 0); + } + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbSamuInit Exit\n"); + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.h new file mode 100644 index 0000000000..44dd8935e0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxSamuInitKB.h @@ -0,0 +1,53 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * various service procedures + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBSAMUINITKB_H_ +#define _GNBSAMUINITKB_H_ + +AGESA_STATUS +GfxSamuInit ( + IN GFX_PLATFORM_CONFIG *Gfx + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxTablesKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxTablesKB.c new file mode 100644 index 0000000000..99e7f933a9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxTablesKB.c @@ -0,0 +1,479 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GFx tables + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87698 $ @e \$Date: 2013-02-07 12:40:51 -0600 (Thu, 07 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbTable.h" +#include "GnbRegistersKB.h" +#include "cpuFamilyTranslation.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T A B L E S + *---------------------------------------------------------------------------------------- + */ + +GNB_TABLE ROMDATA GfxGmcFeature1DisableKB [] = { + //2.1 Disable clock-gating + GNB_ENTRY_WR (0x12, 0x20C0, 0x00000C80), + GNB_ENTRY_WR (0x12, 0x2478, 0x00000400), + GNB_ENTRY_WR (0x12, 0x20B8, 0x00000400), + GNB_ENTRY_WR (0x12, 0x20BC, 0x00000400), + GNB_ENTRY_WR (0x12, 0x2648, 0x00000400), + GNB_ENTRY_WR (0x12, 0x264C, 0x00000400), + GNB_ENTRY_WR (0x12, 0x2650, 0x00000400), + GNB_ENTRY_WR (0x12, 0x15C0, 0x00000400), + GNB_ENTRY_TERMINATE +}; + +GNB_TABLE ROMDATA GfxGmcInitTableKB [] = { + GNB_ENTRY_RMW (D18F5x178_TYPE, D18F5x178_ADDRESS, D18F5x178_SwGfxDis_MASK, 0 << D18F5x178_SwGfxDis_OFFSET), + //2.2 System memory address translation + GNB_ENTRY_COPY (0x12, 0x2814, 0, 32, D18F2x40_dct0_TYPE, D18F2x40_dct0_ADDRESS, 0, 32), + GNB_ENTRY_COPY (0x12, 0x281C, 0, 32, D18F2x44_dct0_TYPE, D18F2x44_dct0_ADDRESS, 0, 32), + GNB_ENTRY_COPY (0x12, 0x2824, 0, 32, D18F2x48_dct0_TYPE, D18F2x48_dct0_ADDRESS, 0, 32), + GNB_ENTRY_COPY (0x12, 0x282C, 0, 32, D18F2x4C_dct0_TYPE, D18F2x4C_dct0_ADDRESS, 0, 32), + GNB_ENTRY_COPY (0x12, 0x2834, 0, 32, D18F2x60_dct0_TYPE, D18F2x60_dct0_ADDRESS, 0, 32), + GNB_ENTRY_COPY (0x12, 0x283C, 0, 32, D18F2x64_dct0_TYPE, D18F2x64_dct0_ADDRESS, 0, 32), + // MC_FUS_DRAM0_BANK_ADDR_MAPPING + GNB_ENTRY_COPY (0x12, 0x2844, 0, 8, D18F2x80_dct0_TYPE, D18F2x80_dct0_ADDRESS, 0, 8), + GNB_ENTRY_COPY (0x12, 0x2844, 8, 1, D18F2x94_dct0_TYPE, D18F2x94_dct0_ADDRESS, 22, 1), + GNB_ENTRY_COPY (0x12, 0x2844, 9, 1, D18F2xA8_dct0_TYPE, D18F2xA8_dct0_ADDRESS, 20, 1), + // MC_FUS_DRAM0_CTL_BASE + GNB_ENTRY_COPY (0x12, 0x284C, 0, 3, D18F1x200_TYPE, D18F1x200_ADDRESS, 4, 3), + GNB_ENTRY_COPY (0x12, 0x284C, 3, 4, D18F1x204_TYPE, D18F1x204_ADDRESS, 0, 4), + GNB_ENTRY_COPY (0x12, 0x284C, 7, 21, D18F1x200_TYPE, D18F1x200_ADDRESS, 11, 21), + GNB_ENTRY_COPY (0x12, 0x284C, 28, 1, D18F1x200_TYPE, D18F1x200_ADDRESS, 3, 1), + GNB_ENTRY_COPY (0x12, 0x284C, 29, 1, D18F1x200_TYPE, D18F1x200_ADDRESS, 0, 1), + // MC_FUS_DRAM0_CTL_LIMIT + GNB_ENTRY_COPY (0x12, 0x2854, 0, 21, D18F1x204_TYPE, D18F1x204_ADDRESS, 11, 21), + GNB_ENTRY_COPY (0x12, 0x2854, 21, 1, D18F1xF0_TYPE, D18F1xF0_ADDRESS, 1, 1), + // MC_FUS_DRAM_MODE + GNB_ENTRY_COPY (0x12, 0x2864, 3, 1, D18F2x78_dct0_TYPE, D18F2x78_dct0_ADDRESS, 8, 1), + GNB_ENTRY_COPY (0x12, 0x2864, 4, 9, D18F1xF0_TYPE, D18F1xF0_ADDRESS, 7, 9), + GNB_ENTRY_COPY (0x12, 0x2864, 0, 2, D18F2x110_TYPE, D18F2x110_ADDRESS, 6, 2), + GNB_ENTRY_COPY (0x12, 0x2864, 2, 1, D18F2x114_TYPE, D18F2x114_ADDRESS, 9, 1), + // MC_FUS_DRAM_CTL_HIGH_01 + GNB_ENTRY_COPY (0x12, 0x285C, 0, 12, D18F1x240_TYPE, D18F1x240_ADDRESS, 11, 12), + + // 2.4 Sequencer model programming + GNB_ENTRY_WR (0x12, 0x276C, 0x000003ff), + + //--------------------------------------------------------------------------- + // 2.5 Power gating init + // Initializing PGFSMs + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x3538, 0x200010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x3538, 0x300010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x210000), + GNB_ENTRY_WR (0x12, 0x3538, 0xa00010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x21003), + GNB_ENTRY_WR (0x12, 0x3538, 0xb00010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x2b00), + GNB_ENTRY_WR (0x12, 0x3538, 0xc00010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x3538, 0xd00010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x420000), + GNB_ENTRY_WR (0x12, 0x3538, 0x100010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x120202), + GNB_ENTRY_WR (0x12, 0x3538, 0x500010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x3e3e36), + GNB_ENTRY_WR (0x12, 0x3538, 0x600010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x373f3e), + GNB_ENTRY_WR (0x12, 0x3538, 0x700010ff), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x0), + GNB_ENTRY_WR (0x12, 0x353C, 0x3e1332), + GNB_ENTRY_WR (0x12, 0x3538, 0xe00010ff), +//--------------------------------------------------------------------------- +// Initializing register engine +// opcode=1, body_cnt=0, mask=0xf, const=0xf: MC_CONFIG (0x800) MC_CONFIG (0x800) + GNB_ENTRY_WR (0x12, 0x3500, 0x0), + GNB_ENTRY_WR (0x12, 0x3504, 0x10000800), + GNB_ENTRY_WR (0x12, 0x3504, 0xf), + GNB_ENTRY_WR (0x12, 0x3504, 0xf), +// opcode=1, body_cnt=0, mask=0x3f, const=0x3f: MC_CONFIG_MCD (0x828) MC_CONFIG_MCD (0x828) + GNB_ENTRY_WR (0x12, 0x3500, 0x4), + GNB_ENTRY_WR (0x12, 0x3504, 0x10000828), + GNB_ENTRY_WR (0x12, 0x3504, 0x3f), + GNB_ENTRY_WR (0x12, 0x3504, 0x3f), +// opcode=1, body_cnt=0, mask=0xffff, const=0xffff: VM_INVALIDATE_REQUEST (0x51e) VM_INVALIDATE_REQUEST (0x51e) + GNB_ENTRY_WR (0x12, 0x3500, 0x8), + GNB_ENTRY_WR (0x12, 0x3504, 0x1000051e), + GNB_ENTRY_WR (0x12, 0x3504, 0xffff), + GNB_ENTRY_WR (0x12, 0x3504, 0xffff), +// opcode=0, body_cnt=2: VM_L2_CNTL (0x500) VM_L2_CNTL3 (0x502) + GNB_ENTRY_WR (0x12, 0x3500, 0xc), + GNB_ENTRY_WR (0x12, 0x3504, 0x20500), +// opcode=0, body_cnt=4: VM_CONTEXT0_CNTL (0x504) VM_SECURE_FAULT_CNTL (0x508) + GNB_ENTRY_WR (0x12, 0x3500, 0x10), + GNB_ENTRY_WR (0x12, 0x3504, 0x40504), +// opcode=0, body_cnt=9: VM_CONTEXT0_CNTL2 (0x50c) VM_CONTEXT15_PAGE_TABLE_BASE_ADDR (0x515) + GNB_ENTRY_WR (0x12, 0x3500, 0x16), + GNB_ENTRY_WR (0x12, 0x3504, 0x9050c), +// opcode=0, body_cnt=9: VM_PRT_APERTURE0_LOW_ADDR (0x52c) VM_CONTEXTS_DISABLE (0x535) + GNB_ENTRY_WR (0x12, 0x3500, 0x21), + GNB_ENTRY_WR (0x12, 0x3504, 0x9052c), +// opcode=0, body_cnt=1: VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR (0x546) VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR (0x547) + GNB_ENTRY_WR (0x12, 0x3500, 0x2c), + GNB_ENTRY_WR (0x12, 0x3504, 0x10546), +// opcode=0, body_cnt=10: VM_FAULT_CLIENT_ID (0x54e) VM_CONTEXT1_PAGE_TABLE_START_ADDR (0x558) + GNB_ENTRY_WR (0x12, 0x3500, 0x2f), + GNB_ENTRY_WR (0x12, 0x3504, 0xa054e), +// opcode=0, body_cnt=1: VM_CONTEXT0_PAGE_TABLE_END_ADDR (0x55f) VM_CONTEXT1_PAGE_TABLE_END_ADDR (0x560) + GNB_ENTRY_WR (0x12, 0x3500, 0x3b), + GNB_ENTRY_WR (0x12, 0x3504, 0x1055f), +// opcode=0, body_cnt=1: VM_DEBUG (0x56f) VM_L2_CG (0x570) + GNB_ENTRY_WR (0x12, 0x3500, 0x3e), + GNB_ENTRY_WR (0x12, 0x3504, 0x1056f), +// opcode=0, body_cnt=1: VM_L2_BANK_SELECT_MASKA (0x572) VM_L2_BANK_SELECT_MASKB (0x573) + GNB_ENTRY_WR (0x12, 0x3500, 0x41), + GNB_ENTRY_WR (0x12, 0x3504, 0x10572), +// opcode=0, body_cnt=2: VM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR (0x575) VM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET (0x577) + GNB_ENTRY_WR (0x12, 0x3500, 0x44), + GNB_ENTRY_WR (0x12, 0x3504, 0x20575), +// opcode=0, body_cnt=53: MC_CITF_PERFCOUNTER_LO (0x7a0) ATC_PERFCOUNTER_RSLT_CNTL (0x7d5) + GNB_ENTRY_WR (0x12, 0x3500, 0x48), + GNB_ENTRY_WR (0x12, 0x3504, 0x3507a0), +// opcode=0, body_cnt=0: MC_ARB_PERF_MON_CNTL0_ECC (0x7db) MC_ARB_PERF_MON_CNTL0_ECC (0x7db) + GNB_ENTRY_WR (0x12, 0x3500, 0x7f), + GNB_ENTRY_WR (0x12, 0x3504, 0x7db), +// opcode=0, body_cnt=26: MC_SHARED_CHMAP (0x801) MC_VM_STEERING (0x81b) + GNB_ENTRY_WR (0x12, 0x3500, 0x81), + GNB_ENTRY_WR (0x12, 0x3504, 0x1a0801), +// opcode=0, body_cnt=2: MC_CG_CONFIG_MCD (0x829) MC_SHARED_BLACKOUT_CNTL (0x82b) + GNB_ENTRY_WR (0x12, 0x3500, 0x9d), + GNB_ENTRY_WR (0x12, 0x3504, 0x20829), +// opcode=0, body_cnt=4: MC_HUB_MISC_POWER (0x82d) MC_HUB_MISC_DBG (0x831) + GNB_ENTRY_WR (0x12, 0x3500, 0xa1), + GNB_ENTRY_WR (0x12, 0x3504, 0x4082d), +// opcode=0, body_cnt=4: MC_HUB_MISC_OVERRIDE (0x833) MC_HUB_WDP_BP (0x837) + GNB_ENTRY_WR (0x12, 0x3500, 0xa7), + GNB_ENTRY_WR (0x12, 0x3504, 0x40833), +// opcode=0, body_cnt=11: MC_HUB_RDREQ_CNTL (0x83b) MC_HUB_SHARED_DAGB_DLY (0x846) + GNB_ENTRY_WR (0x12, 0x3500, 0xad), + GNB_ENTRY_WR (0x12, 0x3504, 0xb083b), +// opcode=0, body_cnt=1: MC_HUB_RDREQ_DMIF_LIMIT (0x848) MC_HUB_RDREQ_ACPG_LIMIT (0x849) + GNB_ENTRY_WR (0x12, 0x3500, 0xba), + GNB_ENTRY_WR (0x12, 0x3504, 0x10848), +// opcode=0, body_cnt=63: MC_HUB_WDP_SH2 (0x84d) MC_HUB_WDP_SAM (0x88c) + GNB_ENTRY_WR (0x12, 0x3500, 0xbd), + GNB_ENTRY_WR (0x12, 0x3504, 0x3f084d), +// opcode=0, body_cnt=0: MC_VM_MB_L1_TLB0_DEBUG (0x891) MC_VM_MB_L1_TLB0_DEBUG (0x891) + GNB_ENTRY_WR (0x12, 0x3500, 0xfe), + GNB_ENTRY_WR (0x12, 0x3504, 0x891), +// opcode=0, body_cnt=0: MC_VM_MB_L1_TLB2_DEBUG (0x893) MC_VM_MB_L1_TLB2_DEBUG (0x893) + GNB_ENTRY_WR (0x12, 0x3500, 0x100), + GNB_ENTRY_WR (0x12, 0x3504, 0x893), +// opcode=0, body_cnt=0: MC_VM_MB_L2ARBITER_L2_CREDITS (0x8a1) MC_VM_MB_L2ARBITER_L2_CREDITS (0x8a1) + GNB_ENTRY_WR (0x12, 0x3500, 0x102), + GNB_ENTRY_WR (0x12, 0x3504, 0x8a1), +// opcode=0, body_cnt=0: MC_VM_MB_L1_TLB3_DEBUG (0x8a5) MC_VM_MB_L1_TLB3_DEBUG (0x8a5) + GNB_ENTRY_WR (0x12, 0x3500, 0x104), + GNB_ENTRY_WR (0x12, 0x3504, 0x8a5), +// opcode=0, body_cnt=51: MC_XPB_RTR_SRC_APRTR0 (0x8cd) MC_XPB_UNC_THRESH_SID (0x900) + GNB_ENTRY_WR (0x12, 0x3500, 0x106), + GNB_ENTRY_WR (0x12, 0x3504, 0x3308cd), +// opcode=0, body_cnt=1: MC_XPB_WCB_CFG (0x902) MC_XPB_P2P_BAR_CFG (0x903) + GNB_ENTRY_WR (0x12, 0x3500, 0x13b), + GNB_ENTRY_WR (0x12, 0x3504, 0x10902), +// opcode=0, body_cnt=19: MC_XPB_P2P_BAR_SETUP (0x90c) MC_XPB_INTF_CFG (0x91f) + GNB_ENTRY_WR (0x12, 0x3500, 0x13e), + GNB_ENTRY_WR (0x12, 0x3504, 0x13090c), +// opcode=0, body_cnt=0: MC_XPB_SUB_CTRL (0x922) MC_XPB_SUB_CTRL (0x922) + GNB_ENTRY_WR (0x12, 0x3500, 0x153), + GNB_ENTRY_WR (0x12, 0x3504, 0x922), +// opcode=0, body_cnt=0: MC_XPB_PERF_KNOBS (0x924) MC_XPB_PERF_KNOBS (0x924) + GNB_ENTRY_WR (0x12, 0x3500, 0x155), + GNB_ENTRY_WR (0x12, 0x3504, 0x924), +// opcode=0, body_cnt=20: MC_XPB_STICKY_W1C (0x926) MC_XPB_CLG_CFG36 (0x93a) + GNB_ENTRY_WR (0x12, 0x3500, 0x157), + GNB_ENTRY_WR (0x12, 0x3504, 0x140926), +// opcode=2, body_cnt=0: MC_RPB_CID_QUEUE_EX (0x95a) + GNB_ENTRY_WR (0x12, 0x3500, 0x16d), + GNB_ENTRY_WR (0x12, 0x3504, 0x2000095a), + GNB_ENTRY_WR (0x12, 0x3504, 0x1), +// opcode=3, body_cnt=31: MC_RPB_CID_QUEUE_EX_DATA (0x95b) + GNB_ENTRY_WR (0x12, 0x3500, 0x16f), + GNB_ENTRY_WR (0x12, 0x3504, 0x301f095b), +// opcode=0, body_cnt=12: MC_RPB_CONF (0x94d) MC_RPB_PERF_COUNTER_STATUS (0x959) + GNB_ENTRY_WR (0x12, 0x3500, 0x190), + GNB_ENTRY_WR (0x12, 0x3504, 0xc094d), +// opcode=0, body_cnt=16: MC_CITF_XTRA_ENABLE (0x96d) MC_CITF_INT_CREDITS_WR (0x97d) + GNB_ENTRY_WR (0x12, 0x3500, 0x19e), + GNB_ENTRY_WR (0x12, 0x3504, 0x10096d), +// opcode=0, body_cnt=12: MC_CITF_WTM_RD_CNTL (0x97f) MC_WR_GRP_LCL (0x98b) + GNB_ENTRY_WR (0x12, 0x3500, 0x1b0), + GNB_ENTRY_WR (0x12, 0x3504, 0xc097f), +// opcode=0, body_cnt=0: MC_CITF_PERF_MON_CNTL2 (0x98e) MC_CITF_PERF_MON_CNTL2 (0x98e) + GNB_ENTRY_WR (0x12, 0x3500, 0x1be), + GNB_ENTRY_WR (0x12, 0x3504, 0x98e), +// opcode=0, body_cnt=2: MC_CITF_MISC_RD_CG (0x992) MC_CITF_MISC_VM_CG (0x994) + GNB_ENTRY_WR (0x12, 0x3500, 0x1c0), + GNB_ENTRY_WR (0x12, 0x3504, 0x20992), +// opcode=0, body_cnt=2: MC_VM_MD_L1_TLB0_DEBUG (0x998) MC_VM_MD_L1_TLB2_DEBUG (0x99a) + GNB_ENTRY_WR (0x12, 0x3500, 0x1c4), + GNB_ENTRY_WR (0x12, 0x3504, 0x20998), +// opcode=0, body_cnt=0: MC_VM_MD_L2ARBITER_L2_CREDITS (0x9a4) MC_VM_MD_L2ARBITER_L2_CREDITS (0x9a4) + GNB_ENTRY_WR (0x12, 0x3500, 0x1c8), + GNB_ENTRY_WR (0x12, 0x3504, 0x9a4), +// opcode=0, body_cnt=0: MC_VM_MD_L1_TLB3_DEBUG (0x9a7) MC_VM_MD_L1_TLB3_DEBUG (0x9a7) + GNB_ENTRY_WR (0x12, 0x3500, 0x1ca), + GNB_ENTRY_WR (0x12, 0x3504, 0x9a7), +// opcode=0, body_cnt=6: MC_ARB_AGE_CNTL (0x9bf) MC_ARB_GECC2_DEBUG2 (0x9c5) + GNB_ENTRY_WR (0x12, 0x3500, 0x1cc), + GNB_ENTRY_WR (0x12, 0x3504, 0x609bf), +// opcode=0, body_cnt=45: MC_ARB_GECC2 (0x9c9) MC_ARB_MAX_LAT_CID (0x9f6) + GNB_ENTRY_WR (0x12, 0x3500, 0x1d4), + GNB_ENTRY_WR (0x12, 0x3504, 0x2d09c9), +// opcode=0, body_cnt=3: MC_ARB_SSM (0x9f9) MC_ARB_DRAM_TIMING_1 (0x9fc) + GNB_ENTRY_WR (0x12, 0x3500, 0x203), + GNB_ENTRY_WR (0x12, 0x3504, 0x309f9), +// opcode=0, body_cnt=0: MC_ARB_DRAM_TIMING2_1 (0x9ff) MC_ARB_DRAM_TIMING2_1 (0x9ff) + GNB_ENTRY_WR (0x12, 0x3500, 0x208), + GNB_ENTRY_WR (0x12, 0x3504, 0x9ff), +// opcode=0, body_cnt=2: MC_ARB_BURST_TIME (0xa02) MC_ARB_SCRAMBLE_KEY1 (0xa04) + GNB_ENTRY_WR (0x12, 0x3500, 0x20a), + GNB_ENTRY_WR (0x12, 0x3504, 0x20a02), +// opcode=0, body_cnt=6: MC_FUS_DRAM0_CTL_BASE (0xa13) MC_FUS_DRAM_MODE (0xa19) + GNB_ENTRY_WR (0x12, 0x3500, 0x20e), + GNB_ENTRY_WR (0x12, 0x3504, 0x60a13), +// opcode=0, body_cnt=3: MC_FUS_ARB_GARLIC_ISOC_PRI (0xa1f) MC_FUS_ARB_GARLIC_WR_PRI2 (0xa22) + GNB_ENTRY_WR (0x12, 0x3500, 0x216), + GNB_ENTRY_WR (0x12, 0x3504, 0x30a1f), +// opcode=1, body_cnt=0, mask=0x3f, const=0x0: ATC_ATS_FAULT_CNTL (0xccd) ATC_ATS_FAULT_CNTL (0xccd) + GNB_ENTRY_WR (0x12, 0x3500, 0x21b), + GNB_ENTRY_WR (0x12, 0x3504, 0x10000ccd), + GNB_ENTRY_WR (0x12, 0x3504, 0x3f), + GNB_ENTRY_WR (0x12, 0x3504, 0x0), +// opcode=0, body_cnt=7: ATC_VM_APERTURE0_LOW_ADDR (0xcc0) ATC_VM_APERTURE1_CNTL2 (0xcc7) + GNB_ENTRY_WR (0x12, 0x3500, 0x21f), + GNB_ENTRY_WR (0x12, 0x3504, 0x70cc0), +// opcode=0, body_cnt=2: ATC_ATS_CNTL (0xcc9) ATC_ATS_FAULT_DEBUG (0xccb) + GNB_ENTRY_WR (0x12, 0x3500, 0x228), + GNB_ENTRY_WR (0x12, 0x3504, 0x20cc9), +// opcode=0, body_cnt=1: ATC_ATS_DEFAULT_PAGE_LOW (0xcd0) ATC_ATS_DEFAULT_PAGE_CNTL (0xcd1) + GNB_ENTRY_WR (0x12, 0x3500, 0x22c), + GNB_ENTRY_WR (0x12, 0x3504, 0x10cd0), +// opcode=0, body_cnt=4: ATC_MISC_CG (0xcd4) ATC_L2_DEBUG2 (0xcd8) + GNB_ENTRY_WR (0x12, 0x3500, 0x22f), + GNB_ENTRY_WR (0x12, 0x3504, 0x40cd4), +// opcode=0, body_cnt=5: ATC_L1_CNTL (0xcdc) ATC_L1WR_STATUS (0xce1) + GNB_ENTRY_WR (0x12, 0x3500, 0x235), + GNB_ENTRY_WR (0x12, 0x3504, 0x50cdc), +// opcode=0, body_cnt=16: ATC_VMID_PASID_MAPPING_UPDATE_STATUS (0xce6) ATC_VMID15_PASID_MAPPING (0xcf6) + GNB_ENTRY_WR (0x12, 0x3500, 0x23c), + GNB_ENTRY_WR (0x12, 0x3504, 0x100ce6), +// opcode=0, body_cnt=0: ATC_ATS_FAULT_CNTL (0xccd) ATC_ATS_FAULT_CNTL (0xccd) + GNB_ENTRY_WR (0x12, 0x3500, 0x24e), + GNB_ENTRY_WR (0x12, 0x3504, 0xccd), +// opcode=0, body_cnt=23: MC_ARB_HARSH_EN_RD (0xdc0) MC_ARB_HARSH_CTL_WR (0xdd7) + GNB_ENTRY_WR (0x12, 0x3500, 0x250), + GNB_ENTRY_WR (0x12, 0x3504, 0x170dc0), +// opcode=0, body_cnt=0: MC_CONFIG (0x800) MC_CONFIG (0x800) + GNB_ENTRY_WR (0x12, 0x3500, 0x269), + GNB_ENTRY_WR (0x12, 0x3504, 0x800), +// opcode=0, body_cnt=0: MC_CONFIG_MCD (0x828) MC_CONFIG_MCD (0x828) + GNB_ENTRY_WR (0x12, 0x3500, 0x26b), + GNB_ENTRY_WR (0x12, 0x3504, 0x828), +//--------------------------------------------------------------------------- +// Setting up end pointers + GNB_ENTRY_RMW (0x12, 0x3508, 0xfffff000, 0x9b26c000), +//--------------------------------------------------------------------------- +// Enabling light sleep + GNB_ENTRY_RMW (0x12, 0x3544, 0x6000000, 0x2000000), + + // 2.7 Performance tuning + GNB_ENTRY_WR (0x12, 0x27D0, 0x10724847), + GNB_ENTRY_WR (0x12, 0x27C0, 0x00C32008), + GNB_ENTRY_WR (0x12, 0x27C4, 0x00C32006), + GNB_ENTRY_WR (0x12, 0x277C, 0x00000007), + GNB_ENTRY_WR (0x12, 0x218C, 0x000021b1), + GNB_ENTRY_WR (0x12, 0x201C, 0x47773337), + GNB_ENTRY_WR (0x12, 0x2020, 0x73773337), + GNB_ENTRY_WR (0x12, 0x2018, 0x66334303), + GNB_ENTRY_WR (0x12, 0x2014, 0x66300333), + GNB_ENTRY_WR (0x12, 0x2794, 0xfcfcfdfc), + GNB_ENTRY_WR (0x12, 0x2798, 0xfcfcfdfc), + GNB_ENTRY_WR (0x12, 0x27A4, 0x00ffffff), + GNB_ENTRY_WR (0x12, 0x27A8, 0x00ffffff), + GNB_ENTRY_WR (0x12, 0x278C, 0x00000008), + GNB_ENTRY_WR (0x12, 0x2790, 0x00000008), + GNB_ENTRY_WR (0x12, 0x2628, 0x55111000), + GNB_ENTRY_WR (0x12, 0x25E0, 0x00000025), + GNB_ENTRY_WR (0x12, 0x262C, 0x10555111), + GNB_ENTRY_WR (0x12, 0x25E4, 0x00000025), + GNB_ENTRY_WR (0x12, 0x25C8, 0x0080685F), + GNB_ENTRY_WR (0x12, 0x25CC, 0x0000807F), + GNB_ENTRY_WR (0x12, 0x2144, 0x50A1421D), + GNB_ENTRY_WR (0x12, 0x20EC, 0x0000001C), + GNB_ENTRY_WR (0x12, 0x2184, 0x0000A1F1), + GNB_ENTRY_WR (0x12, 0x21E0, 0x0000A1F1), + GNB_ENTRY_WR (0x12, 0x217C, 0x0000A1F1), + GNB_ENTRY_WR (0x12, 0x21C0, 0x0000A1F1), + GNB_ENTRY_WR (0x12, 0x2214, 0x000021B1), + GNB_ENTRY_WR (0x12, 0x2220, 0x000021B1), + GNB_ENTRY_WR (0x12, 0x3758, 0x00000800), + GNB_ENTRY_WR (0x12, 0x375C, 0x00000800), + GNB_ENTRY_WR (0x12, 0x3700, 0xD1000000), + GNB_ENTRY_WR (0x12, 0x3704, 0xD0000000), + GNB_ENTRY_WR (0x12, 0x3748, 0x0000007F), + GNB_ENTRY_WR (0x12, 0x3750, 0x18201015), + GNB_ENTRY_WR (0x12, 0x3754, 0x18201015), + GNB_ENTRY_WR (0x12, 0x253C, 0x000000B4), + GNB_ENTRY_WR (0x12, 0x2550, 0x000000A3), + GNB_ENTRY_WR (0x12, 0x2558, 0x00002077), + GNB_ENTRY_WR (0x12, 0x2558, 0x000020B7), + GNB_ENTRY_WR (0x12, 0x2558, 0x00002A3D), + + GNB_ENTRY_WR (0x12, 0x287C, 0x0c000911), + + //2.9 Display latency + GNB_ENTRY_WR (0x12, 0x2114, 0x00000015), + + GNB_ENTRY_WR (0x12, 0x2880, 0xFCFE8000), + + //2.12 Remove blackout + GNB_ENTRY_WR (0x12, 0x20AC, 0x00000000), + + // VCE Optimization + GNB_ENTRY_RMW (0x12, 0x2108, 0xff00, (1 << 8)), + GNB_ENTRY_WR (0x12, 0x21fc, 0xA1F1), + GNB_ENTRY_WR (0x12, 0x2198, 0xA1F1), + + // STCTRL_IGNORE_PROTECTION_FAULT + GNB_ENTRY_RMW (0x12, 0x350C, 0x01000000, (1 << 24)), + + GNB_ENTRY_RMW (0x12, 0x5490, 0x2 | 0x1, (1 << 0) | (1 << 1)), + + GNB_ENTRY_TERMINATE +}; + +GNB_TABLE ROMDATA GfxGmcFeature1EnableKB [] = { + GNB_ENTRY_WR (0x12, 0x20C0, 0x000c0c80), + GNB_ENTRY_WR (0x12, 0x2478, 0x000c0400), + GNB_ENTRY_WR (0x12, 0x20B8, 0x000c0400), + GNB_ENTRY_WR (0x12, 0x20BC, 0x000c0400), + GNB_ENTRY_WR (0x12, 0x2648, 0x00080400), + GNB_ENTRY_WR (0x12, 0x264C, 0x000c0400), + GNB_ENTRY_WR (0x12, 0x2650, 0x000c0400), + GNB_ENTRY_WR (0x12, 0x15C0, 0x000c0400), + GNB_ENTRY_TERMINATE +}; + +GNB_TABLE ROMDATA GfxEnvInitTableKB [] = { + GNB_ENTRY_TERMINATE +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbEarlyInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbEarlyInitKB.c new file mode 100644 index 0000000000..288884b0cf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbEarlyInitKB.c @@ -0,0 +1,459 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB early post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84838 $ @e \$Date: 2012-12-20 10:04:21 -0600 (Thu, 20 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "OptionGnb.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbTable.h" +#include "GnbSmuInitLibV7.h" +#include "GnbSmuFirmwareKB.h" +#include "GnbRegisterAccKB.h" +#include "GnbRegistersKB.h" +#include "cpuF16PowerMgmt.h" +#include "excel925.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GNBEARLYINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_TABLE ROMDATA GnbEarlierInitTableBeforeSmuKB []; +extern GNB_TABLE ROMDATA GnbEarlyInitTableKB []; +extern GNB_BUILD_OPTIONS GnbBuildOptions; +extern BUILD_OPT_CFG UserOptions; + +#define CFG_DISP_PHY_TDP_LIMIT 0 +#define CFG_FCH_PWR_CREDIT 0 + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GnbEarlyInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbEarlierInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbScsInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +OptionGnbInstall581 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +STATIC VOID +GnbEarlyInitKB129_fun ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_EARLY_PARAMS *EarlyParams; + UINT32 v0; + UINT32 v1; + D18F4x110_STRUCT D18F4x110; + D18F5xE0_STRUCT D18F5xE0; + UINT32 v4; + UINT32 Data; + + EarlyParams = (AMD_EARLY_PARAMS *) StdHeader; + + v0 = ((EarlyParams->PlatformConfig.VrmProperties[CoreVrm].CurrentLimit / 10) & 0xFFFF) | + (((EarlyParams->PlatformConfig.VrmProperties[NbVrm].CurrentLimit / 10) & 0xFFFF) << 16); + GnbRegisterWriteKB (GnbGetHandle (StdHeader), 0x4, 0x3FA04, &v0, 0, StdHeader); + + v1 = ((EarlyParams->PlatformConfig.VrmProperties[CoreVrm].SviOcpLevel / 10) & 0xFFFF) | + (((EarlyParams->PlatformConfig.VrmProperties[NbVrm].SviOcpLevel / 10) & 0xFFFF) << 16); + GnbRegisterWriteKB (GnbGetHandle (StdHeader), 0x4, 0x3f994, &v1, 0, StdHeader); + + GnbRegisterReadKB (GnbGetHandle (StdHeader), + D18F4x110_TYPE, D18F4x110_ADDRESS, &D18F4x110, 0, StdHeader); + GnbRegisterReadKB (GnbGetHandle (StdHeader), + D18F5xE0_TYPE, D18F5xE0_ADDRESS, &D18F5xE0, 0, StdHeader); + + // Period = (2^(RunAvgRange + 1)*CSampleTimer*5.12)us - round down to nearest 10uS + Data = D18F5xE0.Field.RunAvgRange + 1; + Data = 1 << Data; + Data *= D18F4x110.Field.CSampleTimer; + Data = ((Data * 512) / 1000) * 10; + + IDS_HDT_CONSOLE (GNB_TRACE, "VPC period = %d\n", Data); + + v4 = Data; + GnbRegisterWriteKB (GnbGetHandle (StdHeader), + 0x4, 0x3F830, &v4, 0, StdHeader); + +} + +/*----------------------------------------------------------------------------------------*/ +STATIC VOID +GnbEarlyInitKB180_fun ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + D18F3xA8_STRUCT D18F3xA8; + UINT32 D0F0xBC_x3F9D8; + UINT64 MsrData; + + GnbRegisterReadKB (GnbGetHandle (StdHeader), D18F3xA8_TYPE, D18F3xA8_ADDRESS, &D18F3xA8, 0, StdHeader); + GnbRegisterReadKB (GnbGetHandle (StdHeader), 0x4, 0x3F9D8, &D0F0xBC_x3F9D8, 0, StdHeader); + D0F0xBC_x3F9D8 &= ~(0xF << 24); + D0F0xBC_x3F9D8 |= (D18F3xA8.Field.PopDownPstate & 0x7) << 24; + LibAmdMsrRead ((PS_REG_BASE + D18F3xA8.Field.PopDownPstate), &MsrData, StdHeader); + D0F0xBC_x3F9D8 |= (((MsrData & (1 << 22)) == 0) ? (1 << 27) :0); + GnbRegisterWriteKB (GnbGetHandle (StdHeader), 0x4, 0x3F9D8, &D0F0xBC_x3F9D8, 0, StdHeader); + return; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Package Power Support + * + * + * + * @param[in] StdHeader Standard configuration header + */ + +STATIC VOID +GnbInitPkgPowerKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 D0F0xBC_x3F834; + UINT32 D0F0xBC_x3F838; + UINT32 D0F0xBC_x3F844; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbInitPkgPowerKB Enter\n"); + + D0F0xBC_x3F834 = CFG_DISP_PHY_TDP_LIMIT; + GnbRegisterWriteKB (GnbGetHandle (StdHeader), TYPE_D0F0xBC, 0x3F834, + &D0F0xBC_x3F834, 0, StdHeader); + + D0F0xBC_x3F838 = CFG_FCH_PWR_CREDIT; + GnbRegisterWriteKB (GnbGetHandle (StdHeader), TYPE_D0F0xBC, 0x3F838, + &D0F0xBC_x3F838, 0, StdHeader); + + GnbRegisterReadKB (GnbGetHandle (StdHeader), 0x4, 0x3f844, + &D0F0xBC_x3F844, 0, StdHeader); + D0F0xBC_x3F844 &= 0xe0000000; + GnbRegisterWriteKB (GnbGetHandle (StdHeader), 0x4, 0x3f844, + &D0F0xBC_x3F844, 0, StdHeader); + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbInitPkgPowerKB Exit\n"); + return; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Request VDDB Pmin + * + * + * + * @param[in] GnbHandle GNB_HANDLE + * @param[in] StdHeader Standard configuration header + */ + +STATIC VOID +GnbRequestVddNbPminKB ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + D18F5x170_STRUCT D18F5x170; + D18F5x160_STRUCT D18F5x160; + UINT32 Millivolt; + UINT32 NbVid; + DEV_OBJECT DevObject; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbRequestVddNbPminKB Enter\n"); + // 1) Read F5x170[NbPstateMaxVal] to find NB Pmin. + GnbRegisterReadKB (GnbHandle, D18F5x170_TYPE, D18F5x170_ADDRESS, &D18F5x170, 0, StdHeader); + // 2) Determine voltage associated with NB Pmin. Read F5x(160+4*NbPstateMaxVal)[NbVid]. (For example, NBP0 is F5x160, NBP1 is F5x164, etc) + GnbRegisterReadKB (GnbHandle, D18F5x160_TYPE, (D18F5x160_ADDRESS + (4 * D18F5x170.Field.NbPstateMaxVal)), &D18F5x160, 0, StdHeader); + NbVid = (D18F5x160.Field.NbVid_7_ << 7) | (D18F5x160.Field.NbVid_6_0_); + // 3) Make voltage request (via BIOSSMC_MSG_VDDNB_REQUEST) for voltage determined by Step 2. Note that message requires encoding in voltage, not VID. + // Use the following equation to decode SVI2 VIDs: + // Voltage = 1.55 - (0.00625*VID) + // Furthermore, VDDNB requests to SMU should be encoded in 0.25mV steps. + // Therefore, voltage should be translated into mV and then multiplied by 4, to be encoded as 0.25mV steps. + // Or... ( 1.55 * 1000 * 4) - (.00625 * 1000 * 4) * VID) = (1550 * 4) - (25 * VID) + Millivolt = (1550 * 4) - (25 * NbVid); + + IDS_HDT_CONSOLE (GNB_TRACE, " Set Voltage for NbPstateMaxVal = 0x%x, Vid code 0x%x = %d mV\n", D18F5x170.Field.NbPstateMaxVal, NbVid, Millivolt); + DevObject.StdHeader = StdHeader; + DevObject.GnbHandle = GnbHandle; + DevObject.DevPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + GnbSmuServiceRequestV7 ( + &DevObject, + SMC_MSG_VDDNB_REQUEST, + Millivolt, + 0 + ); + IDS_HDT_CONSOLE (GNB_TRACE, "GnbRequestVddNbPminKB Exit\n"); + return; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize GFX straps. + * + * + * @param[in] StdHeader Standard configuration header + */ +STATIC VOID +GfxStrapsEarlyInitKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GnbRegistersKB7236_STRUCT v0; + GnbRegistersKB7269_STRUCT v1; + GnbRegistersKB7314_STRUCT v2; + GnbRegistersKB7341_STRUCT v3; + GNB_HANDLE *GnbHandle; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxStrapsEarlyInitKB Enter\n"); + + GnbHandle = GnbGetHandle (StdHeader); + + GnbRegisterReadKB (GnbHandle, TYPE_D0F0xD4, 0x13014AB, &v0.Value, 0, StdHeader); + GnbRegisterReadKB (GnbHandle, TYPE_D0F0xD4, 0x13014AC, &v1.Value, 0, StdHeader); + GnbRegisterReadKB (GnbHandle, TYPE_D0F0xD4, 0x13014B6, &v2.Value, 0, StdHeader); + GnbRegisterReadKB (GnbHandle, TYPE_D0F0xD4, 0x013014BE, &v3.Value, 0, StdHeader); + + v0.Field.bit17 = 1; + + v2.Field.bita = 0x0; + v2.Field.StrapBifF0LegacyDeviceTypeDis = 0x0; + + v1.Field.bit16 = UserOptions.CfgGnbHdAudio; + v2.Field.bit13 = UserOptions.CfgGnbHdAudio; + + // Enable PCI Vendor Specific Capabilities + v3.Field.bit_20 = 1; + + GnbRegisterWriteKB (GnbHandle, TYPE_D0F0xD4, 0x13014AB, &v0.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + GnbRegisterWriteKB (GnbHandle, TYPE_D0F0xD4, 0x13014AC, &v1.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + GnbRegisterWriteKB (GnbHandle, TYPE_D0F0xD4, 0x13014B6, &v2.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + GnbRegisterWriteKB (GnbHandle, TYPE_D0F0xD4, 0x013014BE, &v3.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxStrapsEarlyInitKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable Gfx gBIF + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +STATIC AGESA_STATUS +GfxGBifEnableKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GnbRegistersKB7208_STRUCT var0; + GnbRegistersKB7514_STRUCT var1; + UINT32 D0F0xBC_xC00C0000; + GNB_HANDLE *GnbHandle; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGBifEnableKB Enter\n"); + GnbHandle = GnbGetHandle (StdHeader); + + GnbRegisterReadKB (GnbHandle, 0x4, 0xc00c0000, &D0F0xBC_xC00C0000, 0, StdHeader); + if (((D0F0xBC_xC00C0000 >> 1) & 1 )!= 1) { + GfxStrapsEarlyInitKB (StdHeader); + } + + GnbRegisterReadKB (GnbHandle, TYPE_D0F0xD4, 0x1301486, &var0.Value, 0, StdHeader); + GnbRegisterReadKB (GnbHandle, TYPE_D0F0xD4, 0x1091518, &var1.Value, 0, StdHeader); + var0.Field.bit2 = 0x1; + var1.Field.bit0 = 0x1; + GnbRegisterWriteKB (GnbHandle, TYPE_D0F0xD4, 0x1091518, &var1.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + GnbRegisterWriteKB (GnbHandle, TYPE_D0F0xD4, 0x1301486, &var0.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, "GfxGBifEnableKB Exit\n"); + + return AGESA_SUCCESS; +} +/*----------------------------------------------------------------------------------------*/ +/** + * GNB init at early post + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GnbEarlyInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + GNB_HANDLE *GnbHandle; + UINT32 Property; + + AgesaStatus = AGESA_SUCCESS; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbEarlyInterfaceKB Enter\n"); + GnbHandle = GnbGetHandle (StdHeader); + + Property = TABLE_PROPERTY_DEFAULT; + Property |= UserOptions.CfgGnbSyncFloodPinAsNmi ? 0x00000400ul : 0; + Property |= GnbBuildOptions.CfgSviRevision == 2 ? TABLE_PROPERTY_SVI2 : 0; + + IDS_OPTION_HOOK (IDS_GNB_PROPERTY, &Property, StdHeader); + + while (GnbHandle != NULL) { + GnbEarlyInitKB129_fun (StdHeader); + GnbEarlyInitKB180_fun (StdHeader); + GnbInitPkgPowerKB (StdHeader); + Status = GnbProcessTable ( + GnbHandle, + GnbEarlyInitTableKB, + Property, + 0, + StdHeader + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + GnbRequestVddNbPminKB (GnbHandle, StdHeader); + Status = GfxGBifEnableKB (StdHeader); + ASSERT (Status == AGESA_SUCCESS); + GnbHandle = GnbGetNextHandle (GnbHandle); + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbEarlyInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * GNB init at earlier post + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GnbEarlierInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + GNB_HANDLE *GnbHandle; + + AgesaStatus = AGESA_SUCCESS; + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GnbEarlierInterfaceKB Enter\n"); + GnbHandle = GnbGetHandle (StdHeader); + while (GnbHandle != NULL) { + Status = GnbProcessTable ( + GnbHandle, + GnbEarlierInitTableBeforeSmuKB, + 0, + 0, + StdHeader + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + Status = GnbSmuFirmwareLoadV7 (GnbHandle, (FIRMWARE_HEADER_V7*) &FirmwareKB[0], StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + GnbHandle = GnbGetNextHandle (GnbHandle); + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbEarlierInterfaceKB Exit [0x%x]\n", Status); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +OptionGnbInstall581 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + GNB_HANDLE *GnbHandle; + + AgesaStatus = AGESA_SUCCESS; + Status = AGESA_SUCCESS; + GnbHandle = GnbGetHandle (StdHeader); + + while (GnbHandle != NULL) { + Status = GnbSmuInitLibV7139_fun0 (GnbHandle, &excel925[0], StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + GnbHandle = GnbGetNextHandle (GnbHandle); + } + + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbEnvInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbEnvInitKB.c new file mode 100644 index 0000000000..e9f41de52e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbEnvInitKB.c @@ -0,0 +1,302 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB env post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85506 $ @e \$Date: 2013-01-08 15:38:33 -0600 (Tue, 08 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbCommonLib.h" +#include "GnbTable.h" +#include "GnbPcieConfig.h" +#include "GnbSmuInitLibV7.h" +#include "GnbNbInitLibV1.h" +#include "GnbNbInitLibV4.h" +#include "GnbNbInitLibV5.h" +#include "GnbF1TableKB.h" +#include "GnbF1Table.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GNBENVINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern GNB_BUILD_OPTIONS GnbBuildOptions; +extern GNB_TABLE ROMDATA GnbEnvInitTableKB []; +extern GNB_TABLE ROMDATA GnbIommuInitTableKB []; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GnbEnvInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * NB Dynamic Wake + * ORB_CNB_Wake signal is used to inform the CNB NCLK controller and GNB LCLK controller + * that ORB is (or will soon) push data into the synchronizer FIFO (i.e. wake is high). + * + * @param[in] NbPciAddress Gnb PCI address + * @param[in] StdHeader Standard Configuration Header + */ + +VOID +STATIC +GnbOrbDynamicWakeKB ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + D0F0x98_x2C_STRUCT D0F0x98_x2C; + + GnbLibPciIndirectRead ( + NbPciAddress.AddressValue | D0F0x94_ADDRESS, + D0F0x98_x2C_ADDRESS, + AccessWidth32, + &D0F0x98_x2C.Value, + StdHeader + ); + + // Enable Dynamic wake + // Wake Hysteresis timer value. Specifies the number of SMU pulses to count. + if (GnbBuildOptions.CfgOrbDynWakeEnable) { + D0F0x98_x2C.Field.DynWakeEn = 1; + } else { + D0F0x98_x2C.Field.DynWakeEn = 0; + } + D0F0x98_x2C.Field.WakeHysteresis = 0x19; + + IDS_OPTION_HOOK (IDS_GNB_ORBDYNAMIC_WAKE, &D0F0x98_x2C, StdHeader); + + GnbLibPciIndirectWrite ( + NbPciAddress.AddressValue | D0F0x94_ADDRESS, + D0F0x98_x2C_ADDRESS, + AccessS3SaveWidth32, + &D0F0x98_x2C.Value, + StdHeader + ); +} +/*----------------------------------------------------------------------------------------*/ +/** + * HTC Data + * + * @param[in] GnbHandle Gnb Header + * @param[in] StdHeader Standard Configuration Header + */ + +VOID +STATIC +GnbFillHtcData ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + UINT32 D0F0xBC_x3FDD4; + D18F3x64_STRUCT D18F3x64; + UINT16 *p = (UINT16 *)&D0F0xBC_x3FDD4; + GnbRegisterReadKB (GnbHandle, D18F3x64_TYPE, D18F3x64_ADDRESS, + &D18F3x64.Value, 0, StdHeader); + + GnbRegisterReadKB (GnbHandle, 0x4, 0x3fdd4, + &D0F0xBC_x3FDD4, 0, StdHeader); + + if (D18F3x64.Field.HtcEn == 1) { + + p[1] = D18F3x64.Field.HtcTmpLmt / 2 + 52; + p[0] = + p[1] - (D18F3x64.Field.HtcHystLmt / 2); + + p[1] = + (p[1] + 49) << 3; + p[0] = + (p[0] + 49) << 3; + + } else { + + p[0] = 0; + p[1] = 0; + + } + + + GnbRegisterWriteKB (GnbHandle, 0x4, + 0x3fdd4, &D0F0xBC_x3FDD4, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * LHTC Data + * + * @param[in] GnbHandle Gnb Header + * @param[in] StdHeader Standard Configuration Header + */ + +VOID +STATIC +GnbUpdateLhtcData ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_ENV_PARAMS *EnvParams; + UINT32 LhtcParameter; + D18F3x64_STRUCT D18F3x64; + UINT32 D0F0xBC_xC0104090; + DEV_OBJECT DevObject; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbUpdateLhtcData Enter\n"); + EnvParams = (AMD_ENV_PARAMS *) StdHeader; + + // Make sure both config values are valid + if ((EnvParams->PlatformConfig.LhtcTemperatureLimit >= 520) && (EnvParams->PlatformConfig.HtcTemperatureLimit >= 520)) { + // Platform config value is in .1 degrees + LhtcParameter = (EnvParams->PlatformConfig.LhtcTemperatureLimit - 520) / 5; + // Read HtcTmpLmt field from D18F3 + GnbRegisterReadKB (GnbGetHandle (StdHeader), D18F3x64_TYPE, D18F3x64_ADDRESS, &D18F3x64.Value, 0, StdHeader); + GnbRegisterReadKB (GnbGetHandle (StdHeader), 0x4, 0xC0104090, &D0F0xBC_xC0104090, 0, StdHeader); + if ((D18F3x64.Field.HtcEn == 1) && (LhtcParameter < D18F3x64.Field.HtcTmpLmt) && (LhtcParameter < ((D0F0xBC_xC0104090 >> 23) & 0xFF))) { + // All values are valid, so we can send the service to the SMU + DevObject.StdHeader = StdHeader; + DevObject.GnbHandle = GnbGetHandle (StdHeader); + DevObject.DevPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + GnbSmuServiceRequestV7 ( + &DevObject, + SMC_MSG_LHTC_LIMIT_SetLimit, + LhtcParameter, + GNB_REG_ACC_FLAG_S3SAVE + ); + } + } + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbUpdateLhtcData Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * GNB init at env + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GnbEnvInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + UINT32 Property; + GNB_HANDLE *GnbHandle; + PCI_ADDR GnbPciAddress; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbEnvInterfaceKB Enter\n"); + Property = TABLE_PROPERTY_DEFAULT; + Property |= GnbBuildOptions.CfgBapmSupport ? TABLE_PROPERTY_BAPM : 0; + Property |= GnbBuildOptions.CfgLhtcSupport ? TABLE_PROPERTY_LHTC : 0; + Property |= GnbBuildOptions.CfgTdcSupport ? 0x00040000ul : 0; + Property |= 0x00080000ul; + AgesaStatus = AGESA_SUCCESS; + GnbLoadF1TableKB (StdHeader); + GnbHandle = GnbGetHandle (StdHeader); + while (GnbHandle != NULL) { + GnbPciAddress = GnbGetHostPciAddress (GnbHandle); + Status = GnbSetTomV5 (GnbPciAddress, StdHeader); + GnbOrbDynamicWakeKB (GnbPciAddress, StdHeader); + GnbFillHtcData (GnbHandle, StdHeader); + if (GnbIsGnbConnectedToSb (GnbHandle)) { + GnbLpcDmaDeadlockPreventionV4 (GnbHandle, StdHeader); + } + + IDS_OPTION_HOOK (IDS_GNB_PROPERTY, &Property, StdHeader); + + Status = GnbProcessTable ( + GnbHandle, + GnbEnvInitTableKB, + Property, + GNB_TABLE_FLAGS_FORCE_S3_SAVE, + StdHeader + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + if ((Property & TABLE_PROPERTY_LHTC) != 0) { + GnbUpdateLhtcData (GnbHandle, StdHeader); + } + + Status = GnbProcessTable ( + GnbHandle, + GnbIommuInitTableKB, + Property, + GNB_TABLE_FLAGS_FORCE_S3_SAVE, + StdHeader + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + GnbHandle = GnbGetNextHandle (GnbHandle); + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbEnvInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.c new file mode 100644 index 0000000000..41b7b176f2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.c @@ -0,0 +1,1022 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Gnb f1 table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84159 $ @e \$Date: 2011-12-21 14:49:48 -0600 (Wed, 21 Dec 2011) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbGfxFamServices.h" +#include "GnbCommonLib.h" +#include "GnbF1Table.h" +#include "GnbF1TableKB.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "GnbHandleLib.h" +#include "OptionGnb.h" +#include "Filecode.h" +//#define FILECODE PROC_GNB_MODULES_GNBINITKB_GNBFUSETABLEKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + + +PP_F1_ARRAY_V2 DefaultPpF1ArrayKB = { + 0, + {0x40, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + 8, + {0, 0, 0, 0, 0, 0}, + {0x40, 0x40, 0x40, 0, 0}, + {0, 0, 0, 0, 0}, + 3, + 0x10, + 0, + 0, + 0, + 0, + TRUE, + {0x3, 0xC, 0x30, 0xC0}, + 0, + {0, 0, 0, 0}, + {0x40, 0x40, 0x40, 0x40, 0}, + 0, + 0, + 0, + 0, + { 1, 1, 1, 1}, + { 0, 0, 0, 0}, + { 2, 2, 2, 2}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 1, 1, 1, 1}, + { 0x24, 0x24, 0x24, 0x24, 0x24 }, + { 0x17, 0x18, 0x20, 0x22, 0x24 }, + { 0x17, 0x18, 0x20, 0x22, 0x24 }, + { 0x1, 0x2, 0x3, 0x4, 0x5 }, + 0x1E, + 0x3 +}; + + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0104007_TABLE [] = { + { + 5, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld32[0]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0104008_TABLE [] = { + { + 5, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld32[1]) + }, + { + 13, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld32[2]) + }, + { + 21, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld32[3]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC010400C_TABLE [] = { + { + 25, + 6, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld21) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC010407C_TABLE [] = { + { + 20, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld32[4]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0104080_TABLE [] = { + { + 21, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, VceFlags[0]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0104083_TABLE [] = { + { + 5, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, VceFlags[1]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0104084_TABLE [] = { + { + 5, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, VceFlags[2]) + }, + { + 13, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, VceFlags[3]) + }, + { + 29, + 3, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld16[0]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0104088_TABLE [] = { + { + 0, + 3, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld16[1]) + }, + { + 3, + 3, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld16[2]) + }, + { + 6, + 3, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld16[3]) + }, + { + 12, + 5, + (UINT16) offsetof (PP_F1_ARRAY_V2, VceMclk) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC01040A8_TABLE [] = { + { + 16, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld35[0]) + }, + { + 24, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld35[1]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC01040AC_TABLE [] = { + { + 0, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld35[2]) + }, + { + 8, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld35[3]) + }, + { + 16, + 8, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld35[4]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107044_TABLE [] = { + { + 16, + 3, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld36) + }, +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107064_TABLE [] = { + { + 0, + 4, + (UINT16) offsetof (PP_F1_ARRAY_V2, PPlayTableRev) + }, + { + 4, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld3) + }, + { + 11, + 3, + (UINT16) offsetof (PP_F1_ARRAY_V2, PcieGen2Vid) + }, + { + 17, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld33[0]) + }, + { + 24, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld33[1]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107067_TABLE [] = { + { + 7, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld33[2]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107068_TABLE [] = { + { + 6, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld33[3]) + }, + { + 13, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld33[4]) + }, + { + 20, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, excel841_fld6[0]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC010706B_TABLE [] = { + { + 3, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, excel841_fld6[1]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC010706C_TABLE [] = { + { + 2, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, excel841_fld6[2]) + }, + { + 9, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, excel841_fld6[3]) + }, + { + 16, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, excel841_fld6[4]) + }, + { + 23, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld5[0]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC010706F_TABLE [] = { + { + 6, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld5[1]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107070_TABLE [] = { + { + 5, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld5[2]) + }, + { + 12, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld5[3]) + }, + { + 19, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld5[4]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107073_TABLE [] = { + { + 2, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld2[0]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107074_TABLE [] = { + { + 1, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld2[1]) + }, + { + 8, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld2[2]) + }, + { + 15, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld2[3]) + }, + { + 22, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld2[4]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107077_TABLE [] = { + { + 5, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld1[0]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107078_TABLE [] = { + { + 4, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld1[1]) + }, + { + 11, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld1[2]) + }, + { + 18, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld1[3]) + }, + { + 25, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld1[4]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC010707C_TABLE [] = { + { + 0, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, EclkDid[0]) + }, + { + 7, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, EclkDid[1]) + }, + { + 14, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, EclkDid[2]) + }, + { + 21, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, EclkDid[3]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC010707F_TABLE [] = { + { + 4, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, EclkDid[4]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107080_TABLE [] = { + { + 3, + 5, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld37) + }, + { + 8, + 5, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld38) + }, + { + 13, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld34[0]) + }, + { + 20, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld34[1]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107083_TABLE [] = { + { + 3, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld34[2]) + } +}; + +F1_REGISTER_ENTRY_KB D0F0xBC_xC0107084_TABLE [] = { + { + 2, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld34[3]) + }, + { + 9, + 7, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld34[4]) + } +}; + +F1_REGISTER_ENTRY_KB D18F3x64_TABLE [] = { + { + D18F3x64_HtcEn_OFFSET, + D18F3x64_HtcEn_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, HtcEn) + }, + { + D18F3x64_HtcTmpLmt_OFFSET, + D18F3x64_HtcTmpLmt_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, HtcTmpLmt) + }, + { + D18F3x64_HtcHystLmt_OFFSET, + D18F3x64_HtcHystLmt_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld20) + } +}; + +F1_REGISTER_ENTRY_KB GnbFuseTableKB565_TABLE [] = { + { + 1, + 6, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld21) + } +}; + +F1_REGISTER_ENTRY_KB D18F2x90_dct0_TABLE [] = { + { + D18F2x90_dct0_DisDllShutdownSR_OFFSET, + D18F2x90_dct0_DisDllShutdownSR_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, DisDllShutdownSR[0]) + } +}; + +F1_REGISTER_ENTRY_KB D18F2x94_dct0_TABLE [] = { + { + D18F2x94_dct0_MemClkFreq_OFFSET, + D18F2x94_dct0_MemClkFreq_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, MemClkFreq[0]) + } +}; + +F1_REGISTER_ENTRY_KB D18F2xA8_dct0_TABLE [] = { + { + D18F2xA8_dct0_MemPhyPllPdMode_OFFSET, + D18F2xA8_dct0_MemPhyPllPdMode_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, MemPhyPllPdMode[0]) + } +}; + +F1_REGISTER_ENTRY_KB D18F2x2E0_dct0_TABLE [] = { + { + D18F2x2E0_dct0_M1MemClkFreq_OFFSET, + D18F2x2E0_dct0_M1MemClkFreq_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, M1MemClkFreq[0]) + } +}; + +F1_REGISTER_ENTRY_KB D18F5x160_TABLE [] = { + { + D18F5x160_NbPstateEn_OFFSET, + D18F5x160_NbPstateEn_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld26[0]) + }, + { + D18F5x160_MemPstate_OFFSET, + D18F5x160_MemPstate_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld29[0]) + }, + { + D18F5x160_NbFid_OFFSET, + D18F5x160_NbFid_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld30[0]) + }, + { + D18F5x160_NbDid_OFFSET, + D18F5x160_NbDid_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld31[0]) + }, + { + D18F5x160_NbVid_6_0_OFFSET, + D18F5x160_NbVid_6_0_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld27[0]) + }, + { + D18F5x160_NbVid_7_OFFSET, + D18F5x160_NbVid_7_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld28[0]) + } +}; + +F1_REGISTER_ENTRY_KB D18F5x164_TABLE [] = { + { + D18F5x164_NbPstateEn_OFFSET, + D18F5x164_NbPstateEn_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld26[1]) + }, + { + D18F5x164_MemPstate_OFFSET, + D18F5x164_MemPstate_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld29[1]) + }, + { + D18F5x164_NbFid_OFFSET, + D18F5x164_NbFid_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld30[1]) + }, + { + D18F5x164_NbDid_OFFSET, + D18F5x164_NbDid_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld31[1]) + }, + { + D18F5x164_NbVid_6_0_OFFSET, + D18F5x164_NbVid_6_0_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld27[1]) + }, + { + D18F5x164_NbVid_7_OFFSET, + D18F5x164_NbVid_7_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld28[1]) + } +}; + +F1_REGISTER_ENTRY_KB D18F5x168_TABLE [] = { + { + D18F5x168_NbPstateEn_OFFSET, + D18F5x168_NbPstateEn_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld26[2]) + }, + { + D18F5x168_MemPstate_OFFSET, + D18F5x168_MemPstate_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld29[2]) + }, + { + D18F5x168_NbFid_OFFSET, + D18F5x168_NbFid_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld30[2]) + }, + { + D18F5x168_NbDid_OFFSET, + D18F5x168_NbDid_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld31[2]) + }, + { + D18F5x168_NbVid_6_0_OFFSET, + D18F5x168_NbVid_6_0_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld27[2]) + }, + { + D18F5x168_NbVid_7_OFFSET, + D18F5x168_NbVid_7_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld28[2]) + } +}; + +F1_REGISTER_ENTRY_KB D18F5x16C_TABLE [] = { + { + D18F5x16C_NbPstateEn_OFFSET, + D18F5x16C_NbPstateEn_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld26[3]) + }, + { + D18F5x16C_MemPstate_OFFSET, + D18F5x16C_MemPstate_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld29[3]) + }, + { + D18F5x16C_NbFid_OFFSET, + D18F5x16C_NbFid_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld30[3]) + }, + { + D18F5x16C_NbDid_OFFSET, + D18F5x16C_NbDid_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld31[3]) + }, + { + D18F5x16C_NbVid_6_0_OFFSET, + D18F5x16C_NbVid_6_0_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld27[3]) + }, + { + D18F5x16C_NbVid_7_OFFSET, + D18F5x16C_NbVid_7_WIDTH, + (UINT16) offsetof (PP_F1_ARRAY_V2, PP_FUSE_ARRAY_V2_fld28[3]) + } +}; + + +F1_TABLE_ENTRY_KB F1RegisterTableKB [] = { + + { + 0x4, + 0xC0104007, + sizeof (D0F0xBC_xC0104007_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0104007_TABLE + }, + { + 0x4, + 0xC0104008, + sizeof (D0F0xBC_xC0104008_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0104008_TABLE + }, + { + 0x4, + 0xC010400c, + sizeof (D0F0xBC_xC010400C_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC010400C_TABLE + }, + { + 0x4, + 0xC010407c, + sizeof (D0F0xBC_xC010407C_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC010407C_TABLE + }, + { + 0x4, + 0xC0104080, + sizeof (D0F0xBC_xC0104080_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0104080_TABLE + }, + { + 0x4, + 0xC0104083, + sizeof (D0F0xBC_xC0104083_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0104083_TABLE + }, + { + 0x4, + 0xC0104084, + sizeof (D0F0xBC_xC0104084_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0104084_TABLE + }, + { + 0x4, + 0xC0104088, + sizeof (D0F0xBC_xC0104088_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0104088_TABLE + }, + { + 0x4, + 0xC01040a8, + sizeof (D0F0xBC_xC01040A8_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC01040A8_TABLE + }, + { + 0x4, + 0xC01040ac, + sizeof (D0F0xBC_xC01040AC_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC01040AC_TABLE + }, + { + 0x4, + 0xC0107044, + sizeof (D0F0xBC_xC0107044_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107044_TABLE + }, + { + 0x4, + 0xC0107064, + sizeof (D0F0xBC_xC0107064_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107064_TABLE + }, + { + 0x4, + 0xC0107067, + sizeof (D0F0xBC_xC0107067_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107067_TABLE + }, + { + 0x4, + 0xC0107068, + sizeof (D0F0xBC_xC0107068_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107068_TABLE + }, + { + 0x4, + 0xC010706b, + sizeof (D0F0xBC_xC010706B_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC010706B_TABLE + }, + { + 0x4, + 0xC010706c, + sizeof (D0F0xBC_xC010706C_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC010706C_TABLE + }, + { + 0x4, + 0xC010706f, + sizeof (D0F0xBC_xC010706F_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC010706F_TABLE + }, + { + 0x4, + 0xC0107070, + sizeof (D0F0xBC_xC0107070_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107070_TABLE + }, + { + 0x4, + 0xC0107073, + sizeof (D0F0xBC_xC0107073_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107073_TABLE + }, + { + 0x4, + 0xC0107074, + sizeof (D0F0xBC_xC0107074_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107074_TABLE + }, + { + 0x4, + 0xC0107077, + sizeof (D0F0xBC_xC0107077_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107077_TABLE + }, + { + 0x4, + 0xC0107078, + sizeof (D0F0xBC_xC0107078_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107078_TABLE + }, + { + 0x4, + 0xC010707c, + sizeof (D0F0xBC_xC010707C_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC010707C_TABLE + }, + { + 0x4, + 0xC0107080, + sizeof (D0F0xBC_xC0107080_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107080_TABLE + }, + { + 0x4, + 0xC0107083, + sizeof (D0F0xBC_xC0107083_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107083_TABLE + }, + { + 0x4, + 0xC0107084, + sizeof (D0F0xBC_xC0107084_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D0F0xBC_xC0107084_TABLE + } +}; + +F1_TABLE_ENTRY_KB PPRegisterTableKB [] = { + { + D18F3x64_TYPE, + D18F3x64_ADDRESS, + sizeof (D18F3x64_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D18F3x64_TABLE + }, + { + 0x4, + 0xC0500000, + sizeof (GnbFuseTableKB565_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + GnbFuseTableKB565_TABLE + }, + { + D18F2x90_dct0_TYPE, + D18F2x90_dct0_ADDRESS, + sizeof (D18F2x90_dct0_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D18F2x90_dct0_TABLE + }, + { + D18F2x94_dct0_TYPE, + D18F2x94_dct0_ADDRESS, + sizeof (D18F2x94_dct0_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D18F2x94_dct0_TABLE + }, + { + D18F2xA8_dct0_TYPE, + D18F2xA8_dct0_ADDRESS, + sizeof (D18F2xA8_dct0_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D18F2xA8_dct0_TABLE + }, + { + D18F5x160_TYPE, + D18F5x160_ADDRESS, + sizeof (D18F5x160_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D18F5x160_TABLE + }, + { + D18F5x164_TYPE, + D18F5x164_ADDRESS, + sizeof (D18F5x164_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D18F5x164_TABLE + }, + { + D18F5x168_TYPE, + D18F5x168_ADDRESS, + sizeof (D18F5x168_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D18F5x168_TABLE + }, + { + D18F5x16C_TYPE, + D18F5x16C_ADDRESS, + sizeof (D18F5x16C_TABLE) / sizeof (F1_REGISTER_ENTRY_KB), + D18F5x16C_TABLE + } +}; + + +F1_TABLE_KB F1TableKB = { + sizeof (F1RegisterTableKB) / sizeof (F1_TABLE_ENTRY_KB), + F1RegisterTableKB +}; + +F1_TABLE_KB PPTableKB = { + sizeof (PPRegisterTableKB) / sizeof (F1_TABLE_ENTRY_KB), + PPRegisterTableKB +}; + + +/*----------------------------------------------------------------------------------------*/ +/** + * Load F1 Table KB + * + * + * param[out] PpF1Array Pointer to save f1 table + * param[in] StdHeader Pointer to Standard configuration + * retval AGESA_STATUS + */ + +STATIC VOID +NbF1LoadF1TableKB ( + IN F1_TABLE_KB *F1Table, + OUT PP_F1_ARRAY_V2 *PpF1Array, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN RegisterIndex; + + for (RegisterIndex = 0; RegisterIndex < F1Table->F1TableLength; RegisterIndex++ ) { + UINTN FieldIndex; + UINTN F1RegisterTableLength; + UINT32 F1Value; + F1RegisterTableLength = F1Table->F1Table[RegisterIndex].F1RegisterTableLength; + + GnbRegisterReadKB ( + GnbGetHandle (StdHeader), + F1Table->F1Table[RegisterIndex].RegisterSpaceType, + F1Table->F1Table[RegisterIndex].Register, + &F1Value, + 0, + StdHeader + ); + for (FieldIndex = 0; FieldIndex < F1RegisterTableLength; FieldIndex++) { + F1_REGISTER_ENTRY_KB RegisterEntry; + RegisterEntry = F1Table->F1Table[RegisterIndex].F1RegisterTable[FieldIndex]; + *((UINT8 *) PpF1Array + RegisterEntry.F1Offset) = (UINT8) ((F1Value >> RegisterEntry.FieldOffset) & + ((1 << RegisterEntry.FieldWidth) - 1)); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb load f1 table + * + * + * + * @param[in] StdHeader Pointer to Standard configuration + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GnbLoadF1TableKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PP_F1_ARRAY_V2 *PpF1Array; + AGESA_STATUS Status; + D18F3xA0_STRUCT D18F3xA0; + + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GnbLoadF1TableKB Enter\n"); + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbAllocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, sizeof (PP_F1_ARRAY_V2), StdHeader); + ASSERT (PpF1Array != NULL); + if (PpF1Array != NULL) { + //Support for real f1 table + GnbRegisterReadKB (GnbGetHandle (StdHeader), D18F3xA0_TYPE, D18F3xA0_ADDRESS, &D18F3xA0.Value, 0, StdHeader); + + if ((D18F3xA0.Field.CofVidProg) && (GnbBuildOptions.GnbLoadRealF1Table)) { + NbF1LoadF1TableKB (&F1TableKB, PpF1Array, StdHeader); + PpF1Array->PP_FUSE_ARRAY_V2_fld13 = TRUE; + IDS_HDT_CONSOLE (NB_MISC, " Processor F1d\n"); + } else { + LibAmdMemCopy (PpF1Array, &DefaultPpF1ArrayKB, sizeof (PP_F1_ARRAY_V2), StdHeader); + IDS_HDT_CONSOLE (NB_MISC, " Processor Unf1d\n"); + } + NbF1LoadF1TableKB (&PPTableKB, PpF1Array, StdHeader); + IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_PPF1_OVERRIDE, PpF1Array, StdHeader); + } else { + Status = AGESA_ERROR; + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbLoadF1TableKB Exit [0x%x]\n", Status); + return Status; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.h new file mode 100644 index 0000000000..8ea51d0c0d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.h @@ -0,0 +1,78 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * F1 table initialization + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBF1TABLEKB_H_ +#define _GNBF1TABLEKB_H_ + +#pragma pack (push, 1) + +/// F1 field entry +typedef struct { + UINT8 FieldOffset; ///< Field offset in f1 register + UINT8 FieldWidth; ///< Width of field + UINT16 F1Offset; ///< destination offset in translation table +} F1_REGISTER_ENTRY_KB; + +/// F1 register entry +typedef struct { + UINT8 RegisterSpaceType; ///< Register type + UINT32 Register; ///< FCR register address + UINT8 F1RegisterTableLength; ///< Length of field table for this register + F1_REGISTER_ENTRY_KB *F1RegisterTable; ///< Pointer to field table +} F1_TABLE_ENTRY_KB; + +/// F1 translation table +typedef struct { + UINT8 F1TableLength; ///< Length of translation table + F1_TABLE_ENTRY_KB *F1Table; ///< Pointer to register table +} F1_TABLE_KB; + +#pragma pack (pop) + +AGESA_STATUS +GnbLoadF1TableKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbInitKBInstall.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbInitKBInstall.h new file mode 100644 index 0000000000..47b8fd51a4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbInitKBInstall.h @@ -0,0 +1,234 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * KB service installation file + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86079 $ @e \$Date: 2013-01-16 00:59:04 -0600 (Wed, 16 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNB_INIT_KB_INSTALL_H_ +#define _GNB_INIT_KB_INSTALL_H_ + +//----------------------------------------------------------------------- +// Specify definition used by module services +//----------------------------------------------------------------------- + +#include "GnbPcie.h" +#include "GnbUraServices.h" +#include "GnbPcieFamServices.h" +#include "GnbFamServices.h" +#include "GnbGfxFamServices.h" + +//----------------------------------------------------------------------- +// Export services +//----------------------------------------------------------------------- + +#if (AGESA_ENTRY_INIT_EARLY == TRUE) + + extern F_PCIEFMGETSBCONFIGINFO PcieGetSbConfigInfoKB; + extern F_PCIEFMGETCOMPLEXDATALENGTH PcieGetComplexDataLengthKB; + extern F_PCIEFMBUILDCOMPLEXCONFIGURATION PcieBuildComplexConfigurationKB; + extern F_PCIEFMCONFIGUREENGINESLANEALLOCATION PcieConfigureEnginesLaneAllocationKB; + extern F_PCIEFMCHECKPORTPCIDEVICEMAPPING PcieCheckPortPciDeviceMappingKB; + extern F_PCIEFMMAPPORTPCIADDRESS PcieMapPortPciAddressKB; + extern F_PCIEFMCHECKPORTPCIELANECANBEMUXED PcieCheckPortPcieLaneCanBeMuxedKB; + + + PCIe_FAM_CONFIG_SERVICES GnbPcieConfigProtocolKB = { + PcieGetComplexDataLengthKB, + PcieBuildComplexConfigurationKB, + PcieConfigureEnginesLaneAllocationKB, + PcieCheckPortPciDeviceMappingKB, + PcieMapPortPciAddressKB, + PcieCheckPortPcieLaneCanBeMuxedKB, + PcieGetSbConfigInfoKB + }; + + GNB_SERVICE GnbPcieCongigServicesKB = { + GnbPcieFamConfigService, + AMD_FAMILY_KB, + &GnbPcieConfigProtocolKB, + SERVICES_POINTER + }; + #undef SERVICES_POINTER + #define SERVICES_POINTER &GnbPcieCongigServicesKB +#endif + +#if (AGESA_ENTRY_INIT_EARLY == TRUE) || (AGESA_ENTRY_INIT_POST == TRUE) || (AGESA_ENTRY_INIT_MID == TRUE) + extern F_PCIEFMGETCORECONFIGURATIONVALUE PcieGetCoreConfigurationValueKB; + extern F_PCIEFMGETLINKSPEEDCAP PcieGetLinkSpeedCapKB; + extern F_PCIEFMGETNATIVEPHYLANEBITMAP PcieGetNativePhyLaneBitmapKB; + extern F_PCIEFMSETLINKSPEEDCAP PcieSetLinkSpeedCapV4; + + PCIe_FAM_INIT_SERVICES GnbPcieInitProtocolKB = { + PcieGetCoreConfigurationValueKB, + PcieGetLinkSpeedCapKB, + PcieGetNativePhyLaneBitmapKB, + PcieSetLinkSpeedCapV4 + }; + + GNB_SERVICE GnbPcieInitServicesKB = { + GnbPcieFamInitService, + AMD_FAMILY_KB, + &GnbPcieInitProtocolKB, + SERVICES_POINTER + }; + #undef SERVICES_POINTER + #define SERVICES_POINTER &GnbPcieInitServicesKB +#endif + +#if (AGESA_ENTRY_INIT_EARLY == TRUE) || (AGESA_ENTRY_INIT_POST == TRUE) || (AGESA_ENTRY_INIT_MID == TRUE) + #if IDSOPT_IDS_ENABLED == TRUE + #if IDSOPT_TRACING_ENABLED == TRUE + extern F_PCIEFMDEBUGGETHOSTREGADDRESSSPACESTRING PcieDebugGetHostRegAddressSpaceStringKB; + extern F_PCIEFMDEBUGGETWRAPPERNAMESTRING PcieDebugGetWrapperNameStringKB; + extern F_PCIEFMDEBUGGETCORECONFIGURATIONSTRING PcieDebugGetCoreConfigurationStringKB; + + PCIe_FAM_DEBUG_SERVICES GnbPcieDebugProtocolKB = { + PcieDebugGetHostRegAddressSpaceStringKB, + PcieDebugGetWrapperNameStringKB, + PcieDebugGetCoreConfigurationStringKB + }; + + GNB_SERVICE GnbPcieDebugServicesKB = { + GnbPcieFamDebugService, + AMD_FAMILY_KB, + &GnbPcieDebugProtocolKB, + SERVICES_POINTER + }; + #undef SERVICES_POINTER + #define SERVICES_POINTER &GnbPcieDebugServicesKB + #endif + #endif +#endif + +#if (AGESA_ENTRY_INIT_EARLY == TRUE) || (AGESA_ENTRY_INIT_POST == TRUE) || (AGESA_ENTRY_INIT_MID == TRUE) || (AGESA_ENTRY_INIT_LATE == TRUE) + extern F_GNB_REGISTER_ACCESS GnbRegisterReadKB; + extern F_GNB_REGISTER_ACCESS GnbRegisterWriteKB; + + GNB_REGISTER_SERVICE GnbRegisterAccessProtocolKB = { + GnbRegisterReadKB, + GnbRegisterWriteKB + }; + + GNB_SERVICE GnbRegisterAccessServicesKB = { + GnbRegisterAccessService, + AMD_FAMILY_KB, + &GnbRegisterAccessProtocolKB, + SERVICES_POINTER + }; + #undef SERVICES_POINTER + #define SERVICES_POINTER &GnbRegisterAccessServicesKB + + extern F_GNBURASERVICELOCATEREGTBL GnbUraLocateRegTblKB; + extern F_GNBURASERVICEGET GnbUraGetKB; + extern F_GNBURASERVICESET GnbUraSetKB; + extern F_GNBURASERVICESTREAMSET GnbUraStreamSetKB; + + GNB_URA_SERVICE GnbUraProtocolKB = { + GnbUraLocateRegTblKB, + GnbUraGetKB, + GnbUraSetKB, + GnbUraStreamSetKB + }; + + GNB_SERVICE GnbUraServicesKB = { + GnbUraService, + AMD_FAMILY_KB, + &GnbUraProtocolKB, + SERVICES_POINTER + }; + #undef SERVICES_POINTER + #define SERVICES_POINTER &GnbUraServicesKB + + extern F_GFXMAPENGINETODISPLAYPATH GfxMapEngineToDisplayPathKB; + extern F_GFXDISABLECONTROLLER GfxDisableControllerKB; + extern F_GFXCALCULATECLOCK GfxCalculateClockKB; + extern F_GFXISVBIOSPOSTED GfxIsVbiosPostedKB; + + GFX_FAM_SERVICES GfxFamilyServiceProtocolKB = { + GfxMapEngineToDisplayPathKB, + GfxDisableControllerKB, + GfxCalculateClockKB, + GfxIsVbiosPostedKB + }; + + GNB_SERVICE GfxFamilyServicesKB = { + GfxFamService, + AMD_FAMILY_KB, + &GfxFamilyServiceProtocolKB, + SERVICES_POINTER + }; + #undef SERVICES_POINTER + #define SERVICES_POINTER &GfxFamilyServicesKB + + extern F_GNBTIMESTAMP GnbTimeStampKB; + + GNB_FAM_TS_SERVICES GnbFamTsProtocolKB = { + GnbTimeStampKB, + }; + + GNB_SERVICE GnbFamTsServicesKB = { + GnbFamTsService, + AMD_FAMILY_KB, + &GnbFamTsProtocolKB, + SERVICES_POINTER + }; + #undef SERVICES_POINTER + #define SERVICES_POINTER &GnbFamTsServicesKB + + + extern F_PCIE_MAXPAYLOAD_SETTING PcieMaxPayloadKB; + + PCIE_MAXPAYLOAD_SERVICE PcieMaxPayloadProtocolKB = { + PcieMaxPayloadKB + }; + + GNB_SERVICE PcieMaxPayloadServicesKB = { + GnbPcieMaxPayloadService, + AMD_FAMILY_KB, + &PcieMaxPayloadProtocolKB, + SERVICES_POINTER + }; + #undef SERVICES_POINTER + #define SERVICES_POINTER &PcieMaxPayloadServicesKB + +#endif +#endif // _GNB_INIT_KB_INSTALL_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbIommuTablesKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbIommuTablesKB.c new file mode 100644 index 0000000000..82f32dd62e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbIommuTablesKB.c @@ -0,0 +1,165 @@ +/** + * @file + * + * GNB init tables + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbTable.h" +#include "GnbRegistersKB.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T A B L E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +GNB_TABLE ROMDATA GnbIommuInitTableKB [] = { + + // 1. Program D0F0x64_x0D[PciDev0Fn2RegEn] = 1h + GNB_ENTRY_RMW ( + D0F0x64_x0D_TYPE, + D0F0x64_x0D_ADDRESS, + D0F0x64_x0D_PciDev0Fn2RegEn_MASK, + (0x1 << D0F0x64_x0D_PciDev0Fn2RegEn_OFFSET) + ), + // 2. Program credits for the BIF client as follows + GNB_ENTRY_RMW ( + 0xa, + ((L1_SEL_BIF << 16) | 0x32), + 0x10000 | 0x3F0 | 0xFC00, + (0x1 << 16) | (0x8 << 4) | (0x8 << 10) + ), + // 3. Program credits for the PPD client as follows + GNB_ENTRY_RMW ( + 0xa, + ((L1_SEL_PPD << 16) | 0x32), + 0x3F0 | 0xFC00, + (0x8 << 4) | (0x7 << 10) + ), + // 4. Program credits for the INTGEN client as follows + GNB_ENTRY_RMW ( + 0xa, + ((L1_SEL_INTGEN << 16) | 0x32), + 0x3F0 | 0xFC00, + (0x4 << 4) | (0x4 << 10) + ), + // 5. Program clock gating as follows + GNB_ENTRY_RMW ( + 0xa, + ((L1_SEL_PPD << 16) | 0x33), + 0x10 | 0x20 | + 0x40 | 0x80 | + 0x100 | 0x200 | + 0x400 | 0x80000000 | + 0x800, + (0x1 << 4) | (0x1 << 5) | + (0x1 << 6) | (0x1 << 7) | + (0x1 << 8) | (0x1 << 9) | + (0x1 << 10) | (0x1 << 31) | + (0x1 << 11) + ), + GNB_ENTRY_RMW ( + 0xa, + ((L1_SEL_BIF << 16) | 0x33), + 0x10 | 0x20 | + 0x40 | 0x80 | + 0x100 | 0x200 | + 0x400 | 0x80000000 | + 0x800, + (0x1 << 4) | (0x1 << 5) | + (0x1 << 6) | (0x1 << 7) | + (0x1 << 8) | (0x1 << 9) | + (0x1 << 10) | (0x1 << 31) | + (0x1 << 11) + ), + GNB_ENTRY_RMW ( + 0xa, + ((L1_SEL_INTGEN << 16) | 0x33), + 0x10 | 0x20 | + 0x40 | 0x80 | + 0x100 | 0x200 | + 0x400 | 0x80000000 | + 0x800, + (0x1 << 4) | (0x1 << 5) | + (0x1 << 6) | (0x1 << 7) | + (0x1 << 8) | (0x1 << 9) | + (0x1 << 10) | (0x1 << 31) | + (0x1 << 11) + ), + // 6. Program D0F0x64_x0D[PciDev0Fn2RegEn] = 0h + GNB_ENTRY_RMW ( + D0F0x64_x0D_TYPE, + D0F0x64_x0D_ADDRESS, + D0F0x64_x0D_PciDev0Fn2RegEn_MASK, + 0 + ), + GNB_ENTRY_TERMINATE +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbMidInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbMidInitKB.c new file mode 100644 index 0000000000..b9ba10de20 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbMidInitKB.c @@ -0,0 +1,429 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB mid post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbLib.h" +#include "GnbPcieConfig.h" +#include "GnbF1Table.h" +#include "heapManager.h" +#include "GnbGfxFamServices.h" +#include "GnbCommonLib.h" +#include "GnbNbInitLibV1.h" +#include "GnbNbInitLibV5.h" +#include "GnbGfxInitLibV1.h" +#include "GnbSmuInitLibV7.h" +#include "GnbTable.h" +#include "GnbRegisterAccKB.h" +#include "GnbRegistersKB.h" +#include "GnbFamServices.h" +#include "OptionGnb.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GNBMIDINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_BUILD_OPTIONS GnbBuildOptions; +extern GNB_TABLE ROMDATA GnbMidInitTableKB[]; + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GnbMidInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * + * + * @param[out] Index State index + * @param[in] PpF1s + * @retval TRUE State is valid + */ +STATIC BOOLEAN +GnbIsF1dStateValid ( + IN UINT8 Index, + IN PP_F1_ARRAY_V2 *PpF1s + ) +{ + BOOLEAN Result; + Result = FALSE; + + if (Index >= 5) { + Result = FALSE; + } else if ((PpF1s->PP_FUSE_ARRAY_V2_fld37 & (1 << Index)) || + (PpF1s->PP_FUSE_ARRAY_V2_fld38 & (1 << Index))) { + Result = TRUE; + } + return Result; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * LCLK DPM Initialization + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +STATIC AGESA_STATUS +GnbLclkDpmInitKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + PP_F1_ARRAY_V2 *PpF1Array; + PCI_ADDR GnbPciAddress; + UINT8 Index; + UINT8 LclkDpmMode; + + UINT32 D0F0xBC_x3FD00[8]; + UINT32 D0F0xBC_x3FD04[8]; + UINT32 D0F0xBC_x3FD08[8]; + UINT32 D0F0xBC_x3FD0C[8]; + UINT32 D0F0xBC_x3FD10[8]; + UINT32 D0F0xBC_x3FDC8; + UINT32 D0F0xBC_x3F820; + UINT32 D0F0xBC_x3FDC4; + UINT32 D0F0xBC_xC0200110; + + GNB_HANDLE *GnbHandle; + DEV_OBJECT DevObject; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbLclkDpmInitKB Enter\n"); + Status = AGESA_SUCCESS; + + GnbHandle = GnbGetHandle (StdHeader); + DevObject.DevPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + DevObject.GnbHandle = GnbHandle; + DevObject.StdHeader = StdHeader; + + GnbRegisterReadKB (GnbHandle, 0x4, + 0x3f820, &D0F0xBC_x3F820, 0, StdHeader); + D0F0xBC_x3F820 &= ~0xFF; + GnbRegisterWriteKB (GnbHandle, 0x4, + 0x3f820, &D0F0xBC_x3F820, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + + LclkDpmMode = GnbBuildOptions.LclkDpmEn ? LclkDpmRcActivity : LclkDpmDisabled; + IDS_OPTION_HOOK (IDS_GNB_LCLK_DPM_EN, &LclkDpmMode, StdHeader); + if (LclkDpmMode == LclkDpmRcActivity) { + PpF1Array = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + if (PpF1Array != NULL) { + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + if (Status == AGESA_SUCCESS) { + GnbPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + //Clear DPM_EN bit in LCLK_DPM_CNTL register + //Call BIOS service SMC_MSG_CONFIG_LCLK_DPM to disable LCLK DPM + GnbRegisterReadKB (GnbHandle, 0x4, + 0x3fdc8, &D0F0xBC_x3FDC8, 0, StdHeader); + D0F0xBC_x3FDC8 &= 0x00FFFFFF; + GnbRegisterWriteKB (GnbHandle, 0x4, + 0x3fdc8, &D0F0xBC_x3FDC8, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + + //Initialize LCLK states + LibAmdMemFill (D0F0xBC_x3FD00, 0x00, sizeof (D0F0xBC_x3FD00), StdHeader); + LibAmdMemFill (D0F0xBC_x3FD04, 0x00, sizeof (D0F0xBC_x3FD04), StdHeader); + LibAmdMemFill (D0F0xBC_x3FD08, 0x00, sizeof (D0F0xBC_x3FD08), StdHeader); + LibAmdMemFill (D0F0xBC_x3FD0C, 0x00, sizeof (D0F0xBC_x3FD0C), StdHeader); + LibAmdMemFill (D0F0xBC_x3FD10, 0x00, sizeof (D0F0xBC_x3FD10), StdHeader); + + for (Index = 0; Index < 8; ++Index) { + + if (GnbIsF1dStateValid (Index, PpF1Array)) { + + ASSERT (Index < 5); + IDS_HDT_CONSOLE (GNB_TRACE, " Valid Lclk state: %d\n", Index); + + // CNTL0 + D0F0xBC_x3FD00[Index] = 0; + D0F0xBC_x3FD00[Index] |= (PpF1Array->PP_FUSE_ARRAY_V2_fld5[Index] & 0xFF) << 16; + D0F0xBC_x3FD00[Index] |= 1 << 24; + + // CNTL1 + D0F0xBC_x3FD04[Index] = GnbTranslateVidCodeToMillivoltV5 ( + PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index], StdHeader + ) * 4 / 100; + + // CNTL2 + // D0F0xBC_x3FD08 defined as zero and is already zeroed above + D0F0xBC_x3FD08[Index] = 0; + + // CNTL3 + D0F0xBC_x3FD0C[Index] = + GfxFmCalculateClock (PpF1Array->PP_FUSE_ARRAY_V2_fld5[Index], StdHeader); + D0F0xBC_x3FD10[Index] &= ~(0xFF << 8); + switch (D0F0xBC_x3FD0C[Index]) { + case 20000: + D0F0xBC_x3FD10[Index] |= 0x7 << 8; + break; + case 30000: + D0F0xBC_x3FD10[Index] |= 0x2 << 8; + break; + case 40000: + D0F0xBC_x3FD10[Index] |= 0x3 << 8; + break; + case 15000: + D0F0xBC_x3FD10[Index] |= 0x6 << 8; + break; + case 10000: + D0F0xBC_x3FD10[Index] |= 0x8 << 8; + break; + default: + break; + } + + // Activity Threshold + D0F0xBC_x3FD10[Index] &= ~0xFFFF0000; + D0F0xBC_x3FD10[Index] |= 50 << 24; + } else { + + IDS_HDT_CONSOLE (GNB_TRACE, " Invalid Lclk state: %d\n", Index); + + // CNTL0 + D0F0xBC_x3FD00[Index] = 0xF800; + + // CNTL1 + D0F0xBC_x3FD04[Index] = 0x0; + + // CNTL2 + // D0F0xBC_x3FD08 defined as zero and is already zeroed above + D0F0xBC_x3FD08[Index] = 0; + + // CNTL3 + D0F0xBC_x3FD0C[Index] = 0; + + // Activity Threshold + D0F0xBC_x3FD10[Index] &= ~0xFFFF0000; + D0F0xBC_x3FD10[Index] |= 50 << 24; + } + + GnbRegisterWriteKB ( + GnbHandle, + 0x4, + 0x3fd00 + Index * 0x14, + &D0F0xBC_x3FD00[Index], + GNB_REG_ACC_FLAG_S3SAVE, + StdHeader + ); + GnbRegisterWriteKB ( + GnbHandle, + 0x4, + 0x3fd04 + Index * 0x14, + &D0F0xBC_x3FD04[Index], + GNB_REG_ACC_FLAG_S3SAVE, + StdHeader + ); + GnbRegisterWriteKB ( + GnbHandle, + 0x4, + 0x3fd08 + Index * 0x14, + &D0F0xBC_x3FD08[Index], + GNB_REG_ACC_FLAG_S3SAVE, + StdHeader + ); + GnbRegisterWriteKB ( + GnbHandle, + 0x4, + 0x3fd0c + Index * 0x14, + &D0F0xBC_x3FD0C[Index], + GNB_REG_ACC_FLAG_S3SAVE, + StdHeader + ); + GnbRegisterWriteKB ( + GnbHandle, + 0x4, + 0x3fd10 + Index * 0x14, + &D0F0xBC_x3FD10[Index], + GNB_REG_ACC_FLAG_S3SAVE, + StdHeader + ); + } + //Enable LCLK DPM Voltage Scaling + GnbRegisterReadKB (GnbHandle, 0x4, + 0x3fdc8, &D0F0xBC_x3FDC8, 0, StdHeader); + D0F0xBC_x3FDC8 &= 0xFF; + D0F0xBC_x3FDC8 |= 1 << 16 | 1 << 24; + GnbRegisterWriteKB (GnbHandle, 0x4, + 0x3fdc8, &D0F0xBC_x3FDC8, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + + GnbRegisterReadKB (GnbHandle, 0x4, + 0x3fdc4, &D0F0xBC_x3FDC4, 0, StdHeader); + D0F0xBC_x3FDC4 = 5; + GnbRegisterWriteKB (GnbHandle, 0x4, + 0x3fdc4, &D0F0xBC_x3FDC4, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + + GnbRegisterReadKB (GnbHandle, 0x4, + 0x3f820, &D0F0xBC_x3F820, 0, StdHeader); + D0F0xBC_x3F820 &= ~0xFF; D0F0xBC_x3F820 |= 1; + GnbRegisterWriteKB (GnbHandle, 0x4, + 0x3f820, &D0F0xBC_x3F820, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + + GnbRegisterReadKB (GnbHandle, 0x4, + 0xc0200110, &D0F0xBC_xC0200110, 0, StdHeader); + D0F0xBC_xC0200110 &= ~(1 << 2 | 7 << 5 | 0xfffff800); + D0F0xBC_xC0200110 &= ~(1 << 0 | 1 << 1 | 1 << 8); + D0F0xBC_xC0200110 |= 3<<3 | 1 << 9 | 1 << 10; //.Field.BusyCntSel = 3; + GnbRegisterWriteKB (GnbHandle, 0x4, + 0xc0200110, &D0F0xBC_xC0200110, GNB_REG_ACC_FLAG_S3SAVE, StdHeader); + + + GnbSmuServiceRequestV7 ( + &DevObject, + SMC_MSG_LCLK_DPM_ENABLE, + 0, + GNB_REG_ACC_FLAG_S3SAVE + ); + + } + } else { + Status = AGESA_ERROR; + } + + GnbSmuServiceRequestV7 ( + &DevObject, + SMC_MSG_ENABLE_ALLCLK_MONITOR, + 0, + GNB_REG_ACC_FLAG_S3SAVE + ); + + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbLclkDpmInitKB Exit [0x%x]\n", Status); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe Mid Post Init + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GnbMidInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + UINT32 Property; + AGESA_STATUS AgesaStatus; + GNB_HANDLE *GnbHandle; + PCI_ADDR GnbPciAddress; + + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GnbMidInterfaceKB Enter\n"); + + Property = TABLE_PROPERTY_DEFAULT; + Property |= GfxLibIsControllerPresent (StdHeader) ? 0 : TABLE_PROPERTY_IGFX_DISABLED; + Property |= GnbBuildOptions.LclkDeepSleepEn ? TABLE_PROPERTY_LCLK_DEEP_SLEEP : 0; + Property |= GnbBuildOptions.CfgOrbClockGatingEnable ? 0x00000008ul : 0; + Property |= 0x00000010ul; + Property |= GnbBuildOptions.CfgIocSclkClockGatingEnable ? 0x00000020ul : 0; + + GnbHandle = GnbGetHandle (StdHeader); + while (GnbHandle != NULL) { + IDS_OPTION_HOOK (IDS_GNB_PROPERTY, &Property, StdHeader); + Status = GnbProcessTable ( + GnbHandle, + GnbMidInitTableKB, + Property, + GNB_TABLE_FLAGS_FORCE_S3_SAVE, + StdHeader + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + GnbHandle = GnbGetNextHandle (GnbHandle); + } + + GnbPciAddress = GnbGetHostPciAddress (GnbGetHandle (StdHeader)); + GnbLibPciIndirectWriteField ( + GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, + D0F0xFC_x0F_ADDRESS, + D0F0xFC_x0F_GBIFExtIntrGrp_OFFSET, + D0F0xFC_x0F_GBIFExtIntrGrp_WIDTH, + 5, + AccessS3SaveWidth32, + StdHeader + ); + + GnbLibPciIndirectWriteField ( + GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, + D0F0xFC_x0F_ADDRESS, + D0F0xFC_x0F_GBIFExtIntrSwz_OFFSET, + D0F0xFC_x0F_GBIFExtIntrSwz_WIDTH, + 0, + AccessS3SaveWidth32, + StdHeader + ); + + Status = GnbLclkDpmInitKB (StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbMidInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbPostInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbPostInitKB.c new file mode 100644 index 0000000000..ce6eda2b09 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbPostInitKB.c @@ -0,0 +1,120 @@ +/** + * @file + * + * GNB post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbGfxConfig.h" +#include "GnbGfxInitLibV1.h" +#include "GnbNbInitLibV1.h" +#include "GnbNbInitLibV5.h" +#include "GnbPcieConfig.h" +#include "GfxLibV3.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GNBPOSTINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +GnbPostInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe Early Post Init + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GnbPostInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + GNB_HANDLE *GnbHandle; + PCI_ADDR GnbPciAddress; + GFX_PLATFORM_CONFIG *Gfx; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbPostInterfaceKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + + Status = GfxLocateConfigData (StdHeader, &Gfx); + ASSERT (Status == AGESA_SUCCESS); + + GnbHandle = GnbGetHandle (StdHeader); + while (GnbHandle != NULL) { + GnbPciAddress = GnbGetHostPciAddress (GnbHandle); + Status = GnbSetTomV5 (GnbPciAddress, StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + GnbHandle = GnbGetNextHandle (GnbHandle); + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbPostInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.c new file mode 100644 index 0000000000..499275bb00 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.c @@ -0,0 +1,585 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize PP/DPM fuse table. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbRegisterAccKB.h" +#include "GnbRegistersKB.h" +#include "GnbSmuInitLibV7.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GNBREGISTERACCKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +#define GNB_IGNORED_PARAM 0xFF +#define ORB_WRITE_ENABLE 0x100 +#define IOMMU_L1_WRITE_ENABLE 0x80000000ul +#define IOMMU_L2_WRITE_ENABLE 0x100 + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +GnbRegisterWriteKBDump ( + IN UINT8 RegisterSpaceType, + IN UINT32 Address, + IN VOID *Value + ); + + +/*----------------------------------------------------------------------------------------*/ +/* + * Routine to read all register spaces. + * + * + * + * @param[in] RegisterSpaceType Register space type + * @param[in] Address Register offset, but PortDevice + * @param[out] Value Return value + * @param[in] Flags Flags - BIT0 indicates S3 save/restore + * @param[in] StdHeader Standard configuration header + */ +AGESA_STATUS +GnbRegisterReadKB ( + IN GNB_HANDLE *GnbHandle, + IN UINT8 RegisterSpaceType, + IN UINT32 Address, + OUT VOID *Value, + IN UINT32 Flags, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + ACCESS_WIDTH Width; + UINT32 TempValue; + UINT32 TempAddress; + PCI_ADDR GnbPciAddress; + + GnbPciAddress = GnbGetHostPciAddress (GnbHandle); + Width = (Flags == GNB_REG_ACC_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; + TempAddress = 0; + TempValue = 0; + + + switch (RegisterSpaceType) { + case 0x1: + GnbLibPciRead ( + GnbPciAddress.AddressValue | Address, + Width, + Value, + StdHeader + ); + break; + case 0x8: + GnbPciAddress.Address.Function = 2; + GnbLibPciRead ( + GnbPciAddress.AddressValue | Address, + Width, + Value, + StdHeader + ); + break; + case 0x6: ///@todo has to be DxFx + GnbLibPciRead ( + Address, + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F0: + GnbLibPciRead ( + MAKE_SBDFO (0, 0, 0x18, 0, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F1: + GnbLibPciRead ( + MAKE_SBDFO (0, 0, 0x18, 1, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F2: + case TYPE_D18F2_dct0: + GnbLibPciRead ( + MAKE_SBDFO (0, 0, 0x18, 2, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F3: + GnbLibPciRead ( + MAKE_SBDFO (0, 0, 0x18, 3, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F4: + GnbLibPciRead ( + MAKE_SBDFO (0, 0, 0x18, 4, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F5: + GnbLibPciRead ( + MAKE_SBDFO (0, 0, 0x18, 5, Address), + Width, + Value, + StdHeader + ); + break; + + case 0x2: + // Miscellaneous Index Data, access the registers D0F0x64_x[FF:00] + GnbLibPciIndirectRead ( + GnbPciAddress.AddressValue | D0F0x60_ADDRESS, + Address, + Width, + Value, + StdHeader + ); + break; + + case 0x3: + // Northbridge ORB Configuration Offset, access D0F0x98_x[FF:00] + GnbLibPciIndirectRead ( + GnbPciAddress.AddressValue | D0F0x94_ADDRESS, + Address, + Width, + Value, + StdHeader + ); + break; + + case 0x4: + { + UINT64 TempData; + GnbLibPciIndirectRead ( + GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, + (Address & (~0x3ull)), + Width, + &TempData, + StdHeader + ); + if ((Address & 0x3) != 0) { + //Non aligned access allowed to fuse block + GnbLibPciIndirectRead ( + GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, + (Address & (~0x3ull)) + 4, + Width, + ((UINT32 *) &TempData) + 1, + StdHeader + ); + } + * ((UINT32*) Value) = (UINT32) (TempData >> ((Address & 0x3) * 8)); + break; + } + case 0x22: + // D0F0xD0 Link Index Address, access D0F0xD4_x[0130_14BF:0109_0000] + GnbLibPciIndirectRead ( + GnbPciAddress.AddressValue | 0xD0, + Address, + Width, + Value, + StdHeader + ); + break; + + case 0x5: + // D0F0xE0 Link Index Address, access D0F0xE4_x[FFFF_FFFF:0000_0000] + GnbLibPciIndirectRead ( + GnbPciAddress.AddressValue | D0F0xE0_ADDRESS, + Address, + Width, + Value, + StdHeader + ); + break; + + case 0x9: + GnbPciAddress.Address.Function = 2; + GnbLibPciIndirectRead ( + GnbPciAddress.AddressValue | 0xF0, + Address, + Width, + Value, + StdHeader + ); + break; + + case 0xa: + GnbPciAddress.Address.Function = 2; + GnbLibPciIndirectRead ( + GnbPciAddress.AddressValue | 0xF8, + Address, + Width, + Value, + StdHeader + ); + break; + + case TYPE_MSR: + LibAmdMsrRead (Address, Value, StdHeader); + break; + + case 0x12: + ASSERT (Address < 0x40000); + // SRBM + GnbLibPciIndirectRead ( + MAKE_SBDFO (0, 0, 0, 0, 0xB8), + (0x80080000 | (Address & 0x3FFFF)), + Width, + Value, + StdHeader + ); + break; + + default: + ASSERT (FALSE); + break; + } + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Routine to write all register spaces. + * + * + * @param[in] GnbHandle GnbHandle + * @param[in] RegisterSpaceType Register space type + * @param[in] Address Register offset, but PortDevice + * @param[out] Value The value to write + * @param[in] Flags Flags - BIT0 indicates S3 save/restore + * @param[in] StdHeader Standard configuration header + */ +AGESA_STATUS +GnbRegisterWriteKB ( + IN GNB_HANDLE *GnbHandle, + IN UINT8 RegisterSpaceType, + IN UINT32 Address, + IN VOID *Value, + IN UINT32 Flags, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + ACCESS_WIDTH Width; + UINT32 TempValue; + UINT32 TempAddress; + PCI_ADDR GnbPciAddress; + DEV_OBJECT DevObject; + + GnbPciAddress = GnbGetHostPciAddress (GnbHandle); + Width = (Flags == GNB_REG_ACC_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; + TempAddress = 0; + TempValue = 0; + + GNB_DEBUG_CODE ( + GnbRegisterWriteKBDump (RegisterSpaceType, Address, Value); + ); + + switch (RegisterSpaceType) { + case 0x1: + GnbLibPciWrite ( + GnbPciAddress.AddressValue | Address, + Width, + Value, + StdHeader + ); + break; + case 0x8: + GnbPciAddress.Address.Function = 2; + GnbLibPciWrite ( + GnbPciAddress.AddressValue | Address, + Width, + Value, + StdHeader + ); + break; + case 0x6: /// @todo needs to be DxFx + GnbLibPciWrite ( + Address, + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F0: + GnbLibPciWrite ( + MAKE_SBDFO (0, 0, 0x18, 0, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F1: + GnbLibPciWrite ( + MAKE_SBDFO (0, 0, 0x18, 1, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F2: + case TYPE_D18F2_dct0: + GnbLibPciWrite ( + MAKE_SBDFO (0, 0, 0x18, 2, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F3: + GnbLibPciWrite ( + MAKE_SBDFO (0, 0, 0x18, 3, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F4: + GnbLibPciWrite ( + MAKE_SBDFO (0, 0, 0x18, 4, Address), + Width, + Value, + StdHeader + ); + break; + case TYPE_D18F5: + GnbLibPciWrite ( + MAKE_SBDFO (0, 0, 0x18, 5, Address), + Width, + Value, + StdHeader + ); + break; + + case 0x2: + // Miscellaneous Index Data, access the registers D0F0x64_x[FF:00] + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | D0F0x60_ADDRESS, + Address | IOC_WRITE_ENABLE, + Width, + Value, + StdHeader + ); + break; + + case 0x3: + // Northbridge ORB Configuration Offset, access D0F0x98_x[FF:00] + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | D0F0x94_ADDRESS, + Address | ORB_WRITE_ENABLE, + Width, + Value, + StdHeader + ); + break; + + case 0x4: + //SMU, access D0F0xBC_x[FFFFFFFF:00000000] + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, + Address, + Width, + Value, + StdHeader + ); + break; + + case 0x22: + // D0F0xD0 Link Index Address, access D0F0xD4_x[0130_14BF:0109_0000] + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | 0xD0, + Address, + Width, + Value, + StdHeader + ); + break; + + case 0x5: + // D0F0xE0 Link Index Address, access D0F0xE4_x[FFFF_FFFF:0000_0000] + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | D0F0xE0_ADDRESS, + Address, + Width, + Value, + StdHeader + ); + break; + + case 0x9: + // IOMMU L2 Config Index, to access the registers D0F2xF4_x[FF:00]. + GnbPciAddress.Address.Function = 2; + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | 0xF0, + Address | IOMMU_L2_WRITE_ENABLE, + Width, + Value, + StdHeader + ); + break; + + case 0xa: + GnbPciAddress.Address.Function = 2; + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | 0xF8, + Address | IOMMU_L1_WRITE_ENABLE, + Width, + Value, + StdHeader + ); + break; + + case TYPE_MSR: + LibAmdMsrWrite (Address, Value, StdHeader); + break; + + case 0x12: + ASSERT (Address < 0x40000); + // SRBM + GnbLibPciIndirectWrite ( + MAKE_SBDFO (0, 0, 0, 0, 0xB8), + (0x80080000 | (Address & 0x3FFFF)), + Width, + Value, + StdHeader + ); + break; + + case TYPE_SMU_MSG: + DevObject.StdHeader = StdHeader; + DevObject.GnbHandle = GnbGetHandle (StdHeader); + DevObject.DevPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + GnbSmuServiceRequestV7 (&DevObject, (UINT8) Address, *((UINT32 *)Value), Flags); + break; + + default: + ASSERT (FALSE); + break; + } + + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Routine to dump all write register spaces. + * + * + * + * @param[in] RegisterSpaceType Register space type + * @param[in] Address Register offset + * @param[in] Value The value to write + */ +VOID +GnbRegisterWriteKBDump ( + IN UINT8 RegisterSpaceType, + IN UINT32 Address, + IN VOID *Value + ) +{ + IDS_HDT_CONSOLE (NB_MISC, " R WRITE Space %s Address 0x%04x, Value 0x%04x\n", + (RegisterSpaceType == 0x1) ? "0x1" : ( + (RegisterSpaceType == 0x2) ? "0x2" : ( + (RegisterSpaceType == 0x3) ? "0x3" : ( + (RegisterSpaceType == 0x4) ? "0x4" : ( + (RegisterSpaceType == 0x22) ? "0x22" : ( + (RegisterSpaceType == 0x5) ? "0x5" : ( + (RegisterSpaceType == 0x6) ? "0x6" : ( + (RegisterSpaceType == TYPE_D18F0) ? "TYPE_D18F0" : ( + (RegisterSpaceType == TYPE_D18F1) ? "TYPE_D18F1" : ( + (RegisterSpaceType == TYPE_D18F2) ? "TYPE_D18F2" : ( + (RegisterSpaceType == TYPE_D18F3) ? "TYPE_D18F3" : ( + (RegisterSpaceType == TYPE_D18F4) ? "TYPE_D18F4" : ( + (RegisterSpaceType == TYPE_D18F5) ? "TYPE_D18F5" : ( + (RegisterSpaceType == TYPE_MSR) ? "TYPE_MSR" : ( + (RegisterSpaceType == TYPE_D1F0) ? "TYPE_D1F0" : ( + (RegisterSpaceType == TYPE_D1F1) ? "TYPE_D1F1" : ( + (RegisterSpaceType == 0x12) ? "0x12" : ( + (RegisterSpaceType == TYPE_D18F2x9C_dct0) ? "TYPE_D18F2x9C_dct0" : ( + (RegisterSpaceType == TYPE_D18F2x9C_dct0_mp0) ? "TYPE_D18F2x9C_dct0_mp0" : ( + (RegisterSpaceType == TYPE_D18F2x9C_dct0_mp1) ? "TYPE_D18F2x9C_dct0_mp1" : ( + (RegisterSpaceType == TYPE_D18F2x9C_dct1) ? "TYPE_D18F2x9C_dct1" : ( + (RegisterSpaceType == TYPE_D18F2x9C_dct1_mp0) ? "TYPE_D18F2x9C_dct1_mp0" : ( + (RegisterSpaceType == TYPE_D18F2x9C_dct1_mp1) ? "TYPE_D18F2x9C_dct1_mp1" : ( + (RegisterSpaceType == TYPE_D18F2_dct0) ? "TYPE_D18F2_dct0" : ( + (RegisterSpaceType == TYPE_D18F2_dct0_mp0) ? "TYPE_D18F2_dct0_mp0" : ( + (RegisterSpaceType == TYPE_D18F2_dct0_mp1) ? "TYPE_D18F2_dct0_mp1" : ( + (RegisterSpaceType == TYPE_D18F2_dct1) ? "TYPE_D18F2_dct1" : ( + (RegisterSpaceType == TYPE_D18F2_dct1_mp0) ? "TYPE_D18F2_dct1_mp0" : ( + (RegisterSpaceType == TYPE_SMU_MSG) ? "TYPE_SMU_MSG" : ( + (RegisterSpaceType == TYPE_D18F2_dct1_mp1) ? "TYPE_D18F2_dct1_mp1" : "Invalid"))))))))))))))))))))))))))))), + Address, + *((UINT32*)Value) + ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.h new file mode 100644 index 0000000000..326c0b32f5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbRegisterAccKB.h @@ -0,0 +1,68 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various register access service procedures + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBREGISTERACCKB_H_ +#define _GNBREGISTERACCKB_H_ + +AGESA_STATUS +GnbRegisterWriteKB ( + IN GNB_HANDLE *GnbHandle, + IN UINT8 RegisterSpaceType, + IN UINT32 Address, + IN VOID *Value, + IN UINT32 Flags, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbRegisterReadKB ( + IN GNB_HANDLE *GnbHandle, + IN UINT8 RegisterSpaceType, + IN UINT32 Address, + OUT VOID *Value, + IN UINT32 Flags, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSamuPatchKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSamuPatchKB.h new file mode 100644 index 0000000000..bed59c0d32 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSamuPatchKB.h @@ -0,0 +1,2103 @@ +/** + * @file + * + * SAMU firmware + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBSAMUPATCHKB_H_ +#define _GNBSAMUPATCHKB_H_ + +UINT8 SamuPatchKB[] = { + 0x9d, + 0xaf, + 0x50, + 0x9, + 0x10, + 0x3, + 0xf6, + 0x5f, + 0x7b, + 0x29, + 0x2d, + 0xe0, + 0x33, + 0xbd, + 0x76, + 0x53, + 0x0, + 0x4, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x83, + 0x4f, + 0x17, + 0x8e, + 0x1f, + 0x7e, + 0x2, + 0xbb, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x3, + 0x0, + 0x0, + 0x2, + 0x0, + 0x0, + 0x0, + 0x4, + 0x0, + 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x80, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0xf7, + 0x11, + 0xbd, + 0x4f, + 0x87, + 0x69, + 0x32, + 0x50, + 0x1, + 0x9, + 0x10, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0x8a, + 0x38, + 0x2f, + 0xed, + 0x4d, + 0x1c, + 0x95, + 0x9f, + 0xe2, + 0x0, + 0xc0, + 0x45, + 0x50, + 0xe2, + 0x8, + 0xd2, + 0x9a, + 0xe1, + 0xca, + 0x4d, + 0xd0, + 0xb3, + 0xf1, + 0x3f, + 0x43, + 0x6a, + 0x12, + 0x54, + 0xfb, + 0x99, + 0x99, + 0xf9, + 0x4e, + 0x63, + 0xae, + 0x61, + 0x75, + 0x6a, + 0x90, + 0xf6, + 0x43, + 0xab, + 0xf8, + 0xd4, + 0x69, + 0x4d, + 0xe1, + 0x54, + 0x8e, + 0x68, + 0x9f, + 0x7, + 0x39, + 0x67, + 0xf4, + 0xdc, + 0x25, + 0xcb, + 0x0, + 0x66, + 0x28, + 0x4b, + 0xe5, + 0xdc, + 0x62, + 0x5a, + 0xa6, + 0xd6, + 0x1e, + 0xcd, + 0x48, + 0x15, + 0xde, + 0x62, + 0x53, + 0x7a, + 0xf, + 0xdf, + 0x44, + 0x4e, + 0x95, + 0xa6, + 0x82, + 0xa1, + 0x47, + 0x11, + 0x50, + 0x5f, + 0x18, + 0x8c, + 0x94, + 0x13, + 0xb8, + 0x14, + 0x21, + 0x4c, + 0xba, + 0x7b, + 0x4f, + 0x5e, + 0xe2, + 0x9, + 0x74, + 0x7e, + 0x71, + 0x21, + 0x74, + 0xd2, + 0xb2, + 0xc3, + 0xa8, + 0xa6, + 0x41, + 0x83, + 0x30, + 0xaa, + 0xf3, + 0x88, + 0x7b, + 0x16, + 0xfc, + 0xe5, + 0xe9, + 0x6f, + 0x9a, + 0xdf, + 0x7b, + 0x86, + 0x91, + 0xf5, + 0xb6, + 0x4, + 0x9e, + 0x7a, + 0x5, + 0xea, + 0x18, + 0x2e, + 0x7, + 0xc6, + 0x9, + 0x10, + 0xc5, + 0x1e, + 0xf, + 0x51, + 0x84, + 0x27, + 0x80, + 0x8d, + 0xa3, + 0x0, + 0x2d, + 0x53, + 0x6a, + 0xaa, + 0xad, + 0x2e, + 0x1e, + 0x33, + 0x6a, + 0x3d, + 0x72, + 0x16, + 0x34, + 0x9f, + 0x5f, + 0x33, + 0x70, + 0xe2, + 0x85, + 0xb7, + 0xbe, + 0xdf, + 0x59, + 0xd0, + 0xbc, + 0x7b, + 0xc0, + 0x1f, + 0x8e, + 0xc4, + 0x25, + 0xb5, + 0xe3, + 0x88, + 0x60, + 0x20, + 0x73, + 0x44, + 0x17, + 0x2f, + 0x0, + 0x2b, + 0xa5, + 0xea, + 0x4d, + 0x9, + 0xa5, + 0x42, + 0x95, + 0x23, + 0xb9, + 0x1e, + 0x1, + 0xe8, + 0xf7, + 0x7c, + 0x9f, + 0xbe, + 0xb0, + 0x85, + 0xf4, + 0x18, + 0xa9, + 0xf2, + 0x87, + 0x84, + 0x73, + 0xc2, + 0xfe, + 0x9a, + 0x8c, + 0xbb, + 0x9d, + 0x36, + 0x8d, + 0x2e, + 0x94, + 0xc1, + 0x6c, + 0x5f, + 0xc4, + 0x3, + 0x77, + 0x60, + 0x64, + 0x70, + 0x65, + 0x45, + 0x8, + 0x89, + 0xf9, + 0x4f, + 0x76, + 0x25, + 0x79, + 0x1b, + 0x2a, + 0x46, + 0x4b, + 0xfb, + 0x1b, + 0xed, + 0x32, + 0x16, + 0x6d, + 0x3c, + 0x65, + 0xbb, + 0xc4, + 0xe7, + 0xdd, + 0xf2, + 0xd1, + 0x13, + 0x84, + 0x9a, + 0x5f, + 0x71, + 0x15, + 0x6d, + 0x46, + 0x3, + 0x14, + 0xbc, + 0x54, + 0x17, + 0x3a, + 0x12, + 0x3a, + 0x8, + 0xe6, + 0x9c, + 0xff, + 0xb3, + 0x13, + 0xfd, + 0x37, + 0x17, + 0xb6, + 0x79, + 0x6, + 0x56, + 0x9d, + 0xd1, + 0xb7, + 0x57, + 0x33, + 0x3a, + 0x85, + 0xbc, + 0xb2, + 0xd6, + 0x47, + 0x71, + 0x79, + 0xa1, + 0xf8, + 0xf4, + 0x97, + 0xc6, + 0x67, + 0x6e, + 0xe6, + 0xa7, + 0x7e, + 0xfe, + 0x81, + 0xb5, + 0x6a, + 0x97, + 0xd0, + 0x3e, + 0x4e, + 0x7c, + 0x20, + 0xac, + 0xb, + 0x28, + 0xde, + 0x5e, + 0x73, + 0x9c, + 0xb3, + 0x28, + 0xd6, + 0xa0, + 0xd, + 0x6e, + 0x41, + 0x2b, + 0x82, + 0xa8, + 0xb9, + 0x45, + 0x3d, + 0x5d, + 0xd7, + 0xa, + 0xa6, + 0x16, + 0xcd, + 0xfb, + 0x6a, + 0x63, + 0xab, + 0x50, + 0x4c, + 0x2, + 0xce, + 0x4b, + 0xbf, + 0xac, + 0x68, + 0x24, + 0x5b, + 0x56, + 0xc0, + 0x72, + 0xe6, + 0x63, + 0x0, + 0xff, + 0x71, + 0xbd, + 0x4a, + 0x0, + 0x8b, + 0xff, + 0xff, + 0x2b, + 0xe1, + 0x89, + 0xb0, + 0xd1, + 0x8c, + 0x15, + 0x74, + 0xe9, + 0xef, + 0x5b, + 0x88, + 0xe4, + 0x6e, + 0x94, + 0x52, + 0x66, + 0xcb, + 0xcf, + 0x77, + 0x7f, + 0xb, + 0xc0, + 0x88, + 0x99, + 0x9f, + 0xce, + 0xbe, + 0xf3, + 0xf0, + 0x9d, + 0x42, + 0xe, + 0x8f, + 0x63, + 0x7c, + 0x2, + 0x6f, + 0x7, + 0x2, + 0xb1, + 0x91, + 0xbe, + 0xdc, + 0x28, + 0xc8, + 0x1d, + 0x1c, + 0xfb, + 0xb, + 0xcf, + 0x96, + 0x73, + 0x56, + 0x70, + 0x10, + 0xdc, + 0x41, + 0xad, + 0x15, + 0x70, + 0xab, + 0x4d, + 0x81, + 0x7, + 0x1c, + 0x9a, + 0x31, + 0x1, + 0x2a, + 0xd3, + 0x9e, + 0x3d, + 0x3f, + 0x8c, + 0x88, + 0x38, + 0xc9, + 0xb5, + 0xbe, + 0xaa, + 0x3f, + 0x83, + 0x14, + 0xdc, + 0xc2, + 0x90, + 0x37, + 0x7, + 0xc5, + 0x49, + 0xf3, + 0x3a, + 0xe8, + 0x2d, + 0xc5, + 0xd8, + 0xa9, + 0x4, + 0x54, + 0x21, + 0x32, + 0x76, + 0xd2, + 0x13, + 0x42, + 0x58, + 0x9e, + 0xa7, + 0x36, + 0xfd, + 0xf3, + 0xd1, + 0x42, + 0x69, + 0xe1, + 0x58, + 0x9b, + 0xec, + 0xe9, + 0x4e, + 0x3e, + 0xdf, + 0x3b, + 0x9b, + 0x72, + 0x82, + 0xfc, + 0x7e, + 0xdf, + 0x74, + 0x14, + 0xa7, + 0x2a, + 0xbf, + 0x75, + 0xa5, + 0xb0, + 0xee, + 0x79, + 0xd0, + 0xc4, + 0x3e, + 0xbc, + 0xdc, + 0xc6, + 0xb, + 0xeb, + 0xf6, + 0x6e, + 0x95, + 0xda, + 0x9e, + 0x57, + 0xb5, + 0xc6, + 0xa8, + 0x8d, + 0x79, + 0xf8, + 0xbf, + 0xa9, + 0x79, + 0x96, + 0x2c, + 0x29, + 0x64, + 0x2c, + 0x32, + 0x94, + 0x89, + 0x17, + 0x30, + 0x1a, + 0x4e, + 0x7e, + 0x8d, + 0xfc, + 0x40, + 0xee, + 0x39, + 0x9e, + 0x13, + 0x56, + 0x25, + 0xe1, + 0xd3, + 0x3, + 0x95, + 0x6a, + 0x69, + 0x48, + 0x47, + 0xf8, + 0x5e, + 0x2f, + 0x9f, + 0xcd, + 0x1f, + 0xcb, + 0x35, + 0xbf, + 0x90, + 0x70, + 0x75, + 0xff, + 0x7d, + 0x4e, + 0xa8, + 0x0, + 0xed, + 0x3, + 0xee, + 0xce, + 0x83, + 0x2d, + 0xca, + 0x75, + 0xad, + 0x82, + 0x94, + 0x86, + 0xec, + 0x58, + 0x4, + 0x8f, + 0x6c, + 0x34, + 0x89, + 0x8, + 0xac, + 0x53, + 0x74, + 0x8c, + 0xf1, + 0x8a, + 0xf9, + 0x55, + 0x31, + 0xaf, + 0xb7, + 0x9, + 0xd8, + 0x66, + 0x5, + 0xa0, + 0xe2, + 0x84, + 0x8e, + 0x21, + 0x35, + 0xb0, + 0x66, + 0x87, + 0x40, + 0xd0, + 0xbd, + 0xf3, + 0x6e, + 0x57, + 0xf5, + 0x7e, + 0x3a, + 0xe4, + 0x6f, + 0x8d, + 0x8c, + 0xfb, + 0x45, + 0x36, + 0x53, + 0xd3, + 0xf7, + 0x32, + 0xd5, + 0x21, + 0xb, + 0x81, + 0xe0, + 0x7, + 0xc9, + 0x68, + 0xc4, + 0x93, + 0x59, + 0x7a, + 0xcb, + 0xad, + 0x65, + 0xb7, + 0x66, + 0x84, + 0x2f, + 0x3b, + 0x9f, + 0xe7, + 0x43, + 0x11, + 0x36, + 0xa5, + 0x36, + 0x77, + 0x32, + 0xbd, + 0x1d, + 0x7d, + 0x49, + 0x61, + 0x79, + 0x88, + 0x2d, + 0x8e, + 0x41, + 0xec, + 0x14, + 0x31, + 0xf9, + 0xaa, + 0x97, + 0x1a, + 0x39, + 0x6a, + 0xb3, + 0xe8, + 0xdb, + 0x57, + 0xd4, + 0x6d, + 0xed, + 0xa6, + 0x2a, + 0x3c, + 0xba, + 0x7, + 0x8a, + 0x22, + 0x5f, + 0xa7, + 0xc3, + 0xa1, + 0x3, + 0x86, + 0xa8, + 0xa, + 0x12, + 0x0, + 0x1f, + 0xd0, + 0x1a, + 0xc7, + 0x5d, + 0xdf, + 0x51, + 0xad, + 0x2e, + 0xf6, + 0x1e, + 0xb7, + 0xb2, + 0x1f, + 0x40, + 0x76, + 0x72, + 0xf0, + 0x6, + 0x4a, + 0x1f, + 0x69, + 0x3, + 0xc5, + 0x7f, + 0x93, + 0x5c, + 0x31, + 0x6e, + 0x8b, + 0x3a, + 0xc7, + 0x46, + 0xc5, + 0xe3, + 0x8b, + 0x9d, + 0xf4, + 0x79, + 0x6d, + 0x2e, + 0x7f, + 0x45, + 0x5c, + 0x9e, + 0x2d, + 0xec, + 0xe8, + 0x91, + 0xd0, + 0x37, + 0xc7, + 0xba, + 0x73, + 0x87, + 0x79, + 0x8a, +}; + +UINT32 SamuPatchKBHeader[] = { + 0x53414d55, + 0x410 +}; + +UINT8 SamuPatchKBUnf1[] = { + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0xe8, + 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0xe8, + 0x2, + 0x0, + 0x0, + 0x2, + 0x0, + 0x0, + 0x0, + 0x4, + 0x0, + 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x80, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x98, + 0x0, + 0x0, + 0x0, + 0x34, + 0x3, + 0x80, + 0x1c, + 0x78, + 0xfc, + 0xff, + 0x9c, + 0x3b, + 0x84, + 0x0, + 0x0, + 0xf8, + 0x0, + 0xd0, + 0x5a, + 0x9b, + 0x2, + 0x0, + 0x0, + 0xe0, + 0x0, + 0x0, + 0x0, + 0x34, + 0x1, + 0x0, + 0x5a, + 0x37, + 0xff, + 0xff, + 0xff, + 0xe3, + 0x0, + 0x0, + 0x4, + 0x34, + 0x0, + 0x12, + 0x44, + 0x80, + 0x0, + 0x20, + 0x23, + 0x34, + 0x0, + 0x0, + 0x65, + 0x28, + 0x0, + 0x40, + 0x23, + 0x34, + 0x0, + 0x0, + 0x65, + 0x28, + 0x0, + 0x0, + 0x23, + 0x28, + 0x10, + 0x0, + 0x21, + 0x34, + 0x1, + 0x0, + 0x84, + 0x34, + 0x2, + 0x0, + 0x82, + 0x54, + 0xf8, + 0xff, + 0xff, + 0xe3, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x0, + 0x0, + 0x4, + 0x34, + 0x9, + 0x0, + 0x83, + 0x50, + 0x1, + 0x0, + 0x5, + 0x78, + 0x0, + 0x0, + 0xa5, + 0x38, + 0x8, + 0x5, + 0x22, + 0xa8, + 0x0, + 0x8, + 0x25, + 0xb4, + 0x10, + 0x0, + 0x42, + 0x34, + 0x1, + 0x0, + 0x84, + 0x34, + 0x2, + 0x0, + 0x83, + 0x50, + 0xfb, + 0xff, + 0xff, + 0xe3, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x0, + 0x0, + 0x4, + 0x34, + 0x9, + 0x0, + 0x83, + 0x50, + 0x1, + 0x0, + 0x5, + 0x78, + 0x0, + 0x0, + 0xa5, + 0x38, + 0x8, + 0x15, + 0x20, + 0xa8, + 0x0, + 0x8, + 0x25, + 0xb4, + 0x10, + 0x0, + 0x42, + 0x34, + 0x1, + 0x0, + 0x84, + 0x34, + 0x2, + 0x0, + 0x83, + 0x50, + 0xfb, + 0xff, + 0xff, + 0xe3, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x0, + 0x20, + 0x20, + 0xb8, + 0xb0, + 0x0, + 0xa0, + 0x90, + 0x0, + 0x0, + 0x1, + 0x34, + 0xb0, + 0x0, + 0x20, + 0xd0, + 0x3, + 0x0, + 0x81, + 0x7c, + 0x8, + 0x0, + 0x20, + 0x5c, + 0x0, + 0x12, + 0x58, + 0xbc, + 0xff, + 0x0, + 0x1, + 0x78, + 0xff, + 0xff, + 0x21, + 0x38, + 0x80, + 0x9, + 0xa1, + 0xa0, + 0x0, + 0x28, + 0x41, + 0xb8, + 0xf0, + 0x2, + 0x60, + 0xd0, + 0x18, + 0x0, + 0x0, + 0xe0, + 0x2, + 0x0, + 0x81, + 0x7c, + 0x8, + 0x0, + 0x20, + 0x5c, + 0x0, + 0x12, + 0x50, + 0xbc, + 0x0, + 0xff, + 0x1, + 0x78, + 0xff, + 0xff, + 0x21, + 0x38, + 0x80, + 0x9, + 0xa1, + 0xa0, + 0x0, + 0x28, + 0x41, + 0xb8, + 0xd0, + 0x2, + 0x60, + 0xd0, + 0xf, + 0x0, + 0x0, + 0xe0, + 0x1, + 0x0, + 0x81, + 0x7c, + 0x8, + 0x0, + 0x20, + 0x5c, + 0x0, + 0x12, + 0x48, + 0xbc, + 0xff, + 0xff, + 0x1, + 0x78, + 0xff, + 0x0, + 0x21, + 0x38, + 0x80, + 0x9, + 0xa1, + 0xa0, + 0x0, + 0x28, + 0x41, + 0xb8, + 0xb0, + 0x2, + 0x60, + 0xd0, + 0x6, + 0x0, + 0x0, + 0xe0, + 0x5, + 0x0, + 0x80, + 0x5c, + 0x0, + 0xff, + 0x1, + 0x34, + 0x80, + 0x29, + 0xa1, + 0xa0, + 0x0, + 0x28, + 0xa2, + 0xb8, + 0x90, + 0x2, + 0x60, + 0xd0, + 0xb0, + 0x0, + 0xa0, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x0, + 0x10, + 0x20, + 0xb8, + 0x3, + 0x0, + 0x21, + 0x7c, + 0x4, + 0x0, + 0x20, + 0x5c, + 0x0, + 0x0, + 0x1, + 0x34, + 0xf0, + 0x2, + 0x20, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x2, + 0x0, + 0x41, + 0x7c, + 0x4, + 0x0, + 0x20, + 0x5c, + 0x0, + 0x0, + 0x1, + 0x34, + 0xd0, + 0x2, + 0x20, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x1, + 0x0, + 0x41, + 0x7c, + 0x4, + 0x0, + 0x20, + 0x5c, + 0x0, + 0x0, + 0x1, + 0x34, + 0xb0, + 0x2, + 0x20, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x2, + 0x0, + 0x40, + 0x5c, + 0x90, + 0x2, + 0x40, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x0, + 0x10, + 0x20, + 0xb8, + 0xb0, + 0x0, + 0x60, + 0x90, + 0x3, + 0x0, + 0x21, + 0x7c, + 0x6, + 0x0, + 0x20, + 0x5c, + 0xff, + 0x0, + 0x1, + 0x78, + 0xff, + 0xff, + 0x21, + 0x38, + 0x80, + 0x19, + 0x61, + 0xa0, + 0xb0, + 0x0, + 0x60, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x2, + 0x0, + 0x41, + 0x7c, + 0x6, + 0x0, + 0x20, + 0x5c, + 0x0, + 0xff, + 0x1, + 0x78, + 0xff, + 0xff, + 0x21, + 0x38, + 0x80, + 0x19, + 0x61, + 0xa0, + 0xb0, + 0x0, + 0x60, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x1, + 0x0, + 0x41, + 0x7c, + 0x6, + 0x0, + 0x20, + 0x5c, + 0xff, + 0xff, + 0x1, + 0x78, + 0xff, + 0x0, + 0x21, + 0x38, + 0x80, + 0x19, + 0x61, + 0xa0, + 0xb0, + 0x0, + 0x60, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x4, + 0x0, + 0x40, + 0x5c, + 0x0, + 0xff, + 0x1, + 0x34, + 0x80, + 0x19, + 0x61, + 0xa0, + 0xb0, + 0x0, + 0x60, + 0xd0, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x0, + 0x8, + 0xa0, + 0xbb, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x0, + 0x10, + 0x20, + 0xb8, + 0xff, + 0xff, + 0x42, + 0x34, + 0xff, + 0xff, + 0x41, + 0x64, + 0xfe, + 0xff, + 0x20, + 0x44, + 0x0, + 0x0, + 0xa0, + 0xc3, + 0x2, + 0x0, + 0x1, + 0x78, + 0x0, + 0x20, + 0x21, + 0x38, + 0x41, + 0x0, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x4, + 0x20, + 0x21, + 0x38, + 0x1, + 0x0, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0xd8, + 0x20, + 0x21, + 0x38, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0xd8, + 0x20, + 0x21, + 0x38, + 0x2, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x74, + 0x20, + 0x21, + 0x38, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x0, + 0x20, + 0x21, + 0x38, + 0x38, + 0x0, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x4, + 0x20, + 0x21, + 0x38, + 0x0, + 0x0, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x0, + 0x20, + 0x21, + 0x38, + 0x41, + 0x0, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x4, + 0x20, + 0x21, + 0x38, + 0x0, + 0x0, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x0, + 0x20, + 0x21, + 0x38, + 0x1, + 0x0, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x4, + 0x20, + 0x21, + 0x38, + 0xff, + 0x1, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x0, + 0x20, + 0x21, + 0x38, + 0x25, + 0x1, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x2, + 0x0, + 0x1, + 0x78, + 0x4, + 0x20, + 0x21, + 0x38, + 0x1, + 0x0, + 0x2, + 0x34, + 0x3, + 0x0, + 0x41, + 0xcc, + 0x0, + 0x0, + 0x0, + 0xe0, +}; + +UINT32 SamuPatchKBHeaderUnf1[] = { + 0x53414d55, + 0x3e8 +}; +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSmuFirmwareKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSmuFirmwareKB.h new file mode 100644 index 0000000000..62736a3a20 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSmuFirmwareKB.h @@ -0,0 +1,32414 @@ +/** + * @file + * + * SMU firmware + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87932 $ @e \$Date: 2013-02-13 13:53:55 -0600 (Wed, 13 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBSMUFIRMWAREKB_H_ +#define _GNBSMUFIRMWAREKB_H_ + +UINT32 FirmwareKBHeader [] = { + 0x554D535F, + 0x554D535F, + 0x0001F984, + 0x00002000, + 0x00010000, + 0xECE28940, + 0x0000424B, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +UINT32 FirmwareKB[] = { + 0x63c00f17, + 0xb9cfd803, + 0x196410db, + 0x8c378d8b, + 0xa8f232ce, + 0x000c0d00, + 0x00000100, + 0x00000000, + 0x00020100, + 0x00019900, + 0x0001f954, + 0x000398d8, + 0x0003f900, + 0x0003f000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00038c00, + 0x00038fa8, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xaa55aa55, + 0x98000000, + 0xd0000000, + 0x78010002, + 0x38210100, + 0xd0e10000, + 0xd1210000, + 0xe00000c4, + 0x34000000, + 0x379cff80, + 0x5b9d0074, + 0xf8000059, + 0x34010001, + 0xf8002e56, + 0xe000009a, + 0x34000000, + 0x34000000, + 0x379cff80, + 0x5b9d0074, + 0xf8000051, + 0x34010002, + 0xf8002e4e, + 0x2b980060, + 0x2b990064, + 0xe000006f, + 0x379cff80, + 0x5b9d0074, + 0xf8000049, + 0x34010003, + 0xf8002e46, + 0xe000008a, + 0x34000000, + 0x34000000, + 0x379cff80, + 0x5b9d0074, + 0xf8000041, + 0x34010004, + 0xf8002e3e, + 0x2b980060, + 0x2b990064, + 0xe000005f, + 0x379cff80, + 0x5b9d0074, + 0xf8000039, + 0x34010005, + 0xf8002e36, + 0x2b980060, + 0x2b990064, + 0xe0000057, + 0xe00000ab, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x379cff80, + 0x5b9d0078, + 0xf8000006, + 0xbb800800, + 0xf800008d, + 0xe0000049, + 0x34000000, + 0x34000000, + 0x5b810004, + 0x5b820008, + 0x5b83000c, + 0x5b840010, + 0x5b850014, + 0x5b860018, + 0x5b87001c, + 0x5b880020, + 0x5b890024, + 0x5b8a0028, + 0x5b8b002c, + 0x5b8c0030, + 0x5b8d0034, + 0x5b8e0038, + 0x5b8f003c, + 0x5b900040, + 0x5b910044, + 0x5b920048, + 0x5b93004c, + 0x5b940050, + 0x5b950054, + 0x5b960058, + 0x5b97005c, + 0x5b9a0068, + 0x5b9b006c, + 0x2b810078, + 0x5b810074, + 0x5b9e0078, + 0x5b9f007c, + 0xbb800800, + 0x34210080, + 0x5b810070, + 0x98210800, + 0xd0010000, + 0xc3a00000, + 0x5b810004, + 0x5b820008, + 0x5b83000c, + 0x5b840010, + 0x5b850014, + 0x5b860018, + 0x5b87001c, + 0x5b880020, + 0x5b890024, + 0x5b8a0028, + 0x5b8b002c, + 0x5b8c0030, + 0x5b8d0034, + 0x5b8e0038, + 0x5b8f003c, + 0x5b900040, + 0x5b910044, + 0x5b920048, + 0x5b93004c, + 0x5b940050, + 0x5b950054, + 0x5b960058, + 0x5b97005c, + 0x5b980060, + 0x5b990064, + 0x5b9a0068, + 0x5b9b006c, + 0x5b9e0078, + 0x5b9f007c, + 0x37810080, + 0x5b810070, + 0x78018000, + 0x38210394, + 0x583c0000, + 0xc3a00000, + 0x34010002, + 0xd0010000, + 0x2b810004, + 0x2b820008, + 0x2b83000c, + 0x2b840010, + 0x2b850014, + 0x2b860018, + 0x2b87001c, + 0x2b880020, + 0x2b890024, + 0x2b8a0028, + 0x2b8b002c, + 0x2b8c0030, + 0x2b8d0034, + 0x2b8e0038, + 0x2b8f003c, + 0x2b900040, + 0x2b910044, + 0x2b920048, + 0x2b93004c, + 0x2b940050, + 0x2b950054, + 0x2b960058, + 0x2b97005c, + 0x2b9a0068, + 0x2b9b006c, + 0x2b9d0074, + 0x2b9e0078, + 0x2b9f007c, + 0x2b9c0070, + 0x34000000, + 0xc3c00000, + 0x2b810004, + 0x2b820008, + 0x2b83000c, + 0x2b840010, + 0x2b850014, + 0x2b860018, + 0x2b87001c, + 0x2b880020, + 0x2b890024, + 0x2b8a0028, + 0x2b8b002c, + 0x2b8c0030, + 0x2b8d0034, + 0x2b8e0038, + 0x2b8f003c, + 0x2b900040, + 0x2b910044, + 0x2b920048, + 0x2b93004c, + 0x2b940050, + 0x2b950054, + 0x2b960058, + 0x2b97005c, + 0x2b980060, + 0x2b990064, + 0x2b9a0068, + 0x2b9b006c, + 0x2b9d0074, + 0x2b9e0078, + 0x2b9f007c, + 0x2b9c0070, + 0x34000000, + 0xc3e00000, + 0xe0000000, + 0xc3a00000, + 0x781c0003, + 0x3b9ceffc, + 0x781a0004, + 0x3b5a0da0, + 0x78010003, + 0x38218db0, + 0x78030003, + 0x38638e70, + 0x44230004, + 0x58200000, + 0x34210004, + 0xe3fffffd, + 0x98210800, + 0x98421000, + 0x98631800, + 0xf8000473, + 0xe0000027, + 0x379cff80, + 0x5b9d0078, + 0xfbffff63, + 0x78010003, + 0x382198d8, + 0x28230004, + 0x28220000, + 0x34630001, + 0x585c0000, + 0x58230004, + 0xf800008b, + 0xf80048d4, + 0x78010003, + 0x382198d8, + 0x28230004, + 0x28220000, + 0x3463ffff, + 0x28220000, + 0x58230004, + 0x285c0000, + 0xe3ffff97, + 0xd0000000, + 0x379cff80, + 0x5b9d0078, + 0xb81df000, + 0xfbffff4c, + 0x78010003, + 0x382198d8, + 0x28230004, + 0x28220000, + 0x34630001, + 0x585c0000, + 0x58230004, + 0xe3ffffea, + 0x379cfffc, + 0x5b9d0004, + 0xf80049d9, + 0xe0000000, + 0x99084000, + 0x39080001, + 0xac000007, + 0xe3fffffd, + 0x38080005, + 0xac000007, + 0xc3a00000, + 0x38080004, + 0xac000007, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780cc020, + 0x780bc020, + 0x398c0080, + 0x396b0310, + 0x7801c020, + 0x38210134, + 0x34022000, + 0x34030001, + 0xf8001145, + 0x29830000, + 0x7801eeff, + 0x78021100, + 0x3821ffff, + 0x38420000, + 0xa0610800, + 0xa0621800, + 0x44600002, + 0x59810000, + 0x29610000, + 0x3402ffdf, + 0xa0221000, + 0x20210020, + 0x44200002, + 0x59620000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x78018000, + 0x38210008, + 0x34020001, + 0x58220000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xe3ffffd2, + 0x379cfffc, + 0x5b9d0004, + 0x34020000, + 0x78010003, + 0x38218e94, + 0xf8004941, + 0xf8002804, + 0x7c210000, + 0x33010078, + 0x43010078, + 0x7c220000, + 0xe3fffff8, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x34020000, + 0x38218ea0, + 0xf8004935, + 0xf80010bd, + 0xe3fffffb, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x38218f30, + 0x34020000, + 0x58220024, + 0x58220020, + 0x78010003, + 0x34020000, + 0x38218e88, + 0xf8004928, + 0xf800382a, + 0xe3fffffb, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x38218f58, + 0x34020000, + 0x58220024, + 0x58220020, + 0x78010003, + 0x34020000, + 0x38218e7c, + 0xf800491b, + 0xf800395a, + 0xe3fffffb, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x7803c020, + 0x38630080, + 0x28620000, + 0x78011100, + 0x38210000, + 0xb8411000, + 0x7804c020, + 0x58620000, + 0x38840310, + 0x28820000, + 0x7801c020, + 0x38210134, + 0x38420020, + 0x58820000, + 0x34022000, + 0x34030000, + 0xf80010d9, + 0x90405800, + 0x90200800, + 0xa02b0800, + 0x20210004, + 0x44200002, + 0xf8000686, + 0xd04b0000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x7802e000, + 0x78010002, + 0x38423090, + 0x38210100, + 0x78050003, + 0x58410000, + 0x38a58e70, + 0x7804e000, + 0x38843094, + 0x34a5ffff, + 0x7806e000, + 0x78020002, + 0x58850000, + 0x38420000, + 0x78030003, + 0x38c63098, + 0x58c20000, + 0x3863f000, + 0x7801e000, + 0x3821309c, + 0x3463ffff, + 0x7802e000, + 0x58230000, + 0x384230a4, + 0x28410000, + 0x38210018, + 0x58410000, + 0xc3a00000, + 0xc3a00000, + 0x379cffac, + 0x5b8b003c, + 0x5b8c0038, + 0x5b8d0034, + 0x5b8e0030, + 0x5b8f002c, + 0x5b900028, + 0x5b910024, + 0x5b920020, + 0x5b93001c, + 0x5b940018, + 0x5b950014, + 0x5b960010, + 0x5b97000c, + 0x5b9b0008, + 0x5b9d0004, + 0x781dc010, + 0x3bbd0000, + 0x2ba54074, + 0x780100ff, + 0x38210000, + 0x00a80001, + 0x5b81004c, + 0x2ba54078, + 0x2b82004c, + 0x78017f00, + 0x2ba34078, + 0x38210000, + 0x3847ffff, + 0x00660001, + 0xb8271000, + 0x2ba3407c, + 0x3ca5001f, + 0x78048000, + 0x3c63001f, + 0x38840000, + 0xa0480800, + 0xa0641800, + 0xa0a42800, + 0xa0461000, + 0xb8250800, + 0xb8431000, + 0x00480018, + 0x00230008, + 0x00240010, + 0x00450008, + 0x00460010, + 0x00270018, + 0x781b0003, + 0x3b7b8c00, + 0x33630001, + 0x33680007, + 0x33610000, + 0x33640002, + 0x33670003, + 0x33650005, + 0x33660006, + 0x33620004, + 0x2b84004c, + 0x2ba240a0, + 0x7803ff00, + 0x38630000, + 0x3881ffff, + 0xb8610800, + 0x2ba540a4, + 0x5b830048, + 0xa0220800, + 0x00240018, + 0x00220008, + 0x00230010, + 0x33620009, + 0x3365000c, + 0x33610008, + 0x3363000a, + 0x3364000b, + 0x2ba340a4, + 0x2b86004c, + 0x78080003, + 0x00610008, + 0x38c2ffff, + 0x2ba340a8, + 0xa0411000, + 0x3908fa80, + 0x3c610018, + 0x2ba440a8, + 0x2b830048, + 0x5b880054, + 0x00840008, + 0xa0230800, + 0xb8411000, + 0x00410008, + 0x00450018, + 0x00430010, + 0x3361000e, + 0x3363000f, + 0x33650010, + 0x33640011, + 0x3362000d, + 0x2ba1407c, + 0x34060000, + 0x0f66001c, + 0x0021001c, + 0x0f66001e, + 0x20210001, + 0x33610012, + 0x2ba170c8, + 0x00210014, + 0x2021000f, + 0x33610013, + 0x2ba1407c, + 0x0022001d, + 0x2ba14080, + 0x3c210003, + 0x20210078, + 0xb8411000, + 0x33620014, + 0x2ba14080, + 0x00210004, + 0x2021007f, + 0x33610015, + 0x2ba14080, + 0x0021000b, + 0x20210007, + 0x33610016, + 0x2ba14080, + 0x0021000e, + 0x20210007, + 0x33610017, + 0x2ba14080, + 0x00210011, + 0x20210003, + 0x33610018, + 0x2ba14080, + 0x00210013, + 0x20210003, + 0x33610019, + 0x2ba1408c, + 0x00210015, + 0x202201ff, + 0x0f62001a, + 0x20410100, + 0x44260004, + 0x3401ff00, + 0xb8410800, + 0x0f61001a, + 0x2f62001c, + 0x20410100, + 0x44200004, + 0x3401ff00, + 0xb8410800, + 0x0f61001c, + 0x2f62001e, + 0x20410100, + 0x44200004, + 0x3401ff00, + 0xb8410800, + 0x0f61001e, + 0x34070000, + 0x33670026, + 0x33670027, + 0x2ba1408c, + 0x0f660034, + 0x0f660020, + 0x0022001e, + 0x0f660022, + 0x2ba14090, + 0x78160003, + 0x3ad6f000, + 0x3c210002, + 0x781700fc, + 0xb8220800, + 0x33610028, + 0x2ba24090, + 0x3af70000, + 0x3acd0fff, + 0x2ba14090, + 0x00420006, + 0x78083f00, + 0x00210012, + 0x204201ff, + 0x2021001f, + 0x33610029, + 0x2ba14090, + 0x0f620024, + 0x39080000, + 0x0021000f, + 0xbaed6800, + 0x20210007, + 0x3361002a, + 0x2ba14090, + 0xb90d6800, + 0x780c007c, + 0x00210017, + 0x3367002c, + 0x3367002d, + 0x3367002e, + 0x3367002f, + 0x33670030, + 0x33670031, + 0x3361002b, + 0x2ba340b8, + 0x398c0000, + 0x78040007, + 0x2ba140b4, + 0x00630008, + 0x3884c000, + 0x33670038, + 0x33670039, + 0x3367003a, + 0x3367003b, + 0x3367003c, + 0x3367003d, + 0x00210010, + 0x2ba240bc, + 0x0f630032, + 0x0f610036, + 0x0f62003e, + 0x2ba240bc, + 0x2b81004c, + 0x5b880044, + 0x00430018, + 0x3833ffff, + 0x2ba240c0, + 0x2b880048, + 0x38843fff, + 0x2ba140bc, + 0x3c420008, + 0x78050018, + 0x00210010, + 0xb8431000, + 0x33610042, + 0x2ba140c0, + 0x78030080, + 0x38630000, + 0x00210008, + 0x0f620040, + 0x33610043, + 0x2ba140b8, + 0x3ac20fff, + 0xb9826000, + 0x00210018, + 0xb840a800, + 0x33610044, + 0x2ba140c0, + 0x5b830040, + 0x38a50000, + 0x00210018, + 0x78060fe0, + 0x20210007, + 0x33610045, + 0x2ba140c0, + 0x38c60000, + 0x5b870050, + 0x00210010, + 0x7812001f, + 0x33610046, + 0x2ba140cc, + 0x3a52c000, + 0x3a523fff, + 0x00210015, + 0xb8d29000, + 0x33610047, + 0x2ba170d8, + 0xb9139800, + 0xba60a000, + 0x0022001f, + 0x2ba170dc, + 0x3c210001, + 0x33670049, + 0xb8220800, + 0x33610048, + 0x2ba140cc, + 0x0021001d, + 0x20210001, + 0x3361004a, + 0x2ba14090, + 0x0021001f, + 0x3361004b, + 0x2ba27080, + 0x0041000d, + 0x2ba27084, + 0xa0812000, + 0x3c410013, + 0xa0252800, + 0xa0260800, + 0xb8852000, + 0xb8812000, + 0x00830015, + 0x00810007, + 0x0082000e, + 0x2021007f, + 0x2042007f, + 0x2063007f, + 0x3361004d, + 0x3362004e, + 0x3363004f, + 0x3364004c, + 0x2ba17084, + 0x00210009, + 0x33670054, + 0x2021007f, + 0x33670055, + 0x33670056, + 0x33670057, + 0x33670058, + 0x33670059, + 0x3367005a, + 0x3367005b, + 0x3367005c, + 0x3367005d, + 0x3367005e, + 0x3367005f, + 0x33670060, + 0x33670061, + 0x33670062, + 0x33670063, + 0x33670051, + 0x33670052, + 0x33610050, + 0x2ba14094, + 0x2ba44094, + 0xa1a16800, + 0x01b10018, + 0x0085001e, + 0x01b00006, + 0x2ba44098, + 0x01ae000c, + 0x01af0012, + 0x2ba34098, + 0x3c840002, + 0x2210003f, + 0x0062001c, + 0x2081003c, + 0x2ba3409c, + 0xb8a12800, + 0x20810fc0, + 0x3c630004, + 0xb8a12800, + 0x20610030, + 0xb8411000, + 0x20610fc0, + 0xb8411000, + 0xa0960800, + 0xb8a12800, + 0xa0970800, + 0xb8a12800, + 0x2b810044, + 0xa0763000, + 0xb8461000, + 0xa0773000, + 0xa0812000, + 0xa0611800, + 0xb8461000, + 0xb8a42800, + 0xb8431000, + 0x00a30006, + 0x00a4000c, + 0x00a60012, + 0x00aa0018, + 0x00480006, + 0x0049000c, + 0x004b0012, + 0x2063003f, + 0x2084003f, + 0x00410018, + 0x21ce003f, + 0x21ef003f, + 0x2231003f, + 0x21ad003f, + 0x20c6003f, + 0x3363006a, + 0x3364006b, + 0x336d0064, + 0x33700065, + 0x336e0066, + 0x336f0067, + 0x33710068, + 0x3366006c, + 0x2108003f, + 0x2042003f, + 0x2021003f, + 0x214a003f, + 0x2129003f, + 0x216b003f, + 0x3368006f, + 0x33650069, + 0x336a006d, + 0x3362006e, + 0x33690070, + 0x336b0071, + 0x33610072, + 0x2ba1409c, + 0x0021001a, + 0x33610073, + 0x2ba140b8, + 0x33610081, + 0x2ba140b4, + 0x00210008, + 0x33670053, + 0x33610080, + 0x2ba26000, + 0x2b84004c, + 0x2b860048, + 0x00410018, + 0x2ba26004, + 0x3c420008, + 0x2043ff00, + 0xb8230800, + 0xa0441800, + 0xa0461000, + 0xb8230800, + 0xb8220800, + 0x00240018, + 0x00220008, + 0x00230010, + 0x33640077, + 0x33630076, + 0x33620075, + 0x33610074, + 0x2ba16008, + 0x2ba2600c, + 0xa2619800, + 0x02650018, + 0xa282a000, + 0x02860018, + 0x02610008, + 0x02620010, + 0x02830008, + 0x02840010, + 0x3362007a, + 0x3365007b, + 0x3363007d, + 0x3364007e, + 0x3366007f, + 0x33610079, + 0x33730078, + 0x3374007c, + 0x2ba16014, + 0x00210008, + 0x20210001, + 0x33610099, + 0x2ba16020, + 0x2b880044, + 0x2ba37044, + 0x00210003, + 0x00620019, + 0x202103ff, + 0x2ba37048, + 0x0f610082, + 0x2ba47048, + 0x3c630007, + 0x00850017, + 0x20610f80, + 0x2ba4704c, + 0xb8411000, + 0xa0760800, + 0xb8411000, + 0xa0770800, + 0x3c840009, + 0xb8411000, + 0xa0681800, + 0x20810e00, + 0xb8431000, + 0xb8a12800, + 0xa0962000, + 0x00410006, + 0x00470018, + 0x0043000c, + 0xb8a42800, + 0x2046003f, + 0x00a8000c, + 0x00a40006, + 0x00420012, + 0x2021003f, + 0x2063003f, + 0x2042003f, + 0x20e7003f, + 0x2084003f, + 0x2108003f, + 0x20a5003f, + 0x33610085, + 0x33670088, + 0x33650089, + 0x3368008b, + 0x33660084, + 0x33630086, + 0x33620087, + 0x3364008a, + 0x2ba3704c, + 0x2b840040, + 0x2b860044, + 0x00610009, + 0x2ba37050, + 0xa1816000, + 0x2ba27050, + 0x3c610017, + 0x00420007, + 0xa0241800, + 0xa0260800, + 0xb9836000, + 0xb9816000, + 0xa2a2a800, + 0x01850018, + 0x02a6000c, + 0x01810006, + 0x0182000c, + 0x01830012, + 0x02a40006, + 0x2021003f, + 0x2042003f, + 0x2063003f, + 0x20a5003f, + 0x2084003f, + 0x20c6003f, + 0x218c003f, + 0x22b5003f, + 0x3362008e, + 0x3363008f, + 0x33650090, + 0x33640092, + 0x33660093, + 0x336c008c, + 0x3361008d, + 0x33750091, + 0x2ba17060, + 0x00210001, + 0x3361009a, + 0x2ba1707c, + 0xa2419000, + 0x02410007, + 0x0242000e, + 0x02430015, + 0x2021007f, + 0x2042007f, + 0x2063007f, + 0x33610095, + 0x33620096, + 0x33630097, + 0x33720094, + 0x2ba1707c, + 0x0022001c, + 0x2ba17080, + 0x3c210004, + 0x20210070, + 0xb8411000, + 0x33620098, + 0x2ba240ac, + 0x00440018, + 0x2ba240b0, + 0x2ba340b0, + 0x3c420008, + 0x2ba170d0, + 0x00630008, + 0xb8441000, + 0x00210002, + 0x0f63009e, + 0x2021000f, + 0x3361009b, + 0x2ba34004, + 0x0f62009c, + 0x2b88004c, + 0x0061001d, + 0x2ba34008, + 0x3c630003, + 0x206200f8, + 0xb8220800, + 0x2062ff00, + 0xb8220800, + 0xa0681000, + 0xb8220800, + 0x2b820048, + 0xa0621800, + 0xb8230800, + 0x00240018, + 0x00220008, + 0x00230010, + 0x336200a1, + 0x336300a2, + 0x336400a3, + 0x336100a0, + 0x2ba1407c, + 0x00210014, + 0x336100a4, + 0x2ba140a8, + 0x00220010, + 0x2ba140ac, + 0x3c210010, + 0xa0281800, + 0xb8431000, + 0x2b830048, + 0xa0230800, + 0xb8411000, + 0x00440018, + 0x00410008, + 0x00430010, + 0x336400a8, + 0x336300a7, + 0x336200a5, + 0x336100a6, + 0x2ba140ac, + 0x00210010, + 0x336100a9, + 0x2ba17040, + 0x00210004, + 0x336100aa, + 0x2ba1408c, + 0x00210002, + 0x20210001, + 0x336100ab, + 0x2ba37050, + 0x00610019, + 0x2ba37054, + 0x2ba67054, + 0x3c630007, + 0x00c50017, + 0x20620f80, + 0x2ba67058, + 0xb8220800, + 0xa0762000, + 0x3cc20009, + 0xb8240800, + 0x2b860044, + 0x20440e00, + 0xa077b800, + 0xa0661800, + 0xb8a42800, + 0xa0561000, + 0xb8370800, + 0xb8230800, + 0xb8a22800, + 0x00270018, + 0x00a8000c, + 0x00220006, + 0x0023000c, + 0x00240012, + 0x00a60006, + 0x2042003f, + 0x2063003f, + 0x2084003f, + 0x2021003f, + 0x20e7003f, + 0x20c6003f, + 0x2108003f, + 0x20a5003f, + 0x336200ad, + 0x336300ae, + 0x336400af, + 0x336100ac, + 0x336700b0, + 0x336500b1, + 0x336600b2, + 0x336800b3, + 0x2ba140cc, + 0x0021000d, + 0x336100b4, + 0x2ba1408c, + 0x00210005, + 0x336100b5, + 0x2ba1408c, + 0x0021000d, + 0x336100b6, + 0x2ba140c8, + 0x0021000b, + 0x336100b7, + 0x2ba140c8, + 0x00210003, + 0x336100b8, + 0x2ba14070, + 0x00210011, + 0x336100b9, + 0x2ba140c8, + 0x0022001b, + 0x2ba140cc, + 0x3c210005, + 0xb8220800, + 0x336100ba, + 0x2ba140c0, + 0x0022001b, + 0x2ba140c4, + 0x3c210005, + 0xb8220800, + 0x336100bb, + 0x2ba140c8, + 0x00210013, + 0x336100bc, + 0x2ba140c4, + 0x00210003, + 0x336100bd, + 0x2ba14070, + 0x00220019, + 0x2ba14074, + 0x3c210007, + 0xb8220800, + 0x336100be, + 0x2ba140c4, + 0x0021000b, + 0x336100bf, + 0x2ba24088, + 0x00440019, + 0x2ba2408c, + 0x2ba3705c, + 0x3c420007, + 0x2ba17044, + 0x20420180, + 0xb8822000, + 0x00210010, + 0x00630005, + 0x20210007, + 0x336100c4, + 0x2ba140c4, + 0x0f6400c0, + 0x0f6300c2, + 0x00220013, + 0x2ba140c8, + 0x3c21000d, + 0xb8220800, + 0x0f6100c6, + 0x2b880050, + 0x3d020002, + 0xb45b0800, + 0x28230000, + 0x35080001, + 0x5b880050, + 0x2b810054, + 0xb4411000, + 0x75010031, + 0x58430000, + 0x4420fff6, + 0x2b8b003c, + 0x2b8c0038, + 0x2b8d0034, + 0x2b8e0030, + 0x2b8f002c, + 0x2b900028, + 0x2b910024, + 0x2b920020, + 0x2b93001c, + 0x2b940018, + 0x2b950014, + 0x2b960010, + 0x2b97000c, + 0x2b9b0008, + 0x2b9d0004, + 0x379c0054, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xf8004681, + 0x780b0003, + 0x34040000, + 0x396beffc, + 0x78010003, + 0x3563fc00, + 0xb8802800, + 0xb8803000, + 0x34020003, + 0x38218ee0, + 0xf800464f, + 0x356bfbfc, + 0x78010003, + 0x78050002, + 0x3563ff00, + 0xb9602000, + 0x34020007, + 0x34060000, + 0x38218eb8, + 0x38a5052c, + 0x780cc00c, + 0xf8004644, + 0x398c0000, + 0x29820000, + 0x78010100, + 0x38210000, + 0xa0411000, + 0x00460018, + 0x356bfefc, + 0x5cc0000a, + 0x78010003, + 0x78050003, + 0x3563fc00, + 0xb9602000, + 0x38218f80, + 0x38a57214, + 0x34020006, + 0xf8004634, + 0x356bfbfc, + 0x78010003, + 0x78050002, + 0x3563fe00, + 0xb9602000, + 0x38a50608, + 0x34020004, + 0x34060000, + 0x38218f08, + 0xf800462a, + 0x356bfdfc, + 0x78010003, + 0x78050002, + 0x3563fe00, + 0xb9602000, + 0x38a50658, + 0x34020002, + 0x34060000, + 0x38218f30, + 0xf8004620, + 0x356bfdfc, + 0x78010003, + 0x78050002, + 0x34020001, + 0x3563fe00, + 0x38218f58, + 0xb9602000, + 0x38a5068c, + 0x34060000, + 0xf8004616, + 0x29830000, + 0x78020003, + 0x78010003, + 0x384298d8, + 0x38218ee0, + 0x58410000, + 0x20630002, + 0x5c60000a, + 0x78010002, + 0x382102fc, + 0xb7211800, + 0x28620000, + 0x7801ffef, + 0x3821ffff, + 0x38420010, + 0xa0411000, + 0x58620000, + 0x78038000, + 0x78018000, + 0x38630180, + 0x38210040, + 0x78028000, + 0x58610000, + 0x3842000c, + 0x28410000, + 0x78048000, + 0x38840100, + 0x34010004, + 0x58410000, + 0x28810000, + 0x7803bfff, + 0x3863ffff, + 0xa0230800, + 0x78028000, + 0x58810000, + 0x38420110, + 0x28410000, + 0xa0230800, + 0x58410000, + 0xf800467d, + 0xf8000334, + 0xf8001b4b, + 0x7803c020, + 0x38630000, + 0x28620000, + 0x7801fffe, + 0x3821ffff, + 0xa0411000, + 0x58620000, + 0xfbfffc9e, + 0x34010000, + 0xb8201000, + 0xb8201800, + 0xb8202800, + 0xb8203000, + 0xb8203800, + 0x34040037, + 0xf80046e0, + 0x34010000, + 0xb8202800, + 0xb8203000, + 0xb8203800, + 0xb8201000, + 0xb8201800, + 0x34040037, + 0xf8004719, + 0x78010003, + 0x3821f900, + 0x28230000, + 0x28220004, + 0x88431000, + 0x34010000, + 0x34030064, + 0x34420032, + 0x8c431000, + 0xf800467f, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x78018000, + 0x34030001, + 0x3821001c, + 0x78028000, + 0x58230000, + 0x38420024, + 0x58430000, + 0x78018000, + 0x3821003c, + 0x78028000, + 0x58230000, + 0x38420044, + 0x58430000, + 0x78018000, + 0x3821004c, + 0x78028000, + 0x58230000, + 0x38420054, + 0x58430000, + 0x78018000, + 0x3821005c, + 0x78028000, + 0x58230000, + 0x38420064, + 0x58430000, + 0x7801c210, + 0x38210004, + 0x34020003, + 0x58220000, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78180003, + 0x3b188fa8, + 0xfbfffc3e, + 0x780b0003, + 0xb9601000, + 0x3842f800, + 0x34010000, + 0x58410000, + 0xd0010000, + 0xd0210000, + 0xfbffff3c, + 0xf800044f, + 0x7801c00c, + 0x38210000, + 0x28220000, + 0x78010100, + 0x38210000, + 0xa0411000, + 0x00420018, + 0x5c400002, + 0xf800571c, + 0x78010003, + 0x78020003, + 0x3821ec00, + 0x3842edfc, + 0xf8003130, + 0x34010004, + 0xd0210000, + 0x34010001, + 0xd0010000, + 0xfbffffc1, + 0x396bf800, + 0x34010001, + 0x59610000, + 0x34010000, + 0xfbfffbdc, + 0x34010000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0xb8202000, + 0x6821001f, + 0x78030003, + 0x78068000, + 0x78078000, + 0x5c20000c, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x386398d8, + 0x28620034, + 0x34010001, + 0xbc240800, + 0xb8411000, + 0x58620034, + 0xd0050000, + 0xe000000b, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x386398d8, + 0x28620038, + 0x34010001, + 0xbc240800, + 0xb8411000, + 0x58620038, + 0xd0050000, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x78020003, + 0x384298d8, + 0x28440000, + 0x28410034, + 0x38c68000, + 0x28830020, + 0x38e78004, + 0xa0230800, + 0x58c10000, + 0x28410038, + 0x28820024, + 0xa0220800, + 0x58e10000, + 0xd0050000, + 0xc3a00000, + 0xb8201000, + 0x6821001f, + 0x78030003, + 0x78068000, + 0x78078000, + 0x5c20000d, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xbc220800, + 0x386398d8, + 0x28620034, + 0xa4200800, + 0xa0411000, + 0x58620034, + 0xd0050000, + 0xe000000c, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xbc220800, + 0x386398d8, + 0x28620038, + 0xa4200800, + 0xa0411000, + 0x58620038, + 0xd0050000, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x78020003, + 0x384298d8, + 0x28440000, + 0x28410034, + 0x38c68000, + 0x28830020, + 0x38e78004, + 0xa0230800, + 0x58c10000, + 0x28410038, + 0x28820024, + 0xa0220800, + 0x58e10000, + 0xd0050000, + 0xc3a00000, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x78020003, + 0x384298d8, + 0x34030000, + 0x28440000, + 0x78018000, + 0x58430038, + 0x58430034, + 0x38218000, + 0x58230000, + 0x28420038, + 0x28830024, + 0x78018000, + 0x38218004, + 0xa0431000, + 0x58220000, + 0xd0050000, + 0xc3a00000, + 0x90001800, + 0x34020000, + 0xd0020000, + 0x28240000, + 0x78020003, + 0x384298d8, + 0x58440034, + 0x28210004, + 0x58410038, + 0xd0030000, + 0xc3a00000, + 0xb8202000, + 0x6821001f, + 0x78030003, + 0x78068000, + 0x78078000, + 0x5c20000d, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x386398d8, + 0x28630000, + 0x34020001, + 0xbc441000, + 0x28610020, + 0xb8220800, + 0x58610020, + 0xd0050000, + 0xe000000c, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x386398d8, + 0x28630000, + 0x34020001, + 0xbc441000, + 0x28610024, + 0xb8220800, + 0x58610024, + 0xd0050000, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x78020003, + 0x384298d8, + 0x28440000, + 0x28410034, + 0x38c68000, + 0x28830020, + 0x38e78004, + 0xa0230800, + 0x58c10000, + 0x28410038, + 0x28820024, + 0xa0220800, + 0x58e10000, + 0xd0050000, + 0xc3a00000, + 0xb8201000, + 0x6821001f, + 0x78030003, + 0x78068000, + 0x78078000, + 0x5c20000e, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x386398d8, + 0x28630000, + 0x34010001, + 0xbc220800, + 0x28620020, + 0xa4200800, + 0xa0411000, + 0x58620020, + 0xd0050000, + 0xe000000d, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x386398d8, + 0x28630000, + 0x34010001, + 0xbc220800, + 0x28620024, + 0xa4200800, + 0xa0411000, + 0x58620024, + 0xd0050000, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x78020003, + 0x384298d8, + 0x28440000, + 0x28410034, + 0x38c68000, + 0x28830020, + 0x38e78004, + 0xa0230800, + 0x58c10000, + 0x28410038, + 0x28820024, + 0xa0220800, + 0x58e10000, + 0xd0050000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x38218ea0, + 0xf80043fa, + 0xf80043a6, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x7802c210, + 0x34040001, + 0x38420004, + 0x7801c210, + 0x58440000, + 0x38210000, + 0x28220000, + 0x34030000, + 0x78010001, + 0x3821fffe, + 0xa0411000, + 0x80441000, + 0x7801c210, + 0x5b02006c, + 0x3821003c, + 0x28220000, + 0x5b020070, + 0x33040074, + 0x78010003, + 0x33030075, + 0x38218e94, + 0xf80043de, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x38218e88, + 0xf80043d6, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x38218e7c, + 0xf80043ce, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x78010003, + 0x3821f300, + 0x28220000, + 0x78010008, + 0x38210000, + 0xa0411000, + 0x004b0013, + 0x65610001, + 0x44200051, + 0xf80046b9, + 0xb8206000, + 0xf80046ce, + 0x01810011, + 0x34030000, + 0x20210001, + 0xe4230800, + 0xb8602000, + 0xb8606800, + 0x5c230006, + 0x78010003, + 0x38218de0, + 0x302b0012, + 0xb9606800, + 0xb9602000, + 0x21814000, + 0x4420000b, + 0x78010003, + 0x38218de0, + 0x78020003, + 0x302b0010, + 0x3842f320, + 0x28410000, + 0x38840002, + 0xb9601800, + 0x38210040, + 0x58410000, + 0x21812000, + 0x4420000d, + 0x78010003, + 0x38218de0, + 0x34020000, + 0x78030003, + 0x30220010, + 0x3863f320, + 0x28610000, + 0x3402ffbf, + 0x38840004, + 0xa0220800, + 0x58610000, + 0x34030000, + 0x78010003, + 0x3821f320, + 0x28210000, + 0x20210080, + 0x44200007, + 0x78020050, + 0x38420000, + 0x7801c020, + 0xb8821000, + 0x3821012c, + 0x58220000, + 0x44600004, + 0x78010003, + 0x38218eac, + 0xf8004385, + 0x45a0000f, + 0x78030003, + 0x38638de0, + 0x40610015, + 0x4420000b, + 0x40620010, + 0x34010000, + 0x30610012, + 0x306b0013, + 0x306b000f, + 0x30610015, + 0x44410004, + 0x78010003, + 0x38218eac, + 0xf8004376, + 0x34010001, + 0x3301007b, + 0x3c21001a, + 0x78028000, + 0x38428000, + 0x58410050, + 0x34010000, + 0x34022800, + 0xf80045d2, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x78010003, + 0x3821f300, + 0x28220000, + 0x78010010, + 0x38210000, + 0xa0411000, + 0x004b0014, + 0x65610001, + 0x4420004f, + 0xf8004662, + 0xb8201800, + 0x00210011, + 0x34040000, + 0x20210001, + 0xe4240800, + 0xb8802800, + 0xb8806000, + 0x5c240006, + 0x78010003, + 0x38218de0, + 0x302b0012, + 0xb9606000, + 0xb9602800, + 0x20614000, + 0x4420000b, + 0x78010003, + 0x38218de0, + 0x78020003, + 0x302b0010, + 0x3842f320, + 0x28410000, + 0x38a50002, + 0xb9602000, + 0x38210040, + 0x58410000, + 0x20612000, + 0x4420000d, + 0x78010003, + 0x38218de0, + 0x34020000, + 0x78030003, + 0x30220010, + 0x3863f320, + 0x28610000, + 0x3402ffbf, + 0x38a50004, + 0xa0220800, + 0x58610000, + 0x34040000, + 0x78010003, + 0x3821f320, + 0x28210000, + 0x20210080, + 0x44200007, + 0x78020060, + 0x38420000, + 0x7801c020, + 0xb8a21000, + 0x3821012c, + 0x58220000, + 0x44800004, + 0x78010003, + 0x38218eac, + 0xf8004323, + 0x4580000f, + 0x78030003, + 0x38638de0, + 0x40610015, + 0x4420000b, + 0x40620010, + 0x34010000, + 0x30610012, + 0x306b0014, + 0x306b000f, + 0x30610015, + 0x44410004, + 0x78010003, + 0x38218eac, + 0xf8004314, + 0x34010001, + 0x78028000, + 0x3c240019, + 0x38428000, + 0x3301007b, + 0x58440050, + 0x34022800, + 0xf8004588, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78030003, + 0x38638de0, + 0x40620016, + 0x34050001, + 0x34040000, + 0x3401003c, + 0x44440007, + 0x30640016, + 0x3065000f, + 0xfbfffe4f, + 0x78010003, + 0x38218eac, + 0xf80042f8, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210018, + 0x28220000, + 0x34030000, + 0x78018000, + 0x5b020000, + 0x38210068, + 0x28210000, + 0x34020001, + 0x5b010004, + 0x33020008, + 0x78010003, + 0x33030009, + 0x38218e94, + 0xf80042e4, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210020, + 0x28220000, + 0x34030000, + 0x78018000, + 0x5b02000c, + 0x3821006c, + 0x28210000, + 0x34020001, + 0x5b010010, + 0x33020014, + 0x78010003, + 0x33030015, + 0x38218e94, + 0xf80042d0, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210038, + 0x28220000, + 0x34030000, + 0x78018000, + 0x5b020018, + 0x38210070, + 0x28210000, + 0x34020001, + 0x5b01001c, + 0x33020020, + 0x78010003, + 0x33030021, + 0x38218e94, + 0xf80042bc, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210040, + 0x28220000, + 0x34030000, + 0x78018000, + 0x5b020024, + 0x38210074, + 0x28210000, + 0x34020001, + 0x5b010028, + 0x3302002c, + 0x78010003, + 0x3303002d, + 0x38218e94, + 0xf80042a8, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210048, + 0x28220000, + 0x34030000, + 0x78018000, + 0x5b020030, + 0x38210078, + 0x28210000, + 0x34020001, + 0x5b010034, + 0x33020038, + 0x78010003, + 0x33030039, + 0x38218e94, + 0xf8004294, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210050, + 0x28220000, + 0x34030000, + 0x78018000, + 0x5b02003c, + 0x3821007c, + 0x28210000, + 0x34020001, + 0x5b010040, + 0x33020044, + 0x78010003, + 0x33030045, + 0x38218e94, + 0xf8004280, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210058, + 0x28220000, + 0x34030000, + 0x78018000, + 0x5b020048, + 0x38210080, + 0x28210000, + 0x34020001, + 0x5b01004c, + 0x33020050, + 0x78010003, + 0x33030051, + 0x38218e94, + 0xf800426c, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210060, + 0x28220000, + 0x34030000, + 0x78018000, + 0x5b020054, + 0x38210084, + 0x28210000, + 0x34020001, + 0x5b010058, + 0x3302005c, + 0x78010003, + 0x3303005d, + 0x38218e94, + 0xf8004258, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78018000, + 0x38210120, + 0x28220000, + 0x34030001, + 0x78018000, + 0x5b020060, + 0x38210140, + 0x28220000, + 0x78010003, + 0x5b020064, + 0x33030068, + 0x38218e94, + 0xf8004246, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x78018000, + 0x38218000, + 0x28210058, + 0x5c20001c, + 0x780c8000, + 0xb9806800, + 0x39ad8000, + 0x29ab005c, + 0x78018000, + 0x38210430, + 0x582b0000, + 0x3d630002, + 0x78020003, + 0x384289cc, + 0x34010000, + 0xb4621800, + 0x3301007b, + 0x28610000, + 0xd8200000, + 0x4301007b, + 0x6963001f, + 0x5c200007, + 0x34010001, + 0xbc2b1000, + 0x5c600003, + 0x59a20050, + 0xe0000002, + 0x59a20054, + 0x398c8000, + 0x29810058, + 0xe3ffffe5, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x780d0003, + 0xb9a01000, + 0x3842899c, + 0x10410000, + 0x340b0000, + 0x6421ffff, + 0x5c2b0014, + 0xb8406000, + 0xb9a00800, + 0xb56b1800, + 0x3821899c, + 0xb4611800, + 0x10610000, + 0x78028000, + 0x38428000, + 0xb5621000, + 0x30410010, + 0x10620001, + 0x358c0002, + 0x356b0001, + 0x7c420001, + 0x5c400002, + 0xfbfffd24, + 0x11810000, + 0x6421ffff, + 0x4420ffef, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0xb8206800, + 0x44200029, + 0x780b0003, + 0x34010190, + 0x502d0008, + 0x396bf900, + 0x29620004, + 0xb5a20800, + 0x3421ffff, + 0x8c220800, + 0xf80041c1, + 0xe000001f, + 0xf800435d, + 0xb9604800, + 0x3929f900, + 0x29250000, + 0x34080064, + 0xb8402000, + 0x89a52800, + 0xb8201800, + 0x34060000, + 0x34a50032, + 0x8ca82800, + 0xb4660800, + 0xb4451000, + 0xf4822800, + 0xb8406000, + 0xb4a12800, + 0xb8a05800, + 0x34010009, + 0x502d0007, + 0x29220004, + 0x35a1fffa, + 0x00430001, + 0xb4230800, + 0x8c220800, + 0xf80041a7, + 0xf8004344, + 0xb8201800, + 0x5563fffe, + 0x5d630002, + 0x5582fffc, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78020003, + 0x3842f900, + 0x28420000, + 0x88220800, + 0x34020064, + 0x34210032, + 0x8c220800, + 0xf8004340, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x206300ff, + 0x88431000, + 0x88231800, + 0x00420008, + 0x00630008, + 0xb4220800, + 0xc8230800, + 0xc3a00000, + 0x88432800, + 0x88230800, + 0xbc441000, + 0xc8451000, + 0xb4220800, + 0x80240800, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xf800431b, + 0x78050003, + 0x38a58db0, + 0x58a20000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8db0, + 0x29610000, + 0x780241c6, + 0x38424e6d, + 0x3783000c, + 0xf8003931, + 0x2b810010, + 0x34213039, + 0x59610000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cffec, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x202cffff, + 0x204bffff, + 0xb9800800, + 0x516c000c, + 0xfbffffe7, + 0x00220010, + 0x37830010, + 0xb56b0800, + 0x34210001, + 0x3c210010, + 0xf800391b, + 0x2b820010, + 0xc98b0800, + 0xb4220800, + 0x2021ffff, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x202400ff, + 0x7c850000, + 0x5ca00017, + 0x7801c050, + 0x382100ac, + 0x28210000, + 0x7802c050, + 0x384200a4, + 0x2021007f, + 0x33010124, + 0x28410000, + 0xb8801800, + 0x2021007f, + 0x7802c050, + 0x33010123, + 0x3842009c, + 0x28410000, + 0x7802c050, + 0x2021007f, + 0x33010122, + 0x384200e4, + 0x28410000, + 0x2021007f, + 0x33010120, + 0xe0000003, + 0x43010124, + 0x2023007f, + 0x7801c050, + 0x382100ac, + 0x7802c050, + 0x58230000, + 0x384200b0, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0xb8801800, + 0x44a00003, + 0x43010123, + 0x2023007f, + 0x7801c050, + 0x382100a4, + 0x7802c050, + 0x58230000, + 0x384200a8, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0xb8801800, + 0x44a00003, + 0x43010122, + 0x2023007f, + 0x7801c050, + 0x3821009c, + 0x7802c050, + 0x58230000, + 0x384200a0, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0xb8801800, + 0x44a00003, + 0x43010120, + 0x2023007f, + 0x7801c050, + 0x382100e4, + 0x7802c050, + 0x58230000, + 0x384200e8, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0xc3a00000, + 0x208400ff, + 0x5041000e, + 0x40a20001, + 0x34010000, + 0x30a10000, + 0x5c410007, + 0x40a20002, + 0x30a40001, + 0x74410006, + 0x5c20001b, + 0x34410001, + 0xe000000d, + 0x3441ffff, + 0x30a10001, + 0xc3a00000, + 0x40a20000, + 0x5023000d, + 0x34010000, + 0x30a10001, + 0x5c410007, + 0x40a10002, + 0x30a40000, + 0x4420000e, + 0x3421ffff, + 0x30a10002, + 0xc3a00000, + 0x3441ffff, + 0x30a10000, + 0xc3a00000, + 0x44400003, + 0x3441ffff, + 0x30a10000, + 0x40a10001, + 0x44200003, + 0x3421ffff, + 0x30a10001, + 0xc3a00000, + 0x208400ff, + 0x5041000e, + 0x40a20001, + 0x34010000, + 0x30a10000, + 0x5c410005, + 0x34010002, + 0x30a10003, + 0x30a40001, + 0xc3a00000, + 0x3442ffff, + 0x34010001, + 0x30a10003, + 0x30a20001, + 0xc3a00000, + 0x50230005, + 0x34010000, + 0x30a10003, + 0x30a10001, + 0xc3a00000, + 0x40a10000, + 0x44200003, + 0x3421ffff, + 0x30a10000, + 0x40a10001, + 0x44200003, + 0x3421ffff, + 0x30a10001, + 0x34010001, + 0x30a10003, + 0xc3a00000, + 0xb8201800, + 0xb8400800, + 0x50430002, + 0xb8600800, + 0xc3a00000, + 0xb8201800, + 0xb8400800, + 0x4c430002, + 0xb8600800, + 0xc3a00000, + 0x08220019, + 0x34011838, + 0xc8220800, + 0xc3a00000, + 0x379cfff4, + 0x5b9d0004, + 0x2f020240, + 0x34040010, + 0x34030000, + 0x2f010242, + 0x2042ffff, + 0x2021ffff, + 0x54410002, + 0x34030001, + 0xb4630800, + 0xb4380800, + 0x2c210240, + 0x2f0202b2, + 0x2021ffff, + 0x2f0302b0, + 0x2042ffff, + 0x2063ffff, + 0xfbffff1b, + 0x0f0102b2, + 0x430102b5, + 0x3804fd71, + 0x37850008, + 0x33810008, + 0x430102b6, + 0x33810009, + 0x2f0102b2, + 0x2f0202ee, + 0x2021ffff, + 0x2f0302ee, + 0x2042ffff, + 0x2063ffff, + 0x88641800, + 0x430402b7, + 0x14630010, + 0x208400ff, + 0xfbffffaf, + 0x43810008, + 0x330102b5, + 0x43810009, + 0x330102b6, + 0x4381000b, + 0x330106e4, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x78010003, + 0x34060000, + 0x3821f818, + 0x58260000, + 0x78070003, + 0x38e7fdd0, + 0x78010003, + 0x58e60000, + 0x3821fdd4, + 0x58260000, + 0x78020003, + 0x3842fdcc, + 0x78010003, + 0x58460000, + 0x3821fdc8, + 0x78050003, + 0x78030001, + 0x58260000, + 0x38630501, + 0x38a5f820, + 0x78040003, + 0x78020101, + 0x58a30000, + 0x38420101, + 0x3884f824, + 0x78010003, + 0x58820000, + 0x3821f82c, + 0x58220000, + 0x78010003, + 0x58e60000, + 0x3821f808, + 0x58260000, + 0x78020003, + 0x3842f99c, + 0x78010003, + 0x58460000, + 0x3821f9e8, + 0x78030003, + 0x58260000, + 0x3863f9ec, + 0x78020003, + 0x58660000, + 0x3842f9f0, + 0x78040003, + 0x58460000, + 0x38848b20, + 0x78010003, + 0x28830000, + 0x3821fa04, + 0x3402ffff, + 0x58220000, + 0x34010008, + 0x586100c0, + 0x340103ff, + 0x586100a4, + 0x3401fc00, + 0x586100a8, + 0x34010003, + 0x586100ac, + 0x3401000a, + 0x586100b0, + 0x34010400, + 0x586100b4, + 0x34010007, + 0x586100b8, + 0x340100ff, + 0x7804c020, + 0x586100bc, + 0x586600a0, + 0x38840088, + 0x28810000, + 0x3402ffc7, + 0x7803c020, + 0xa0220800, + 0x38210028, + 0x58810000, + 0x38630024, + 0x7802c050, + 0x58660000, + 0x384200dc, + 0x7801c050, + 0x58460000, + 0x38210100, + 0x58260000, + 0xc3a00000, + 0x2b0206c4, + 0x78040003, + 0x3884f004, + 0x2b0106e0, + 0xc8411000, + 0x5b0206c8, + 0x2b0206c8, + 0x3c410003, + 0xb4220800, + 0xb4220800, + 0x5b0106c8, + 0x2b0206c8, + 0x34010000, + 0x4c22000d, + 0x430106e4, + 0x5c20000f, + 0x430106e7, + 0x5c20000d, + 0x430106e6, + 0x5c20000b, + 0x430106e5, + 0x5c200009, + 0x430106fe, + 0x5c200007, + 0x430106fb, + 0x5c200005, + 0x2b0106cc, + 0x2b0206c8, + 0xb4220800, + 0x5b0106cc, + 0x2b0106cc, + 0x28820008, + 0x4c220002, + 0xe0000004, + 0x2b0106cc, + 0x28820004, + 0x4c410002, + 0x5b0206cc, + 0x28830000, + 0x2b0106cc, + 0x78028000, + 0x28840014, + 0x94230800, + 0x38420418, + 0xb4240800, + 0x5b0106d0, + 0x2b0106d0, + 0x58410000, + 0xc3a00000, + 0x78050003, + 0x38a5f000, + 0x40a4004c, + 0xb8603000, + 0x78070003, + 0x3484ffff, + 0x58640000, + 0x40a3004c, + 0xb8204000, + 0x38e7f054, + 0x34040000, + 0x4c83000b, + 0x34e30004, + 0x28610000, + 0x3463001c, + 0x55010003, + 0x58c40000, + 0xe0000005, + 0x40a1004c, + 0x34840001, + 0x4c810002, + 0xe3fffff8, + 0x28c30000, + 0x44600007, + 0x3c610003, + 0xc8230800, + 0x3c210002, + 0xb4270800, + 0x28210004, + 0x5d010003, + 0x58430000, + 0xc3a00000, + 0x3461ffff, + 0x58410000, + 0xc3a00000, + 0x430206e8, + 0x78010003, + 0x3821f000, + 0x4025004c, + 0xb0401000, + 0x78040003, + 0x3884f054, + 0x34430001, + 0x4c650010, + 0x3c610003, + 0xc8230800, + 0x3c210002, + 0xb4242000, + 0x40810011, + 0x44200006, + 0x28820004, + 0x2b0106f4, + 0x54220003, + 0xb8600800, + 0xc3a00000, + 0x34630001, + 0x3484001c, + 0x4c650002, + 0xe3fffff6, + 0x430106e8, + 0xb0200800, + 0xc3a00000, + 0x430106e8, + 0x78020003, + 0x3842f054, + 0xb0200800, + 0x3423ffff, + 0x34010000, + 0x48230011, + 0x3c610003, + 0xc8230800, + 0x3c210002, + 0xb4222000, + 0x2b0206f4, + 0x28810004, + 0x50220002, + 0xe0000009, + 0x40810011, + 0x3484ffe4, + 0x44200003, + 0xb8600800, + 0xc3a00000, + 0x3463ffff, + 0x48230002, + 0xe3fffff5, + 0x430106e8, + 0xb0200800, + 0xc3a00000, + 0x430106e8, + 0x78020003, + 0x3842f054, + 0xb0200800, + 0x48200005, + 0x34010000, + 0xc3a00000, + 0xb8600800, + 0xc3a00000, + 0x430106e8, + 0xb0200800, + 0x3423ffff, + 0x3c610003, + 0xc8230800, + 0x3c210002, + 0xb4220800, + 0x34220012, + 0x40410000, + 0x3442ffe4, + 0x5c20fff4, + 0x3463ffff, + 0xe3fffffc, + 0x202100ff, + 0x3c220003, + 0x78030003, + 0xc8411000, + 0x3c420002, + 0x3863f054, + 0xb4431000, + 0x28420010, + 0x780100ff, + 0x3821ff00, + 0xa0411000, + 0x34010001, + 0x5c400002, + 0xb8400800, + 0xc3a00000, + 0x78010003, + 0x3821f000, + 0x4021004c, + 0x78040003, + 0x3884f054, + 0x34020000, + 0x5041000e, + 0xb8202800, + 0x3c410003, + 0x34430001, + 0xc8220800, + 0x3c210002, + 0xb4240800, + 0x40210011, + 0x44200003, + 0xb8400800, + 0xc3a00000, + 0x206200ff, + 0x50450002, + 0xe3fffff5, + 0x34010000, + 0xc3a00000, + 0x2b0206d0, + 0x78040003, + 0x3884f004, + 0x2883001c, + 0x2b0106d4, + 0x78058000, + 0xa0431000, + 0xb4220800, + 0x5b0106d4, + 0x2b0106d4, + 0x38a50418, + 0x34030000, + 0x58a10000, + 0x2b0106d4, + 0x2882001c, + 0x50410006, + 0x2b0106d4, + 0x34030001, + 0xc8220800, + 0x3421ffff, + 0x5b0106d4, + 0x2b0106d0, + 0x28820020, + 0x80220800, + 0xb4230800, + 0x5b0106d8, + 0x2b0106d8, + 0x58a10000, + 0x28820018, + 0x2b0106d8, + 0x50410002, + 0x5b0206d8, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2f010728, + 0x78030002, + 0x34020000, + 0x38632ce4, + 0x4422000c, + 0x0f020728, + 0x2b020720, + 0x34010001, + 0x5c430008, + 0x2b020724, + 0xd8400000, + 0x2b020724, + 0x34010002, + 0xd8400000, + 0x2b010724, + 0x5b010720, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x780c0003, + 0x202b00ff, + 0x398cf054, + 0x5d600046, + 0x78020003, + 0xb8406800, + 0x38428db6, + 0x2c410000, + 0x5c200036, + 0xfbffff67, + 0x430206e8, + 0xb0401000, + 0x5c220006, + 0x78010003, + 0x38218db4, + 0x34020007, + 0x30220000, + 0xe0000008, + 0xfbffff43, + 0x430206e8, + 0xb0401000, + 0x5c220004, + 0x78010003, + 0x38218db4, + 0x302b0000, + 0x78030003, + 0xb8600800, + 0x38218db4, + 0x40220000, + 0x7c410007, + 0x5c20000a, + 0x430106e8, + 0xb0200800, + 0x3c220003, + 0xc8411000, + 0x3c420002, + 0xb44c1000, + 0x40410013, + 0x330106eb, + 0xe000000a, + 0x5c400009, + 0x430106e8, + 0xb0200800, + 0x3c220003, + 0xc8411000, + 0x3c420002, + 0xb44c1000, + 0x40410014, + 0x330106ec, + 0x38638db4, + 0x40610000, + 0xb9a05800, + 0x396b8db6, + 0x5b0106d8, + 0x2f010728, + 0x2f02072a, + 0x2021ffff, + 0x2042ffff, + 0xfbfffd91, + 0x3421ffff, + 0x0d610000, + 0xe0000006, + 0x3421ffff, + 0x0c410000, + 0x430106e8, + 0xb0200800, + 0x5b0106d8, + 0x34010000, + 0x330106e6, + 0x330106e4, + 0x330106e5, + 0x330106fe, + 0xe0000007, + 0x7d610001, + 0x5c200005, + 0x78010003, + 0x38218db6, + 0x34020000, + 0x0c220000, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2f020728, + 0x34010001, + 0x44400007, + 0x2b020720, + 0x5b020724, + 0xfbffff9f, + 0x78010002, + 0x38212ce4, + 0x5b010720, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x43010736, + 0x78030003, + 0x78050003, + 0x202400ff, + 0x78028000, + 0x5c80000d, + 0x78010003, + 0x38218dc0, + 0x38638db8, + 0x58240000, + 0x58640000, + 0x3842014c, + 0x28420000, + 0x38a58dbc, + 0x34010001, + 0x58a20000, + 0x33010736, + 0xe0000036, + 0xb8606800, + 0x39ad8db8, + 0xb8407000, + 0x29a30000, + 0x39ce014c, + 0xb8a07800, + 0x39ef8dbc, + 0x29c20000, + 0x29e10000, + 0x34630001, + 0x59a30000, + 0x5c410003, + 0x646107d0, + 0x44200028, + 0x44600027, + 0x78020003, + 0x3842e800, + 0x8c431000, + 0x780c0003, + 0xb9805800, + 0x396b8dc0, + 0x29610000, + 0x430306fc, + 0x206300ff, + 0xfbfffd0e, + 0x78050003, + 0xb8a03000, + 0xb8201800, + 0x38c6f000, + 0x2cc10052, + 0x29c20000, + 0x3c240008, + 0x59e20000, + 0x34010000, + 0x59a10000, + 0x59630000, + 0x50830003, + 0x34010002, + 0xe000000e, + 0x54640006, + 0x2cc102f6, + 0x3c210008, + 0x54230003, + 0x34010001, + 0xe0000008, + 0x38a5f000, + 0x2ca102f6, + 0x398c8dc0, + 0x29820000, + 0x3c210008, + 0x50410003, + 0x34010000, + 0x330106fe, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x202100ff, + 0x5c200003, + 0xfbfffe44, + 0xfbffff07, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x430106f8, + 0x7803c020, + 0x78040003, + 0x78020002, + 0x7805c020, + 0x38630008, + 0x38848b24, + 0x38423e94, + 0x38a50024, + 0x202100ff, + 0x5c20000a, + 0x330106f9, + 0x28610000, + 0x58820000, + 0x28620000, + 0x38420030, + 0x58620000, + 0x58610000, + 0x34010003, + 0x58a10000, + 0x34010000, + 0xc3a00000, + 0x202100ff, + 0x7802c020, + 0x44200008, + 0xb8400800, + 0x38210304, + 0x28220000, + 0x3403fffd, + 0xa0431000, + 0x58220000, + 0xc3a00000, + 0x38420304, + 0x28410000, + 0xb8401800, + 0x38210002, + 0x58410000, + 0x28610000, + 0x20218000, + 0x4420fffe, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x430100a9, + 0x780b0003, + 0x396bf054, + 0x7c210001, + 0x5c200002, + 0xf8001438, + 0x43010085, + 0x7c210001, + 0x5c200002, + 0xf8001395, + 0x430106e9, + 0x7806c020, + 0x38c60014, + 0x330106e8, + 0x430106e9, + 0x7804ffe0, + 0x7805001f, + 0xb0200800, + 0xb4210800, + 0xb4380800, + 0x34210708, + 0x2c220008, + 0x3884ffff, + 0x38a50000, + 0x34420001, + 0x0c220008, + 0x430206e9, + 0x7803c020, + 0x38630130, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb42b0800, + 0x2c21000a, + 0x5b0106e0, + 0x28c20000, + 0x430106e9, + 0xa0441000, + 0xb0200800, + 0x3c210010, + 0xa0250800, + 0xb8411000, + 0x58c20000, + 0x28610000, + 0x3402fffd, + 0xa0220800, + 0x58610000, + 0x430106ea, + 0x202200ff, + 0x5c400030, + 0x430106ee, + 0x5c200013, + 0x33020760, + 0x78010003, + 0x330206ef, + 0x38218ba8, + 0x7805c020, + 0x30220019, + 0x30220000, + 0x38a50004, + 0x28a40000, + 0x78030003, + 0x78020002, + 0x3401ffef, + 0xa0812000, + 0x38638b24, + 0x38424a68, + 0x58620000, + 0x58a40000, + 0xe0000023, + 0x430106f0, + 0x78060003, + 0x44200007, + 0x78010002, + 0x38c68b24, + 0x38213dc8, + 0x58c10000, + 0x330206ef, + 0xe000001a, + 0x34010001, + 0x7802c020, + 0x330106ef, + 0x38420008, + 0x28450000, + 0x78030002, + 0x7804c020, + 0x28410000, + 0x38c68b24, + 0x38633e94, + 0x38210030, + 0x58410000, + 0x58450000, + 0x38840024, + 0x34010003, + 0x58c30000, + 0x58810000, + 0xe0000008, + 0x34030000, + 0x78020003, + 0x78010002, + 0x330306ea, + 0x38428b24, + 0x38213e94, + 0x58410000, + 0x34010000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x7805c020, + 0x38a50304, + 0xb8203000, + 0x28a10000, + 0x3cc30001, + 0x3404fffd, + 0xa0240800, + 0x20630002, + 0xb8230800, + 0x58a10000, + 0x204200ff, + 0x44400006, + 0xb8a01000, + 0x28410000, + 0x20218000, + 0x0021000f, + 0x5c26fffd, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x430100a9, + 0x780c0003, + 0x398cf054, + 0x7c210001, + 0x5c200002, + 0xf80013b4, + 0x43010085, + 0x7c210001, + 0x5c200002, + 0xf8001311, + 0x430106f2, + 0x202300ff, + 0x5c60000e, + 0x430106e9, + 0xb0200800, + 0x3c220003, + 0xc8411000, + 0x3c420002, + 0xb44c1000, + 0x404b0010, + 0x7d610001, + 0x5c200005, + 0xb8600800, + 0xb8601000, + 0xfbffffd2, + 0x330b06f2, + 0x430106e9, + 0x7806c020, + 0x38c60014, + 0x330106e8, + 0x430106e9, + 0x7804ffe0, + 0x7805001f, + 0xb0200800, + 0xb4210800, + 0xb4380800, + 0x34210708, + 0x2c220008, + 0x3884ffff, + 0x38a50000, + 0x34420001, + 0x0c220008, + 0x430206e9, + 0x7803c020, + 0x38630130, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb42c0800, + 0x2c21000a, + 0x5b0106e0, + 0x28c20000, + 0x430106e9, + 0xa0441000, + 0xb0200800, + 0x3c210010, + 0xa0250800, + 0xb8411000, + 0x58c20000, + 0x28610000, + 0x3402fffd, + 0xa0220800, + 0x58610000, + 0x430106ea, + 0x202200ff, + 0x5c400030, + 0x430106ee, + 0x5c200013, + 0x33020760, + 0x78010003, + 0x330206ef, + 0x38218ba8, + 0x7805c020, + 0x30220019, + 0x30220000, + 0x38a50004, + 0x28a40000, + 0x78030003, + 0x78020002, + 0x3401ffef, + 0xa0812000, + 0x38638b24, + 0x38424a68, + 0x58620000, + 0x58a40000, + 0xe0000023, + 0x430106f0, + 0x78060003, + 0x44200007, + 0x78010002, + 0x38c68b24, + 0x38213dc8, + 0x58c10000, + 0x330206ef, + 0xe000001a, + 0x34010001, + 0x7802c020, + 0x330106ef, + 0x38420008, + 0x28450000, + 0x78030002, + 0x7804c020, + 0x28410000, + 0x38c68b24, + 0x38633e94, + 0x38210030, + 0x58410000, + 0x58450000, + 0x38840024, + 0x34010003, + 0x58c30000, + 0x58810000, + 0xe0000008, + 0x34030000, + 0x78020003, + 0x78010002, + 0x330306ea, + 0x38428b24, + 0x38213e94, + 0x58410000, + 0x34010000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x430206e9, + 0x78030003, + 0x3863f054, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb4236000, + 0x4181000d, + 0x3301077f, + 0x4181000e, + 0x33010781, + 0x41810017, + 0x20260008, + 0x44c00011, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x3402ffc7, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x7802c050, + 0x384200cc, + 0x38210800, + 0x58810000, + 0x34010000, + 0x58410000, + 0xe0000015, + 0x20220002, + 0x780bc050, + 0x44400015, + 0x7805c050, + 0x38a501c8, + 0x28a30000, + 0x20210007, + 0x3c210003, + 0x3402ffc7, + 0xa0621800, + 0xb8611800, + 0x7804c050, + 0x58a30000, + 0x38840118, + 0x28810000, + 0x3402f7ff, + 0x396b00cc, + 0xa0220800, + 0x58810000, + 0x59660000, + 0x34010001, + 0x33010918, + 0xe0000016, + 0x33020918, + 0xf8002453, + 0x4181000f, + 0x396b00cc, + 0x7802c050, + 0x59610000, + 0x384200d0, + 0x28410000, + 0x4420ffff, + 0x7803c050, + 0x38630118, + 0x28610000, + 0x3402f7ff, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x388401c8, + 0x28810000, + 0x3402ffc7, + 0xa0220800, + 0x58810000, + 0x29820004, + 0x78010003, + 0x38218b88, + 0x58220000, + 0x41820016, + 0x7806c020, + 0x78057fff, + 0x44400014, + 0x7804c020, + 0x38840088, + 0x28810000, + 0x3c420003, + 0x3403ffc7, + 0xa0230800, + 0x20420038, + 0xb8220800, + 0xb8c01800, + 0x58810000, + 0x38630080, + 0x28620000, + 0x38a5ffff, + 0x78018000, + 0xa0451000, + 0x38210000, + 0xb8411000, + 0x58620000, + 0xe0000007, + 0xb8c01000, + 0x38420080, + 0x28410000, + 0x38a5ffff, + 0xa0250800, + 0x58410000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8b88, + 0x29610000, + 0xf80011d1, + 0xb8206000, + 0x29610000, + 0xf800126a, + 0xb8206800, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x430106fa, + 0x44200004, + 0xd00b0000, + 0x34030000, + 0xe0000029, + 0xb98d0800, + 0x5c20000a, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x382132b0, + 0x58410000, + 0xfbffff6d, + 0xd00b0000, + 0xfbfffee8, + 0xe000001d, + 0xd00b0000, + 0x658e0000, + 0x340f0000, + 0x5dcf0003, + 0xf80011e9, + 0x442f0002, + 0x340f0001, + 0x65ac0000, + 0x340b0000, + 0x5d8b0003, + 0xf8001282, + 0x442b0002, + 0x340b0001, + 0x65e10000, + 0x65620000, + 0x34030000, + 0xb8220800, + 0xe4230800, + 0x4423000b, + 0x5dc30002, + 0xf80011e6, + 0x5d800002, + 0xf8001283, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x382137b0, + 0x58410000, + 0x34030001, + 0xb8600800, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xf80011f2, + 0xb8206000, + 0xf800128f, + 0xb8203000, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x430106fa, + 0x202100ff, + 0xb8202800, + 0xb8202000, + 0x44200003, + 0xd00b0000, + 0xe000000c, + 0x78030003, + 0x78020002, + 0x38638b24, + 0x384232b0, + 0x4d800002, + 0x34040001, + 0x4cc00002, + 0x34050001, + 0xb8850800, + 0x44200004, + 0xd00b0000, + 0x34010001, + 0xe0000005, + 0x58620000, + 0xfbffff23, + 0xd00b0000, + 0xfbfffe9e, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x430206e9, + 0x78030003, + 0x3863f054, + 0xb0401000, + 0x3c410003, + 0x430406f2, + 0xc8220800, + 0x3c210002, + 0x208400ff, + 0x7c820001, + 0xb4236000, + 0x5c400007, + 0x418b0010, + 0x5d600005, + 0xb8800800, + 0xb8801000, + 0xfbfffe72, + 0x330b06f2, + 0x41820016, + 0x7807c020, + 0x78057fff, + 0x78060003, + 0x44400014, + 0x7804c020, + 0x38840088, + 0x28810000, + 0x3c420003, + 0x3403ffc7, + 0xa0230800, + 0x20420038, + 0xb8220800, + 0xb8e01800, + 0x58810000, + 0x38630080, + 0x28620000, + 0x38a5ffff, + 0x78018000, + 0xa0451000, + 0x38210000, + 0xb8411000, + 0x58620000, + 0xe0000007, + 0xb8e01000, + 0x38420080, + 0x28410000, + 0x38a5ffff, + 0xa0250800, + 0x58410000, + 0x4181000d, + 0x38c68b88, + 0x3301077f, + 0x4181000e, + 0x33010781, + 0x41810017, + 0x29820004, + 0x58c20000, + 0x20260008, + 0x44c00011, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x3402ffc7, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x7802c050, + 0x384200cc, + 0x38210800, + 0x58810000, + 0x34010000, + 0x58410000, + 0xe0000015, + 0x20220002, + 0x780bc050, + 0x44400015, + 0x7805c050, + 0x38a501c8, + 0x28a30000, + 0x20210007, + 0x3c210003, + 0x3402ffc7, + 0xa0621800, + 0xb8611800, + 0x7804c050, + 0x58a30000, + 0x38840118, + 0x28810000, + 0x3402f7ff, + 0x396b00cc, + 0xa0220800, + 0x58810000, + 0x59660000, + 0x34010001, + 0x33010918, + 0xe0000016, + 0x33020918, + 0xf8002343, + 0x4181000f, + 0x396b00cc, + 0x7802c050, + 0x59610000, + 0x384200d0, + 0x28410000, + 0x4420ffff, + 0x7803c050, + 0x38630118, + 0x28610000, + 0x3402f7ff, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x388401c8, + 0x28810000, + 0x3402ffc7, + 0xa0220800, + 0x58810000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x430206e9, + 0x78030003, + 0x3863f054, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb4230800, + 0x282b0004, + 0xb9600800, + 0xf80010db, + 0xb8206000, + 0xb9600800, + 0xf8001174, + 0xb8206800, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x430106fa, + 0x44200004, + 0xd00b0000, + 0x34030000, + 0xe0000029, + 0xb98d0800, + 0x5c20000a, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x382130a4, + 0x58410000, + 0xfbffff5c, + 0xd00b0000, + 0xfbfffd6f, + 0xe000001d, + 0xd00b0000, + 0x658e0000, + 0x340f0000, + 0x5dcf0003, + 0xf80010f3, + 0x442f0002, + 0x340f0001, + 0x65ac0000, + 0x340b0000, + 0x5d8b0003, + 0xf800118c, + 0x442b0002, + 0x340b0001, + 0x65e10000, + 0x65620000, + 0x34030000, + 0xb8220800, + 0xe4230800, + 0x4423000b, + 0x5dc30002, + 0xf80010f0, + 0x5d800002, + 0xf800118d, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x382143c8, + 0x58410000, + 0x34030001, + 0xb8600800, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x430106ea, + 0x780e0003, + 0x39cef054, + 0x5c200047, + 0x780d0003, + 0x78010002, + 0x38213b88, + 0x39ad8b24, + 0x59a10000, + 0x430106f0, + 0x44200004, + 0x430106f1, + 0x330106e9, + 0xe000003b, + 0x780c0003, + 0x398cf000, + 0x418b02f0, + 0x216100ff, + 0xfbfffbe4, + 0x4420000a, + 0x330b06e9, + 0x418102f3, + 0x7802c020, + 0x38420004, + 0x33010760, + 0x28410000, + 0x38210010, + 0x58410000, + 0xe000002c, + 0x430106ee, + 0x7804c020, + 0x202200ff, + 0x5c400010, + 0x330206ef, + 0x78010003, + 0x33020760, + 0x38218ba8, + 0x30220019, + 0x30220000, + 0x38840004, + 0x28830000, + 0x78010002, + 0x3402ffef, + 0xa0621800, + 0x38214a68, + 0x59a10000, + 0x58830000, + 0xe0000017, + 0x34010001, + 0x330106ef, + 0x418302f3, + 0x78010002, + 0x38213e94, + 0x59a10000, + 0x7802c020, + 0x33030760, + 0x38420008, + 0x28450000, + 0x7803c020, + 0x38630024, + 0x28410000, + 0x38840004, + 0x38210030, + 0x58410000, + 0x58450000, + 0x34010003, + 0x58610000, + 0x28810000, + 0x38210010, + 0x58810000, + 0x34010000, + 0xe000003c, + 0x34010001, + 0x330106ea, + 0x430306e9, + 0x34020000, + 0xb0601800, + 0x3c610003, + 0xc8230800, + 0x3c210002, + 0xb42e0800, + 0x28210000, + 0xf8001b18, + 0x34060000, + 0x330606ed, + 0x2f02073c, + 0x2f010748, + 0x5422002b, + 0x330606eb, + 0x330606ec, + 0x7802c020, + 0x330606ed, + 0x38420130, + 0x28410000, + 0x7805c020, + 0x38a50014, + 0x38210002, + 0x58410000, + 0x28a40000, + 0x7802fc1f, + 0x780303e0, + 0x430106e9, + 0x3842ffff, + 0x38630000, + 0xb0200800, + 0x3c210015, + 0xa0822000, + 0xa0230800, + 0xb8812000, + 0x58a40000, + 0x330606ea, + 0x430206e9, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb42e0800, + 0x40210010, + 0x330106f2, + 0x430106f2, + 0x202100ff, + 0xfbfffcb5, + 0x430206e9, + 0x430106e8, + 0xb0401000, + 0xb0200800, + 0x48410003, + 0xfbffff2c, + 0xe0000002, + 0xfbfffe3b, + 0x34010001, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x430106f8, + 0x34050000, + 0x78040003, + 0x202300ff, + 0x78020002, + 0x7c610001, + 0x38848b24, + 0x38423000, + 0xb8a04000, + 0x5c250005, + 0x330306f9, + 0x330506f0, + 0x58820000, + 0xe0000020, + 0x430106f0, + 0x7803c020, + 0x78050003, + 0x78040002, + 0x7806c020, + 0x34070001, + 0x38630008, + 0x38a58b24, + 0x38843e94, + 0x38c60024, + 0x202200ff, + 0x34080000, + 0x44480009, + 0x430206f1, + 0x430106e8, + 0x204200ff, + 0xb0200800, + 0x4441000e, + 0xfbffff4e, + 0xb8204000, + 0xe000000b, + 0x330706ef, + 0x28610000, + 0xb8404000, + 0x58a40000, + 0x28620000, + 0x38420030, + 0x58620000, + 0x58610000, + 0x34010003, + 0x58c10000, + 0xb9000800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x430106ff, + 0x780c0003, + 0x398cf054, + 0x44200002, + 0xfbfffbf4, + 0x430106f8, + 0x202400ff, + 0x7c810001, + 0x5c20000a, + 0x430306e8, + 0x78020003, + 0x78010002, + 0x330306e9, + 0x330406f9, + 0x38428b24, + 0x38213000, + 0x58410000, + 0xe0000007, + 0x430106ee, + 0x44200004, + 0x430106f0, + 0x64210001, + 0x44200004, + 0xfbffff22, + 0x34010000, + 0xe000012b, + 0x78010003, + 0x38218b88, + 0x28220000, + 0x2b0106f4, + 0x5041000c, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb42c0800, + 0x40210013, + 0x330106eb, + 0x34010007, + 0x5b0106d8, + 0xe0000032, + 0x430106fd, + 0x7c210001, + 0x5c20002c, + 0x34030000, + 0x330306fd, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb42c0800, + 0x402b0011, + 0x5d630025, + 0x330306e6, + 0x330306e4, + 0x330306e5, + 0x330306fe, + 0xfbfffaaf, + 0x430206e8, + 0xb0401000, + 0x4422000c, + 0x34010007, + 0x5b0106d8, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb42c0800, + 0x40210013, + 0x330106eb, + 0xe0000012, + 0xfbfffabb, + 0x430206e8, + 0xb0401000, + 0x4422000e, + 0x5b0b06d8, + 0x430106e8, + 0xb0200800, + 0x3c220003, + 0xc8411000, + 0x3c420002, + 0xb44c1000, + 0x40410014, + 0x330106ec, + 0xe0000004, + 0x2b020720, + 0x34010000, + 0xd8400000, + 0x430106ea, + 0x5c2000e6, + 0x430106e8, + 0x2b0206d8, + 0xb0200800, + 0x48220010, + 0x430106e6, + 0x64210002, + 0x5c20000d, + 0x430106e4, + 0x64210002, + 0x5c20000a, + 0x430106e5, + 0x64210002, + 0x5c200007, + 0x430106fe, + 0x64210002, + 0x5c200004, + 0x430106fb, + 0x202b00ff, + 0x45600065, + 0x430106e6, + 0x64210002, + 0x5c20000c, + 0x430106e4, + 0x64210002, + 0x5c200009, + 0x430106e5, + 0x64210002, + 0x5c200006, + 0x430106fe, + 0x64210002, + 0x5c200003, + 0x430106fb, + 0x44200028, + 0x430106e6, + 0x7c210002, + 0x5c200003, + 0x34010001, + 0x330106e6, + 0x430106e4, + 0x7c210002, + 0x5c200003, + 0x34010001, + 0x330106e4, + 0x430106e5, + 0x7c210002, + 0x5c200003, + 0x34010001, + 0x330106e5, + 0x430106fe, + 0x7c210002, + 0x5c200003, + 0x34010001, + 0x330106fe, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb42c0800, + 0x40210014, + 0x34210001, + 0x330106ec, + 0x430106fb, + 0x44200003, + 0xfbfffaa7, + 0xe0000002, + 0xfbfffa80, + 0x330106e9, + 0x430106e8, + 0xb0200800, + 0x5b0106d8, + 0xe0000006, + 0x430106ec, + 0x34210001, + 0x330106ec, + 0xfbfffa5d, + 0x330106e9, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0x430306ec, + 0xc8220800, + 0x3c210002, + 0x206300ff, + 0xb42c0800, + 0x40210014, + 0x50230074, + 0x340b0000, + 0x330b06ec, + 0x430206e8, + 0x430106e9, + 0xb0401000, + 0xb0200800, + 0x4441006d, + 0x34010001, + 0x7802c020, + 0x330106ea, + 0x38420130, + 0x28410000, + 0x7805c020, + 0x38a50014, + 0x38210002, + 0x58410000, + 0x28a40000, + 0x7802fc1f, + 0x780303e0, + 0x430106e9, + 0x3842ffff, + 0x38630000, + 0xb0200800, + 0x3c210015, + 0xa0822000, + 0xa0230800, + 0xb8812000, + 0x58a40000, + 0xfbfffe1a, + 0x5c2b0056, + 0x330b06ea, + 0xe0000054, + 0x430106e6, + 0x64210001, + 0x5c20004f, + 0x430106e4, + 0x64210001, + 0x5c20004c, + 0x430106e5, + 0x64210001, + 0x5c200049, + 0x430106fe, + 0x64210001, + 0x5c200046, + 0x430106e8, + 0x2b0206d8, + 0xb0200800, + 0x4c220042, + 0x430106eb, + 0x34210001, + 0x330106eb, + 0xfbfffa03, + 0x330106e9, + 0x330b06ed, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0x430306eb, + 0xc8220800, + 0x3c210002, + 0x206300ff, + 0xb42c0800, + 0x40210013, + 0x50230034, + 0x430206e8, + 0x430106e9, + 0xb0401000, + 0xb0200800, + 0x44410029, + 0x430306e9, + 0xb9601000, + 0xb0601800, + 0x3c610003, + 0xc8230800, + 0x3c210002, + 0xb42c0800, + 0x28210000, + 0xf80019a8, + 0x2f02073c, + 0x2f010748, + 0x5422001d, + 0x34010001, + 0x330106ea, + 0x330b06eb, + 0x330b06ec, + 0x7802c020, + 0x330b06ed, + 0x38420130, + 0x28410000, + 0x7805c020, + 0x38a50014, + 0x38210002, + 0x58410000, + 0x28a40000, + 0x7802fc1f, + 0x780303e0, + 0x430106e9, + 0x3842ffff, + 0x38630000, + 0xb0200800, + 0x3c210015, + 0xa0822000, + 0xa0230800, + 0xb8812000, + 0x58a40000, + 0xfbfffcde, + 0x5c200009, + 0x330106ea, + 0xe0000007, + 0x430106eb, + 0x3421ffff, + 0x330106eb, + 0xe0000003, + 0x430106e8, + 0x330106e9, + 0x430106e8, + 0x2b0206d8, + 0xb0200800, + 0x48410018, + 0x430106ed, + 0x34210001, + 0x330106ed, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0x430306ed, + 0xc8220800, + 0x3c210002, + 0x206300ff, + 0xb42c0800, + 0x40210015, + 0x5023000b, + 0x34010000, + 0x330106ed, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb42c0800, + 0x28210000, + 0x0f010748, + 0x430106ea, + 0x202100ff, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xf8000eec, + 0xb8206000, + 0xf8000f89, + 0xb8203000, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x430106fa, + 0x202100ff, + 0xb8202800, + 0xb8202000, + 0x44200003, + 0xd00b0000, + 0xe000000c, + 0x78030003, + 0x78020002, + 0x38638b24, + 0x384230a4, + 0x4d800002, + 0x34040001, + 0x4cc00002, + 0x34050001, + 0xb8850800, + 0x44200004, + 0xd00b0000, + 0x34010001, + 0xe0000005, + 0x58620000, + 0xfbfffd02, + 0xd00b0000, + 0xfbfffb15, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x430106ef, + 0x7c210001, + 0x5c200009, + 0x430106e8, + 0xb0200800, + 0xb4210800, + 0xb4380800, + 0x342106f8, + 0x2c220008, + 0x34420001, + 0x0c220008, + 0xc3a00000, + 0x7804c020, + 0x38840130, + 0x28820000, + 0x202100ff, + 0x3c210005, + 0x3403fc1f, + 0xa0431000, + 0xb8411000, + 0x58820000, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x7805c020, + 0x38a50024, + 0x28a80000, + 0x7804c020, + 0x780b0003, + 0x34070000, + 0x7802c020, + 0x65010003, + 0x38840008, + 0x396bf900, + 0x3842002c, + 0x340300e0, + 0xb8e03000, + 0x44270015, + 0x58a70000, + 0x28420000, + 0x7801c020, + 0x38210028, + 0x44470004, + 0x28210000, + 0x08210064, + 0x8c223000, + 0x5b0606c4, + 0x28810000, + 0x28820000, + 0x38420030, + 0x58820000, + 0x58810000, + 0x58a80000, + 0x2b0206c4, + 0x29610018, + 0x3c420008, + 0xfbfff78d, + 0x59610018, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78010003, + 0x3821f900, + 0x28210008, + 0x20220001, + 0x64410000, + 0x5c20001c, + 0x430106ef, + 0x5c20001b, + 0x430106f0, + 0x340b0001, + 0x5c200018, + 0x330b06ee, + 0xfbfffd7a, + 0x78010003, + 0x3821f000, + 0x402502f1, + 0x78030003, + 0x78040002, + 0x78010003, + 0x78020003, + 0x38218ba8, + 0x38638b24, + 0x3884e6e0, + 0x38422680, + 0x58620058, + 0x302b0016, + 0x30250000, + 0x5864002c, + 0x30250019, + 0x302b0024, + 0x302b000b, + 0x302b002f, + 0xe0000002, + 0x330206ee, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x430106ef, + 0x78070003, + 0x38e7f054, + 0x34060000, + 0x5c26004b, + 0x430106f0, + 0x5c260049, + 0x78020003, + 0x3842f000, + 0x4041004c, + 0xb8c02000, + 0x50c10020, + 0xb8405800, + 0x340a0001, + 0x3c830003, + 0x34890001, + 0xc8641000, + 0x3c420002, + 0x34050001, + 0xb4471000, + 0x40410011, + 0xb8404000, + 0xb8401800, + 0x44200007, + 0x2b010730, + 0xbd441000, + 0x80240800, + 0xa0250800, + 0x5c200002, + 0xb8c23000, + 0x2b010730, + 0x80240800, + 0x20210001, + 0x64210000, + 0x5c200002, + 0x30650011, + 0x41010011, + 0x44200002, + 0x33040734, + 0x4161004c, + 0x212400ff, + 0x50810002, + 0xe3ffffe4, + 0x5b06072c, + 0x2b020730, + 0x78010003, + 0x3821f900, + 0x2b03072c, + 0x340b0001, + 0xb8431000, + 0x30220024, + 0x330b06ee, + 0xfbfffd29, + 0x78010003, + 0x3821f000, + 0x402202f1, + 0x78050003, + 0x38a5f818, + 0x78010003, + 0x38218ba8, + 0x30220000, + 0x30220019, + 0x302b0016, + 0x302b0024, + 0x302b000b, + 0x302b002f, + 0x28a10000, + 0x78030003, + 0x78040002, + 0xb82b0800, + 0x58a10000, + 0x78020003, + 0x38638b24, + 0x3884e6e0, + 0x38422680, + 0x34010000, + 0x58620058, + 0x5864002c, + 0x5b010738, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x34010000, + 0x78030003, + 0x330106ee, + 0x3863f818, + 0x28610000, + 0x3402fffe, + 0xa0220800, + 0x58610000, + 0xc3a00000, + 0x2b2502c0, + 0x78040fff, + 0x7806f000, + 0x3884ffff, + 0x206300ff, + 0x38c60000, + 0x202700ff, + 0xa0442000, + 0x20a50100, + 0xb8604000, + 0x44a00002, + 0x44600013, + 0x44600005, + 0x2b2102c0, + 0x3402feff, + 0xa0220800, + 0x5b2102c0, + 0x2b2102c0, + 0x3402ff00, + 0x34080001, + 0xa0220800, + 0xb8270800, + 0x5b2102c0, + 0x2b2102c4, + 0xa0260800, + 0xb8240800, + 0x5b2102c4, + 0x2b2102c0, + 0x38210100, + 0x5b2102c0, + 0xb9000800, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x4304092c, + 0x34020000, + 0x3401005d, + 0x7c840001, + 0xb8401800, + 0x5c820006, + 0xfbffffd8, + 0x34020000, + 0x44220003, + 0x3302092b, + 0x3302092c, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x430106ef, + 0x78030003, + 0x3863f054, + 0x4420002f, + 0x780b0003, + 0xb9600800, + 0x3821f000, + 0x282102fc, + 0x4420002a, + 0x430106e6, + 0x5c20000a, + 0x430106e4, + 0x5c200008, + 0x430106e5, + 0x5c200006, + 0x430106fe, + 0x5c200004, + 0x43020734, + 0x204200ff, + 0xe0000003, + 0x430206e8, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb4230800, + 0x28220004, + 0x2b010738, + 0x5c200003, + 0x5b020738, + 0xe0000005, + 0x2b010738, + 0x340300c0, + 0xfbfff6ab, + 0x5b010738, + 0x396bf000, + 0x296202fc, + 0x2b010738, + 0x5022000c, + 0x43010735, + 0x4420000a, + 0x340100ff, + 0x34020001, + 0x34030000, + 0xfbffffa1, + 0x44200005, + 0x34010000, + 0x33010735, + 0x34010001, + 0x3301092b, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbffffb5, + 0xfbffffc4, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x780dc020, + 0xb9a01000, + 0x38420130, + 0x28410000, + 0x340c0000, + 0x38210001, + 0x58410000, + 0xfbfffed3, + 0x78010003, + 0x38218ba8, + 0xb5815800, + 0x41630000, + 0x44600013, + 0x41620019, + 0x218100ff, + 0x3442ffff, + 0x31620019, + 0x204200ff, + 0x44400004, + 0x41620032, + 0x64420001, + 0x4440000a, + 0x31630019, + 0xfbfffeb9, + 0x3d810002, + 0x78020003, + 0x38428b24, + 0xb4220800, + 0x28210000, + 0xd8200000, + 0x31610032, + 0x358c0001, + 0x75810018, + 0x4420ffe7, + 0xfbfffea2, + 0xfbffffd1, + 0x43010830, + 0x44200011, + 0x43010831, + 0x7c210010, + 0x5c200003, + 0xf8003518, + 0xe000000c, + 0x43010831, + 0x4420000a, + 0x43010831, + 0x7c210001, + 0x5c200003, + 0xf800347f, + 0xe0000005, + 0x43010831, + 0x7c210002, + 0x5c200002, + 0xf800348a, + 0x3401001f, + 0xfbfffe99, + 0xb9a00800, + 0x38210130, + 0x28220000, + 0x3403fffe, + 0xa0431000, + 0x58220000, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0xb8202000, + 0x206300ff, + 0x90003000, + 0x34010000, + 0xd0010000, + 0xa4402800, + 0x44600004, + 0x28810000, + 0xb8220800, + 0xe0000003, + 0x28810000, + 0xa0250800, + 0x58810000, + 0xd0060000, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0008, + 0x5b9d0004, + 0x43010813, + 0x202400ff, + 0x5c800019, + 0x43010814, + 0x7c210001, + 0x5c200016, + 0x78030003, + 0x78020002, + 0x78010003, + 0x38218ba8, + 0x38638b24, + 0x38424a68, + 0x30240006, + 0x3024001f, + 0x58620018, + 0x33040814, + 0x33040812, + 0x78030003, + 0x330407ae, + 0x3863fdd0, + 0x28620000, + 0x7801ff00, + 0x3821ffff, + 0xa0411000, + 0x58620000, + 0x330406e6, + 0xe0000045, + 0x34010001, + 0x7802c030, + 0x33010814, + 0x38420000, + 0x28410010, + 0x378b000c, + 0x28420014, + 0x202107ff, + 0x204207ff, + 0xfbfff6db, + 0x0f01080c, + 0x43010815, + 0xb9602800, + 0x3381000c, + 0x43010816, + 0x3381000d, + 0x430106e6, + 0x3381000f, + 0x2f01080c, + 0x2f020804, + 0x2021ffff, + 0x2f030806, + 0xdc401000, + 0x43040819, + 0xdc601800, + 0x208400ff, + 0xfbfff6ab, + 0x4382000c, + 0x78010003, + 0x3821f000, + 0x33020815, + 0x4382000d, + 0x33020816, + 0x402102f2, + 0x44200002, + 0x4381000f, + 0x330106e6, + 0x78010003, + 0x38218b20, + 0x28210000, + 0x402100d3, + 0x44200004, + 0x4382000f, + 0x330207ae, + 0xe0000002, + 0x330107ae, + 0x43010817, + 0xb9602800, + 0x3381000c, + 0x43010818, + 0x3381000d, + 0x430102bd, + 0x3381000e, + 0x2f01080e, + 0x2f020808, + 0x2021ffff, + 0x2f03080a, + 0xdc401000, + 0x43040819, + 0xdc601800, + 0x208400ff, + 0xfbfff663, + 0x4381000c, + 0x33010817, + 0x4382000d, + 0x33020818, + 0x4381000e, + 0x330102bd, + 0x34010000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x34060000, + 0x78050003, + 0x330607ae, + 0x38a5fdd0, + 0x28a30000, + 0x7801ff00, + 0x3821ffff, + 0x43020812, + 0xa0611800, + 0x78040003, + 0x204200ff, + 0x3c420010, + 0x78010002, + 0xb8621800, + 0x58a30000, + 0x330606e6, + 0x38848b24, + 0x38214aac, + 0x58810018, + 0x34020001, + 0x78010003, + 0x33020813, + 0x38218b20, + 0x28220000, + 0x78040003, + 0x3884f820, + 0x2c4100d4, + 0x78030003, + 0x38638ba8, + 0x0f010804, + 0x2c4100d6, + 0x0f010806, + 0x2c4100d4, + 0x0f010808, + 0x2c4100d6, + 0x0f01080a, + 0x28810000, + 0x2021ff00, + 0x00210008, + 0x30610006, + 0x3061001f, + 0xc3a00000, + 0x34010000, + 0x33010813, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2f0107f0, + 0x78030002, + 0x34020000, + 0x38634e00, + 0x44220009, + 0x0f0207f0, + 0x2b0207e8, + 0x34010001, + 0x5c430005, + 0x2b0207ec, + 0xd8400000, + 0x2b0107ec, + 0x5b0107e8, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x78010003, + 0x38218b20, + 0x430207b0, + 0x28230000, + 0xb0401000, + 0xb8400800, + 0x44400010, + 0xe0000003, + 0xb8400800, + 0xc3a00000, + 0x430107b0, + 0xb0200800, + 0x3422ffff, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4231800, + 0x40610000, + 0x3463ffec, + 0x5c20fff5, + 0x3442ffff, + 0xe3fffffc, + 0xc3a00000, + 0x78010003, + 0x38218b20, + 0x28240000, + 0x430107b0, + 0x288300c4, + 0xb0200800, + 0x34220001, + 0x5043000e, + 0x3c410002, + 0xb8602800, + 0xb4220800, + 0x3c210002, + 0xb4241800, + 0x40610000, + 0x34630014, + 0x44200003, + 0xb8400800, + 0xc3a00000, + 0x34420001, + 0x50450002, + 0xe3fffff9, + 0x430107b0, + 0xb0200800, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x202b00ff, + 0x5d60002a, + 0x78020003, + 0xb8406000, + 0x38428dc5, + 0x40410000, + 0x5c20001f, + 0xfbffffc6, + 0x430207b0, + 0xb0401000, + 0x5c220006, + 0x78010003, + 0x38218dc4, + 0x34020007, + 0x30220000, + 0xe0000008, + 0xfbffffd4, + 0x430207b0, + 0xb0401000, + 0x5c220004, + 0x78010003, + 0x38218dc4, + 0x302b0000, + 0x2f0107f0, + 0xb9805800, + 0x396b8dc5, + 0x2f0207f2, + 0x2021ffff, + 0x2042ffff, + 0xfbfff568, + 0x78020003, + 0x38428dc4, + 0x40420000, + 0x3421ffff, + 0x31610000, + 0x5b0207a0, + 0xe000000d, + 0x3421ffff, + 0x30410000, + 0x430107b0, + 0xb0200800, + 0x5b0107a0, + 0xe0000007, + 0x7d610001, + 0x5c200005, + 0x78010003, + 0x38218dc5, + 0x34020000, + 0x30220000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2f0207f0, + 0x34010001, + 0x44400007, + 0x2b0207e8, + 0x5b0207ec, + 0xfbffffbf, + 0x78010002, + 0x38214e00, + 0x5b0107e8, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x28430000, + 0xb8402000, + 0x7806ff00, + 0x2842001c, + 0xb8202800, + 0x38c6ffff, + 0xc8621800, + 0x3c620003, + 0x34010000, + 0xb4431000, + 0xb4431000, + 0x58820004, + 0x4c220004, + 0x28810020, + 0xa0260800, + 0x5c200004, + 0x28810008, + 0xb4220800, + 0x58810008, + 0x28820008, + 0x28a10008, + 0x4c410002, + 0xe0000003, + 0x28a10004, + 0x4c220002, + 0x58810008, + 0x28a10000, + 0x28820008, + 0x28a30014, + 0x94411000, + 0xb4431000, + 0x5882000c, + 0xc3a00000, + 0x2846000c, + 0xb8202800, + 0xb8402000, + 0x2821001c, + 0x28420010, + 0x34070000, + 0xa0c10800, + 0xb4411000, + 0x58820010, + 0x28a3001c, + 0xc8430800, + 0x3421ffff, + 0x50620003, + 0x58810010, + 0x34070001, + 0x28a10020, + 0x80c10800, + 0xb4270800, + 0x58810014, + 0x28a20018, + 0x50410002, + 0x58820014, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x202100ff, + 0x780b0003, + 0x7c230001, + 0x396b8b20, + 0x3702078c, + 0x5c200009, + 0x29610000, + 0x342100a0, + 0xfbffffbd, + 0x29610000, + 0x3702078c, + 0x342100a0, + 0xfbffffda, + 0xe0000004, + 0x5c600003, + 0x34010000, + 0x5b010794, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x78010003, + 0x38218b20, + 0x430207b0, + 0x28230000, + 0xb0401000, + 0xb8400800, + 0x44400011, + 0xe0000003, + 0xb8400800, + 0xc3a00000, + 0x430107b0, + 0xb0200800, + 0x3422ffff, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4230800, + 0x34230011, + 0x40610000, + 0x3463ffec, + 0x5c20fff4, + 0x3442ffff, + 0xe3fffffc, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x78010003, + 0x38218b20, + 0x282c0000, + 0x7802c050, + 0x384200d8, + 0x28410000, + 0x4420ffff, + 0x340b0000, + 0x7801c020, + 0xb9601800, + 0x38210130, + 0x330b07b2, + 0x34020004, + 0xfbfffe5b, + 0x430207b1, + 0x78030003, + 0x38638b88, + 0xb0401000, + 0x3c410002, + 0x7808c020, + 0xb4220800, + 0x3c210002, + 0x39080014, + 0xb42c0800, + 0x2821000c, + 0x7806e3ff, + 0x78071c00, + 0x58610004, + 0x430107b1, + 0x38c6ffff, + 0x38e70000, + 0x330107b0, + 0x430207b1, + 0x78050003, + 0x78040002, + 0xb0401000, + 0x3c410002, + 0x38a58b24, + 0xb4220800, + 0x3c210002, + 0x388456c0, + 0xb42c0800, + 0x40220010, + 0x5b0207a8, + 0x29030000, + 0xb9600800, + 0x430207b0, + 0xa0661800, + 0x3c42001a, + 0x58a40004, + 0xa0471000, + 0xb8621800, + 0x59030000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x38218b20, + 0x28260000, + 0x7802c050, + 0x384200d8, + 0x28410000, + 0x4420ffff, + 0x430207b1, + 0x78030003, + 0x38638b88, + 0xb0401000, + 0x3c410002, + 0x7805c020, + 0xb4220800, + 0x3c210002, + 0x38a50014, + 0xb4260800, + 0x2821000c, + 0x78041c00, + 0x38840000, + 0x58610004, + 0x430107b1, + 0x7803e3ff, + 0x3863ffff, + 0x330107b0, + 0x430207b1, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4260800, + 0x40210010, + 0x5b0107a8, + 0x28a20000, + 0x430107b0, + 0xa0431000, + 0x3c21001a, + 0xa0240800, + 0xb8411000, + 0x58a20000, + 0x430107b2, + 0x202400ff, + 0x5c800027, + 0x430107b6, + 0x5c200010, + 0x7801c020, + 0x38210114, + 0x58240000, + 0x330407b7, + 0x78030003, + 0x78020002, + 0x78010003, + 0x33040761, + 0x38218ba8, + 0x38638b24, + 0x38424a68, + 0x58620004, + 0x3024001a, + 0x30240001, + 0xe0000021, + 0x430107b8, + 0x7803c020, + 0x78050003, + 0x44200009, + 0x78010002, + 0x38630114, + 0x38a58b24, + 0x38215e24, + 0x58a10004, + 0x58640000, + 0x330407b7, + 0xe0000015, + 0x34020001, + 0x38630114, + 0x58620000, + 0x78010002, + 0x330207b7, + 0x38a58b24, + 0x382156c0, + 0x58a10004, + 0xe000000c, + 0x34030000, + 0x7801c020, + 0x38210130, + 0x34020004, + 0x330307b2, + 0xfbfffdd6, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x382156c0, + 0x58410004, + 0x34010000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x202100ff, + 0x3c220002, + 0x78030003, + 0xb4411000, + 0x38638b20, + 0x28610000, + 0x3c420002, + 0xb4411000, + 0x40410011, + 0x5c200004, + 0x40410000, + 0xb8201000, + 0x44200002, + 0x34020001, + 0xb8400800, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x430107b2, + 0x5c200038, + 0x780d0003, + 0x78010002, + 0x38215380, + 0x39ad8b24, + 0x59a10004, + 0x430107b8, + 0x44200004, + 0x430107b9, + 0x330107b1, + 0xe0000028, + 0x780c0003, + 0x398c8b20, + 0x29810000, + 0x402b00ca, + 0x216100ff, + 0xfbffffd8, + 0x44200006, + 0x330b07b1, + 0x29810000, + 0x402100c9, + 0x33010761, + 0xe000001c, + 0x430107b6, + 0x7802c020, + 0x202300ff, + 0x5c60000d, + 0x38420114, + 0x58430000, + 0x330307b7, + 0x78020002, + 0x78010003, + 0x33030761, + 0x38218ba8, + 0x38424a68, + 0x59a20004, + 0x3023001a, + 0x30230001, + 0xe0000099, + 0x34010001, + 0x38420114, + 0x58410000, + 0x330107b7, + 0x29820000, + 0x78010002, + 0x382156c0, + 0x59a10004, + 0x404100c9, + 0x33010761, + 0xe000008e, + 0x34030001, + 0x7801c020, + 0x330307b2, + 0x38210130, + 0x34020004, + 0xfbfffd7d, + 0x430207b1, + 0x780e0003, + 0x39ce8b20, + 0xb0401000, + 0x3c410002, + 0x29c30000, + 0xb4220800, + 0x3c210002, + 0x34020001, + 0xb4230800, + 0x28210004, + 0x340b0000, + 0x780dc050, + 0x2021ffff, + 0xf8001524, + 0x330b07b5, + 0x330b07b3, + 0x330b07b4, + 0x7804c020, + 0x330b07b5, + 0x38840014, + 0x28830000, + 0x78011fff, + 0x3821ffff, + 0x430207b1, + 0xa0611800, + 0x7801c020, + 0x3c42001d, + 0x38210130, + 0xb8621800, + 0x58830000, + 0x34020004, + 0x330b07b2, + 0xb9601800, + 0xfbfffd5a, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x382151b8, + 0x58410004, + 0x430207b1, + 0x29c70000, + 0x39ad00d4, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4270800, + 0x40210001, + 0x59a10000, + 0x430207b1, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4270800, + 0x40210012, + 0x20280008, + 0x450b0010, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x3402fe3f, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x34020001, + 0x38210002, + 0x58810000, + 0x59ab0000, + 0x33020919, + 0xe000003d, + 0x430107b1, + 0x780cc050, + 0x780fc050, + 0xb0200800, + 0x3c220002, + 0xb4411000, + 0x3c420002, + 0xb4471000, + 0x40410012, + 0x20210002, + 0x4420001b, + 0xb9802000, + 0x388401c8, + 0x28830000, + 0x3401fe3f, + 0xb9e02800, + 0x430207b1, + 0xa0611800, + 0x38a50118, + 0xb0401000, + 0x3c410002, + 0x34060001, + 0xb4220800, + 0x3c210002, + 0x3402fffd, + 0xb4270800, + 0x40210012, + 0x3c210006, + 0x202101c0, + 0xb8611800, + 0x58830000, + 0x28a10000, + 0xa0220800, + 0x58a10000, + 0x59a80000, + 0x33060919, + 0xe0000018, + 0x330b0919, + 0xf8001c2d, + 0x430207b1, + 0x29c30000, + 0xb9802800, + 0xb0401000, + 0x3c410002, + 0x38a501c8, + 0xb4220800, + 0x3c210002, + 0x3402fe3f, + 0xb4230800, + 0x40210001, + 0xb9e02000, + 0x38840118, + 0x59a10000, + 0x28a10000, + 0xa0220800, + 0x58a10000, + 0x28810000, + 0x3402fffd, + 0xa0220800, + 0x58810000, + 0xfbfffec8, + 0x34010000, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cffe4, + 0x5b8b001c, + 0x5b8c0018, + 0x5b8d0014, + 0x5b8e0010, + 0x5b8f000c, + 0x5b900008, + 0x5b9d0004, + 0x780d0003, + 0xb9a00800, + 0x38218b20, + 0x282c0000, + 0xb9a07000, + 0x430107b6, + 0x44200004, + 0x430107b8, + 0x64210001, + 0x44200004, + 0xfbffff1e, + 0x34010000, + 0xe00001bc, + 0x430107c5, + 0x7c210001, + 0x5c200028, + 0x34010000, + 0x330107c5, + 0x430207b0, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb42c0800, + 0x402b0000, + 0x5d60003e, + 0xfbfffd96, + 0x430207b0, + 0xb0401000, + 0x4422000c, + 0x34010007, + 0x5b0107a0, + 0x430207b0, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb42c0800, + 0x4021000a, + 0x330107b3, + 0xe000002f, + 0xfbfffd70, + 0x430207b0, + 0xb0401000, + 0x4422002b, + 0x5b0b07a0, + 0x430107b0, + 0xb0200800, + 0x3c220002, + 0xb4411000, + 0x3c420002, + 0xb44c1000, + 0x4041000b, + 0x330107b4, + 0xe0000021, + 0x7805c020, + 0xb8a01000, + 0x38420114, + 0x7803c020, + 0x34010000, + 0x58410000, + 0x38630118, + 0x28640000, + 0x4c80ffff, + 0x780200ff, + 0x3842ffff, + 0x7801c020, + 0xa0821000, + 0x3821011c, + 0x28210000, + 0x08420064, + 0x38a50114, + 0x780b0003, + 0x8c411000, + 0x396bf900, + 0x340300e0, + 0x5b02078c, + 0x34010001, + 0x58a10000, + 0x2b02078c, + 0x29610020, + 0x3c420008, + 0xfbfff2d6, + 0x2b0207e8, + 0x59610020, + 0x34010000, + 0xd8400000, + 0x430107b2, + 0x202b00ff, + 0x5d60016e, + 0x430107b0, + 0x2b0207a0, + 0xb0200800, + 0x54220004, + 0x430107ae, + 0x64210002, + 0x442000a5, + 0x430107ae, + 0x7c210002, + 0x5c200015, + 0x34010001, + 0x330107ae, + 0x430307b0, + 0xb9c01000, + 0x38428b20, + 0xb0601800, + 0x3c610002, + 0x28420000, + 0xb4230800, + 0x3c210002, + 0xb4220800, + 0x4021000b, + 0x34210001, + 0x330107b4, + 0xfbfffdee, + 0x330107b1, + 0x430107b0, + 0xb0200800, + 0x5b0107a0, + 0xe0000006, + 0x430107b4, + 0x34210001, + 0x330107b4, + 0xfbfffd1e, + 0x330107b1, + 0x430207b0, + 0x780d0003, + 0x39ad8b20, + 0xb0401000, + 0x3c410002, + 0x29a30000, + 0xb4220800, + 0x3c210002, + 0x430207b4, + 0xb4230800, + 0x4021000b, + 0x204200ff, + 0x5022011f, + 0x34100000, + 0x331007b4, + 0x430207b0, + 0x430107b1, + 0xb0401000, + 0xb0200800, + 0x44410118, + 0x340f0001, + 0x7801c020, + 0x38210130, + 0x34020004, + 0xb9e01800, + 0x330f07b2, + 0xfbfffc4d, + 0x7805c020, + 0x38a50014, + 0x28a40000, + 0x78011fff, + 0x3821ffff, + 0x430207b1, + 0xa0812000, + 0x78030003, + 0x3c42001d, + 0x78010002, + 0xb8822000, + 0x382150c0, + 0x38638b24, + 0x58a40000, + 0x58610004, + 0x430207b1, + 0x29a60000, + 0x780cc050, + 0xb0401000, + 0x3c410002, + 0x398c00d4, + 0xb4220800, + 0x3c210002, + 0xb4260800, + 0x40210001, + 0x59810000, + 0x430207b1, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4260800, + 0x40210012, + 0x20270008, + 0x44f0000e, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x3402fe3f, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x38210002, + 0x58810000, + 0x59900000, + 0xe0000023, + 0x430107b1, + 0x780bc050, + 0x780ec050, + 0xb0200800, + 0x3c220002, + 0xb4411000, + 0x3c420002, + 0xb4461000, + 0x40410012, + 0x20210002, + 0x4420001a, + 0xb9602000, + 0x388401c8, + 0x28830000, + 0x3401fe3f, + 0xb9c02800, + 0x430207b1, + 0xa0611800, + 0x38a50118, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0x3402fffd, + 0xb4260800, + 0x40210012, + 0x3c210006, + 0x202101c0, + 0xb8611800, + 0x58830000, + 0x28a10000, + 0xa0220800, + 0x58a10000, + 0x59870000, + 0x330f0919, + 0xe0000018, + 0x33100919, + 0xf8001b18, + 0x430207b1, + 0x29a30000, + 0xb9602800, + 0xb0401000, + 0x3c410002, + 0x38a501c8, + 0xb4220800, + 0x3c210002, + 0x3402fe3f, + 0xb4230800, + 0x40210001, + 0xb9c02000, + 0x38840118, + 0x59810000, + 0x28a10000, + 0xa0220800, + 0x58a10000, + 0x28810000, + 0x3402fffd, + 0xa0220800, + 0x58810000, + 0xfbfffd75, + 0xe00000a4, + 0x430107ae, + 0x7c210001, + 0x442000a1, + 0x430107b0, + 0x2b0207a0, + 0xb0200800, + 0x5022009d, + 0x430107b3, + 0xb9a07800, + 0x39ef8b20, + 0x34210001, + 0x330107b3, + 0xfbfffc9f, + 0x330107b1, + 0x330b07b5, + 0x430207b0, + 0x29e40000, + 0xb0401000, + 0x3c410002, + 0x430307b3, + 0xb4220800, + 0x3c210002, + 0x206300ff, + 0xb4240800, + 0x4021000a, + 0x5023008a, + 0x430207b0, + 0x430107b1, + 0xb0401000, + 0xb0200800, + 0x44410082, + 0x430307b1, + 0x34020001, + 0xb8406800, + 0xb0601800, + 0x3c610002, + 0x780cc050, + 0xb4230800, + 0x3c210002, + 0x398c00d4, + 0xb4240800, + 0x28210004, + 0x2021ffff, + 0xf800136a, + 0x7801c020, + 0x38210130, + 0x34020004, + 0xb9a01800, + 0x330d07b2, + 0xfbfffbae, + 0x330b07b3, + 0x330b07b4, + 0x7805c020, + 0x330b07b5, + 0x38a50014, + 0x28a40000, + 0x78011fff, + 0x3821ffff, + 0x430207b1, + 0xa0812000, + 0x78030003, + 0x3c42001d, + 0x78010002, + 0xb8822000, + 0x382151b8, + 0x38638b24, + 0x58a40000, + 0x58610004, + 0x430207b1, + 0x29e60000, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4260800, + 0x40210001, + 0x59810000, + 0x430207b1, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4260800, + 0x40210012, + 0x20270008, + 0x44e0000e, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x3402fe3f, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x38210002, + 0x58810000, + 0x598b0000, + 0xe0000023, + 0x430107b1, + 0x780bc050, + 0x780ec050, + 0xb0200800, + 0x3c220002, + 0xb4411000, + 0x3c420002, + 0xb4461000, + 0x40410012, + 0x20210002, + 0x4420001a, + 0xb9602000, + 0x388401c8, + 0x28830000, + 0x3401fe3f, + 0xb9c02800, + 0x430207b1, + 0xa0611800, + 0x38a50118, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0x3402fffd, + 0xb4260800, + 0x40210012, + 0x3c210006, + 0x202101c0, + 0xb8611800, + 0x58830000, + 0x28a10000, + 0xa0220800, + 0x58a10000, + 0x59870000, + 0x330d0919, + 0xe0000018, + 0x33010919, + 0xf8001a78, + 0x430207b1, + 0x29e30000, + 0xb9602800, + 0xb0401000, + 0x3c410002, + 0x38a501c8, + 0xb4220800, + 0x3c210002, + 0x3402fe3f, + 0xb4230800, + 0x40210001, + 0xb9c02000, + 0x38840118, + 0x59810000, + 0x28a10000, + 0xa0220800, + 0x58a10000, + 0x28810000, + 0x3402fffd, + 0xa0220800, + 0x58810000, + 0xfbfffd13, + 0xe0000004, + 0x430107b3, + 0x3421ffff, + 0x330107b3, + 0x430107b0, + 0x2b0207a0, + 0xb0200800, + 0x5441001c, + 0x430107b5, + 0x78050003, + 0x38a58b20, + 0x34210001, + 0x330107b5, + 0x430207b0, + 0x28a40000, + 0xb0401000, + 0x3c410002, + 0x430307b5, + 0xb4220800, + 0x3c210002, + 0x206300ff, + 0xb4240800, + 0x40210003, + 0x5023000c, + 0x34010000, + 0x330107b5, + 0x430207b0, + 0x28a30000, + 0xb0401000, + 0x3c410002, + 0xb4220800, + 0x3c210002, + 0xb4230800, + 0x28210004, + 0x0f01074a, + 0x34010001, + 0x2b8b001c, + 0x2b8c0018, + 0x2b8d0014, + 0x2b8e0010, + 0x2b8f000c, + 0x2b900008, + 0x2b9d0004, + 0x379c001c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x430107b8, + 0x7805c020, + 0x78040003, + 0x78020002, + 0x38a50114, + 0x34060001, + 0x38848b24, + 0x384256c0, + 0x202100ff, + 0x34030000, + 0x44230008, + 0x430207b9, + 0x430107b0, + 0x204200ff, + 0xb0200800, + 0x44410007, + 0xfbfffd45, + 0xe0000004, + 0x58a60000, + 0x330607b7, + 0x58820004, + 0xb8201800, + 0xb8600800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x38218b20, + 0x28210000, + 0x402100c8, + 0x44200010, + 0x430107b7, + 0x5c20000f, + 0x430107b8, + 0x34020001, + 0x5c20000c, + 0x330207b6, + 0xfbfffd2e, + 0x78010003, + 0x3821f820, + 0x28220000, + 0x78010003, + 0x38218ba8, + 0x30220001, + 0x3022001a, + 0xe0000002, + 0x330107b6, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x430107b7, + 0x340b0000, + 0x5c2b002b, + 0x430107b8, + 0x5c2b0029, + 0x34010001, + 0x330107b6, + 0xfbfffd17, + 0x78010003, + 0x3821f820, + 0x28220000, + 0x78030003, + 0x3863f818, + 0x78010003, + 0x38218ba8, + 0x30220001, + 0x3022001a, + 0x28620000, + 0x78010003, + 0x38218b20, + 0x28210000, + 0x38420004, + 0x58620000, + 0x282300c4, + 0xb9601000, + 0x51630011, + 0xb8202800, + 0xb8602000, + 0x34060001, + 0x3c410002, + 0xbcc21800, + 0xb4220800, + 0x3c210002, + 0x34420001, + 0xb4250800, + 0x40210000, + 0xb9631800, + 0x204200ff, + 0x44200002, + 0x206b00ff, + 0x50440002, + 0xe3fffff4, + 0x78010003, + 0x3821f900, + 0x302b0026, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x34010000, + 0x78030003, + 0x330107b6, + 0x3863f818, + 0x28610000, + 0x3402fffb, + 0xa0220800, + 0x58610000, + 0xc3a00000, + 0x202400ff, + 0x340100ff, + 0x44800011, + 0x7802c050, + 0x384200d8, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0x7801c050, + 0x382100d4, + 0x7803c050, + 0x58240000, + 0x386300d8, + 0x28610000, + 0x18210001, + 0x20220001, + 0x64410000, + 0x4420fffc, + 0xb8400800, + 0xc3a00000, + 0x7802e000, + 0x38423020, + 0x28420000, + 0x08420064, + 0x3c420008, + 0x8c411800, + 0x00610008, + 0x00620006, + 0x34240040, + 0x204200ff, + 0x34011fff, + 0x50230003, + 0x208200ff, + 0xe0000008, + 0xb4630800, + 0x3421e000, + 0x00240008, + 0x34010fff, + 0x50230003, + 0x34810040, + 0x202200ff, + 0x74410007, + 0x5c200002, + 0x34020008, + 0x204100ff, + 0xc3a00000, + 0x78020003, + 0x3842f000, + 0x4043004e, + 0x34040000, + 0x34020001, + 0xbc411000, + 0x48610002, + 0xe0000004, + 0x2b010094, + 0xa0220800, + 0x7c240000, + 0xb8800800, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780c0003, + 0x4301008a, + 0xb9801000, + 0x3842f000, + 0x4042004e, + 0x34210001, + 0x202b00ff, + 0x5162000d, + 0xb9600800, + 0xfbffffe6, + 0xb9801800, + 0x3863f000, + 0x35620001, + 0x44200003, + 0xb9600800, + 0xe0000007, + 0x4061004e, + 0x204b00ff, + 0x51610002, + 0xe3fffff5, + 0x4301008a, + 0x202100ff, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78010003, + 0x3821f000, + 0x4021004e, + 0x4302008a, + 0x3421ffff, + 0x202b00ff, + 0x204200ff, + 0x504b000c, + 0xb9600800, + 0xfbffffc8, + 0x3562ffff, + 0x44200003, + 0xb9600800, + 0xe0000008, + 0x4301008a, + 0x204b00ff, + 0x202100ff, + 0x502b0002, + 0xe3fffff6, + 0x4301008a, + 0x202100ff, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x4301008a, + 0x202100ff, + 0x342bffff, + 0x34010000, + 0x482b0008, + 0xb9600800, + 0xfbffffaf, + 0x44200003, + 0x216100ff, + 0xe0000005, + 0x356bffff, + 0xe3fffff9, + 0x4301008a, + 0x202100ff, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8206000, + 0x4021000c, + 0x20260008, + 0x44c00011, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x34028fff, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x7802c050, + 0x384200a4, + 0x38210010, + 0x58810000, + 0x34010000, + 0x58410000, + 0xe0000015, + 0x20220002, + 0x780bc050, + 0x44400015, + 0x7805c050, + 0x38a501c8, + 0x28a30000, + 0x3c21000c, + 0x34028fff, + 0xa0621800, + 0x20217000, + 0xb8611800, + 0x7804c050, + 0x58a30000, + 0x38840118, + 0x28810000, + 0x3402ffef, + 0x396b00a4, + 0xa0220800, + 0x58810000, + 0x59660000, + 0x34010001, + 0x3301091b, + 0xe0000017, + 0x3302091b, + 0xf8001906, + 0x4181000a, + 0x396b00a4, + 0x7802c050, + 0x59610000, + 0x384200a8, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x34028fff, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x3402ffef, + 0xa0220800, + 0x58810000, + 0x4181000d, + 0x20260008, + 0x44c00011, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x3402f1ff, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x7802c050, + 0x3842009c, + 0x38210008, + 0x58810000, + 0x34010000, + 0x58410000, + 0xe0000015, + 0x20220002, + 0x780bc050, + 0x44400015, + 0x7805c050, + 0x38a501c8, + 0x28a30000, + 0x3c210009, + 0x3402f1ff, + 0xa0621800, + 0x20210e00, + 0xb8611800, + 0x7804c050, + 0x58a30000, + 0x38840118, + 0x28810000, + 0x3402fff7, + 0x396b009c, + 0xa0220800, + 0x58810000, + 0x59660000, + 0x34010001, + 0x3301091c, + 0xe0000017, + 0x3302091c, + 0xf80018c6, + 0x4181000b, + 0x396b009c, + 0x7802c050, + 0x59610000, + 0x384200a0, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x3402f1ff, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x3402fff7, + 0xa0220800, + 0x58810000, + 0x29820000, + 0x78010003, + 0x38218b88, + 0x58220008, + 0x298c0004, + 0x582c000c, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2f02073c, + 0x78030003, + 0x3863f148, + 0x2f010754, + 0x34050000, + 0x54220025, + 0x4301008b, + 0x202100ff, + 0x3c210004, + 0xb4230800, + 0xfbffff64, + 0x4303008b, + 0x78020003, + 0x78010002, + 0x3303008a, + 0x38428b24, + 0x38216788, + 0x58410030, + 0x43020089, + 0x43010088, + 0x5c220009, + 0x4301008d, + 0x34030000, + 0x34020001, + 0x44230003, + 0x3303008d, + 0xe0000005, + 0x33020087, + 0xe0000003, + 0x43010088, + 0x33010089, + 0x7804e000, + 0x38843028, + 0x28830000, + 0x3402f1ff, + 0x34050001, + 0x4301008a, + 0xa0621800, + 0x3c210009, + 0x20210e00, + 0xb8611800, + 0x58830000, + 0xb8a00800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x7805e000, + 0x38a53028, + 0x28a20000, + 0x202100ff, + 0x3c230006, + 0x3404fe3f, + 0xa0441000, + 0x206301c0, + 0xb8431000, + 0x58a20000, + 0x3301008b, + 0x34030001, + 0x3c210004, + 0x78020003, + 0x33030766, + 0x3842f148, + 0x33030766, + 0xb4220800, + 0x2c210008, + 0x34020006, + 0xf80010f5, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x3821645c, + 0x58410030, + 0xfbffffb4, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x4301008c, + 0x340b0000, + 0x442b0016, + 0x330b008c, + 0x43010086, + 0x5c2b0013, + 0x4302008a, + 0x340c0001, + 0x2b010094, + 0xbd821000, + 0xa0220800, + 0x5c2b000d, + 0xfbfffec0, + 0xb8205800, + 0x4301008a, + 0x202100ff, + 0x5c2b0003, + 0xfbfffef6, + 0xb8205800, + 0x4301008a, + 0x202100ff, + 0x442b0003, + 0x330c008d, + 0xe0000049, + 0x4301008e, + 0x202c00ff, + 0x5d800025, + 0x43010086, + 0x202b00ff, + 0x65610002, + 0x5c200012, + 0x69610002, + 0x5c200004, + 0x65610001, + 0x5c200005, + 0xe0000043, + 0x65610004, + 0x5c200012, + 0xe0000040, + 0xfbfffea5, + 0x330c0086, + 0x4302008a, + 0x204200ff, + 0x5c410036, + 0x34010002, + 0x33010087, + 0xb9600800, + 0xe0000038, + 0xfbfffed7, + 0x330c0086, + 0x4302008a, + 0x204200ff, + 0x5c41002d, + 0x330b0087, + 0xe0000030, + 0xfbfffeb4, + 0x330c0086, + 0x4302008a, + 0x204200ff, + 0x5c410026, + 0x34010001, + 0x33010087, + 0xe0000029, + 0x2f01009c, + 0x5c200023, + 0x4301008e, + 0x7c210001, + 0x5c20000a, + 0xfbfffe88, + 0xb8205800, + 0x4301008a, + 0x202100ff, + 0x5c2b0011, + 0x34010002, + 0x3301008e, + 0xfbfffebc, + 0xe000000c, + 0x4301008e, + 0x7c210002, + 0x5c20000a, + 0xfbfffeb7, + 0xb8205800, + 0x4301008a, + 0x202100ff, + 0x5c2b0005, + 0x34010001, + 0x3301008e, + 0xfbfffe75, + 0xb8205800, + 0x2f010098, + 0x2f02009a, + 0x2021ffff, + 0x2042ffff, + 0xfbffef41, + 0x3421ffff, + 0x0f01009c, + 0xb9600800, + 0xfbffff7b, + 0xe0000005, + 0x2f01009c, + 0x3421ffff, + 0x0f01009c, + 0x34010001, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x2f010098, + 0x34020000, + 0x34030001, + 0x44220003, + 0x0f02009c, + 0x3303008e, + 0xc3a00000, + 0x34010000, + 0x3301008e, + 0x0f010098, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x43020088, + 0x43010089, + 0x4422006f, + 0x43010088, + 0x5c200068, + 0x430100a2, + 0x7804c050, + 0x7805c050, + 0x7806c050, + 0x5c200018, + 0x388401c8, + 0x28830000, + 0x34028fff, + 0x38a50118, + 0x4301009e, + 0xa0621800, + 0x3402ffef, + 0x3c21000c, + 0x38c600a4, + 0x20217000, + 0xb8611800, + 0x58830000, + 0x28a30000, + 0x430100a0, + 0xa0621800, + 0x3c210004, + 0x20210010, + 0xb8611800, + 0x58a30000, + 0x430100a2, + 0x202100ff, + 0x58c10000, + 0xe0000017, + 0x430100a2, + 0x38c600a4, + 0x388401c8, + 0x202100ff, + 0x58c10000, + 0x28830000, + 0x34028fff, + 0x38a50118, + 0x4301009e, + 0xa0621800, + 0x3402ffef, + 0x3c21000c, + 0x20217000, + 0xb8611800, + 0x58830000, + 0x28a30000, + 0x430100a0, + 0xa0621800, + 0x3c210004, + 0x20210010, + 0xb8611800, + 0x58a30000, + 0x430100a3, + 0x7804c050, + 0x7805c050, + 0x7806c050, + 0x5c200018, + 0x388401c8, + 0x28830000, + 0x3402f1ff, + 0x38a50118, + 0x4301009f, + 0xa0621800, + 0x3402fff7, + 0x3c210009, + 0x38c6009c, + 0x20210e00, + 0xb8611800, + 0x58830000, + 0x28a30000, + 0x430100a1, + 0xa0621800, + 0x3c210003, + 0x20210008, + 0xb8611800, + 0x58a30000, + 0x430100a3, + 0x202100ff, + 0x58c10000, + 0xe0000017, + 0x430100a3, + 0x38c6009c, + 0x388401c8, + 0x202100ff, + 0x58c10000, + 0x28830000, + 0x3402f1ff, + 0x38a50118, + 0x4301009f, + 0xa0621800, + 0x3402fff7, + 0x3c210009, + 0x20210e00, + 0xb8611800, + 0x58830000, + 0x28a30000, + 0x430100a1, + 0xa0621800, + 0x3c210003, + 0x20210008, + 0xb8611800, + 0x58a30000, + 0x34010000, + 0x33010089, + 0xe0000006, + 0x78010003, + 0x3821f000, + 0x402102e8, + 0xfbfffef4, + 0xe0000007, + 0x43010089, + 0x202100ff, + 0x44200003, + 0xfbffff0f, + 0xe0000002, + 0x33010766, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x78010003, + 0x3821f900, + 0x28210008, + 0x78060003, + 0x78070003, + 0x78050003, + 0x78040002, + 0x78030003, + 0x38c68ba8, + 0x38e7f000, + 0x38a58b24, + 0x38846788, + 0x34080001, + 0x34020000, + 0x38638b88, + 0x20210010, + 0x4422000c, + 0x40e702ec, + 0x58a40030, + 0x30c80025, + 0x30c7000c, + 0x33020086, + 0x33020766, + 0x33020089, + 0x5862000c, + 0x58620008, + 0x33080088, + 0xc3a00000, + 0x33010088, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b8e0004, + 0x43010088, + 0x7804c050, + 0x7805c050, + 0x7803c050, + 0x7806c050, + 0x78090003, + 0x780c0003, + 0x780b0003, + 0x780a0002, + 0x78070003, + 0x78080003, + 0x780d0003, + 0x388400a4, + 0x38a5009c, + 0x386301c8, + 0x38c60118, + 0x39298ba8, + 0x398cf000, + 0x396b8b24, + 0x394a6788, + 0x340e0001, + 0x38e78b88, + 0x3908f818, + 0x39adf900, + 0x202200ff, + 0x5c400026, + 0x28810000, + 0x2021007f, + 0x330100a2, + 0x28a10000, + 0x2021007f, + 0x330100a3, + 0x28610000, + 0x20217000, + 0x0021000c, + 0x3301009e, + 0x28610000, + 0x20210e00, + 0x00210009, + 0x3301009f, + 0x28c10000, + 0x20210010, + 0x00210004, + 0x330100a0, + 0x28c10000, + 0x20210008, + 0x00210003, + 0x330100a1, + 0x418c02ec, + 0x312e0025, + 0x596a0030, + 0x312c000c, + 0x33020086, + 0x33020766, + 0x33020089, + 0x58e2000c, + 0x58e20008, + 0x330e0088, + 0x29010000, + 0x38210008, + 0x59010000, + 0x2b010094, + 0x31a10028, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b8e0004, + 0x379c0010, + 0xc3a00000, + 0x34010000, + 0x78030003, + 0x33010088, + 0x3863f818, + 0x28610000, + 0x3402fff7, + 0xa0220800, + 0x58610000, + 0xc3a00000, + 0x78020003, + 0x3842f000, + 0x40430051, + 0x34040000, + 0x34020001, + 0xbc411000, + 0x48610002, + 0xe0000004, + 0x2b010108, + 0xa0220800, + 0x7c240000, + 0xb8800800, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780c0003, + 0x430100f9, + 0xb9801000, + 0x3842f000, + 0x40420051, + 0x34210001, + 0x202b00ff, + 0x5162000d, + 0xb9600800, + 0xfbffffe6, + 0xb9801800, + 0x3863f000, + 0x35620001, + 0x44200003, + 0xb9600800, + 0xe0000007, + 0x40610051, + 0x204b00ff, + 0x51610002, + 0xe3fffff5, + 0x430100f9, + 0x202100ff, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78010003, + 0x3821f000, + 0x40210051, + 0x430200f9, + 0x3421ffff, + 0x202b00ff, + 0x204200ff, + 0x504b000c, + 0xb9600800, + 0xfbffffc8, + 0x3562ffff, + 0x44200003, + 0xb9600800, + 0xe0000008, + 0x430100f9, + 0x204b00ff, + 0x202100ff, + 0x502b0002, + 0xe3fffff6, + 0x430100f9, + 0x202100ff, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x430100f9, + 0x202100ff, + 0x342bffff, + 0x34010000, + 0x482b0008, + 0xb9600800, + 0xfbffffaf, + 0x44200003, + 0x216100ff, + 0xe0000005, + 0x356bffff, + 0xe3fffff9, + 0x430100f9, + 0x202100ff, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x40230007, + 0xb8206000, + 0x20660008, + 0x44c00012, + 0x7803c050, + 0x386301c8, + 0x28620000, + 0x7801f8ff, + 0x3821ffff, + 0xa0411000, + 0x7804c050, + 0x58620000, + 0x38840118, + 0x28810000, + 0x7802c050, + 0x384200e4, + 0x38210400, + 0x58810000, + 0x34010000, + 0x58410000, + 0xe0000018, + 0x20610002, + 0x780bc050, + 0x44200018, + 0x7805c050, + 0x38a501c8, + 0x28a40000, + 0x3c630018, + 0x7801f8ff, + 0x78020700, + 0x3821ffff, + 0x38420000, + 0xa0621800, + 0xa0812000, + 0xb8832000, + 0x7803c050, + 0x58a40000, + 0x38630118, + 0x28610000, + 0x3402fbff, + 0x396b00e4, + 0xa0220800, + 0x58610000, + 0x59660000, + 0x34010001, + 0x33010921, + 0xe0000018, + 0x33010921, + 0xf800165d, + 0x41810006, + 0x396b00e4, + 0x7802c050, + 0x59610000, + 0x384200e8, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0x7804c050, + 0x388401c8, + 0x28820000, + 0x7801f8ff, + 0x3821ffff, + 0xa0411000, + 0x7803c050, + 0x58820000, + 0x38630118, + 0x28610000, + 0x3402fbff, + 0xa0220800, + 0x58610000, + 0x298c0000, + 0x78010003, + 0x38218b88, + 0x582c0010, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2f02073c, + 0x78030003, + 0x3863f288, + 0x2f01075a, + 0x34060000, + 0x5422002a, + 0x430200fa, + 0x204200ff, + 0x3c410001, + 0xb4220800, + 0x3c210002, + 0xb4230800, + 0xfbffff9f, + 0x430300fa, + 0x78020003, + 0x78010002, + 0x330300f9, + 0x38428b24, + 0x3821714c, + 0x5841003c, + 0x430200f8, + 0x430100f7, + 0x5c220009, + 0x430100fe, + 0x34030000, + 0x34020001, + 0x44230003, + 0x330300fe, + 0xe0000005, + 0x330200f6, + 0xe0000003, + 0x430100f7, + 0x330100f8, + 0x7805e000, + 0x38a53028, + 0x28a20000, + 0x7803c7ff, + 0x78043800, + 0x430100f9, + 0x3863ffff, + 0x38840000, + 0x3c21001b, + 0xa0431000, + 0xa0240800, + 0xb8411000, + 0x34060001, + 0x58a20000, + 0xb8c00800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x7807e000, + 0x38e73028, + 0x28e50000, + 0x202100ff, + 0x3c260018, + 0x7802f8ff, + 0x78040700, + 0x38840000, + 0x3842ffff, + 0xa0c43000, + 0x3c230001, + 0xa0a22800, + 0xb8a62800, + 0x58e50000, + 0xb4611800, + 0x330100fa, + 0x3c630002, + 0x78020003, + 0x3842f288, + 0x34010001, + 0xb4621800, + 0x33010769, + 0x2c610004, + 0x34020009, + 0xf8000e84, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x38216dfc, + 0x5841003c, + 0xfbffffab, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x430100fb, + 0x340b0000, + 0x442b0016, + 0x330b00fb, + 0x430100f5, + 0x5c2b0013, + 0x430200f9, + 0x340c0001, + 0x2b010108, + 0xbd821000, + 0xa0220800, + 0x5c2b000d, + 0xfbfffef4, + 0xb8205800, + 0x430100f9, + 0x202100ff, + 0x5c2b0003, + 0xfbffff2a, + 0xb8205800, + 0x430100f9, + 0x202100ff, + 0x442b0003, + 0x330c00fe, + 0xe0000049, + 0x430100ff, + 0x202c00ff, + 0x5d800025, + 0x430100f5, + 0x202b00ff, + 0x65610002, + 0x5c200012, + 0x69610002, + 0x5c200004, + 0x65610001, + 0x5c200005, + 0xe0000043, + 0x65610004, + 0x5c200012, + 0xe0000040, + 0xfbfffed9, + 0x330c00f5, + 0x430200f9, + 0x204200ff, + 0x5c410036, + 0x34010002, + 0x330100f6, + 0xb9600800, + 0xe0000038, + 0xfbffff0b, + 0x330c00f5, + 0x430200f9, + 0x204200ff, + 0x5c41002d, + 0x330b00f6, + 0xe0000030, + 0xfbfffee8, + 0x330c00f5, + 0x430200f9, + 0x204200ff, + 0x5c410026, + 0x34010001, + 0x330100f6, + 0xe0000029, + 0x2f0100fc, + 0x5c200023, + 0x430100ff, + 0x7c210001, + 0x5c20000a, + 0xfbfffebc, + 0xb8205800, + 0x430100f9, + 0x202100ff, + 0x5c2b0011, + 0x34010002, + 0x330100ff, + 0xfbfffef0, + 0xe000000c, + 0x430100ff, + 0x7c210002, + 0x5c20000a, + 0xfbfffeeb, + 0xb8205800, + 0x430100f9, + 0x202100ff, + 0x5c2b0005, + 0x34010001, + 0x330100ff, + 0xfbfffea9, + 0xb8205800, + 0x2f01010c, + 0x2f02010e, + 0x2021ffff, + 0x2042ffff, + 0xfbffecd0, + 0x3421ffff, + 0x0f0100fc, + 0xb9600800, + 0xfbffff77, + 0xe0000005, + 0x2f0100fc, + 0x3421ffff, + 0x0f0100fc, + 0x34010001, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x2f01010c, + 0x34020000, + 0x34030001, + 0x44220003, + 0x0f0200fc, + 0x330300ff, + 0xc3a00000, + 0x34010000, + 0x330100ff, + 0x0f01010c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x430200f7, + 0x430100f8, + 0x44220041, + 0x430100f7, + 0x5c20003a, + 0x43010110, + 0x7803c050, + 0x7805f8ff, + 0x78060700, + 0x7804c050, + 0x7807c050, + 0x5c200019, + 0x386301c8, + 0x28620000, + 0x38a5ffff, + 0x38c60000, + 0x43010111, + 0xa0451000, + 0x38840118, + 0x3c210018, + 0x38e700e4, + 0xa0260800, + 0xb8411000, + 0x58620000, + 0x28830000, + 0x3402fbff, + 0x43010112, + 0xa0621800, + 0x3c21000a, + 0x20210400, + 0xb8611800, + 0x58830000, + 0x43010110, + 0x202100ff, + 0x58e10000, + 0xe0000018, + 0x43010110, + 0x38e700e4, + 0x386301c8, + 0x202100ff, + 0x58e10000, + 0x28620000, + 0x38a5ffff, + 0x38c60000, + 0x43010111, + 0xa0451000, + 0x38840118, + 0x3c210018, + 0xa0260800, + 0xb8411000, + 0x58620000, + 0x28830000, + 0x3402fbff, + 0x43010112, + 0xa0621800, + 0x3c21000a, + 0x20210400, + 0xb8611800, + 0x58830000, + 0x34010000, + 0x330100f8, + 0xe0000006, + 0x78010003, + 0x3821f000, + 0x402102eb, + 0xfbffff1e, + 0xe0000007, + 0x430100f8, + 0x202100ff, + 0x44200003, + 0xfbffff3d, + 0xe0000002, + 0x33010769, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x78010003, + 0x3821f900, + 0x28210008, + 0x78060003, + 0x78070003, + 0x78050003, + 0x78040002, + 0x78030003, + 0x38c68ba8, + 0x38e7f000, + 0x38a58b24, + 0x3884714c, + 0x34080001, + 0x34020000, + 0x38638b88, + 0x20210080, + 0x4422000b, + 0x40e702ef, + 0x58a4003c, + 0x30c80028, + 0x30c7000f, + 0x330200f5, + 0x33020769, + 0x58620010, + 0x330200f8, + 0x330800f7, + 0xc3a00000, + 0x330100f7, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b8e0004, + 0x430100f7, + 0x7807c050, + 0x780ac050, + 0x78080700, + 0x780bc050, + 0x78040003, + 0x780d0003, + 0x78090003, + 0x78050002, + 0x78060003, + 0x78030003, + 0x780c0003, + 0x38e700e4, + 0x394a01c8, + 0x39080000, + 0x396b0118, + 0x38848ba8, + 0x39adf000, + 0x39298b24, + 0x38a5714c, + 0x340e0001, + 0x38c68b88, + 0x3863f818, + 0x398cf900, + 0x202200ff, + 0x5c40001a, + 0x28e10000, + 0x2021007f, + 0x33010110, + 0x29410000, + 0xa0280800, + 0x00210018, + 0x33010111, + 0x29610000, + 0x20210400, + 0x0021000a, + 0x33010112, + 0x41ad02ef, + 0x308e0028, + 0x5925003c, + 0x308d000f, + 0x330200f5, + 0x33020769, + 0x58c20010, + 0x330200f8, + 0x330e00f7, + 0x28610000, + 0x38210040, + 0x58610000, + 0x2b010108, + 0x31810029, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b8e0004, + 0x379c0010, + 0xc3a00000, + 0x34010000, + 0x78030003, + 0x330100f7, + 0x3863f818, + 0x28610000, + 0x3402ffbf, + 0xa0220800, + 0x58610000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x40230007, + 0xb8206000, + 0x20650008, + 0x44a00011, + 0x7803c050, + 0x386301c8, + 0x28610000, + 0x3402fff8, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x38840118, + 0x28810000, + 0x7802c050, + 0x384200ac, + 0x38210001, + 0x58810000, + 0x34010000, + 0x58410000, + 0xe0000014, + 0x20610002, + 0x780bc050, + 0x44200014, + 0x7804c050, + 0x388401c8, + 0x28810000, + 0x3402fff8, + 0x20630007, + 0xa0220800, + 0xb8230800, + 0x7803c050, + 0x58810000, + 0x38630118, + 0x28610000, + 0x3402fffe, + 0x396b00ac, + 0xa0220800, + 0x58610000, + 0x59650000, + 0x34010001, + 0x3301091a, + 0xe0000017, + 0x3301091a, + 0xf8001489, + 0x41810006, + 0x396b00ac, + 0x7802c050, + 0x59610000, + 0x384200b0, + 0x28410000, + 0x20210001, + 0x4420fffe, + 0x7803c050, + 0x38630118, + 0x28610000, + 0x3402fffe, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x388401c8, + 0x28810000, + 0x3402fff8, + 0xa0220800, + 0x58810000, + 0x298c0000, + 0x78010003, + 0x38218b88, + 0x582c0018, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2f02073c, + 0x78030003, + 0x3863f1c8, + 0x2f010756, + 0x34040000, + 0x54220020, + 0x430200a8, + 0x204200ff, + 0x3c410001, + 0xb4220800, + 0x3c210002, + 0xb4230800, + 0xfbffffa5, + 0x430300a8, + 0x78020003, + 0x78010002, + 0x330300a7, + 0x38428b24, + 0x382179d0, + 0x58410034, + 0x430100a5, + 0x7805e000, + 0x38a53028, + 0x330100a6, + 0x28a40000, + 0x7802fffc, + 0x78030003, + 0x430100a7, + 0x38427fff, + 0x38638000, + 0x202100ff, + 0x3c21000f, + 0xa0822000, + 0xa0230800, + 0xb8812000, + 0x58a40000, + 0x34040001, + 0xb8800800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x7806e000, + 0x38c63028, + 0x28c50000, + 0x202100ff, + 0x3c24000c, + 0x34028fff, + 0x20847000, + 0x3c230001, + 0xa0a22800, + 0xb8a42800, + 0x58c50000, + 0xb4611800, + 0x330100a8, + 0x3c630002, + 0x78020003, + 0x3842f1c8, + 0x34010001, + 0xb4621800, + 0x33010767, + 0x2c610004, + 0x34020007, + 0xf8000cbe, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x38217548, + 0x58410034, + 0xfbffffb8, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x78080003, + 0xb9001000, + 0x3842f000, + 0x4042004f, + 0x34050000, + 0xb8203800, + 0xb8a02000, + 0x50a20015, + 0x34090001, + 0x2b0100bc, + 0xbd241000, + 0xb9003000, + 0x38c6f000, + 0x34830001, + 0xa0220800, + 0x44200002, + 0xb8802800, + 0x3ca10001, + 0x206400ff, + 0xb4250800, + 0x3c210002, + 0xb4260800, + 0x282101c8, + 0x54e10002, + 0xe0000004, + 0x40c1004f, + 0x50810002, + 0xe3ffffee, + 0xb8a00800, + 0xc3a00000, + 0x78020003, + 0x3842f000, + 0x4043004f, + 0x34040000, + 0x34020001, + 0xbc411000, + 0x48610002, + 0xe0000004, + 0x2b0100bc, + 0xa0220800, + 0x7c240000, + 0xb8800800, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780c0003, + 0x430100a7, + 0xb9801000, + 0x3842f000, + 0x4042004f, + 0x34210001, + 0x202b00ff, + 0x5162000d, + 0xb9600800, + 0xfbffffe6, + 0xb9801800, + 0x3863f000, + 0x35620001, + 0x44200003, + 0xb9600800, + 0xe0000007, + 0x4061004f, + 0x204b00ff, + 0x51610002, + 0xe3fffff5, + 0x430100a7, + 0x202100ff, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x430100a7, + 0x202100ff, + 0x342bffff, + 0x34010000, + 0x482b0008, + 0xb9600800, + 0xfbffffcb, + 0x44200003, + 0x216100ff, + 0xe0000005, + 0x356bffff, + 0xe3fffff9, + 0x430100a7, + 0x202100ff, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x78020003, + 0x3842f000, + 0x4043004f, + 0x34040000, + 0xb8203800, + 0xb8802800, + 0x4c83000f, + 0xb8603000, + 0x344301c8, + 0x34080001, + 0x2b0100bc, + 0xbd051000, + 0x34a50001, + 0xa0220800, + 0x44200004, + 0x28640000, + 0x54e40002, + 0xe0000004, + 0x3463000c, + 0x4ca60002, + 0xe3fffff6, + 0xb8800800, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x430100aa, + 0x340b0000, + 0x442b0017, + 0x78010003, + 0x330b00aa, + 0x38218b88, + 0x28220018, + 0x2b0100b8, + 0x5c410011, + 0x430300a7, + 0x34010001, + 0x2b0200bc, + 0xbc230800, + 0xa0411000, + 0x5c4b000b, + 0xfbffffa3, + 0xb8205800, + 0x430100a7, + 0x202100ff, + 0x5c2b0003, + 0xfbffffbd, + 0xb8205800, + 0x430100a7, + 0x202100ff, + 0x5c2b002f, + 0x430100ab, + 0x5c20000c, + 0x78010003, + 0x38218b88, + 0x28220018, + 0x2b0100b8, + 0x4441002e, + 0x2b0100b8, + 0xfbffff66, + 0x430200a7, + 0x204200ff, + 0x44410029, + 0xe0000023, + 0x2f0100c4, + 0x5c200023, + 0x430100ab, + 0x7c210001, + 0x5c20000a, + 0xfbffff87, + 0xb8205800, + 0x430100a7, + 0x202100ff, + 0x5c2b0011, + 0x34010002, + 0x330100ab, + 0xfbffff9f, + 0xe000000c, + 0x430100ab, + 0x7c210002, + 0x5c20000a, + 0xfbffff9a, + 0xb8205800, + 0x430100a7, + 0x202100ff, + 0x5c2b0005, + 0x34010001, + 0x330100ab, + 0xfbffff74, + 0xb8205800, + 0x2f0100c0, + 0x2f0200c2, + 0x2021ffff, + 0x2042ffff, + 0xfbffeaae, + 0x3421ffff, + 0x0f0100c4, + 0xb9600800, + 0xfbffff1e, + 0xe0000005, + 0x2f0100c4, + 0x3421ffff, + 0x0f0100c4, + 0x34010001, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x2f0100c0, + 0x34020000, + 0x34030001, + 0x44220003, + 0x0f0200c4, + 0x330300ab, + 0xc3a00000, + 0x34010000, + 0x330100ab, + 0x0f0100c0, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x430200a5, + 0x430100a6, + 0x44220039, + 0x430100a5, + 0x5c200032, + 0x430100c8, + 0x7804c050, + 0x7805c050, + 0x7806c050, + 0x5c200016, + 0x388401c8, + 0x28830000, + 0x3402fff8, + 0x38a50118, + 0x430100c6, + 0xa0621800, + 0x3402fffe, + 0x20210007, + 0xb8611800, + 0x58830000, + 0x28a30000, + 0x38c600ac, + 0x430100c7, + 0xa0621800, + 0x20210001, + 0xb8611800, + 0x58a30000, + 0x430100c8, + 0x202100ff, + 0x58c10000, + 0xe0000015, + 0x430100c8, + 0x38c600ac, + 0x388401c8, + 0x202100ff, + 0x58c10000, + 0x28830000, + 0x3402fff8, + 0x38a50118, + 0x430100c6, + 0xa0621800, + 0x20210007, + 0xb8611800, + 0x58830000, + 0x28a10000, + 0x3403fffe, + 0x430200c7, + 0xa0230800, + 0x20420001, + 0xb8220800, + 0x58a10000, + 0x34010000, + 0x330100a6, + 0xe0000006, + 0x78010003, + 0x3821f000, + 0x402102e9, + 0xfbfffece, + 0xe0000007, + 0x430100a6, + 0x202100ff, + 0x44200003, + 0xfbffff60, + 0xe0000002, + 0x33010767, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x78010003, + 0x3821f900, + 0x28210008, + 0x78050003, + 0x78060003, + 0x78040003, + 0x78020002, + 0x78070003, + 0x38c6f000, + 0x38a58ba8, + 0x38848b24, + 0x384279d0, + 0x34030001, + 0x34080000, + 0x38e78b88, + 0x20210020, + 0x44280011, + 0x40c102ed, + 0x30a30026, + 0x58820034, + 0x30a1000d, + 0x33030767, + 0x330800a6, + 0x40c202e9, + 0xbc430800, + 0xb4220800, + 0x3c210002, + 0xb4260800, + 0x282101c8, + 0x5b0100b8, + 0x58e80018, + 0x330300a5, + 0xc3a00000, + 0x330100a5, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b8d0004, + 0x430100a5, + 0x7806c050, + 0x7809c050, + 0x780ac050, + 0x78020003, + 0x78040003, + 0x78070003, + 0x78050002, + 0x780b0003, + 0x78080003, + 0x780c0003, + 0x38c601c8, + 0x39290118, + 0x394a00ac, + 0x3884f000, + 0x38428ba8, + 0x38e78b24, + 0x38a579d0, + 0x340d0001, + 0x396b8b88, + 0x3908f818, + 0x398cf900, + 0x202300ff, + 0x5c60001d, + 0x28c10000, + 0x20210007, + 0x330100c6, + 0x29210000, + 0xa02d0800, + 0x330100c7, + 0x29410000, + 0x2021007f, + 0x330100c8, + 0x408102ed, + 0x304d0026, + 0x58e50034, + 0x3041000d, + 0x330300a6, + 0x408202e9, + 0xbc4d0800, + 0xb4220800, + 0x3c210002, + 0xb4240800, + 0x282101c8, + 0x5b0100b8, + 0x59630018, + 0x330d00a5, + 0x29010000, + 0x38210010, + 0x59010000, + 0x2b0100bc, + 0x3181002b, + 0x2b8b000c, + 0x2b8c0008, + 0x2b8d0004, + 0x379c000c, + 0xc3a00000, + 0x34010000, + 0x78030003, + 0x330100a5, + 0x3863f818, + 0x28610000, + 0x3402ffef, + 0xa0220800, + 0x58610000, + 0xc3a00000, + 0x430100d0, + 0x34020000, + 0x44220002, + 0x2b0200d8, + 0xb8400800, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbfffff8, + 0xb8201000, + 0x430100a4, + 0x44200008, + 0x2b0100ac, + 0x50220002, + 0xb8400800, + 0x2b0300b0, + 0x50610002, + 0xb8201800, + 0xb8601000, + 0x43010084, + 0x44200005, + 0x2b010090, + 0x50220002, + 0xb8400800, + 0xb8201000, + 0x430100f4, + 0x44200005, + 0x2b010100, + 0x50220002, + 0xb8400800, + 0xb8201000, + 0xb8400800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x430100a4, + 0x34020000, + 0x44220002, + 0x2b0200b8, + 0xb8400800, + 0xc3a00000, + 0x430100d0, + 0x34020000, + 0x44220002, + 0x2b0200e0, + 0xb8400800, + 0xc3a00000, + 0x430100f4, + 0x34020000, + 0x44220002, + 0x2b020104, + 0xb8400800, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20210004, + 0x64210000, + 0xc3a00000, + 0x3801f6bc, + 0xb7210800, + 0x28210000, + 0x00210001, + 0x20210001, + 0xc3a00000, + 0x3c210008, + 0x20420003, + 0x20210300, + 0xb8411000, + 0x3801ef58, + 0xb7210800, + 0x58220000, + 0xc3a00000, + 0x7801c020, + 0x38210304, + 0x28210000, + 0x78020001, + 0x38420000, + 0xa0220800, + 0x00210010, + 0x7c210000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x34010001, + 0xb8201000, + 0xfbffffeb, + 0x34010002, + 0x33010085, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x78020003, + 0x3842f900, + 0x2842000c, + 0xb8206000, + 0x34030000, + 0x204b0200, + 0x5d63000f, + 0xfbffffce, + 0xb8201800, + 0x5c200003, + 0x33010085, + 0xe000000a, + 0x2b010090, + 0xb9601800, + 0x542c0002, + 0xe0000006, + 0xfbffffcb, + 0x34030001, + 0x5c200003, + 0x33010085, + 0xb8201800, + 0xb8600800, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78010003, + 0x3821f900, + 0x2821000c, + 0x34020000, + 0x20210100, + 0xb8205800, + 0x5c220007, + 0xfbffffb0, + 0x44200004, + 0xfbffffb4, + 0x44200002, + 0x340b0001, + 0xb9601000, + 0xb8400800, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x43010085, + 0x34020000, + 0x5c220005, + 0xfbffffb4, + 0xb8201000, + 0x44200002, + 0x34020001, + 0xb8400800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x34010000, + 0x34020001, + 0xfbffffa0, + 0x34010001, + 0x33010085, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbffff8c, + 0x34020002, + 0x44200003, + 0x34010000, + 0xfbffff94, + 0x34010000, + 0x33010085, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbffff80, + 0x34020002, + 0x44200003, + 0x34010001, + 0xfbffff88, + 0x34010000, + 0x33010085, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbffff74, + 0xb8201000, + 0x44200008, + 0xfbffff77, + 0xb8201000, + 0x44200005, + 0xfbffff82, + 0x64210000, + 0xc8010800, + 0x38220001, + 0xb8400800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20210002, + 0x64210000, + 0xc3a00000, + 0x78010002, + 0x38210004, + 0xb7210800, + 0x28210000, + 0x00210001, + 0x20210001, + 0xc3a00000, + 0x3c210008, + 0x78030002, + 0x20210300, + 0x20420003, + 0xb8411000, + 0x386315b4, + 0xb7230800, + 0x58220000, + 0xc3a00000, + 0x7801c020, + 0x38210304, + 0x28210000, + 0x78020002, + 0x38420000, + 0xa0220800, + 0x00210011, + 0x7c210000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x34010001, + 0xb8201000, + 0xfbffffea, + 0x34010002, + 0x330100a9, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x78020003, + 0x3842f900, + 0x2843000c, + 0xb8206000, + 0x78020002, + 0x38420000, + 0xa0625800, + 0x34020000, + 0x5d62000f, + 0xfbffffca, + 0xb8201000, + 0x5c200003, + 0x330100a9, + 0xe000000a, + 0x2b0100ac, + 0xb9601000, + 0x542c0002, + 0xe0000006, + 0xfbffffc7, + 0x34020001, + 0x5c200003, + 0x330100a9, + 0xb8201000, + 0xb8400800, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78010003, + 0x3821f900, + 0x2822000c, + 0x78010001, + 0x38210000, + 0xa0411000, + 0xb8405800, + 0x34010000, + 0x5c410007, + 0xfbffffaa, + 0x44200004, + 0xfbffffae, + 0x44200002, + 0x340b0001, + 0xb9600800, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x430100a9, + 0x34020000, + 0x5c220005, + 0xfbffffb1, + 0xb8201000, + 0x44200002, + 0x34020001, + 0xb8400800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x34010000, + 0x34020001, + 0xfbffff9c, + 0x34010001, + 0x330100a9, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbffff87, + 0x34020002, + 0x44200003, + 0x34010000, + 0xfbffff90, + 0x34010000, + 0x330100a9, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbffff7b, + 0x34020002, + 0x44200003, + 0x34010001, + 0xfbffff84, + 0x34010000, + 0x330100a9, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbffff6f, + 0xb8201000, + 0x44200008, + 0xfbffff72, + 0xb8201000, + 0x44200005, + 0xfbffff7f, + 0x64210000, + 0xc8010800, + 0x38220001, + 0xb8400800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x78010003, + 0x78040003, + 0x34020003, + 0x38848e34, + 0x38218e30, + 0x7803c020, + 0x58820000, + 0x58220000, + 0x38630264, + 0x28610000, + 0xb8220800, + 0x58610000, + 0x28810000, + 0x28620000, + 0xa4200800, + 0xa0411000, + 0x58620000, + 0xc3a00000, + 0x78030003, + 0x3863f800, + 0x28620000, + 0x78010100, + 0x38210000, + 0xb4411000, + 0x58620000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8202000, + 0x78018000, + 0x38210428, + 0x78050003, + 0x74830184, + 0x58240000, + 0xb8406000, + 0x38a5fa04, + 0x5c60035c, + 0x3c810002, + 0x78020003, + 0x38427df4, + 0xb4220800, + 0x28210000, + 0xc0200000, + 0x34030000, + 0xe0000357, + 0x340300fe, + 0xe0000355, + 0x340300fe, + 0xe0000353, + 0x340300fe, + 0xe0000351, + 0x340300fe, + 0xe000034f, + 0x340300fe, + 0xe000034d, + 0x340300fe, + 0xe000034b, + 0x340300fe, + 0xe0000349, + 0x340300fe, + 0xe0000347, + 0x340300fe, + 0xe0000345, + 0x340300fe, + 0xe0000343, + 0x340300fe, + 0xe0000341, + 0x340300fe, + 0xe000033f, + 0x430106ee, + 0x340300ff, + 0x4420033c, + 0x34010000, + 0x78030003, + 0x330106f0, + 0x3863f818, + 0x28620000, + 0x7801fffb, + 0x3821ffff, + 0xa0411000, + 0x58620000, + 0x34030000, + 0xe0000331, + 0x340300fe, + 0xe000032f, + 0x340300fe, + 0xe000032d, + 0xf8001005, + 0x34030000, + 0xe000032a, + 0xf800101a, + 0x34030000, + 0xe0000327, + 0x78030003, + 0x38638c00, + 0x2ca20002, + 0x2c61003e, + 0x48220003, + 0x406100ab, + 0x5c20031f, + 0xf8000c7a, + 0xe000031d, + 0x78030003, + 0x38638c00, + 0x2ca20002, + 0x2c61003e, + 0x48220003, + 0x406100ab, + 0x5c200316, + 0xf8000bc0, + 0xe0000314, + 0x340300fe, + 0xe0000313, + 0x340300fe, + 0xe0000311, + 0x340300fe, + 0xe000030f, + 0x340300fe, + 0xe000030d, + 0x34010001, + 0xe0000002, + 0x34010000, + 0x33010114, + 0xe0000307, + 0x5b0c0118, + 0xe0000305, + 0x34010000, + 0xe0000002, + 0x34010001, + 0x33010079, + 0xe0000300, + 0xf8001dd7, + 0xe00002fe, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34020001, + 0x3302082c, + 0x7801c201, + 0x33020774, + 0x3821c588, + 0xf800161a, + 0x38220003, + 0x7801c201, + 0x3821c588, + 0xf80015fc, + 0xf8001d74, + 0xd00b0000, + 0xe00002ee, + 0xf8001e3d, + 0xe00002ec, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34020001, + 0x3302082c, + 0x7801c201, + 0x33020774, + 0x3821c588, + 0xf8001608, + 0x38220003, + 0x7801c201, + 0x3821c588, + 0xf80015ea, + 0xf8001df1, + 0xd00b0000, + 0xe00002dc, + 0xf8001d32, + 0xe00002da, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001cf1, + 0xd00b0000, + 0xe00002d4, + 0xf8001e65, + 0xe00002d2, + 0xf8001e54, + 0xe00002d0, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001e70, + 0xd00b0000, + 0xe00002ca, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001e69, + 0xd00b0000, + 0xe00002c4, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xf8001018, + 0xd00b0000, + 0xe00002bd, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001012, + 0xd00b0000, + 0x34030000, + 0xe00002b7, + 0x340300fe, + 0xe00002b5, + 0x340300fe, + 0xe00002b3, + 0x340300fe, + 0xe00002b1, + 0x340300fe, + 0xe00002af, + 0x340300fe, + 0xe00002ad, + 0x340300fe, + 0xe00002ab, + 0x340300fe, + 0xe00002a9, + 0x340300fe, + 0xe00002a7, + 0x340300fe, + 0xe00002a5, + 0x340300fe, + 0xe00002a3, + 0x340300fe, + 0xe00002a1, + 0x340300fe, + 0xe000029f, + 0x340300fe, + 0xe000029d, + 0x340300fe, + 0xe000029b, + 0x340300fe, + 0xe0000299, + 0x340300fe, + 0xe0000297, + 0x340300fe, + 0xe0000295, + 0x340300fe, + 0xe0000293, + 0x340300fe, + 0xe0000291, + 0x340300fe, + 0xe000028f, + 0x340300fe, + 0xe000028d, + 0x340300fe, + 0xe000028b, + 0x340300fe, + 0xe0000289, + 0x340300fe, + 0xe0000287, + 0x34010001, + 0xd0810000, + 0xe0000003, + 0x34010001, + 0xd0610000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xe000027c, + 0x340300fe, + 0xe000027b, + 0x340300fe, + 0xe0000279, + 0x340300fe, + 0xe0000277, + 0x340300fe, + 0xe0000275, + 0x340300fe, + 0xe0000273, + 0x340300fe, + 0xe0000271, + 0x340300fe, + 0xe000026f, + 0x340300fe, + 0xe000026d, + 0x340300fe, + 0xe000026b, + 0x340300fe, + 0xe0000269, + 0x78018000, + 0x38210068, + 0x35820001, + 0x58220000, + 0xe0000263, + 0x7d810000, + 0x33010760, + 0xe0000260, + 0xfbffe739, + 0xfbffe9dc, + 0xfbfff202, + 0xfbfff81e, + 0xfbfffa8e, + 0xfbfffcae, + 0x34030001, + 0xe0000259, + 0xfbffe966, + 0xfbfff180, + 0xfbfff81e, + 0xfbfffa8e, + 0xfbfffcae, + 0x34030001, + 0xe0000252, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbffef8e, + 0x34030000, + 0xe0000249, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbffefab, + 0xd00b0000, + 0x34030000, + 0xe000023c, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbffeff4, + 0xd00b0000, + 0x34030000, + 0xe000022f, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff5b4, + 0xd00b0000, + 0x34030000, + 0xe0000222, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff5c1, + 0xd00b0000, + 0x34030000, + 0xe0000215, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff5e8, + 0xd00b0000, + 0x34030000, + 0xe0000208, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x78030003, + 0x38638b20, + 0x28610000, + 0x34070001, + 0x282200c4, + 0x3401ffff, + 0xbc220800, + 0xa4200800, + 0xa1810800, + 0x5c200004, + 0xd00b0000, + 0x340300ff, + 0xe00001f8, + 0x34040000, + 0x50820015, + 0xb8603000, + 0xb8802800, + 0x28c10000, + 0x81841000, + 0xb4a10800, + 0x40210000, + 0x20430001, + 0x44230007, + 0x34010001, + 0x330107c5, + 0x28c10000, + 0x34070000, + 0xb4a10800, + 0x30230000, + 0x28c10000, + 0x34840001, + 0x34a50014, + 0x282100c4, + 0x50810002, + 0xe3ffffef, + 0x78010003, + 0x3821f900, + 0x302c0026, + 0xd00b0000, + 0xb8e01800, + 0xe00001dc, + 0x78010003, + 0x38218b20, + 0x28210000, + 0x34050000, + 0xb8a02000, + 0x282200c4, + 0x50a2000a, + 0xb8401800, + 0xb8201000, + 0x40410000, + 0xbc240800, + 0x34420014, + 0xb8a12800, + 0x34840001, + 0x50830002, + 0xe3fffffa, + 0x78018000, + 0x38210068, + 0x58250000, + 0x34030001, + 0xe00001c7, + 0x01810010, + 0x0f0c07f0, + 0x0f0107f2, + 0x34030001, + 0xe00001c2, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x78030003, + 0x3863f000, + 0x4062004c, + 0x3401ffff, + 0x34070001, + 0xbc220800, + 0xa4200800, + 0xa1810800, + 0x5c200004, + 0xd00b0000, + 0x340300ff, + 0xe00001b3, + 0x5b0c072c, + 0x2b020730, + 0x34660060, + 0x34040000, + 0x2b01072c, + 0xb8412800, + 0x80a40800, + 0x40c20005, + 0x20230001, + 0x44430005, + 0x34010001, + 0x330106fd, + 0x30c30005, + 0x34070000, + 0x64610000, + 0x5c200002, + 0x33040734, + 0x34840001, + 0x74810007, + 0x34c6001c, + 0x4420fff2, + 0x78010003, + 0x3821f900, + 0x30250024, + 0xd00b0000, + 0xb8e01800, + 0xe0000198, + 0x2b02072c, + 0x78018000, + 0x38210068, + 0x58220000, + 0x34030001, + 0xe0000192, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0x330106ff, + 0x34010000, + 0x33010736, + 0xd00b0000, + 0x34030001, + 0xe0000188, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x330106ff, + 0x33010736, + 0x330106fe, + 0xd00b0000, + 0x34030001, + 0xe000017f, + 0x01810010, + 0x0f0c0728, + 0x0f01072a, + 0x34030001, + 0xe000017a, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff7b8, + 0xd00b0000, + 0x34030000, + 0xe000016d, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff7c9, + 0xd00b0000, + 0x34030000, + 0xe0000160, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff806, + 0xd00b0000, + 0x34030000, + 0xe0000153, + 0x78010003, + 0x3821f000, + 0x4022004e, + 0x340300ff, + 0x3401ffff, + 0xbc220800, + 0xa4200800, + 0xa1810800, + 0x4420014a, + 0x5b0c0094, + 0x43010088, + 0x34030001, + 0x44200146, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34020001, + 0x78010003, + 0x3302008c, + 0x3821f900, + 0x302c0028, + 0xd00b0000, + 0x34030000, + 0xe000013b, + 0x2b020094, + 0x78018000, + 0x38210068, + 0x58220000, + 0x34030001, + 0xe0000135, + 0x01810010, + 0x0f0c0098, + 0x0f01009a, + 0x34030001, + 0xe0000130, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff9b1, + 0xd00b0000, + 0x34030000, + 0xe0000123, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff9c1, + 0xd00b0000, + 0x34030000, + 0xe0000116, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff9f2, + 0xd00b0000, + 0x34030000, + 0xe0000109, + 0x78010003, + 0x3821f000, + 0x40220051, + 0x340300ff, + 0x3401ffff, + 0xbc220800, + 0xa4200800, + 0xa1810800, + 0x44200100, + 0x5b0c0108, + 0x430100f7, + 0x34030001, + 0x442000fc, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34020001, + 0x78010003, + 0x330200fb, + 0x3821f900, + 0x302c0029, + 0xd00b0000, + 0x34030000, + 0xe00000f1, + 0x2b020108, + 0x78018000, + 0x38210068, + 0x58220000, + 0x34030001, + 0xe00000eb, + 0x01810010, + 0x0f0c010c, + 0x0f01010e, + 0x34030001, + 0xe00000e6, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfffb80, + 0xd00b0000, + 0x34030000, + 0xe00000d9, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfffb96, + 0xd00b0000, + 0x34030000, + 0xe00000cc, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfffbc6, + 0xd00b0000, + 0x34030000, + 0xe00000bf, + 0x78010003, + 0x3821f000, + 0x4022004f, + 0x340300ff, + 0x3401ffff, + 0xbc220800, + 0xa4200800, + 0xa1810800, + 0x442000b6, + 0x5b0c00bc, + 0x430100a5, + 0x34030001, + 0x442000b2, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34020001, + 0x78010003, + 0x330200aa, + 0x3821f900, + 0x302c002b, + 0xd00b0000, + 0x34030000, + 0xe00000a7, + 0x2b0200bc, + 0x78018000, + 0x38210068, + 0x58220000, + 0x34030001, + 0xe00000a1, + 0x01810010, + 0x0f0c00c0, + 0x0f0100c2, + 0x34030001, + 0xe000009c, + 0x340300fe, + 0xe000009a, + 0x430106ee, + 0x340300ff, + 0x44200097, + 0x218100ff, + 0xfbffe75d, + 0x340300ff, + 0x44200093, + 0x34010001, + 0x330106f0, + 0x78040003, + 0x330c06f1, + 0x3884f818, + 0x28830000, + 0x7801fffb, + 0x3821ffff, + 0x78020004, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0x34030000, + 0xe0000084, + 0x340300fe, + 0xe0000082, + 0x340300fe, + 0xe0000080, + 0x340300fe, + 0xe000007e, + 0x340300fe, + 0xe000007c, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x45800007, + 0x0f0c074e, + 0x34010001, + 0x33010763, + 0xd00b0000, + 0x34030000, + 0xe0000072, + 0x330c0763, + 0xd00b0000, + 0xe000006e, + 0x78019800, + 0x38210000, + 0x34020000, + 0x58410000, + 0xfbffe268, + 0x78018000, + 0x38218000, + 0x3402ffff, + 0x58220050, + 0x7803e000, + 0x58220054, + 0x386330a4, + 0x28610000, + 0x3402ffef, + 0xa0220800, + 0x58610000, + 0xe000005d, + 0x340300fe, + 0xe000005c, + 0x340300fe, + 0xe000005a, + 0x340300fe, + 0xe0000058, + 0x340300fe, + 0xe0000056, + 0x340300fe, + 0xe0000054, + 0x340300fe, + 0xe0000052, + 0x340300fe, + 0xe0000050, + 0x340300fe, + 0xe000004e, + 0x340300fe, + 0xe000004c, + 0x340300fe, + 0xe000004a, + 0xf8001875, + 0xe0000047, + 0xf80018d2, + 0xe0000045, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x43010789, + 0x5c200002, + 0xf8001553, + 0xd00b0000, + 0xe000003d, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x4301078a, + 0x7c210001, + 0x5c200002, + 0xf80015a6, + 0xd00b0000, + 0xe0000034, + 0x43010789, + 0x202200ff, + 0x7c410001, + 0x5c200030, + 0x33020785, + 0x34030000, + 0xe000002e, + 0x43010789, + 0x202200ff, + 0x7c410001, + 0x5c200029, + 0x33020787, + 0x34030000, + 0xe0000027, + 0x43010789, + 0x7c210001, + 0x5c200023, + 0x34010000, + 0x33010785, + 0x33010787, + 0xb8201800, + 0xe000001f, + 0xf8002212, + 0xe000001c, + 0xf800224c, + 0xe000001a, + 0xf800225a, + 0xe0000018, + 0xf800228d, + 0xe0000016, + 0xf800243d, + 0xe0000014, + 0xf8002445, + 0xe0000012, + 0x218100ff, + 0xf8000e2f, + 0xe000000f, + 0xf8000e4d, + 0xe000000d, + 0x218100ff, + 0xf8000e64, + 0xe000000a, + 0xf8000e82, + 0xe0000008, + 0xf80018ef, + 0xe0000006, + 0x34010001, + 0x33010735, + 0xe0000003, + 0x340300fe, + 0xe0000002, + 0x34030001, + 0xb8600800, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0xb8201800, + 0x64210142, + 0xb8402000, + 0x5c2000aa, + 0x74610142, + 0x5c20002d, + 0x64610124, + 0x5c200094, + 0x74610124, + 0x5c200014, + 0x64610052, + 0x5c200081, + 0x74610052, + 0x5c200006, + 0x64610041, + 0x5c200077, + 0x64610051, + 0x5c200077, + 0xe00000a8, + 0x64610102, + 0x5c20003b, + 0x74610102, + 0x5c200004, + 0x64610063, + 0x5c200093, + 0xe00000a1, + 0x64610104, + 0x5c200060, + 0xe000009e, + 0x6461012c, + 0x5c200048, + 0x7461012c, + 0x5c20000b, + 0x64610129, + 0x5c20003b, + 0x74610129, + 0x5c200004, + 0x64610125, + 0x5c20006a, + 0xe0000093, + 0x6461012a, + 0x5c200046, + 0xe0000090, + 0x6461012e, + 0x5c200047, + 0x3401012e, + 0x54230033, + 0x64610130, + 0x5c20003a, + 0xe0000089, + 0x74610153, + 0x5c200010, + 0x70610152, + 0x5c200066, + 0x64610145, + 0x5c20001c, + 0x74610145, + 0x5c200006, + 0x64610143, + 0x5c200074, + 0x64610144, + 0x5c200078, + 0xe000007c, + 0x3461feb2, + 0x74210001, + 0x5c200079, + 0xe000000d, + 0x74610157, + 0x5c200004, + 0x70610156, + 0x5c200020, + 0xe0000016, + 0x3401015a, + 0x54230071, + 0x3401015b, + 0x50230024, + 0x6461015c, + 0x5c200053, + 0xe000006c, + 0x430206ee, + 0x34040001, + 0x430106ef, + 0xe000004c, + 0x430206e8, + 0x78030003, + 0x3863f000, + 0xb0401000, + 0x3c410003, + 0xc8220800, + 0x3c210002, + 0xb4230800, + 0x40210065, + 0xe0000055, + 0x43020088, + 0x34040001, + 0x43010089, + 0xe000003e, + 0x4303008a, + 0x34020001, + 0xb8402000, + 0x2b010094, + 0xe0000012, + 0x430200f7, + 0x34040001, + 0x430100f8, + 0xe0000035, + 0x430300f9, + 0x34020001, + 0xb8402000, + 0x2b010108, + 0xe0000009, + 0x430200a5, + 0x34040001, + 0x430100a6, + 0xe000002c, + 0x430300a7, + 0x34020001, + 0xb8402000, + 0x2b0100bc, + 0xbc431000, + 0xa0220800, + 0x5c200042, + 0xe0000040, + 0x7801c020, + 0x38210014, + 0x28220000, + 0x7801001f, + 0x38210000, + 0xa0411000, + 0x00420010, + 0x208100ff, + 0x5c410037, + 0x430106ef, + 0xe0000033, + 0x430106ef, + 0xe0000029, + 0x430106ac, + 0x34040001, + 0x7c21000a, + 0xe000002e, + 0x430106ac, + 0x34040001, + 0x7c210004, + 0xe000002a, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x2f01073c, + 0x2021ffff, + 0x54810004, + 0xd0020000, + 0x34040001, + 0xe0000023, + 0xd0020000, + 0xe0000020, + 0x430207b6, + 0x34040001, + 0x430107b7, + 0x4422001d, + 0xe000001b, + 0x430307b0, + 0x78020003, + 0x38428b20, + 0xb0601800, + 0x3c610002, + 0x28420000, + 0xb4230800, + 0x3c210002, + 0xb4220800, + 0x40210000, + 0xe0000007, + 0x43010825, + 0xe000000c, + 0x43010786, + 0xe0000002, + 0x43010788, + 0x202100ff, + 0x7c220001, + 0xb8202000, + 0x44400008, + 0xe0000006, + 0x43010788, + 0x5c200004, + 0x43010786, + 0x34040001, + 0x44200002, + 0x34040000, + 0xb8800800, + 0xc3a00000, + 0xb8201000, + 0x64210001, + 0x34030000, + 0x5c230007, + 0x3441ff80, + 0x74210007, + 0x340300fe, + 0x4440000c, + 0x5c20000b, + 0xe0000003, + 0x0f0300cc, + 0xe0000007, + 0x78010003, + 0x38218408, + 0xb4421000, + 0xb4411000, + 0x2c41ff00, + 0x0f0100cc, + 0x34030001, + 0xb8600800, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xb8202000, + 0x34010001, + 0x64830011, + 0x33010084, + 0x5c600020, + 0x74810011, + 0x5c200006, + 0x64810001, + 0x5c200009, + 0x64810010, + 0x5c20000f, + 0xe0000030, + 0x64810012, + 0x5c200022, + 0x64810013, + 0x5c20002e, + 0xe000002b, + 0x5b020090, + 0x430106ef, + 0x340200ff, + 0x7c210001, + 0x5c20002d, + 0xfbfffa21, + 0x5b0106f4, + 0xe0000021, + 0x43010088, + 0x340200ff, + 0x44200027, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x33010087, + 0x34010002, + 0x33010086, + 0xd0020000, + 0xe0000016, + 0x43010088, + 0x340200ff, + 0x4420001c, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x33010087, + 0x34010001, + 0x33010086, + 0xd0020000, + 0xe000000b, + 0x43010088, + 0x340200ff, + 0x44200011, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x33010087, + 0x34010004, + 0x33010086, + 0xd0020000, + 0x34020000, + 0xe0000008, + 0x340200fe, + 0xe0000006, + 0xf80026cf, + 0x78028000, + 0x38420074, + 0x58410000, + 0x34020001, + 0xb8400800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0xb8201800, + 0x64210001, + 0x5c200006, + 0x44600013, + 0x3461fff0, + 0x74210002, + 0x5c200010, + 0xe0000007, + 0x78010003, + 0x38218b88, + 0x28210000, + 0x5441000b, + 0xb8601000, + 0xe000000a, + 0x43010088, + 0x340200ff, + 0x44200007, + 0x43010087, + 0x44200004, + 0x43010087, + 0x202200ff, + 0xe0000002, + 0x34020000, + 0xb8400800, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0xb8202000, + 0x34010001, + 0x64830011, + 0x330100a4, + 0xb8405800, + 0x5c60002d, + 0x74810011, + 0x5c20000b, + 0x64810002, + 0x5c20001b, + 0x74810002, + 0x5c200004, + 0x64810001, + 0x5c20000f, + 0xe0000059, + 0x64810004, + 0x5c200016, + 0xe0000056, + 0x64810015, + 0x5c20002a, + 0x74810015, + 0x5c200004, + 0x64810014, + 0x5c20001f, + 0xe000004f, + 0x64810017, + 0x5c200034, + 0xe000004c, + 0x5b0200ac, + 0x430106ef, + 0x340200ff, + 0x7c210001, + 0x5c200048, + 0xfbfff9b4, + 0x5b0106f4, + 0xe0000008, + 0x5b0200b0, + 0xe0000006, + 0xb8400800, + 0xfbfff882, + 0xb8201800, + 0x55610004, + 0x5b0b00b8, + 0x34020000, + 0xe000003c, + 0x78018000, + 0x38210078, + 0x58230000, + 0x340200ff, + 0xe0000037, + 0x78010003, + 0x38218b88, + 0x28220000, + 0xe0000004, + 0x78010003, + 0x38218b88, + 0x28220018, + 0x78018000, + 0x38210078, + 0x58220000, + 0xe0000029, + 0x78020003, + 0x3842f000, + 0x4041004c, + 0x34030000, + 0xb8602000, + 0x50610020, + 0xb8202800, + 0x40410065, + 0x34840001, + 0x7c210001, + 0x5c200004, + 0x28410058, + 0x50610002, + 0xb8201800, + 0x3442001c, + 0x50850016, + 0xe3fffff7, + 0x78020003, + 0x3842f000, + 0x4041004f, + 0x34030000, + 0xb8602000, + 0x5061000f, + 0xb8203000, + 0x344501c8, + 0x34070001, + 0x2b0100bc, + 0xbce41000, + 0x34840001, + 0xa0220800, + 0x44200004, + 0x28a10000, + 0x50610002, + 0xb8201800, + 0x34a5000c, + 0x50860002, + 0xe3fffff6, + 0x78018000, + 0x38210078, + 0x58230000, + 0x34020001, + 0xe0000002, + 0x340200fe, + 0xb8400800, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0xb8201800, + 0x64210002, + 0x5c20000f, + 0x74610002, + 0x5c200004, + 0x64610001, + 0x5c200005, + 0xe0000015, + 0x64610004, + 0x5c20000c, + 0xe0000012, + 0x78010003, + 0x38218b88, + 0x28210000, + 0xf4411000, + 0xc8621000, + 0xe000000d, + 0x78010003, + 0x38218b88, + 0x28210000, + 0xe0000004, + 0x78010003, + 0x38218b88, + 0x28210018, + 0xf4411000, + 0x34010001, + 0xc8221000, + 0xe0000002, + 0x34020000, + 0xb8400800, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x3423ffff, + 0xb8402000, + 0x74610006, + 0x340200fe, + 0x5c200048, + 0x3c610002, + 0x78020003, + 0x38428418, + 0xb4220800, + 0x28210000, + 0xc0200000, + 0x78018000, + 0x3821007c, + 0x34820001, + 0x58220000, + 0xe000003c, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001826, + 0x43010824, + 0x7c210001, + 0x5c200008, + 0x43010826, + 0x202200ff, + 0x7c410001, + 0x5c200004, + 0x34010000, + 0x33010826, + 0x3302082c, + 0x34010000, + 0x33010779, + 0xd00b0000, + 0xe000002a, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x43010824, + 0x202200ff, + 0x7c410001, + 0x5c20000d, + 0x43010826, + 0x5c20000b, + 0x33020826, + 0x3302082c, + 0x7801c201, + 0x33020774, + 0x3821c588, + 0xf8001127, + 0x38220003, + 0x7801c201, + 0x3821c588, + 0xf8001109, + 0x34010001, + 0x33010779, + 0x4301077b, + 0x5c200004, + 0xd00b0000, + 0x34020000, + 0xe0000011, + 0xd00b0000, + 0xe000000e, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf80017dd, + 0xd00b0000, + 0xe0000008, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf80017f2, + 0xd00b0000, + 0xe0000002, + 0xf80006ae, + 0x34020001, + 0xb8400800, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x64210006, + 0x4420000b, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x4301077b, + 0x7c210001, + 0x5c200004, + 0xd0020000, + 0x34010001, + 0xc3a00000, + 0xd0020000, + 0x34010000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xb8202000, + 0x34010001, + 0x64830012, + 0x330100f4, + 0x5c600021, + 0x74810012, + 0x5c20000b, + 0x64810002, + 0x5c200017, + 0x74810002, + 0x5c200004, + 0x64810001, + 0x5c200011, + 0xe0000041, + 0x64810011, + 0x5c200012, + 0xe000003e, + 0x64810022, + 0x5c20001a, + 0x74810022, + 0x5c200004, + 0x64810014, + 0x5c20003a, + 0xe0000037, + 0x64810023, + 0x5c20001e, + 0x64810024, + 0x5c200027, + 0xe0000032, + 0x5b020100, + 0xe000002e, + 0x5b020104, + 0xe000002c, + 0x78010003, + 0x38218b88, + 0x28220000, + 0xe0000004, + 0x78010003, + 0x38218b88, + 0x28220010, + 0x78018000, + 0x38210084, + 0x58220000, + 0xe0000029, + 0x430100f7, + 0x340200ff, + 0x44200027, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x330100f6, + 0x34010004, + 0x330100f5, + 0xd0020000, + 0xe0000016, + 0x430100f7, + 0x340200ff, + 0x4420001c, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x330100f6, + 0x34010002, + 0x330100f5, + 0xd0020000, + 0xe000000b, + 0x430100f7, + 0x340200ff, + 0x44200011, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x330100f6, + 0x34010001, + 0x330100f5, + 0xd0020000, + 0x34020000, + 0xe0000008, + 0x340200fe, + 0xe0000006, + 0xf800256a, + 0x78028000, + 0x38420084, + 0x58410000, + 0x34020001, + 0xb8400800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0xb8201800, + 0x64210002, + 0x5c200010, + 0x74610002, + 0x5c200004, + 0x64610001, + 0x5c200006, + 0xe000001c, + 0x3461ffde, + 0x74210002, + 0x5c200019, + 0xe000000e, + 0x78010003, + 0x38218b88, + 0x28210000, + 0xf4411000, + 0xc8621000, + 0xe0000013, + 0x78010003, + 0x38218b88, + 0x28210010, + 0xf4411000, + 0x34010001, + 0xc8221000, + 0xe000000c, + 0x430100f7, + 0x340200ff, + 0x44200009, + 0x430100f6, + 0x202100ff, + 0xb8201000, + 0x44200005, + 0x430100f6, + 0x202200ff, + 0xe0000002, + 0x34020000, + 0xb8400800, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x3423ffff, + 0x78040003, + 0x74610059, + 0xb8406000, + 0x3884fa04, + 0x5c200195, + 0x3c610002, + 0x78020003, + 0x38428434, + 0xb4220800, + 0x28210000, + 0xc0200000, + 0xfbfff9d0, + 0xe000018f, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001e51, + 0xd00b0000, + 0xe0000189, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001e72, + 0xd00b0000, + 0xe0000183, + 0x78010003, + 0x38218c00, + 0x402100ab, + 0x5c20017f, + 0x34010001, + 0xe0000005, + 0x78010003, + 0x38218c00, + 0x402100ab, + 0x5c200179, + 0x3301069b, + 0xf80014ac, + 0xe0000176, + 0x78010003, + 0x38218c00, + 0x402100ab, + 0x5c200172, + 0xf8001415, + 0xe0000170, + 0x78030003, + 0x38638c00, + 0x2c820002, + 0x2c61003e, + 0x48220003, + 0x406100ab, + 0x5c200169, + 0x34010001, + 0xf8001326, + 0xe0000166, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001a93, + 0xd00b0000, + 0xe0000160, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf8001aaf, + 0xd00b0000, + 0xe000015a, + 0x35810068, + 0x3c210007, + 0x78020003, + 0x5b01081c, + 0x38428c00, + 0x40410029, + 0x2b02081c, + 0x3c210007, + 0xc8411000, + 0x5b020820, + 0xe000014f, + 0x78030003, + 0x38638c00, + 0x2c820002, + 0x2c61003e, + 0x4822001e, + 0x406100ab, + 0x5c200148, + 0xe000001b, + 0x78030003, + 0x38638c00, + 0x2c820002, + 0x2c61003e, + 0x48220003, + 0x406100ab, + 0x5c200140, + 0x43010158, + 0x7c210001, + 0x5c20013d, + 0x34010000, + 0x33010158, + 0xb8201800, + 0xe000013a, + 0x78030003, + 0x38638c00, + 0x2c820002, + 0x2c61003e, + 0x48220003, + 0x406100ab, + 0x5c200132, + 0x78010003, + 0x3821f9d8, + 0x28210000, + 0x20220004, + 0x44400005, + 0x43010158, + 0x5c20012b, + 0xf800167a, + 0xe0000129, + 0x43010158, + 0x7c210001, + 0x5c200126, + 0x33020158, + 0xb8401800, + 0xe0000124, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x5b0c0730, + 0x430106ee, + 0x34070003, + 0xb8e01800, + 0x4420011c, + 0x2b010730, + 0x78020003, + 0x3842f000, + 0x2b03072c, + 0x34450060, + 0x34040000, + 0xb8233000, + 0x80c40800, + 0x40a20005, + 0x20230001, + 0x44430005, + 0x34010001, + 0x330106fd, + 0x30a30005, + 0x34070000, + 0x64610000, + 0x5c200002, + 0x33040734, + 0x34840001, + 0x74810007, + 0x34a5001c, + 0x4420fff2, + 0x78010003, + 0x3821f900, + 0x30260024, + 0xd00b0000, + 0xe000006d, + 0x2b020730, + 0x7801c210, + 0x3821003c, + 0x58220000, + 0xe00000fb, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff036, + 0xe00000c6, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff048, + 0xe00000be, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbfff074, + 0xe00000b6, + 0x430107b6, + 0x340300ff, + 0x442000e1, + 0x218100ff, + 0xfbffed4b, + 0x340300ff, + 0x442000dd, + 0x34010001, + 0x330107b8, + 0x78040003, + 0x330c07b9, + 0x3884f818, + 0x28830000, + 0x7801ffef, + 0x3821ffff, + 0x78020010, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0xe00000a1, + 0x430107b6, + 0x340300ff, + 0x442000cc, + 0x34010000, + 0x78030003, + 0x330107b8, + 0x3863f818, + 0x28620000, + 0x7801ffef, + 0x3821ffff, + 0xa0411000, + 0x58620000, + 0xe0000094, + 0x78040003, + 0xb8800800, + 0x38218b20, + 0x28210000, + 0x34070003, + 0x340300ff, + 0x282200c4, + 0x3401ffff, + 0xbc220800, + 0xa4200800, + 0xa1810800, + 0x442000b6, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xb8801000, + 0x38428b20, + 0x28410000, + 0x34040000, + 0x282100c4, + 0x50810015, + 0xb8403000, + 0xb8802800, + 0x28c10000, + 0x81841000, + 0xb4a10800, + 0x40210000, + 0x20430001, + 0x44230007, + 0x34010001, + 0x330107c5, + 0x28c10000, + 0x34070000, + 0xb4a10800, + 0x30230000, + 0x28c10000, + 0x34840001, + 0x34a50014, + 0x282100c4, + 0x50810002, + 0xe3ffffef, + 0x78010003, + 0x3821f900, + 0x302c0026, + 0xd00b0000, + 0xb8e01800, + 0xe0000093, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xf80002f0, + 0xd00b0000, + 0xe0000086, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xf8000305, + 0xd00b0000, + 0xe000007a, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x45800006, + 0x0f0c0750, + 0x34010001, + 0x33010764, + 0xd00b0000, + 0xe0000044, + 0x330c0764, + 0xd00b0000, + 0xe000006e, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x43010814, + 0x5c20000a, + 0x34010001, + 0xd0810000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbffeb11, + 0xd00b0000, + 0xe0000033, + 0xd00b0000, + 0xe000005e, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x43010814, + 0x202200ff, + 0x7c410001, + 0x5c200009, + 0xd0820000, + 0x34000000, + 0x34000000, + 0x34000000, + 0x34000000, + 0xfbffeb2a, + 0xd00b0000, + 0xe0000022, + 0xd00b0000, + 0xe000004d, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x3401001e, + 0xfbffdd9d, + 0xd00b0000, + 0xe0000046, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x3401001e, + 0xfbffddc3, + 0xd00b0000, + 0xe000003f, + 0x78010003, + 0x38218c00, + 0x402100ab, + 0x5c20003b, + 0x34010001, + 0x33010174, + 0xf8002126, + 0xe0000037, + 0x78010003, + 0x38218c00, + 0x402100ab, + 0x5c200033, + 0xf8002157, + 0xe0000031, + 0xf8000a75, + 0xe000002f, + 0xf8000a8d, + 0x34030000, + 0xe000002d, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xb9800800, + 0xf8001b46, + 0x5c200005, + 0x7801c210, + 0x3821003c, + 0x370201c4, + 0x58220000, + 0xd00b0000, + 0xe0000020, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf80019d2, + 0xd00b0000, + 0xe000001a, + 0x90005800, + 0x34010000, + 0xd0010000, + 0xf80019da, + 0xd00b0000, + 0xe0000014, + 0xf80032ac, + 0xe0000012, + 0xf8001be9, + 0x34010000, + 0xfbffe0cd, + 0xe000000e, + 0x7801c00c, + 0x38210000, + 0x28210000, + 0x20210002, + 0x5c200009, + 0x34010001, + 0xfbffe0c5, + 0xf8001c57, + 0xe0000005, + 0xf8001d07, + 0xe0000003, + 0x340300fe, + 0xe0000002, + 0x34030003, + 0xb8600800, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0xb8201800, + 0x74210028, + 0xb8402800, + 0x5c200017, + 0x70610026, + 0x34040003, + 0x5c200065, + 0x6461001c, + 0x5c200043, + 0x7461001c, + 0x5c20000b, + 0x64610009, + 0x5c20002c, + 0x74610009, + 0x5c200005, + 0x64610001, + 0x340400fe, + 0x5c20005a, + 0xe0000058, + 0x6461000e, + 0xe000000b, + 0x6461001d, + 0x5c200041, + 0x7461001f, + 0x5c200052, + 0xe000001f, + 0x74610039, + 0x5c200006, + 0x70610038, + 0x5c200043, + 0x6461002f, + 0x5c20000c, + 0xe000004a, + 0x6461004c, + 0x5c20001b, + 0x7461004c, + 0x5c200004, + 0x6461003a, + 0x5c200036, + 0xe0000043, + 0x64610058, + 0x5c200004, + 0xe0000040, + 0x43010159, + 0xe0000029, + 0x430206e8, + 0x78030003, + 0x3863f000, + 0xb0401000, + 0x3c410003, + 0x34040003, + 0xc8220800, + 0x3c210002, + 0xb4230800, + 0x40210065, + 0xe0000022, + 0x430207b6, + 0x34040003, + 0x430107b7, + 0x44220030, + 0xe000002e, + 0x430307b0, + 0x78020003, + 0x38428b20, + 0xb0601800, + 0x3c610002, + 0x28420000, + 0xb4230800, + 0x3c210002, + 0xb4220800, + 0x40210000, + 0x7c220001, + 0xb8202000, + 0x44400022, + 0xe0000020, + 0x7801c020, + 0x38210014, + 0x28220000, + 0x78011c00, + 0x38210000, + 0xa0411000, + 0x0042001a, + 0x20a100ff, + 0x5c410017, + 0x430107b7, + 0x34040003, + 0xe0000004, + 0x430107b7, + 0x34040003, + 0x7c210001, + 0x44200011, + 0xe000000f, + 0x2f01073c, + 0x2021ffff, + 0x5441000c, + 0xe0000008, + 0x90001800, + 0x34010000, + 0xd0010000, + 0x43020813, + 0x43010814, + 0x5c220004, + 0xd0030000, + 0x34040003, + 0xe0000003, + 0xd0030000, + 0x34040000, + 0xb8800800, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8201800, + 0x6421016c, + 0x5c200022, + 0x7461016c, + 0x5c200007, + 0x64610001, + 0x5c200028, + 0x4460000b, + 0x64610125, + 0x5c20000e, + 0xe000003c, + 0x6461016e, + 0x5c20001d, + 0x3401016e, + 0x54230019, + 0x6461016f, + 0x5c20001c, + 0xe0000035, + 0x78018000, + 0x38210140, + 0x34420001, + 0x58220000, + 0xe0000032, + 0x90006000, + 0x34010000, + 0xd0010000, + 0x44400007, + 0x0f02075c, + 0x34010001, + 0x3301076a, + 0xd00c0000, + 0x34010000, + 0xe0000029, + 0x3302076a, + 0xd00c0000, + 0xe0000025, + 0x204100ff, + 0xf8000934, + 0xe0000022, + 0xf8000952, + 0xe0000020, + 0x204100ff, + 0xf8000969, + 0xe000001d, + 0xf8000987, + 0xe000001b, + 0x90006000, + 0x34010000, + 0xd0010000, + 0x4301092b, + 0x202b00ff, + 0x5d600007, + 0x3401005d, + 0xb9601000, + 0x34030001, + 0xfbffe8cf, + 0x330b092c, + 0xe000000b, + 0x34020000, + 0x3401005d, + 0xb8401800, + 0xfbffe8c9, + 0x44200004, + 0x34010000, + 0x3301092b, + 0xe0000002, + 0x34010001, + 0x3301092c, + 0xd00c0000, + 0xe0000003, + 0x340100fe, + 0xe0000002, + 0x34010001, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x64210125, + 0x34030000, + 0x4423000c, + 0x90001800, + 0x34010000, + 0xd0010000, + 0x2f01073c, + 0x2021ffff, + 0x54410004, + 0xd0030000, + 0x34030001, + 0xe0000003, + 0xd0030000, + 0x34030000, + 0xb8600800, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8206000, + 0x3c210001, + 0x78030003, + 0xb42c0800, + 0x3c210002, + 0xb8601000, + 0x38428fa8, + 0xb4225800, + 0x90002000, + 0x34010000, + 0xd0010000, + 0x29650000, + 0x5ca00003, + 0xd0040000, + 0xe000003a, + 0x5d800007, + 0x38638fa8, + 0x40610015, + 0x7c210001, + 0x5c20000d, + 0xd0040000, + 0xe0000009, + 0x7d810001, + 0x5c200009, + 0x78010003, + 0x38218fa8, + 0x40210009, + 0x7c210001, + 0x5c200004, + 0xd0040000, + 0x3401ffff, + 0xe0000029, + 0x41610008, + 0x34020001, + 0x34030000, + 0x29660004, + 0x31620009, + 0x31630008, + 0xd0040000, + 0x3d820002, + 0x44200004, + 0x78010003, + 0x38217dcc, + 0xe0000003, + 0x78010003, + 0x38217da4, + 0xb4410800, + 0x28230000, + 0xb8c01000, + 0xb8a00800, + 0xd8600000, + 0xb8201800, + 0x3401ffff, + 0x44600013, + 0x78010003, + 0x3d820002, + 0x38217d7c, + 0xb4411000, + 0x28410000, + 0x34020000, + 0x59620000, + 0x58230000, + 0x7d810005, + 0x31620009, + 0x5c220007, + 0x78020003, + 0x38428e70, + 0x28410000, + 0x44200003, + 0xb8400800, + 0xf800210c, + 0x34010000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x34010000, + 0xfbffffab, + 0xb8205800, + 0x34010001, + 0xfbffffa8, + 0xb9615800, + 0x34010002, + 0xfbffffa5, + 0xb9615800, + 0x34010003, + 0xfbffffa2, + 0xb9615800, + 0x34010004, + 0xfbffff9f, + 0xb9615800, + 0x34010005, + 0xfbffff9c, + 0xb9615800, + 0x34010007, + 0xfbffff99, + 0xb9615800, + 0x34010008, + 0xfbffff96, + 0xb9615800, + 0x34010009, + 0xfbffff93, + 0xb9610800, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x43030744, + 0x7801c020, + 0x38210134, + 0x206300ff, + 0x34020100, + 0xfbffe8e7, + 0x43020744, + 0x7803c020, + 0x38630134, + 0x43010745, + 0x44220006, + 0x28610000, + 0x18210080, + 0x58610000, + 0x43010744, + 0x33010745, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x780dc020, + 0x39ad0090, + 0x29ab0000, + 0x340cfe01, + 0x43020744, + 0x396b0001, + 0xa16c5800, + 0xb4220800, + 0x202100ff, + 0x3c210001, + 0x2f020740, + 0xb9615800, + 0x01610001, + 0x2042ffff, + 0x202100ff, + 0x4c220006, + 0x2f010740, + 0xa16c5800, + 0x202100ff, + 0x3c210001, + 0xb9615800, + 0xfbffffd1, + 0x01620001, + 0x204200ff, + 0x34410001, + 0x202100ff, + 0x3c210001, + 0xa16c5800, + 0xb9615800, + 0x33020747, + 0x59ab0000, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780bc020, + 0xb9600800, + 0x38210094, + 0x28210000, + 0x20210001, + 0x5c20000a, + 0x78018000, + 0x38210054, + 0x28230000, + 0x78010003, + 0x38218e70, + 0xb8601000, + 0x5c60fff5, + 0xf80020cb, + 0xe3fffff3, + 0x7804c020, + 0x38840090, + 0x28830000, + 0x3402fe01, + 0x780bc020, + 0x00610001, + 0x3421ffff, + 0x202100ff, + 0x3c210001, + 0xa0621800, + 0xb8611800, + 0xb9601000, + 0x38420094, + 0x58830000, + 0x28410000, + 0x20210001, + 0x5c20000d, + 0x78018000, + 0x38210054, + 0x28230000, + 0x78010003, + 0x38218e70, + 0xb8601000, + 0x5c600002, + 0xf80020b1, + 0xb9600800, + 0x38210094, + 0x28210000, + 0xe3fffff3, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x34050000, + 0x78020003, + 0x202600ff, + 0x38428c00, + 0xb8a01800, + 0x34630001, + 0x404100a0, + 0x74640004, + 0x5c260003, + 0x404500a5, + 0xe0000003, + 0x34420001, + 0x4480fff9, + 0xb8a00800, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x34031838, + 0xc8611800, + 0x34010019, + 0x8c615800, + 0x204200ff, + 0x34030000, + 0x5c43000f, + 0x43010826, + 0x7802c020, + 0x3842029c, + 0x5c23000b, + 0x28410000, + 0x20210002, + 0x44230008, + 0x28420000, + 0x216100ff, + 0x20420004, + 0x44430004, + 0xfbffffdc, + 0x33010743, + 0xe0000002, + 0x33030743, + 0x43010743, + 0x202100ff, + 0xb5615800, + 0x216100ff, + 0xfbffff77, + 0xfbffffa0, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0xb8402000, + 0x4303076e, + 0xb4581000, + 0x34450758, + 0xb8205800, + 0x4460000f, + 0xb4841000, + 0xb4581000, + 0x34430740, + 0x40a20008, + 0x4440000a, + 0x0c610008, + 0x2f03073c, + 0x34020000, + 0x2063ffff, + 0x54230002, + 0xe0000004, + 0xfbffffc9, + 0x0f0b073c, + 0x0f0b073e, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x4301076e, + 0x34070000, + 0x5c270016, + 0x4301076f, + 0x7c210001, + 0x5c270013, + 0x78020003, + 0x78010002, + 0x38214a68, + 0x38428b24, + 0x58410040, + 0x37010758, + 0x3404000b, + 0x34020000, + 0x30220008, + 0x3484ffff, + 0x34210001, + 0x4c82fffc, + 0x78010003, + 0x38218ba8, + 0x30220010, + 0x30220029, + 0x3302076f, + 0xe000003c, + 0x34010000, + 0x0f01073e, + 0x43010765, + 0x37030740, + 0x37050758, + 0x202100ff, + 0xb8202000, + 0x44200004, + 0x2f010752, + 0x0f01073e, + 0xe0000010, + 0x40a10008, + 0x34840001, + 0x7486000b, + 0x34a50001, + 0x44200007, + 0x2c620008, + 0x34070001, + 0x2f01073e, + 0x50220003, + 0x2c610008, + 0x0f01073e, + 0x34630002, + 0x44c0fff4, + 0x7ce10000, + 0x44200022, + 0x2f02073e, + 0x2f01073c, + 0x44220007, + 0x2f01073e, + 0x34020000, + 0x2021ffff, + 0xfbffff87, + 0x2f01073e, + 0x0f01073c, + 0x4301082c, + 0x7c210001, + 0x5c200014, + 0x340b0000, + 0x330b082c, + 0x2f01073e, + 0xb9601000, + 0x2021ffff, + 0xfbffff7c, + 0x43010774, + 0x7c210001, + 0x5c2b000b, + 0x7801c201, + 0x330b0774, + 0x3821c588, + 0xf8000c80, + 0x3402fffc, + 0xa0221000, + 0x7801c201, + 0x3821c588, + 0x38420002, + 0xf8000c60, + 0x34010001, + 0x3301076f, + 0x34010000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x202100ff, + 0x33010744, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x3821a9b4, + 0x58410040, + 0x34020001, + 0x78010003, + 0x3302076e, + 0x3821f820, + 0x28230000, + 0x78020003, + 0x38428ba8, + 0x780100ff, + 0x38210000, + 0xa0611800, + 0x00630010, + 0x7801c201, + 0x30430010, + 0x30430029, + 0x3821c57c, + 0xf8000c59, + 0x202100ff, + 0x78020003, + 0x0f010740, + 0x3842f818, + 0x28410000, + 0x38212000, + 0x58410000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x34010000, + 0x78030003, + 0x3301076e, + 0x3863f818, + 0x28610000, + 0x3402dfff, + 0xa0220800, + 0x58610000, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0xb8205800, + 0x7801c201, + 0x3821c574, + 0xf8000c3f, + 0x78040003, + 0xb8801000, + 0x38428acc, + 0x58410038, + 0x7d6b0000, + 0x78010003, + 0x78050003, + 0x5d600006, + 0x38218c00, + 0x4023000c, + 0xe0000005, + 0x40830008, + 0xe0000022, + 0x38218c00, + 0x40230011, + 0x38848acc, + 0x28810038, + 0x38a5fe14, + 0x34060000, + 0x0022000c, + 0x78040003, + 0x00210010, + 0x2042007f, + 0x20210080, + 0xb8221000, + 0x58a20000, + 0x38848c00, + 0x34c60001, + 0x408500a0, + 0x68c70004, + 0x5c450004, + 0x4560ffec, + 0x4083000d, + 0xe000000d, + 0x408100a5, + 0xb4a10800, + 0x5c410008, + 0x5d600003, + 0x40830008, + 0xe0000002, + 0x4083000d, + 0x408100a5, + 0xb4611800, + 0xe0000003, + 0x34840001, + 0x44e0ffee, + 0xb8600800, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x7801c040, + 0x38210c08, + 0x28210000, + 0x3402007f, + 0x202101ff, + 0x50410002, + 0xb8400800, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x88211000, + 0x082312bc, + 0x0042000f, + 0x0063000c, + 0x88410800, + 0x0021000f, + 0x08423377, + 0x08213698, + 0x0042000d, + 0x0021000e, + 0xc8220800, + 0xb4230800, + 0x3421daca, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x34031000, + 0x20240008, + 0x20220002, + 0x20210004, + 0x44400002, + 0x34030eec, + 0x44200002, + 0x3463ff26, + 0x44800002, + 0x3463ff59, + 0x43010779, + 0x5c200002, + 0x3463f8a8, + 0xb8600800, + 0xc3a00000, + 0xb8201000, + 0x88210800, + 0x084259f0, + 0x0021000f, + 0x0042000e, + 0x08213b06, + 0x0021000d, + 0xc8220800, + 0x342147c4, + 0xc3a00000, + 0x78010001, + 0x38213880, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78010003, + 0x38218b88, + 0x282b0000, + 0xfbfffff7, + 0x096b0492, + 0x3c210007, + 0x780200fe, + 0xb5615800, + 0x3842f490, + 0xb5625800, + 0x01610012, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cffc8, + 0x5b8b0038, + 0x5b8c0034, + 0x5b8d0030, + 0x5b8e002c, + 0x5b8f0028, + 0x5b900024, + 0x5b910020, + 0x5b92001c, + 0x5b930018, + 0x5b940014, + 0x5b950010, + 0x5b96000c, + 0x5b970008, + 0x5b9d0004, + 0xb840a800, + 0xb820b000, + 0xb860b800, + 0xb8808000, + 0xb8a09000, + 0xb8c06800, + 0xfbffffd9, + 0x78030003, + 0x38638c00, + 0xb8209800, + 0x40620017, + 0x78010003, + 0x382185e0, + 0xb4411000, + 0x10410000, + 0x40630015, + 0x340b0000, + 0x3421000a, + 0x88618800, + 0x78020001, + 0x384286a0, + 0x3e230010, + 0xb6d50800, + 0x8c628800, + 0xb433a000, + 0x8a110800, + 0xb9606000, + 0x3652ffff, + 0x00210009, + 0xcae17800, + 0xb9e00800, + 0xfbffffb3, + 0x8a815800, + 0xb8207000, + 0xb9e00800, + 0xfbffff8f, + 0x0f010268, + 0x2f010268, + 0x29a30000, + 0x016b000f, + 0x2f02026c, + 0x2021ffff, + 0x6645ffff, + 0x2042ffff, + 0x88220800, + 0x2b020264, + 0x0021000c, + 0xc8621800, + 0x2021ffff, + 0x88611800, + 0x0064000c, + 0xb5645800, + 0x3d61000f, + 0x8c2f8000, + 0x458b0002, + 0x44a0ffe2, + 0x8aae0800, + 0x8a6e1000, + 0x8ace1800, + 0x0021000f, + 0x0042000f, + 0x0063000f, + 0x59a1001c, + 0x59ab0004, + 0x59af0008, + 0x59b0000c, + 0x59a40010, + 0x59a20014, + 0x59a30018, + 0x2b8b0038, + 0x2b8c0034, + 0x2b8d0030, + 0x2b8e002c, + 0x2b8f0028, + 0x2b900024, + 0x2b910020, + 0x2b92001c, + 0x2b930018, + 0x2b940014, + 0x2b950010, + 0x2b96000c, + 0x2b970008, + 0x2b9d0004, + 0x379c0038, + 0xc3a00000, + 0x34030000, + 0x34020007, + 0x58230000, + 0x3442ffff, + 0x34210004, + 0x4c40fffd, + 0xc3a00000, + 0x379cfff4, + 0x5b9d0004, + 0x7801c040, + 0x38210c28, + 0x28220000, + 0x78017fff, + 0x3821ffff, + 0xa0411000, + 0x7801c040, + 0x5b820008, + 0x38210c24, + 0x28220000, + 0x78010003, + 0x5b82000c, + 0x3821f900, + 0x28230000, + 0x2b0202ac, + 0x37810008, + 0x88431000, + 0x34030064, + 0x8c431000, + 0xf800166b, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffc8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x7802c020, + 0x3842029c, + 0x284c0000, + 0xb8207800, + 0x340b0000, + 0xfbffffdb, + 0x5b010264, + 0xfbffff2b, + 0xfbffff2c, + 0x0f01026a, + 0xfbffff3a, + 0x0f01026c, + 0xb9602800, + 0x21810004, + 0x5c2b000f, + 0x78010003, + 0x38218b88, + 0x2822000c, + 0x2b040274, + 0x28210008, + 0x2b030270, + 0x00420003, + 0x00210003, + 0x88621800, + 0x88812000, + 0x340130d4, + 0x8c611800, + 0x8c815800, + 0xb5635800, + 0x21810002, + 0x5c20000a, + 0x78010003, + 0x38218b88, + 0x28210018, + 0x2b020278, + 0x00210003, + 0x88411000, + 0x340130d4, + 0x8c411000, + 0xb5625800, + 0x21810008, + 0x5c20000a, + 0x78010003, + 0x38218b88, + 0x28210010, + 0x2b02027c, + 0x00210003, + 0x88411000, + 0x340130d4, + 0x8c411000, + 0xb5625800, + 0x21810001, + 0x5c20000a, + 0x78010003, + 0x38218b88, + 0x28210014, + 0x2b020284, + 0x00210003, + 0x88411000, + 0x340130d4, + 0x8c411000, + 0xb5625800, + 0x430107b0, + 0x78020003, + 0x38428b88, + 0xb0200800, + 0x3c210002, + 0x28420004, + 0xb4380800, + 0x2823028c, + 0x00420003, + 0xb8a06000, + 0x88621800, + 0x340130d4, + 0x8c611800, + 0x78020003, + 0x3842f000, + 0x284202f8, + 0x2b010288, + 0xb5635800, + 0xb5615800, + 0xb5625800, + 0x378e001c, + 0xb9c00800, + 0xfbffff85, + 0xb58c6800, + 0x78010003, + 0x5d800004, + 0x38218c00, + 0x2c21009c, + 0xe0000003, + 0x38218c00, + 0x2c21009e, + 0x5b81001c, + 0xb9800800, + 0xfbfffe91, + 0xfbffdd52, + 0x3c21000f, + 0x34020fa0, + 0x8c222800, + 0xb5b81800, + 0x34640240, + 0x34630248, + 0xb9c03000, + 0x0c650004, + 0xb9e00800, + 0xb9601000, + 0xb8a01800, + 0x44a00006, + 0x2c840004, + 0x430502b4, + 0x2084ffff, + 0x20a500ff, + 0xfbffff04, + 0x2b81002c, + 0xb5b81000, + 0x34430230, + 0x0c410230, + 0x2b810030, + 0x34440238, + 0x35850001, + 0x0c610004, + 0x2b810034, + 0x34430240, + 0x20ac00ff, + 0x0c410238, + 0x2f81003a, + 0x0c810004, + 0x2b810020, + 0x0c410240, + 0x2b810028, + 0x0c610004, + 0x2b810024, + 0x75830001, + 0x0c410248, + 0x4460ffcb, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0038, + 0xc3a00000, + 0x379cfff4, + 0x5b9d0004, + 0x7801c040, + 0x38210c18, + 0x28220000, + 0x78017fff, + 0x3821ffff, + 0xa0411000, + 0x7801c040, + 0x5b820008, + 0x38210c0c, + 0x28220000, + 0x5b82000c, + 0x2b0202ac, + 0x37810008, + 0xf80015c1, + 0x00210008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x7801c040, + 0x38210c04, + 0x28210000, + 0x7803c040, + 0x78028000, + 0x20210001, + 0x64210000, + 0x38630c18, + 0x38420000, + 0x5c200008, + 0x28610000, + 0xa0220800, + 0x0021001f, + 0x7c210000, + 0x5c200003, + 0xfbffffdb, + 0xfbffff43, + 0x34010000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x78010003, + 0x38218ba8, + 0x34020000, + 0x78040003, + 0x30220005, + 0x3022001e, + 0x3884f818, + 0x28830000, + 0x7801ffff, + 0x38217fff, + 0xa0611800, + 0x78020003, + 0x38428b24, + 0x34010000, + 0x58410014, + 0x58830000, + 0xd0050000, + 0x7802c040, + 0x38420c04, + 0x28410000, + 0x3403fffe, + 0xa0230800, + 0x58410000, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x7801c040, + 0x34030000, + 0x38210d04, + 0x7802c040, + 0x58230000, + 0x38420d08, + 0x58430000, + 0xb8606800, + 0x780f0003, + 0x3dae0002, + 0xb9e00800, + 0x38217cec, + 0xb5c10800, + 0x40210001, + 0x340c0000, + 0x51810014, + 0xb9e05800, + 0x396b7cec, + 0xb5cb5800, + 0x41610002, + 0x41620000, + 0x3d840016, + 0x3c210001, + 0x3c420011, + 0x7803c040, + 0xb8220800, + 0xb8240800, + 0x38630d00, + 0x38210001, + 0x58610000, + 0x34010001, + 0xfbffdbd2, + 0x41610001, + 0x358c0001, + 0xe3ffffed, + 0x35ad0001, + 0x75a10007, + 0x4420ffe3, + 0x7801c040, + 0x34040000, + 0x38210d34, + 0x58240000, + 0x7802c040, + 0x38420d38, + 0x7801c040, + 0x58440000, + 0x38210d40, + 0x58240000, + 0x7802c040, + 0x38420d44, + 0x7801c040, + 0x58440000, + 0x38210d4c, + 0x58240000, + 0x7802c040, + 0x780d0003, + 0x38420d50, + 0xb9a00800, + 0x58440000, + 0x38217cec, + 0x4022008d, + 0x7803c040, + 0x38630d58, + 0x7801c040, + 0x58640000, + 0x38210d5c, + 0x58240000, + 0xb8806000, + 0x5082001d, + 0xb9a05800, + 0x396b7cec, + 0x4162008e, + 0x4161008c, + 0x3d840016, + 0x3c420001, + 0x3c210011, + 0x7803c040, + 0xb8411000, + 0xb8441000, + 0x38420001, + 0x38630d30, + 0x7801c040, + 0x58620000, + 0x38210d3c, + 0x58220000, + 0x7803c040, + 0x38630d48, + 0x7801c040, + 0x58620000, + 0x38210d54, + 0x58220000, + 0x34010001, + 0xfbffdb95, + 0x4161008d, + 0x358c0001, + 0x51810002, + 0xe3ffffe5, + 0x7801c040, + 0x34030000, + 0x38210d84, + 0x7802c040, + 0x58230000, + 0x38420d88, + 0x58430000, + 0xb8606800, + 0x780f0003, + 0x3dae0002, + 0xb9e00800, + 0x38217cec, + 0xb5c10800, + 0x40210021, + 0x340c0000, + 0x51810014, + 0xb9e05800, + 0x396b7cec, + 0xb5cb5800, + 0x41610022, + 0x41620020, + 0x3d840016, + 0x3c210001, + 0x3c420011, + 0x7803c040, + 0xb8220800, + 0xb8240800, + 0x38630d80, + 0x38210001, + 0x58610000, + 0x34010001, + 0xfbffdb71, + 0x41610021, + 0x358c0001, + 0xe3ffffed, + 0x35ad0001, + 0x75a1001a, + 0x4420ffe3, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x780fc040, + 0xb9e02800, + 0x38a50c00, + 0x28a30000, + 0x7801ff00, + 0x38210000, + 0x7802000a, + 0xa0611800, + 0x38422710, + 0xb8621800, + 0x7804c040, + 0x58a30000, + 0x38840c14, + 0x28810000, + 0x780cffff, + 0xb9801000, + 0x38420000, + 0xa0220800, + 0x3821ffff, + 0x7802c040, + 0x38420c10, + 0x58810000, + 0x28410000, + 0x780bc040, + 0x780e00ff, + 0x3401ffff, + 0x58410000, + 0xb9601000, + 0x340d0000, + 0x38420000, + 0x34010118, + 0x584d0000, + 0x3421ffff, + 0x34420004, + 0x4c20fffd, + 0xfbffff40, + 0xb9602000, + 0x38840000, + 0x28820000, + 0x78010065, + 0x38210000, + 0x2042ffff, + 0xb8411000, + 0x7803c040, + 0x58820000, + 0x38630004, + 0x28610000, + 0xb9803000, + 0x38c60000, + 0xa0260800, + 0x38210005, + 0x58610000, + 0x28610000, + 0x78020019, + 0x38420000, + 0x2021ffff, + 0xb8220800, + 0x7805c040, + 0x58610000, + 0x38a50020, + 0x28a10000, + 0x78020007, + 0x38420000, + 0xa0260800, + 0x3821002d, + 0x58a10000, + 0x28a10000, + 0x7804c040, + 0x38840024, + 0x2021ffff, + 0xb8220800, + 0x58a10000, + 0x28820000, + 0x78010023, + 0x38210000, + 0x2042ffff, + 0xb8411000, + 0x7803c040, + 0x58820000, + 0x38630060, + 0x28620000, + 0x7801002d, + 0x38210000, + 0x2042ffff, + 0xb8411000, + 0x7807c040, + 0x58620000, + 0x38e70064, + 0x28e10000, + 0x7802c040, + 0x38420080, + 0xa0260800, + 0x38210009, + 0x58e10000, + 0x28410000, + 0x7804c040, + 0x38840084, + 0xa0260800, + 0x38210021, + 0x58410000, + 0x28820000, + 0x78010053, + 0x38210000, + 0x2042ffff, + 0xb8411000, + 0x7803c040, + 0x58820000, + 0x38630100, + 0x28610000, + 0x7804006f, + 0x38840000, + 0xa0260800, + 0x38210012, + 0x58610000, + 0x28610000, + 0x7802c040, + 0x38420108, + 0x2021ffff, + 0xb8240800, + 0x58610000, + 0x28410000, + 0x7803c040, + 0x386300a0, + 0xa0260800, + 0x38210041, + 0x58410000, + 0x28610000, + 0x7802c040, + 0x384200e0, + 0xa0260800, + 0x38210037, + 0x58610000, + 0x28410000, + 0x7803c040, + 0x386300e4, + 0xa0260800, + 0x38210009, + 0x58410000, + 0x28610000, + 0x7802c040, + 0x38420120, + 0xa0260800, + 0x38210008, + 0x58610000, + 0x28410000, + 0x7803c040, + 0x38630160, + 0xa0260800, + 0x38210014, + 0x58410000, + 0x28610000, + 0x7802c040, + 0x38420180, + 0xa0260800, + 0x38210012, + 0x58610000, + 0x28410000, + 0x7803c040, + 0x38630184, + 0xa0260800, + 0x38210004, + 0x58410000, + 0x28610000, + 0x7804c040, + 0x388400c0, + 0xa0260800, + 0x38210005, + 0x58610000, + 0x28820000, + 0x78010099, + 0x38210000, + 0x2042ffff, + 0xb8411000, + 0x7805c040, + 0x58820000, + 0x38a500c4, + 0x28a10000, + 0x7802002e, + 0x38420000, + 0xa0260800, + 0x382100b1, + 0x58a10000, + 0x28e10000, + 0x78030066, + 0x38630000, + 0x2021ffff, + 0xb8220800, + 0x58e10000, + 0x28a10000, + 0x7802c040, + 0x384200c8, + 0x2021ffff, + 0xb8230800, + 0x58a10000, + 0x28410000, + 0x7804c040, + 0x388400cc, + 0xa0260800, + 0x382100ec, + 0x58410000, + 0x28810000, + 0x7803001f, + 0x38630000, + 0xa0260800, + 0x3821002c, + 0x58810000, + 0x28810000, + 0x7802c040, + 0x384200d0, + 0x2021ffff, + 0xb8230800, + 0x58810000, + 0x28410000, + 0x7804c040, + 0x38840454, + 0xa0260800, + 0x38210003, + 0x58410000, + 0x28810000, + 0x78020024, + 0x38420000, + 0xa0260800, + 0x38210024, + 0x58810000, + 0x28810000, + 0x7803c040, + 0x38630464, + 0x2021ffff, + 0xb8220800, + 0x58810000, + 0x28610000, + 0x7802c040, + 0x38420c04, + 0xa0260800, + 0x38210001, + 0x58610000, + 0x28410000, + 0x38210001, + 0x58410000, + 0x90006000, + 0xd00d0000, + 0x780b0003, + 0x396b8c00, + 0x41610080, + 0x39ceffff, + 0xfbffdb4a, + 0x00210002, + 0x0f01022a, + 0x41610081, + 0xfbffdb46, + 0x78020003, + 0x3842f900, + 0x28480000, + 0x00210002, + 0x340a0003, + 0x34020064, + 0x8d024000, + 0x0f010228, + 0xb9e00800, + 0x38210c00, + 0x28240000, + 0x340b028f, + 0x78060003, + 0x2084ffff, + 0x28210000, + 0x38c68ba8, + 0x34090001, + 0xa02e0800, + 0x00210010, + 0x78070003, + 0x38e7f818, + 0x7805ffff, + 0x38a57fff, + 0x78030003, + 0x38638b24, + 0x8c882000, + 0x78020002, + 0x3842b2a4, + 0x88240800, + 0x5b0102ac, + 0x330a02b4, + 0x0f0b02b0, + 0x30c9001e, + 0x30c90005, + 0x28e10000, + 0x58620014, + 0xa0250800, + 0x38218000, + 0x58e10000, + 0xd00c0000, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cfff8, + 0xb8202800, + 0x64a20003, + 0x64210001, + 0x78078000, + 0xb8220800, + 0x34020000, + 0x64210000, + 0x38e70338, + 0x5b820004, + 0x5c220016, + 0xbbe01800, + 0x3401fffc, + 0xa0611800, + 0xb8402000, + 0xb8204000, + 0x3c820002, + 0x34860001, + 0xb4471000, + 0x28410000, + 0xa0280800, + 0x58410000, + 0x44230005, + 0x20c400ff, + 0x74810003, + 0x4420fff7, + 0xe0000007, + 0x37810008, + 0xb4241000, + 0x34010001, + 0x3041fffc, + 0xe0000002, + 0xbbc01800, + 0x7ca10002, + 0x5c20000d, + 0x78018000, + 0x38210398, + 0x28220000, + 0x3403ff00, + 0xb8202000, + 0xa0431000, + 0x38420030, + 0x58220000, + 0x28810000, + 0x202100ff, + 0x5c20fffe, + 0xe0000087, + 0x7ca10004, + 0x5c20000d, + 0x78018000, + 0x38210398, + 0x28220000, + 0x3403ff00, + 0xb8202000, + 0xa0431000, + 0x38420040, + 0x58220000, + 0x28810000, + 0x202100ff, + 0x5c20fffe, + 0xe0000079, + 0x7ca10005, + 0x78038000, + 0x5c20000d, + 0xb8600800, + 0x38210398, + 0x28220000, + 0x3403ff00, + 0xb8202000, + 0xa0431000, + 0x38420020, + 0x58220000, + 0x28810000, + 0x202100ff, + 0x5c20fffe, + 0xe000006a, + 0xb8600800, + 0x38210398, + 0x28210000, + 0x20210100, + 0x00220008, + 0x44200017, + 0xd1020000, + 0xb8600800, + 0x38210398, + 0x28220000, + 0x3403ff00, + 0xb8202000, + 0xa0431000, + 0x38420006, + 0x58220000, + 0x28810000, + 0x202100ff, + 0x7c210006, + 0x4420fffd, + 0x28810000, + 0x20210100, + 0x00220008, + 0x7c410000, + 0x5c200052, + 0xd1020000, + 0x34010001, + 0xd0610000, + 0xe000004e, + 0x43810004, + 0x4420000f, + 0x28e10000, + 0xd2010000, + 0x38630398, + 0x28610000, + 0x3402ff00, + 0xb8602000, + 0xa0220800, + 0x38210001, + 0x58610000, + 0x28810000, + 0x202100ff, + 0x7c210001, + 0x4420fffd, + 0xe000003e, + 0x43810005, + 0x4420000f, + 0x28e10004, + 0xd2210000, + 0x38630398, + 0x28610000, + 0x3402ff00, + 0xb8602000, + 0xa0220800, + 0x38210002, + 0x58610000, + 0x28810000, + 0x202100ff, + 0x7c210002, + 0x4420fffd, + 0xe000002e, + 0x43810006, + 0x4420000f, + 0x28e10008, + 0xd2410000, + 0x38630398, + 0x28610000, + 0x3402ff00, + 0xb8602000, + 0xa0220800, + 0x38210003, + 0x58610000, + 0x28810000, + 0x202100ff, + 0x7c210003, + 0x4420fffd, + 0xe000001e, + 0x43810007, + 0x4420000f, + 0x28e1000c, + 0xd2610000, + 0x38630398, + 0x28610000, + 0x3402ff00, + 0xb8602000, + 0xa0220800, + 0x38210004, + 0x58610000, + 0x28810000, + 0x202100ff, + 0x7c210004, + 0x4420fffd, + 0xe000000e, + 0x34010001, + 0xd0610000, + 0x38630398, + 0x28610000, + 0x3402ff00, + 0xb8602000, + 0xa0220800, + 0x38210005, + 0x58610000, + 0x28810000, + 0x202100ff, + 0x7c210005, + 0x4420fffd, + 0x379c0008, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x430206f8, + 0x780c0003, + 0x398cf054, + 0x430106f9, + 0x340b0004, + 0x34030001, + 0x5c220087, + 0x430106ae, + 0x202200ff, + 0x64410006, + 0x5c200008, + 0x68410006, + 0x4420000b, + 0x64410008, + 0x5c200006, + 0x6441000a, + 0x5c200006, + 0xe0000006, + 0x340b0005, + 0xe0000004, + 0x340b0006, + 0xe0000002, + 0x340b0007, + 0x430206ae, + 0x430106ac, + 0x4422005d, + 0x430106ae, + 0x202200ff, + 0x64410006, + 0x5c200024, + 0x68410006, + 0x5c200004, + 0x64410004, + 0x5c200007, + 0xe0000054, + 0x64410008, + 0x5c20001d, + 0x6441000a, + 0x5c20001b, + 0xe000004f, + 0x7804c020, + 0x38840014, + 0x28810000, + 0x3403fff0, + 0x3562fffc, + 0xa0230800, + 0x2042000f, + 0xb8220800, + 0x58810000, + 0x34010001, + 0x33010765, + 0x370606b0, + 0x28c30004, + 0x78020003, + 0x78010002, + 0x3821c154, + 0x38428b24, + 0x0f030752, + 0x58410044, + 0x40c1000d, + 0x34030001, + 0x3301077f, + 0x40c1000e, + 0x33010781, + 0xe000004d, + 0x430106ac, + 0x7c210004, + 0x5c200033, + 0xfbffdb4c, + 0xb0200800, + 0x3c220003, + 0x7805c020, + 0xc8411000, + 0x3c420002, + 0x38a50014, + 0xb44c1000, + 0x28410000, + 0x3564fffc, + 0x2084000f, + 0x5b0106b4, + 0x4041000f, + 0x78060003, + 0x38c6f134, + 0x330106bc, + 0x28410004, + 0x7803c050, + 0x386300cc, + 0x5b0106b8, + 0x4041000d, + 0x7807c050, + 0x38e700d0, + 0x330106bd, + 0x4041000e, + 0x330106be, + 0x40410010, + 0x330106bf, + 0x40410016, + 0x330106c0, + 0x28a10000, + 0x3402fff0, + 0xa0220800, + 0xb8240800, + 0x58a10000, + 0x40c1000c, + 0x58610000, + 0x28e10000, + 0x4420ffff, + 0x34010001, + 0x33010765, + 0x28c30004, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x3821c154, + 0x0f030752, + 0x58410044, + 0x34030001, + 0xe0000018, + 0x430206ae, + 0x78010003, + 0x38218ba8, + 0x330206ac, + 0x34020000, + 0x7804c020, + 0x3022002a, + 0x30220011, + 0x388400b0, + 0x28830000, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x38214a68, + 0x58410044, + 0x430206ad, + 0x780100ff, + 0x3821ffff, + 0x3c420018, + 0xa0611800, + 0xb8621800, + 0x58830000, + 0x34030000, + 0xb8600800, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x7801c020, + 0x38210000, + 0x28210000, + 0x20210001, + 0x64210000, + 0x5c20005b, + 0x7804c020, + 0xb8800800, + 0x382100b0, + 0x28220000, + 0x780100ff, + 0x38210000, + 0xa0411000, + 0x00420010, + 0x330206ae, + 0x430106ae, + 0x202100ff, + 0x3422fffc, + 0x74410008, + 0x5c20004d, + 0x3c410002, + 0x78020003, + 0x3842859c, + 0xb4220800, + 0x28210000, + 0xc0200000, + 0x388400b0, + 0x28830000, + 0x780100ff, + 0x3821ffff, + 0x78020c00, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0xe000003d, + 0x388400b0, + 0x28830000, + 0x780100ff, + 0x3821ffff, + 0x78020400, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0x34010005, + 0xe0000021, + 0x388400b0, + 0x28830000, + 0x780100ff, + 0x3821ffff, + 0x78020600, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0x34010007, + 0xe0000016, + 0x388400b0, + 0x28830000, + 0x780100ff, + 0x3821ffff, + 0x78020800, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0x34010009, + 0xe000000b, + 0x388400b0, + 0x28830000, + 0x780100ff, + 0x3821ffff, + 0x78020a00, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0x3401000b, + 0x330106ad, + 0x430106ee, + 0x44200003, + 0x34010001, + 0x330106f8, + 0x78010003, + 0x38218ba8, + 0x34040001, + 0x78030003, + 0x78020002, + 0x38638b24, + 0x3842bd64, + 0x3024002a, + 0x30240011, + 0x58620044, + 0x34010020, + 0xfbffd567, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x430106ad, + 0x64210005, + 0x5c200023, + 0x780c0003, + 0x398cf134, + 0x2f01073c, + 0x29820004, + 0x2021ffff, + 0x5c22006e, + 0x43010746, + 0x5c20006c, + 0x7804c020, + 0x38840014, + 0x28830000, + 0x3402ff0f, + 0x78050003, + 0x28810000, + 0xa0621800, + 0x38a598d8, + 0x2021000f, + 0x3c210004, + 0xb8611800, + 0x58830000, + 0x28a10034, + 0x5b0106a4, + 0x28a10038, + 0x5b0106a8, + 0xfbffd59f, + 0x3401000e, + 0xfbffd541, + 0x34010012, + 0xfbffd53f, + 0x34010006, + 0xfbffd53d, + 0x3401000a, + 0xfbffd53b, + 0xe0000054, + 0x370c06b0, + 0x2f01073c, + 0x29820004, + 0x2021ffff, + 0x5c22004d, + 0x43010746, + 0x202b00ff, + 0x5d60004a, + 0xfbffda66, + 0x780dc020, + 0xb9a02800, + 0x330106e9, + 0x38a50014, + 0x28a40000, + 0x7802fc1f, + 0x780303e0, + 0x430106e9, + 0x3842ffff, + 0x38630000, + 0xb0200800, + 0x3c210015, + 0xa0822000, + 0xa0230800, + 0xb8812000, + 0x58a40000, + 0x330b0765, + 0x330b06f8, + 0x4182000c, + 0x7801c050, + 0x382100cc, + 0x7803c050, + 0x58220000, + 0x386300d0, + 0x28610000, + 0x4420ffff, + 0x29820008, + 0x78010003, + 0x38218b88, + 0x58220000, + 0x4181000f, + 0x330106f2, + 0x430106f2, + 0x202100ff, + 0xfbffdb6c, + 0x41830010, + 0x7804c020, + 0x38840088, + 0x28810000, + 0x3c630003, + 0x3402ffc7, + 0xa0220800, + 0x20630038, + 0xb8230800, + 0x58810000, + 0x430106e9, + 0xb9a02800, + 0x38a50014, + 0x330106e8, + 0x28a20000, + 0x7803ffe0, + 0x7804001f, + 0x430106e8, + 0x3863ffff, + 0x38840000, + 0xb0200800, + 0x3c210010, + 0xa0431000, + 0xa0240800, + 0xb8411000, + 0x58a20000, + 0x28a40000, + 0x3403ff0f, + 0x370106a4, + 0x28a20000, + 0xa0832000, + 0x2042000f, + 0x3c420004, + 0xb8822000, + 0x58a40000, + 0xfbffd55a, + 0xe0000003, + 0x34010001, + 0xe0000018, + 0x430206ae, + 0x78010003, + 0x38218ba8, + 0x330206ac, + 0x34020000, + 0x7804c020, + 0x3022002a, + 0x30220011, + 0x388400b0, + 0x28830000, + 0x78020003, + 0x78010002, + 0x38428b24, + 0x38214a68, + 0x58410044, + 0x430206ad, + 0x780100ff, + 0x3821ffff, + 0x3c420018, + 0xa0611800, + 0xb8621800, + 0x58830000, + 0x34010000, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x3401000a, + 0x330106ae, + 0x430206ee, + 0x78070003, + 0x78060002, + 0x78040003, + 0x38848ba8, + 0x38e78b24, + 0x38c6bd64, + 0x34050001, + 0x34010020, + 0x44400002, + 0x330506f8, + 0x58e60044, + 0x3085002a, + 0x30850011, + 0xfbffd4b7, + 0x3401000a, + 0xfbfffe56, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x34010004, + 0x330106ae, + 0x430206ee, + 0x78070003, + 0x78060002, + 0x78040003, + 0x38848ba8, + 0x38e78b24, + 0x38c6bd64, + 0x34050001, + 0x34010020, + 0x44400002, + 0x330506f8, + 0x58e60044, + 0x3085002a, + 0x30850011, + 0xfbffd49f, + 0x34010004, + 0xfbfffe3e, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x7801c020, + 0x38210000, + 0x28210000, + 0x20210001, + 0x64210000, + 0x5c200049, + 0x7804c020, + 0x388400bc, + 0x28810000, + 0x780200ff, + 0x38420000, + 0xa0220800, + 0x00220010, + 0x64410006, + 0x5c200017, + 0x74410006, + 0x5c200004, + 0x64410004, + 0x5c200007, + 0xc3a00000, + 0x64410008, + 0x5c20001f, + 0x6441000a, + 0x5c200029, + 0xc3a00000, + 0x28820000, + 0x780300ff, + 0x3863ffff, + 0x78010400, + 0x38210000, + 0xa0431000, + 0xb8411000, + 0x58820000, + 0x28820000, + 0x78010500, + 0x38210000, + 0xe000000c, + 0x28820000, + 0x780300ff, + 0x3863ffff, + 0x78010600, + 0x38210000, + 0xa0431000, + 0xb8411000, + 0x58820000, + 0x28820000, + 0x78010700, + 0x38210000, + 0xa0431000, + 0xb8411000, + 0x58820000, + 0xc3a00000, + 0x28820000, + 0x780300ff, + 0x3863ffff, + 0x78010800, + 0x38210000, + 0xa0431000, + 0xb8411000, + 0x58820000, + 0x28820000, + 0x78010900, + 0x38210000, + 0xe3fffff1, + 0x28820000, + 0x780300ff, + 0x3863ffff, + 0x78010a00, + 0x38210000, + 0xa0431000, + 0xb8411000, + 0x58820000, + 0x28820000, + 0x78010b00, + 0x38210000, + 0xa0431000, + 0xb8411000, + 0x58820000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x33010824, + 0x34030001, + 0xb8201000, + 0x33010825, + 0x5c200005, + 0x33030826, + 0x2f01073c, + 0x2021ffff, + 0xfbfff8b7, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780bc050, + 0x396b0080, + 0x29620000, + 0x340c0014, + 0xb9800800, + 0x38420020, + 0x59620000, + 0xf8001a95, + 0x29620000, + 0xb9800800, + 0x38420001, + 0x59620000, + 0xf8001a90, + 0x34010000, + 0x33010926, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x43010927, + 0x5c20000b, + 0x7804c050, + 0x38840170, + 0x28830000, + 0x7801dfff, + 0x3821ffff, + 0x78022000, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0x780cc050, + 0xb9800800, + 0x38210194, + 0x28210000, + 0x780b0080, + 0xb9601000, + 0x38420000, + 0xa0220800, + 0x00210017, + 0x202100ff, + 0x64210001, + 0x5c200007, + 0x34010014, + 0xf8001a6b, + 0xb9800800, + 0x38210194, + 0x28210000, + 0xe3fffff4, + 0x34010001, + 0x33010926, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x43010928, + 0x780cc050, + 0xb9805800, + 0x7c210001, + 0x396b0080, + 0x5c20002b, + 0x29620000, + 0x34010014, + 0x20420001, + 0x7c420001, + 0x5c40001d, + 0x43020927, + 0x7805c050, + 0x7804dfff, + 0x78032000, + 0x38a50170, + 0x3884ffff, + 0x38630000, + 0x5c400005, + 0x28a20000, + 0xa0441000, + 0xb8431000, + 0x58a20000, + 0x29620000, + 0x3403fffe, + 0xa0431000, + 0x59620000, + 0xf8001a40, + 0x29620000, + 0x34010014, + 0x38420040, + 0x59620000, + 0xf8001a3b, + 0x29620000, + 0x3403ffbf, + 0x34010014, + 0xa0431000, + 0x59620000, + 0xf8001a35, + 0xfbffffac, + 0xb9801000, + 0x38420080, + 0x28430000, + 0x3404ffdf, + 0x34010014, + 0xa0641800, + 0x58430000, + 0xf8001a2c, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x43010927, + 0x5c20000b, + 0x7804c050, + 0x38840170, + 0x28830000, + 0x7801dfff, + 0x3821ffff, + 0x78022000, + 0xa0611800, + 0x38420000, + 0xb8621800, + 0x58830000, + 0x7801c050, + 0x38210194, + 0x28220000, + 0x78010080, + 0x38210000, + 0xa0411000, + 0x00420017, + 0x7801c050, + 0x33020926, + 0x38210080, + 0x28220000, + 0x43010918, + 0x20420001, + 0x7c210001, + 0x5c20001c, + 0x43010919, + 0x7c210001, + 0x5c200019, + 0x4301091a, + 0x7c210001, + 0x5c200016, + 0x4301091b, + 0x7c210001, + 0x5c200013, + 0x4301091c, + 0x7c210001, + 0x5c200010, + 0x4301091d, + 0x7c210001, + 0x5c20000d, + 0x4301091e, + 0x7c210001, + 0x5c20000a, + 0x43010921, + 0x202300ff, + 0x7c610001, + 0x5c200006, + 0x7c410000, + 0x33030924, + 0x5c200005, + 0xfbffff50, + 0xe0000003, + 0x34010000, + 0x33010924, + 0x34010000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x202100ff, + 0x90005000, + 0x34020000, + 0xd0020000, + 0x20220007, + 0x3c48000f, + 0x7804c050, + 0x7802c050, + 0x7803fffc, + 0xb8403000, + 0x388401c8, + 0x38637fff, + 0x34070001, + 0x38c60118, + 0x20210008, + 0x44200006, + 0x28c10000, + 0x38210020, + 0x58c10000, + 0x3307091e, + 0xe000000a, + 0x28810000, + 0x3402ffdf, + 0xa0230800, + 0xb8280800, + 0x58810000, + 0x28c10000, + 0xa0220800, + 0x58c10000, + 0x3307091e, + 0xd00a0000, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x3301091e, + 0xfbffff62, + 0x7803c050, + 0x38630118, + 0x28610000, + 0x3402ffdf, + 0x7804c050, + 0xa0220800, + 0x58610000, + 0x388401c8, + 0x28820000, + 0x7801fffc, + 0x38217fff, + 0xa0411000, + 0x58820000, + 0xd00b0000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x202100ff, + 0x90005000, + 0x34020000, + 0xd0020000, + 0x20220007, + 0x3c480012, + 0x7804c050, + 0x7802c050, + 0x7803ffe3, + 0xb8403000, + 0x388401c8, + 0x3863ffff, + 0x34070001, + 0x38c60118, + 0x20210008, + 0x44200006, + 0x28c10000, + 0x38210040, + 0x58c10000, + 0x3307091d, + 0xe000000a, + 0x28810000, + 0x3402ffbf, + 0xa0230800, + 0xb8280800, + 0x58810000, + 0x28c10000, + 0xa0220800, + 0x58c10000, + 0x3307091d, + 0xd00a0000, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x3301091d, + 0xfbffff28, + 0x7804c050, + 0x388401c8, + 0x28820000, + 0x7801ffe3, + 0x3821ffff, + 0xa0411000, + 0x7803c050, + 0x58820000, + 0x38630118, + 0x28610000, + 0x3402ffbf, + 0xa0220800, + 0x58610000, + 0xd00b0000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x90003000, + 0x34010000, + 0xd0010000, + 0x34020001, + 0x78010003, + 0x33020928, + 0x38218ba8, + 0x78050003, + 0x30220018, + 0x30220031, + 0x38a5f818, + 0x28a40000, + 0x7801ffbf, + 0x3821ffff, + 0xa0812000, + 0x78020040, + 0x38420000, + 0x78030003, + 0x78010002, + 0xb8822000, + 0x38638b24, + 0x3821c7d8, + 0x58610060, + 0x58a40000, + 0xd0060000, + 0xc3a00000, + 0x90003000, + 0x34010000, + 0xd0010000, + 0x34020000, + 0x78010003, + 0x33020928, + 0x38218ba8, + 0x78050003, + 0x30220031, + 0x30220018, + 0x38a5f818, + 0x28a40000, + 0x7801ffbf, + 0x3821ffff, + 0x78030003, + 0x78020002, + 0xa0812000, + 0x38638b24, + 0x38424a68, + 0x58620060, + 0x58a40000, + 0xd0060000, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0xb8206800, + 0x340c0000, + 0x3d8b0002, + 0x78010003, + 0x382185c0, + 0xb5610800, + 0x28250000, + 0x340400d0, + 0x3406000f, + 0x34010000, + 0xb8201000, + 0xb8201800, + 0xf8002af9, + 0x34010000, + 0xb8201000, + 0xb8201800, + 0x340400d4, + 0x3405000f, + 0xf8002b2a, + 0x358c0001, + 0xb56d5800, + 0x75820006, + 0x59610000, + 0x4440ffeb, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0xb8206800, + 0x340c0000, + 0x3d8b0002, + 0x78010003, + 0x382185c0, + 0xb5610800, + 0x28250000, + 0x340400d0, + 0x3406000f, + 0x34010000, + 0xb8201000, + 0xb8201800, + 0xf8002ad6, + 0xb56d5800, + 0x29650000, + 0x34010000, + 0xb8201000, + 0xb8201800, + 0x340400d4, + 0x3406000f, + 0xf8002ace, + 0x358c0001, + 0x75810006, + 0x4420ffeb, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x7801c000, + 0x38210000, + 0x28210010, + 0x00210017, + 0xf80018f7, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x780de000, + 0x39ad302c, + 0x29a10000, + 0x780cc000, + 0x398c0000, + 0x38210002, + 0x59a10000, + 0x29810010, + 0x29820000, + 0x7801ffff, + 0x38217fff, + 0x298b0000, + 0xa1615800, + 0x598b0000, + 0xfbffffe3, + 0x396b8000, + 0x598b0000, + 0x29a10000, + 0x3402fffd, + 0xa0220800, + 0x59a10000, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x780de000, + 0x39ad302c, + 0x29a10000, + 0x780cc000, + 0x398c0000, + 0x38210002, + 0x59a10000, + 0x29810010, + 0x298b0000, + 0x7801fffd, + 0x3821ffff, + 0xa1615800, + 0x598b0000, + 0xfbffffc4, + 0x78010002, + 0x38210000, + 0xb9615800, + 0x598b0000, + 0x29a10000, + 0x3402fffd, + 0xa0220800, + 0x59a10000, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cffd4, + 0x5b8b002c, + 0x5b8c0028, + 0x5b8d0024, + 0x5b8e0020, + 0x5b8f001c, + 0x5b900018, + 0x5b910014, + 0x5b920010, + 0x5b93000c, + 0x5b940008, + 0x5b950004, + 0x780bc00c, + 0x396b0000, + 0x29680000, + 0x7801c000, + 0x38210000, + 0x28210004, + 0x780dc010, + 0x39ad0000, + 0x29a54068, + 0x7803000f, + 0x38638000, + 0x00a10011, + 0x78043ff0, + 0x29a5406c, + 0x38840000, + 0x20217c00, + 0x3ca2000f, + 0x78134000, + 0x29a54070, + 0xa0431800, + 0xa0441000, + 0xb8230800, + 0xb8220800, + 0x20a20078, + 0xb8220800, + 0x20a20080, + 0xb8220800, + 0x00a30009, + 0x20a20300, + 0xb8220800, + 0x3ca40012, + 0x20620002, + 0xb8220800, + 0x3a730000, + 0x20630004, + 0x78078000, + 0xa0931000, + 0xb8230800, + 0x38e70000, + 0x01060015, + 0xb8220800, + 0xa0872000, + 0x20c60001, + 0xb8240800, + 0x780e8008, + 0x39ce0000, + 0xb8260800, + 0x59c101d4, + 0x29a94068, + 0x780107e0, + 0x38210000, + 0x3d220008, + 0x780a0003, + 0x29a9406c, + 0xa0411000, + 0x394af800, + 0x0123000e, + 0x7805001c, + 0x29a94070, + 0x206107fe, + 0xb8411000, + 0x3d240012, + 0x3d21000d, + 0xa06a1800, + 0x38a50000, + 0x78090800, + 0xa0852000, + 0xb8431000, + 0x39290000, + 0xb8441000, + 0xa0290800, + 0xb8411000, + 0xb8461000, + 0x38018000, + 0x59c201d8, + 0xb5a10800, + 0x28230000, + 0x210f0001, + 0x78050007, + 0x3c620009, + 0x780101ff, + 0x29a34068, + 0x3821f000, + 0x38210e00, + 0xa0220800, + 0x00620012, + 0x78040008, + 0x2043001e, + 0xb8230800, + 0x204201e0, + 0xb8220800, + 0xb82f0800, + 0x59c101dc, + 0x29a34038, + 0x38a5fffe, + 0x38840000, + 0x0061000d, + 0x78021ff0, + 0x29a3403c, + 0xa0250800, + 0x38420000, + 0x3c630013, + 0x78112000, + 0xa0642000, + 0xa0621000, + 0xb8240800, + 0xb8220800, + 0x3a310000, + 0xa0711000, + 0xb8220800, + 0xa0731000, + 0xb8220800, + 0xa0671800, + 0xb8230800, + 0xb82f0800, + 0x59c10180, + 0x29a64000, + 0x78030200, + 0x38630000, + 0x3cc1000a, + 0x78140040, + 0x29a64004, + 0x20210400, + 0x3a940000, + 0x3cc20012, + 0x78120080, + 0x29a6403c, + 0xa0431000, + 0xb8220800, + 0x00c3000c, + 0x00c4000b, + 0x20620002, + 0xb8220800, + 0x20620004, + 0xb8220800, + 0x20620008, + 0xb8220800, + 0x20620010, + 0xb8220800, + 0x20620020, + 0xb8220800, + 0x20620040, + 0xb8220800, + 0x20620080, + 0xb8220800, + 0x20620100, + 0xb8220800, + 0x20630200, + 0x20820800, + 0xb8230800, + 0xb8220800, + 0x20821000, + 0x00c50004, + 0xb8220800, + 0x20822000, + 0x29a62170, + 0xb8220800, + 0x20844000, + 0xa0b41800, + 0xb8240800, + 0xb8230800, + 0x3a520000, + 0x78020100, + 0x38420000, + 0xa0b22000, + 0x3cc30010, + 0x78100400, + 0xa0a22800, + 0xb8240800, + 0x3a100000, + 0xb8250800, + 0xa0701800, + 0xb8230800, + 0xb82f0800, + 0x59c10184, + 0x5961001c, + 0x01010004, + 0x29c20184, + 0x0108000b, + 0x20210001, + 0x21150001, + 0x5c2000c9, + 0x29a12170, + 0x78081000, + 0x39080000, + 0x00210009, + 0x78046000, + 0x2021007e, + 0xb82f0800, + 0x59610018, + 0x29a34000, + 0x38840000, + 0x780500ff, + 0x00620015, + 0x38a50000, + 0x29a34004, + 0x20420600, + 0x7806ff00, + 0x3c61000b, + 0x38c60000, + 0x3c630014, + 0xa02a0800, + 0xb8411000, + 0xa0690800, + 0xb8411000, + 0xa0680800, + 0xa0641800, + 0xb8411000, + 0xb8431000, + 0xb84f1000, + 0x59620004, + 0x29a34004, + 0x78040003, + 0x3884ffc0, + 0x0061001d, + 0x3884003e, + 0x29a34008, + 0x7807e000, + 0x38e73030, + 0x3c630003, + 0x780a0001, + 0x206200f8, + 0xb8220800, + 0x2062ff00, + 0xa0652800, + 0xb8220800, + 0xa0661800, + 0xb8250800, + 0xb8230800, + 0x59610008, + 0x29a14008, + 0x78060001, + 0x38c60000, + 0x0022001c, + 0x394af000, + 0x29a1400c, + 0x2042000e, + 0x780c0001, + 0x3c210004, + 0x398cfffe, + 0x202107f0, + 0xb8411000, + 0xb84f1000, + 0x5962000c, + 0x29a1400c, + 0xb9301000, + 0xb9024000, + 0x00210006, + 0xba284000, + 0xa0812000, + 0xb88f2000, + 0x59640010, + 0x28e10000, + 0xba684000, + 0x38c5c000, + 0x29a24050, + 0x7809003e, + 0x39290000, + 0x00410017, + 0x00430016, + 0x00440015, + 0x206300e0, + 0x20210008, + 0x0042000f, + 0xb8230800, + 0x20840200, + 0xa0461000, + 0xb8240800, + 0xb8220800, + 0x59c152b0, + 0x59c1541c, + 0x29a44048, + 0x780bffff, + 0x396b0000, + 0x00810014, + 0x7807000f, + 0x29a4404c, + 0x20210ffe, + 0x78060030, + 0x3c82000c, + 0x3c830012, + 0xa04a1000, + 0x3c840014, + 0xb8220800, + 0xa0721800, + 0xb8230800, + 0xa0902000, + 0xb8240800, + 0x59c152f8, + 0x29a1404c, + 0x38e7fff0, + 0x38c60000, + 0x3c220006, + 0xb8c73000, + 0x00210006, + 0xa0511000, + 0xa02c0800, + 0xb8220800, + 0x59c152f0, + 0x29a1404c, + 0x780a00c0, + 0x394a0000, + 0x3c210002, + 0x78070f00, + 0xa1014000, + 0x59c852e8, + 0x29a2404c, + 0x38e70000, + 0x78080004, + 0x0041000f, + 0x39080000, + 0x29a24050, + 0xa0a12800, + 0x3c410011, + 0xa0294800, + 0xa0340800, + 0xb8a92800, + 0xb8a12800, + 0x59c552e0, + 0x29a24050, + 0x00450004, + 0x00410005, + 0x20a30020, + 0x2021000e, + 0x00440003, + 0xb8230800, + 0x00430002, + 0x20a50040, + 0x20840100, + 0xb8250800, + 0xb8240800, + 0x20630400, + 0xb8230800, + 0x20422000, + 0xb8220800, + 0x59c152d8, + 0x59c15388, + 0x29a24050, + 0x0044000b, + 0x0041000d, + 0x20830100, + 0x0042000a, + 0x2021003e, + 0xb8230800, + 0x20840600, + 0x20431000, + 0xb8240800, + 0xb8230800, + 0x20432000, + 0x2042c000, + 0xb8230800, + 0xb8220800, + 0x59c15384, + 0x29a14054, + 0x3c22000e, + 0x3c210008, + 0xa04b1000, + 0x20210300, + 0xb8220800, + 0xb82f0800, + 0x59c1538c, + 0x29a14048, + 0x00210004, + 0xa02c0800, + 0xb8350800, + 0x59c152a4, + 0x29a24034, + 0x0041000a, + 0x29a24038, + 0xa0c13000, + 0x3c410016, + 0xa02a5000, + 0xa0270800, + 0xb8ca3000, + 0xb8c13000, + 0xb8d53000, + 0x59c652a8, + 0x29a1400c, + 0x3c210007, + 0xa0280800, + 0xb82f0800, + 0x59c152ac, + 0x2b8b002c, + 0x2b8c0028, + 0x2b8d0024, + 0x2b8e0020, + 0x2b8f001c, + 0x2b900018, + 0x2b910014, + 0x2b920010, + 0x2b93000c, + 0x2b940008, + 0x2b950004, + 0x379c002c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b8d0004, + 0x7801c00c, + 0x38210000, + 0x28280000, + 0x7806c010, + 0x38c60000, + 0x28c54034, + 0x7803000f, + 0x78010030, + 0x00a4000a, + 0x3863fff0, + 0x28c54038, + 0x38210000, + 0x780200c0, + 0x3ca50016, + 0xb8230800, + 0x38420000, + 0xa0a21000, + 0xa0240800, + 0x78030f00, + 0xb8220800, + 0x38630000, + 0x7804f000, + 0xa0a31800, + 0x38840000, + 0x0102000b, + 0xa0a42800, + 0xb8230800, + 0xb8250800, + 0x20420001, + 0x78078008, + 0x38e70000, + 0xb8220800, + 0x58e15564, + 0x28c14038, + 0x0103000c, + 0x780201e0, + 0x3c21000b, + 0x38420000, + 0x20630001, + 0xa0220800, + 0xb8230800, + 0x58e164b4, + 0x28c14068, + 0x01080015, + 0x780d000f, + 0x0021000c, + 0x21080001, + 0x2021007e, + 0xb8280800, + 0x58e15dfc, + 0x28c12170, + 0x39ad0000, + 0x78020003, + 0x3c210001, + 0x3842c00c, + 0x202107fe, + 0xb8230800, + 0x58e16460, + 0x28c14070, + 0xb4e21000, + 0x3804e3fc, + 0x3c21000d, + 0xb4e42000, + 0xa02d0800, + 0xb8280800, + 0x58410000, + 0x28c14070, + 0x78050001, + 0x78030300, + 0x00210009, + 0x38a50000, + 0x20210002, + 0xb8280800, + 0x58810000, + 0x28c14070, + 0x38630000, + 0x780a0003, + 0x3c220010, + 0x394a0800, + 0x3c210009, + 0xa0431000, + 0xa0250800, + 0xb8220800, + 0x38038900, + 0xb4e31800, + 0xb8280800, + 0x78024000, + 0x58610000, + 0xb4ea5000, + 0x38420000, + 0x59420000, + 0x28c14068, + 0x380598f4, + 0xb4e52800, + 0x00210003, + 0x7802001f, + 0xa02d0800, + 0xb8280800, + 0x58a10000, + 0x28c94068, + 0x38420000, + 0x780303e0, + 0x0121000b, + 0x38630000, + 0x28c9406c, + 0xa0220800, + 0x380c89bc, + 0x3d220015, + 0xb4ec6000, + 0x28c94070, + 0xa0431000, + 0xb8220800, + 0x0123000a, + 0x01240009, + 0x20620002, + 0xb8220800, + 0x20630004, + 0x0122000b, + 0xb8230800, + 0x20840010, + 0xb8240800, + 0x20420008, + 0xb8220800, + 0xb8280800, + 0x59810000, + 0x28c1406c, + 0x780303ff, + 0x38630000, + 0x3c210001, + 0x38028c1c, + 0xb4e23800, + 0xa0230800, + 0xb8280800, + 0x78024001, + 0x58e10000, + 0x38420000, + 0x59420000, + 0x28c14068, + 0x7809007f, + 0x780b0380, + 0x00210007, + 0x39290000, + 0xa02d0800, + 0xb8280800, + 0x58a10000, + 0x28cd406c, + 0x396b0000, + 0x7805e000, + 0x3da1000b, + 0x38a50000, + 0x28cd4070, + 0xa0230800, + 0x01a3000a, + 0x01a40009, + 0x20620002, + 0xb8220800, + 0x20630004, + 0x01a2000b, + 0xb8230800, + 0x20840010, + 0xb8240800, + 0x20420008, + 0xb8220800, + 0xb8280800, + 0x59810000, + 0x28c1406c, + 0x00220009, + 0x28c14070, + 0xa0491000, + 0x3c210017, + 0xa02b0800, + 0xb8411000, + 0xb8481000, + 0x58e20000, + 0x59450000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b8d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x780cc000, + 0x398c0000, + 0x298d0014, + 0x7802c00c, + 0x38420000, + 0x29810010, + 0x7805c050, + 0x38a50118, + 0x298b0000, + 0x7801fff7, + 0x3821ffff, + 0x284e0000, + 0xa1615800, + 0x7803ffdf, + 0x28a10000, + 0x7802ffef, + 0x3842ffff, + 0x38210020, + 0x58a10000, + 0xa1625800, + 0x3863ffff, + 0x7801f7ff, + 0x28a40000, + 0xa1635800, + 0x3821ffff, + 0xa1615800, + 0x7802efff, + 0x3842ffff, + 0x7801fffe, + 0xa1625800, + 0x3821ffff, + 0x38840040, + 0xa1615800, + 0x58a40000, + 0x598b0000, + 0xfbfffd3d, + 0x78010008, + 0x38210000, + 0x78020010, + 0xb9615800, + 0x38420000, + 0xb9625800, + 0x78010020, + 0x38210000, + 0x78020800, + 0xb9615800, + 0x38420000, + 0xb9625800, + 0x01ad001e, + 0x78011000, + 0x38210000, + 0x78020001, + 0xb9615800, + 0x38420000, + 0x21ad0001, + 0x01ce0004, + 0xb9625800, + 0x65ad0000, + 0x598b0000, + 0x21ce0001, + 0x5da00003, + 0x5dc00002, + 0xfbffff04, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780be000, + 0x396b302c, + 0x29610000, + 0x38210002, + 0x59610000, + 0x2b212f4c, + 0x38210001, + 0x5b212f4c, + 0x34010004, + 0x5b2120ac, + 0xf8000d84, + 0xfbffffa6, + 0xf8000dbf, + 0x2b212f4c, + 0x3402fffe, + 0xa0220800, + 0x5b212f4c, + 0x34010000, + 0x5b2120ac, + 0x29610000, + 0x3402fffd, + 0xa0220800, + 0x59610000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x780cc000, + 0x398c0000, + 0x29820010, + 0x7806c050, + 0x38c60118, + 0x298b0000, + 0x7802c00c, + 0x38420000, + 0x284e0000, + 0x7803ffef, + 0x3863ffff, + 0x7802fff7, + 0x3842ffff, + 0x28c50000, + 0xa1625800, + 0x7804ffdf, + 0xa1635800, + 0x3884ffff, + 0x7802f7ff, + 0xa1645800, + 0x3842ffff, + 0x38a50020, + 0xa1625800, + 0x7803efff, + 0x58c50000, + 0x3863ffff, + 0x7802fffe, + 0x28c40000, + 0xa1635800, + 0x3842ffff, + 0xa1625800, + 0x3402ffdf, + 0x7803fffd, + 0xa1625800, + 0x38840040, + 0x3863ffff, + 0xa1635800, + 0x58c40000, + 0x598b0000, + 0x202d00ff, + 0xfbfffcce, + 0x396b0020, + 0x598b0000, + 0x45a00002, + 0xfbfffd15, + 0x78010008, + 0x38210000, + 0x78020010, + 0xb9615800, + 0x38420000, + 0xb9625800, + 0x78010020, + 0x38210000, + 0x78020800, + 0xb9615800, + 0x38420000, + 0x78031000, + 0xb9625800, + 0x38630000, + 0x78010001, + 0xb9635800, + 0x38210000, + 0x01c20004, + 0xb9615800, + 0x7da30000, + 0xa4401000, + 0x78010002, + 0xa0431000, + 0x38210000, + 0x396b8000, + 0xb9615800, + 0x64420000, + 0x598b0000, + 0x5c400002, + 0xfbfffe8e, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cffc8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x780fe000, + 0xb9e01800, + 0x3863302c, + 0x28610000, + 0x7802c000, + 0x38420000, + 0x38210002, + 0x58610000, + 0x284d0010, + 0x7801c00c, + 0x38210000, + 0x282b0000, + 0x378e001c, + 0x01ad0001, + 0x284c0014, + 0x016b0006, + 0x21ad0001, + 0x2b212f4c, + 0x018c001e, + 0x216b0001, + 0x38210001, + 0x5b212f4c, + 0x34010004, + 0x5b2120ac, + 0xf8000cfc, + 0xb9c00800, + 0xfbfffc3d, + 0x21810001, + 0x64220000, + 0x5dab0005, + 0x5c400002, + 0x34010001, + 0xfbffff81, + 0xe0000002, + 0xfbffff15, + 0xf8000d2e, + 0xb9c00800, + 0xfbfffc55, + 0x2b212f4c, + 0x3402fffe, + 0xb9e01800, + 0xa0220800, + 0x5b212f4c, + 0x34010000, + 0x5b2120ac, + 0x3863302c, + 0x28610000, + 0x3402fffd, + 0xa0220800, + 0x58610000, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0038, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780be000, + 0xb9601800, + 0x3863302c, + 0x28610000, + 0x7802c000, + 0x38420000, + 0x38210002, + 0x58610000, + 0x28420014, + 0x34010001, + 0x0043001f, + 0x4c400002, + 0xe0000002, + 0xb8600800, + 0xfbffff56, + 0xb9600800, + 0x3821302c, + 0x28220000, + 0x3403fffd, + 0xa0431000, + 0x58220000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x78058002, + 0x38a50000, + 0x58a10000, + 0x78030003, + 0x78040003, + 0x58a20004, + 0x38638dc8, + 0x38848dcc, + 0x58610000, + 0x58820000, + 0xc3a00000, + 0x78028002, + 0x38420000, + 0x28410020, + 0x20210001, + 0x64210000, + 0x4420fffd, + 0xc3a00000, + 0x78018002, + 0x38210000, + 0x28210020, + 0xc3a00000, + 0x78058002, + 0x38a50000, + 0x28a40008, + 0x78030800, + 0x38630001, + 0x58830000, + 0x34840004, + 0x58810000, + 0x34840004, + 0x58820000, + 0x34840004, + 0x58a40008, + 0xc3a00000, + 0x78088002, + 0xb9001800, + 0x38630000, + 0x28640008, + 0x00420002, + 0x34050000, + 0x50a20010, + 0x78070003, + 0x78060003, + 0x38e78dcc, + 0x38c68dc8, + 0xb8201800, + 0x28610000, + 0x34a50001, + 0x58810000, + 0x28e10000, + 0x34840004, + 0x34630004, + 0x50240002, + 0x28c40000, + 0x50a20002, + 0xe3fffff7, + 0x39080000, + 0x59040008, + 0xc3a00000, + 0x78038002, + 0x38630000, + 0x28640008, + 0x34050001, + 0x58850000, + 0x34840004, + 0x58810000, + 0x34840004, + 0x58820000, + 0x34840004, + 0x58640008, + 0xc3a00000, + 0x58220000, + 0xc3a00000, + 0x28220000, + 0x28230004, + 0x3c420002, + 0x7801c200, + 0x38210000, + 0xb4411000, + 0x58430000, + 0xc3a00000, + 0x2063ffff, + 0x20420007, + 0x20650f00, + 0x3c420008, + 0x2021001f, + 0x3c21000b, + 0x206300ff, + 0xb8621800, + 0xb8611800, + 0x3ca50008, + 0x7801c200, + 0xb8651800, + 0x38210000, + 0xb8611800, + 0x58640000, + 0xc3a00000, + 0x28210000, + 0xc3a00000, + 0x28230000, + 0x7802c200, + 0x38420000, + 0x3c630002, + 0xb4621800, + 0x28620000, + 0x58220004, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b8c0004, + 0xb8205800, + 0xb8405000, + 0xb8604800, + 0x208400ff, + 0x34010000, + 0x50230016, + 0x7807c200, + 0x38e70000, + 0xe4812000, + 0xb8e06000, + 0x3c230002, + 0x34280001, + 0xb46b1000, + 0x3c420002, + 0xb46a3000, + 0xb8400800, + 0xb44c1000, + 0xb4272800, + 0x5c800004, + 0x28c10000, + 0x58a10000, + 0xe0000003, + 0x28410000, + 0x58c10000, + 0xb9000800, + 0x51090002, + 0xe3fffff0, + 0x2b8b0008, + 0x2b8c0004, + 0x379c0008, + 0xc3a00000, + 0xb8403800, + 0xb8204000, + 0x206300ff, + 0x34020000, + 0x50470017, + 0x7805c200, + 0x38a50000, + 0xe4621800, + 0xb8a04800, + 0x3c410003, + 0x34460001, + 0xb4282000, + 0x5c600007, + 0x28810000, + 0x28820004, + 0x3c210002, + 0xb4250800, + 0x58220000, + 0xe0000006, + 0x28810000, + 0x3c210002, + 0xb4290800, + 0x28210000, + 0x58810004, + 0xb8c01000, + 0x50c70002, + 0xe3ffffef, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x7803c020, + 0x38630004, + 0x28620000, + 0x202c00ff, + 0x7801c201, + 0x3842000c, + 0x58620000, + 0x3821c574, + 0xfbffffac, + 0x780b0003, + 0x00230016, + 0xb9601000, + 0x38428acc, + 0x58410038, + 0x20630001, + 0x5c60000a, + 0x7801c201, + 0x3821c574, + 0xfbffffa2, + 0x00220016, + 0xb9601800, + 0x38638acc, + 0x58610038, + 0x20420001, + 0x4440fff8, + 0x78040003, + 0x38848acc, + 0x28820034, + 0x21810003, + 0x3403ff3f, + 0x3c210006, + 0xa0431000, + 0xb8411000, + 0x7801c201, + 0x58820034, + 0x3821c570, + 0xfbffff76, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x7803c020, + 0x38630004, + 0x28620000, + 0x202c00ff, + 0x3401fffb, + 0xa0411000, + 0x3401fff7, + 0xa0411000, + 0x7801c201, + 0x58620000, + 0x3821c574, + 0xfbffff7b, + 0x780b0003, + 0x00230015, + 0xb9601000, + 0x38428acc, + 0x58410038, + 0x20630002, + 0x4460000a, + 0x7801c201, + 0x3821c574, + 0xfbffff71, + 0x00220015, + 0xb9601800, + 0x38638acc, + 0x58610038, + 0x20420002, + 0x5c40fff8, + 0x78040003, + 0x38848acc, + 0x28820034, + 0x21810003, + 0x3403ffe7, + 0x3c210003, + 0xa0431000, + 0xb8411000, + 0x7801c201, + 0x58820034, + 0x3821c570, + 0xfbffff45, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x202d00ff, + 0x34030001, + 0x204c00ff, + 0x7801c020, + 0xb8601000, + 0x33030778, + 0x38210130, + 0xfbffdaad, + 0x780ec020, + 0xb9c00800, + 0x38210004, + 0x282f0000, + 0x780b0003, + 0x396b8acc, + 0x7801c201, + 0x3821c574, + 0xfbffff42, + 0x29640034, + 0x00230015, + 0x59610038, + 0x00810003, + 0x00820006, + 0x20630002, + 0x20210003, + 0x20450003, + 0x5c610007, + 0xb9800800, + 0x20820003, + 0x49a30009, + 0x49a20008, + 0xb9a00800, + 0xe000000a, + 0xb9a00800, + 0x20820003, + 0x48ac0007, + 0x49820006, + 0xb9800800, + 0xfbffffa3, + 0xb9a00800, + 0xfbffff73, + 0xe0000004, + 0xfbffff71, + 0xb9800800, + 0xfbffff9d, + 0x39ce0004, + 0x34040000, + 0x59cf0000, + 0x7801c020, + 0x38210130, + 0x34020001, + 0xb8801800, + 0x33040778, + 0xfbffda80, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780c0003, + 0xb9800800, + 0x38218b1c, + 0x43030779, + 0x28220000, + 0x206400ff, + 0x4301077a, + 0x40420005, + 0x202100ff, + 0x20230001, + 0x44400002, + 0x34030000, + 0xb9800800, + 0x38218b1c, + 0x28210000, + 0x40210006, + 0x5c200004, + 0x20810001, + 0xb8230800, + 0xe0000002, + 0x7c610000, + 0x4420002f, + 0xb9801000, + 0x38428b1c, + 0x28410000, + 0x40210007, + 0x3301077c, + 0x28410000, + 0x40210007, + 0x3301077d, + 0x4301077b, + 0x202b00ff, + 0x5d600010, + 0x28410000, + 0x40210004, + 0x4420000b, + 0x78030003, + 0x38638acc, + 0x2862003c, + 0x3404ffdf, + 0x7801c201, + 0xa0441000, + 0x5862003c, + 0x3821c588, + 0xfbfffecb, + 0x330b0782, + 0x34010001, + 0x3301077b, + 0x43010785, + 0x5c200049, + 0x43010787, + 0x202b00ff, + 0x5d600046, + 0x398c8b1c, + 0x29810000, + 0x40220001, + 0x40210000, + 0xfbffff7f, + 0x78020003, + 0x78010002, + 0x330b0784, + 0x38428b24, + 0x3821e2a4, + 0x58410028, + 0x330b0783, + 0x330b0786, + 0x330b0788, + 0xe0000037, + 0x43010785, + 0x5c20001e, + 0x43010787, + 0x202b00ff, + 0x5d60001b, + 0x4301077b, + 0x5c200009, + 0x398c8b1c, + 0x29810000, + 0x40220003, + 0x40210002, + 0xfbffff69, + 0x34010001, + 0x33010784, + 0xe0000007, + 0x398c8b1c, + 0x29810000, + 0x40220001, + 0x40210000, + 0xfbffff61, + 0x330b0784, + 0x78010003, + 0x78020002, + 0x38218b24, + 0x3842e2a4, + 0x58220028, + 0x34010000, + 0x33010783, + 0x33010786, + 0x33010788, + 0xe0000018, + 0x4301077c, + 0x44200016, + 0x4301077c, + 0x3421ffff, + 0x3301077c, + 0x4301077c, + 0x202b00ff, + 0x5d600010, + 0x398c8b1c, + 0x29810000, + 0x40210004, + 0x4420000b, + 0x78030003, + 0x38638acc, + 0x2862003c, + 0x7801c201, + 0x3821c588, + 0x38420020, + 0x5862003c, + 0xfbfffe81, + 0x34010001, + 0x33010782, + 0x330b077b, + 0x34010001, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x43010785, + 0x5c200004, + 0x43010787, + 0x202400ff, + 0x4480001e, + 0x43010785, + 0x78020003, + 0x780c0003, + 0x780b0002, + 0x4420000b, + 0x38428b1c, + 0x28410000, + 0x40220001, + 0x40210000, + 0xfbffff26, + 0x34010000, + 0x33010784, + 0x34010001, + 0x33010786, + 0xe0000009, + 0x38428b1c, + 0x28410000, + 0x40220003, + 0x40210002, + 0xfbffff1c, + 0x34010001, + 0x33010784, + 0x33010788, + 0x398c8b24, + 0x396be094, + 0x598b0028, + 0x34010005, + 0x33010783, + 0xe0000055, + 0x78060003, + 0xb8c00800, + 0x38218b1c, + 0x43030779, + 0x28220000, + 0x206500ff, + 0x4301077a, + 0x40420005, + 0x202100ff, + 0x20230001, + 0x44400002, + 0xb8801800, + 0xb8c00800, + 0x38218b1c, + 0x28210000, + 0x40210006, + 0x5c200005, + 0x20a10001, + 0xb8230800, + 0x5c200003, + 0xe0000022, + 0x44600021, + 0xb8c06000, + 0x398c8b1c, + 0x29810000, + 0x40210007, + 0x3301077c, + 0x29810000, + 0x40210007, + 0x3301077d, + 0x4301077b, + 0x202b00ff, + 0x5d600034, + 0x29810000, + 0x40210004, + 0x4420000b, + 0x78030003, + 0x38638acc, + 0x2862003c, + 0x3404ffdf, + 0x7801c201, + 0xa0441000, + 0x5862003c, + 0x3821c588, + 0xfbfffe25, + 0x330b0782, + 0x29810000, + 0x40220001, + 0x40210000, + 0xfbfffee1, + 0x34010001, + 0x3301077b, + 0x330b0784, + 0xe000001f, + 0x4301077c, + 0x4420001d, + 0x4301077c, + 0x3421ffff, + 0x3301077c, + 0x4301077c, + 0x202100ff, + 0x5c200017, + 0xb8c05800, + 0x3301077b, + 0x396b8b1c, + 0x29610000, + 0x40210004, + 0x4420000b, + 0x78030003, + 0x38638acc, + 0x2862003c, + 0x7801c201, + 0x3821c588, + 0x38420020, + 0x5862003c, + 0xfbfffe06, + 0x34010001, + 0x33010782, + 0x29610000, + 0x40220003, + 0x40210002, + 0xfbfffec1, + 0x34010001, + 0x33010784, + 0x34010000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x78020003, + 0x3842f9d8, + 0x28420000, + 0x780d0003, + 0x7801c201, + 0x20420020, + 0x78070003, + 0x780e0003, + 0x78050003, + 0x7806c020, + 0x78040003, + 0x78030002, + 0x004c0005, + 0x39ad8b1c, + 0x340b0000, + 0x3821c570, + 0x39ce8acc, + 0x38e7f824, + 0x38a58ba8, + 0x38c60004, + 0x38848b24, + 0x3863e2a4, + 0x444b0039, + 0x330c0789, + 0x330c0779, + 0x330c077a, + 0x330c077f, + 0x29a20000, + 0x40420007, + 0x3302077c, + 0x29a20000, + 0x40420007, + 0x3302077d, + 0x330b0781, + 0x330b0785, + 0x330b0786, + 0x330b0787, + 0x330b0788, + 0x330c077b, + 0x330b0784, + 0x28e20000, + 0x58830028, + 0x30a2000a, + 0x30a20023, + 0x28c20000, + 0x00430004, + 0x38440014, + 0x3402fff7, + 0xa0822000, + 0x20630001, + 0x5c6b0002, + 0x58c40000, + 0xfbfffdd7, + 0x59c10034, + 0x7801c201, + 0x3821c588, + 0xfbfffdd3, + 0x29a30000, + 0x59c1003c, + 0x3402ffdf, + 0xa0222000, + 0x40630004, + 0x7801c201, + 0x3821c588, + 0xb8801000, + 0x44600004, + 0x59c4003c, + 0xfbfffdae, + 0x330b0782, + 0x29a10000, + 0x40220001, + 0x40210000, + 0xfbfffe6a, + 0x78020003, + 0x3842f818, + 0x28410000, + 0x38210400, + 0x58410000, + 0x330c078a, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x4301078a, + 0x780c0003, + 0x340b0000, + 0x398c8b1c, + 0x442b0026, + 0x330b0789, + 0x29820000, + 0x78040003, + 0x7801c201, + 0x40420004, + 0x38848acc, + 0x3821c588, + 0x444b0007, + 0x2882003c, + 0x3403ffdf, + 0xa0431000, + 0x5882003c, + 0xfbfffd86, + 0x330b0782, + 0x29810000, + 0x40220001, + 0x40210000, + 0xfbfffe42, + 0x34010001, + 0x3301077b, + 0x78010003, + 0x330b0784, + 0x38218ba8, + 0x78050003, + 0x302b000a, + 0x302b0023, + 0x38a5f818, + 0x28a40000, + 0x78030003, + 0x78020002, + 0x3401fbff, + 0xa0812000, + 0x38638b24, + 0x38424a68, + 0x58620028, + 0x58a40000, + 0x330b078a, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x7803c020, + 0x38630004, + 0x28620000, + 0x43010781, + 0x7c210001, + 0x5c200003, + 0x3842000c, + 0xe0000009, + 0x4301077f, + 0x5c200004, + 0x3401fffb, + 0xa0411000, + 0xe0000002, + 0x38420004, + 0x3401fff7, + 0xa0411000, + 0x58620000, + 0x34010000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780cc020, + 0xb9801800, + 0x38630130, + 0x28620000, + 0x7801c200, + 0x3821c5f4, + 0x38420010, + 0x58620000, + 0x780b0003, + 0xfbfffd62, + 0x396b8acc, + 0x59610018, + 0x7801c200, + 0x3821c5e0, + 0xfbfffd5d, + 0x29630018, + 0x59610008, + 0x34010000, + 0x78040003, + 0x5b010150, + 0x38848c00, + 0x0063001d, + 0x40820018, + 0xb4641800, + 0x78010003, + 0x40630000, + 0x382185dc, + 0xb4411000, + 0x10410000, + 0x08630019, + 0x34051838, + 0x3c210002, + 0xc8a32800, + 0xb4a12800, + 0x3ca2000f, + 0x34010fa0, + 0x8c412800, + 0x29630008, + 0x398c0130, + 0x780103ff, + 0x3821fff0, + 0xa0610800, + 0x3c210006, + 0x2063000f, + 0x1421000a, + 0x34630001, + 0x94230800, + 0x29620014, + 0x2c830082, + 0x20420fff, + 0xc8411000, + 0x88431000, + 0x3c42000e, + 0x8c451000, + 0x00420001, + 0x0f020148, + 0x2b01014c, + 0xb4220800, + 0x5b01014c, + 0x2f01014a, + 0x34210001, + 0x0f01014a, + 0x43010830, + 0x4420000b, + 0x43010831, + 0x14a20003, + 0x7c210010, + 0x5c200007, + 0x2b0108b8, + 0xb4220800, + 0x5b0108b8, + 0x2b010914, + 0x34210001, + 0x5b010914, + 0x29810000, + 0x3402ffef, + 0xa0220800, + 0x59810000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x202100ff, + 0x7c210001, + 0x5c20002c, + 0x34040000, + 0xb4840800, + 0xb4380800, + 0x34030000, + 0x34840001, + 0x0c230128, + 0x74820007, + 0x0c230138, + 0x4443fff9, + 0x0f030148, + 0x0f03014a, + 0x7801c202, + 0x5b03014c, + 0x3821c450, + 0xfbfffd05, + 0x78020003, + 0x38428acc, + 0x58410014, + 0x78038000, + 0x38638000, + 0x34010010, + 0x58610054, + 0x34010001, + 0xf8001194, + 0x78010003, + 0x78030003, + 0x3821f830, + 0x3863f900, + 0x28220000, + 0x28630000, + 0x34010001, + 0x88431000, + 0x34030064, + 0x34420032, + 0x8c431000, + 0xf800119d, + 0x34010024, + 0xfbffcb6c, + 0x78020003, + 0x3842f818, + 0x28410000, + 0x38211000, + 0xe000000e, + 0x78018000, + 0x34020010, + 0x38218000, + 0x58220054, + 0x34010024, + 0xfbffcb8e, + 0x34010001, + 0xf8001184, + 0x78020003, + 0x3842f818, + 0x28410000, + 0x3403efff, + 0xa0230800, + 0x58410000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0xc3a00000, + 0xc3a00000, + 0x379cffe4, + 0x5b8b001c, + 0x5b8c0018, + 0x5b8d0014, + 0x5b8e0010, + 0x5b8f000c, + 0x5b900008, + 0x5b9d0004, + 0x90006000, + 0x34010000, + 0xd0010000, + 0x7801c200, + 0x3821c5c4, + 0x780b0003, + 0x396b8acc, + 0xfbfffcc6, + 0x59610000, + 0xd00c0000, + 0x78100003, + 0xba001800, + 0x38638acc, + 0x40610000, + 0x44200082, + 0x2861000c, + 0x780f001f, + 0x780e0010, + 0x00240010, + 0x28630000, + 0xb9e00800, + 0x3821ffff, + 0xa0616000, + 0x7802fff0, + 0xb9c00800, + 0x38420000, + 0x38210000, + 0x208400ff, + 0xa1810800, + 0xb9821800, + 0x5c200002, + 0xb9801800, + 0xba005800, + 0x396b8acc, + 0x41650000, + 0x2b0102cc, + 0x780d0003, + 0x88851000, + 0xc8616000, + 0xb9a01800, + 0xc84c6000, + 0x6d810000, + 0x38638c00, + 0xc8010800, + 0xa1816000, + 0x3d8c0007, + 0x2c620082, + 0x8d850800, + 0x34040010, + 0x39ce0000, + 0x88220800, + 0x34210100, + 0x00210009, + 0x0f0102c4, + 0x2f0102c4, + 0x2f0206a0, + 0x2021ffff, + 0x2f0302b0, + 0x2042ffff, + 0x2063ffff, + 0xfbffce3f, + 0x0f0106a0, + 0x2b020198, + 0x7801c201, + 0x3821c40c, + 0x3162000d, + 0x2962000c, + 0xfbfffc70, + 0x78050003, + 0x38a5fa64, + 0x28a40000, + 0x7802fffe, + 0x38420001, + 0x2b030198, + 0x78010001, + 0x3821fffe, + 0x3c630001, + 0xa0822000, + 0x29660000, + 0xa0611800, + 0xb9e01000, + 0x3842ffff, + 0x7801fff0, + 0xa0c23000, + 0xb8832000, + 0x38210000, + 0x58a40000, + 0xa0ce1000, + 0xb8c11800, + 0x5c400002, + 0xb8c01800, + 0x2b01069c, + 0x7c210002, + 0x5c20001e, + 0x34010000, + 0x4c23001f, + 0x39ad8c00, + 0x41a30045, + 0x78010003, + 0x38218bf8, + 0xb4611800, + 0x40640000, + 0xba002800, + 0x38a58acc, + 0x28a20000, + 0xb9e01800, + 0x3863ffff, + 0xa0430800, + 0x88246000, + 0x7801ffe0, + 0x158c0007, + 0x38210000, + 0xa0411000, + 0xa1831800, + 0xb8431000, + 0x7801c200, + 0x3821c5c4, + 0x58a20000, + 0xfbfffc3d, + 0x34010001, + 0x5b01069c, + 0x5b0c02cc, + 0xe0000005, + 0x2b01069c, + 0x34210001, + 0x5b01069c, + 0x5b0302cc, + 0x2f010240, + 0x78030003, + 0x3863f9b0, + 0x2021ffff, + 0x00210008, + 0x78020003, + 0x08210083, + 0x3842f9b4, + 0x34210100, + 0x00210009, + 0x0f0102ca, + 0x2f0102c4, + 0x2021ffff, + 0x58610000, + 0x2f0102ca, + 0x2021ffff, + 0x58410000, + 0x34010000, + 0x2b8b001c, + 0x2b8c0018, + 0x2b8d0014, + 0x2b8e0010, + 0x2b8f000c, + 0x2b900008, + 0x2b9d0004, + 0x379c001c, + 0xc3a00000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x78010003, + 0x38218c00, + 0x40220099, + 0xb8205800, + 0x5c400003, + 0x780b0003, + 0x396bfa80, + 0x7801c210, + 0x38210034, + 0x28220000, + 0x780c0003, + 0xb9801800, + 0x3863fa64, + 0x28610000, + 0x20420001, + 0x64420000, + 0x38210001, + 0x58610000, + 0x34060000, + 0x44460016, + 0x7801c200, + 0x3821c5f0, + 0xfbfffc18, + 0x00220001, + 0x00230003, + 0x00240005, + 0x20420001, + 0x20630001, + 0x00250007, + 0x64460000, + 0x64630000, + 0x20840001, + 0x64840000, + 0x20a50001, + 0xb4c33000, + 0x64a50000, + 0x78020003, + 0xb4c43000, + 0x38428acc, + 0x5841004c, + 0xb4c53000, + 0xb9802000, + 0x3884fa64, + 0x28820000, + 0x7801ffe1, + 0x3821ffff, + 0x3cc30011, + 0xa0411000, + 0xb8431000, + 0x58820000, + 0x2b02017c, + 0x3cc30004, + 0x2b010178, + 0xc8621000, + 0xb4220800, + 0x5b010178, + 0x2b020184, + 0x2b010180, + 0xc8621800, + 0xb4230800, + 0x5b010180, + 0x43010779, + 0x7c210001, + 0x5c200004, + 0x2b010188, + 0x34210100, + 0x5b010188, + 0x2b010188, + 0x2b02018c, + 0xc8220800, + 0x5b010188, + 0x2b020178, + 0x4301019c, + 0x3c420002, + 0x202100ff, + 0x8c411000, + 0x5b02017c, + 0x4301019f, + 0x2b02017c, + 0x202100ff, + 0x50410003, + 0x416100b5, + 0xe0000008, + 0x430101a0, + 0x2b02017c, + 0x202100ff, + 0x50410003, + 0x416100b6, + 0xe0000002, + 0x416100b4, + 0x5b010190, + 0x4301019d, + 0x2b020180, + 0x202100ff, + 0x8c411000, + 0x5b020184, + 0x430101a2, + 0x2b020184, + 0x202100ff, + 0x50220003, + 0x416100b4, + 0xe0000008, + 0x430101a1, + 0x2b020184, + 0x202100ff, + 0x50220003, + 0x416100b6, + 0xe0000002, + 0x416100b5, + 0x5b010194, + 0x2b020190, + 0x2b010194, + 0x50220003, + 0x2b010194, + 0xe0000002, + 0x2b010190, + 0x5b010198, + 0x2b020188, + 0x4301019e, + 0x3c420002, + 0x202100ff, + 0x8c411000, + 0x5b02018c, + 0x430101a3, + 0x2b02018c, + 0x202100ff, + 0x50410009, + 0x2f0101a4, + 0x2b020198, + 0x2021ffff, + 0x88411000, + 0x5b020198, + 0x2b010198, + 0x00210007, + 0x5b010198, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffe0, + 0x5b8b0020, + 0x5b8c001c, + 0x5b8d0018, + 0x5b8e0014, + 0x5b8f0010, + 0x5b90000c, + 0x5b910008, + 0x5b9d0004, + 0x78020003, + 0x38428c00, + 0x40430099, + 0x202b00ff, + 0x5c600003, + 0x78020003, + 0x3842fa80, + 0x2c410032, + 0x780d0003, + 0x780c0003, + 0x3c210008, + 0x340203e8, + 0xf80022a1, + 0x0f0102ee, + 0x34010001, + 0x5b01069c, + 0x780e0003, + 0x78100003, + 0x780f8000, + 0x78110003, + 0x4560005c, + 0x7801c201, + 0x3821c2b4, + 0xfbfffb82, + 0x78020200, + 0x38420000, + 0xb8221000, + 0x7801c201, + 0x3821c2b4, + 0xfbfffb62, + 0x78010003, + 0x340b0000, + 0x3821f9b0, + 0x78020003, + 0x582b0004, + 0x582b0000, + 0x3842f998, + 0x584b0000, + 0x0f0b02c4, + 0x0f0b02c0, + 0x0f0b02ca, + 0x0f0b02c8, + 0x5b0b02cc, + 0x0f0b02c4, + 0x0f0b0300, + 0x0f0b02fc, + 0x0f0b0302, + 0x7801c201, + 0x0f0b02fe, + 0x3821c40c, + 0xfbfffb67, + 0xb9a01800, + 0x38638c00, + 0x406200b7, + 0x398c8acc, + 0x5981000c, + 0x3302019c, + 0x406100b8, + 0x78050003, + 0x38a5f82c, + 0x3301019d, + 0x406100b9, + 0xba003000, + 0x38c68ba8, + 0x3301019e, + 0x406100ba, + 0x78040002, + 0x3884e994, + 0x3301019f, + 0x406100bb, + 0x39ce8b24, + 0x39ef8000, + 0x330101a0, + 0x406200bc, + 0x34010002, + 0x330201a1, + 0x406200bd, + 0x330201a2, + 0x406200be, + 0x330201a3, + 0x2c6200c0, + 0x59c40024, + 0x0f0201a4, + 0x5b0b0178, + 0x5b0b017c, + 0x5b0b0180, + 0x5b0b0184, + 0x5b0b0188, + 0x5b0b018c, + 0x28a20000, + 0x30c20009, + 0x30c20022, + 0x34020100, + 0x59e20054, + 0xf8000fd3, + 0x78010003, + 0x3821f900, + 0x28220000, + 0x34030064, + 0x084200c8, + 0x34010002, + 0x34420032, + 0x8c431000, + 0xf8000fdf, + 0x34010028, + 0xfbffc9ae, + 0xba201000, + 0x3842f818, + 0x28410000, + 0x38210100, + 0x58410000, + 0xe0000028, + 0x39ad8c00, + 0x41ad00aa, + 0xb9801000, + 0x38428acc, + 0x304d000d, + 0x2842000c, + 0x7801c201, + 0x3821c40c, + 0xfbfffb07, + 0x78010002, + 0x38214a68, + 0x39ce8b24, + 0xba001000, + 0x38428ba8, + 0x59c10024, + 0x304b0009, + 0x304b0022, + 0x34010100, + 0x39ef8000, + 0x59e10054, + 0x34010028, + 0xfbffc9bf, + 0x34010002, + 0xf8000fb5, + 0xba202000, + 0x3884f818, + 0x28820000, + 0x3403feff, + 0x7801c201, + 0xa0431000, + 0x58820000, + 0x3821c2b4, + 0xfbfffb09, + 0x7802fdff, + 0x3842ffff, + 0xa0221000, + 0x7801c201, + 0x3821c2b4, + 0xfbfffae9, + 0x2b8b0020, + 0x2b8c001c, + 0x2b8d0018, + 0x2b8e0014, + 0x2b8f0010, + 0x2b90000c, + 0x2b910008, + 0x2b9d0004, + 0x379c0020, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x90007000, + 0x34010000, + 0xd0010000, + 0x2b0d007c, + 0x7da10001, + 0x5c20004c, + 0x340c0000, + 0x7801c201, + 0x5b0c007c, + 0x3821c45c, + 0x780b0003, + 0xfbfffae7, + 0x396b8acc, + 0x59610040, + 0xb8201800, + 0x43010698, + 0x3402fffc, + 0xa0621800, + 0x20210003, + 0xb8611800, + 0x59630040, + 0x43020699, + 0x3401ff7f, + 0xa0611800, + 0x20420001, + 0x3c420007, + 0x7801c201, + 0xb8621800, + 0xb8601000, + 0x59630040, + 0x3821c45c, + 0xfbfffab9, + 0x7801c201, + 0x3821c570, + 0xfbfffad0, + 0x59610034, + 0x4303069a, + 0xb8201000, + 0x3401f1ff, + 0x20630007, + 0x3c630009, + 0xa0411000, + 0xb8431000, + 0x7801c201, + 0x59620034, + 0x3821c570, + 0xfbfffaaa, + 0x78010003, + 0x3821f900, + 0x28230000, + 0x28220004, + 0x88431000, + 0xb9800800, + 0x34030064, + 0x34420032, + 0x8c431000, + 0xf8000f67, + 0x2b010080, + 0x20218000, + 0x442c0002, + 0xfbfff0ed, + 0x2b010080, + 0x20211000, + 0x44200003, + 0xb9a00800, + 0xfbfffd99, + 0x2b010080, + 0x20214000, + 0x44200002, + 0xf8000126, + 0x2b010080, + 0x20210100, + 0x44200003, + 0xb9a00800, + 0xfbffff06, + 0x2b010080, + 0x00210017, + 0x20210001, + 0x64210000, + 0x5c200002, + 0xf8000cb9, + 0xd00e0000, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x90006800, + 0x34010000, + 0xd0010000, + 0x2b0c007c, + 0x5d80004c, + 0x34020001, + 0x7801c201, + 0x5b02007c, + 0x3821c45c, + 0x780b0003, + 0xfbfffa8a, + 0x396b8acc, + 0x59610040, + 0x20210003, + 0x33010698, + 0x29620040, + 0x7801c201, + 0x3821c45c, + 0x00420007, + 0x20420001, + 0x33020699, + 0x29630040, + 0x3402fffc, + 0xa0621800, + 0x3402ff7f, + 0xa0621800, + 0xb8601000, + 0x59630040, + 0xfbfffa5e, + 0x7801c201, + 0x3821c570, + 0xfbfffa75, + 0x00220009, + 0x59610034, + 0x20420007, + 0x3302069a, + 0x29620034, + 0x3403f1ff, + 0x7801c201, + 0xa0431000, + 0x3821c570, + 0x59620034, + 0xfbfffa50, + 0x78010003, + 0x3821f818, + 0x28210000, + 0x5b010080, + 0x2b010080, + 0x00210017, + 0x20210001, + 0x64210000, + 0x5c200002, + 0xf8000cae, + 0x2b010080, + 0x20210100, + 0x44200003, + 0xb9800800, + 0xfbfffeb9, + 0x2b010080, + 0x20214000, + 0x44200002, + 0xf8000047, + 0x2b010080, + 0x20211000, + 0x44200003, + 0xb9800800, + 0xfbfffd3a, + 0x2b010080, + 0x20218000, + 0x44200002, + 0xfbffefd4, + 0x78010003, + 0x3821f900, + 0x28220000, + 0x34030064, + 0x08421388, + 0xb9800800, + 0x34420032, + 0x8c431000, + 0xf8000ef2, + 0xd00d0000, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x78050003, + 0x34030000, + 0x38a5f910, + 0xb8602000, + 0xb4a40800, + 0x40210000, + 0x3422ffff, + 0x7441000c, + 0x5c200020, + 0x3c410002, + 0x78020003, + 0x384285e8, + 0xb4220800, + 0x28210000, + 0xc0200000, + 0x34630001, + 0xe0000018, + 0x34630002, + 0xe0000016, + 0x34630003, + 0xe0000014, + 0x34630004, + 0xe0000012, + 0x34630005, + 0xe0000010, + 0x34630006, + 0xe000000e, + 0x34630007, + 0xe000000c, + 0x34630008, + 0xe000000a, + 0x34630009, + 0xe0000008, + 0x3463000a, + 0xe0000006, + 0x3463000b, + 0xe0000004, + 0x3463000c, + 0xe0000002, + 0x3463000d, + 0x34840001, + 0x74810007, + 0x4420ffda, + 0x5b03011c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78040003, + 0x78030002, + 0x78020003, + 0x34010000, + 0x38428ba8, + 0x38848b24, + 0x38634a68, + 0x58830010, + 0x30410004, + 0x3041001d, + 0x330102b8, + 0xb8205800, + 0x33010159, + 0x7801c020, + 0xb9601800, + 0x330b06e5, + 0x38210134, + 0x34020020, + 0xfbffd55d, + 0x78010003, + 0x38218acc, + 0x7802c201, + 0x582b0020, + 0x3842c43c, + 0x78030003, + 0x584b0000, + 0x3863f818, + 0x28610000, + 0x3402bfff, + 0xa0220800, + 0x58610000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cffec, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x90001800, + 0x34010000, + 0xd0010000, + 0x2f01014a, + 0x34040000, + 0x44240008, + 0x2f01014a, + 0x2b02014c, + 0x2021ffff, + 0x8c411000, + 0x0f02015c, + 0x5b04014c, + 0x0f04014a, + 0xd0030000, + 0x2f01015c, + 0x780b0003, + 0x396b8c00, + 0x2f02015a, + 0x41630044, + 0x34040008, + 0x2042ffff, + 0x2021ffff, + 0xfbffcb7e, + 0x0f01015a, + 0x2f020244, + 0x378c0010, + 0x34040008, + 0x2f010246, + 0x34030000, + 0x2042ffff, + 0x2021ffff, + 0x54410002, + 0x34030001, + 0xb4630800, + 0xb4380800, + 0x34210240, + 0x2c210004, + 0x0f010160, + 0x2f010160, + 0x41630044, + 0x2f02015e, + 0x2021ffff, + 0x2042ffff, + 0xfbffcb69, + 0x0f01015e, + 0x43010158, + 0xb9802800, + 0x5c200003, + 0xfbffffa6, + 0xe0000028, + 0x43010154, + 0x41640047, + 0x33810010, + 0x43010155, + 0x33810011, + 0x430102b8, + 0x33810012, + 0x2f01015a, + 0x2f020162, + 0x2021ffff, + 0x2f030166, + 0x2042ffff, + 0x2063ffff, + 0xfbffcbd6, + 0x43810010, + 0xb9802800, + 0x33010154, + 0x43810011, + 0x33010155, + 0x43810012, + 0x330102b8, + 0x43010156, + 0x41640047, + 0x33810010, + 0x43010157, + 0x33810011, + 0x2f01015e, + 0x2f020164, + 0x2021ffff, + 0x2f030168, + 0x2042ffff, + 0x2063ffff, + 0xfbffcbe8, + 0x43810010, + 0x33010156, + 0x43810011, + 0x33010157, + 0x43810013, + 0x330106e5, + 0x34010000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x7801c201, + 0x3821c43c, + 0x28230000, + 0x78020003, + 0x38428acc, + 0x38630001, + 0x78010003, + 0x58430020, + 0x3821f82c, + 0x28250000, + 0x78040003, + 0x78030002, + 0x780100ff, + 0x38210000, + 0xa0a12800, + 0x00a50010, + 0x78010003, + 0x38218ba8, + 0x3863f540, + 0x38848b24, + 0x780b0003, + 0x780c0003, + 0x58830010, + 0x30250004, + 0x3025001d, + 0x398c8c00, + 0x396bfa04, + 0x2d610002, + 0x2d83003e, + 0x34020064, + 0x50610002, + 0xb8600800, + 0x0f010162, + 0x2f010162, + 0x2021ffff, + 0x3c210008, + 0xf8002073, + 0x0f010162, + 0x2d610000, + 0x2d830040, + 0x34020064, + 0x50610002, + 0xb8600800, + 0x0f010164, + 0x2f010164, + 0x2021ffff, + 0x3c210008, + 0xf8002068, + 0x0f010164, + 0x2f010162, + 0x41820042, + 0x34040001, + 0x2021ffff, + 0x88220800, + 0x78030003, + 0x3863f818, + 0x14210008, + 0x0f010166, + 0x2f010164, + 0x41820043, + 0x2021ffff, + 0x88220800, + 0x14210008, + 0x0f010168, + 0x33040158, + 0x33040159, + 0x28610000, + 0x38214000, + 0x58610000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x78040003, + 0x3884f000, + 0x408102f4, + 0x44200017, + 0x7801c050, + 0x382100b4, + 0x28210000, + 0x78020003, + 0x38428dd0, + 0x20217f00, + 0x00210008, + 0x34030001, + 0x58410000, + 0x330306fa, + 0x408302f5, + 0x28410000, + 0x54610002, + 0xc3a00000, + 0x2062007f, + 0x7801c050, + 0x382100cc, + 0x7803c050, + 0x58220000, + 0x386300d0, + 0x28610000, + 0x4420ffff, + 0xc3a00000, + 0x78010003, + 0x3821f000, + 0x402102f4, + 0x4420000e, + 0x78010003, + 0x38218dd0, + 0x28220000, + 0x7803c050, + 0x386300d0, + 0x7801c050, + 0x382100cc, + 0x2042007f, + 0x58220000, + 0x28610000, + 0x4420ffff, + 0x34010000, + 0x330106fa, + 0xc3a00000, + 0xc3a00000, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20210008, + 0x44200037, + 0x43010112, + 0x5c200004, + 0x43010111, + 0x20210002, + 0x44200002, + 0x34010001, + 0x7806c050, + 0x33010921, + 0x38c601c8, + 0x28c40000, + 0x7802f8ff, + 0x78030700, + 0x43010111, + 0x3842ffff, + 0x38630000, + 0x3c210018, + 0xa0822000, + 0xa0230800, + 0xb8812000, + 0x7805c050, + 0x58c40000, + 0x38a50118, + 0x28a30000, + 0x3402fbff, + 0x7806c050, + 0x43010112, + 0xa0621800, + 0x38c600e4, + 0x3c21000a, + 0x78040002, + 0x20210400, + 0xb8611800, + 0x58a30000, + 0x28c30000, + 0x3401ff80, + 0x78050002, + 0x43020110, + 0xa0611800, + 0x38a520dc, + 0x2042007f, + 0xb8621800, + 0x58c30000, + 0xb7251000, + 0x340100ff, + 0x58410000, + 0x388420d0, + 0xb7241000, + 0x7803c020, + 0x34010002, + 0x58410000, + 0x3863029c, + 0x28610000, + 0x20210008, + 0x5c20fffe, + 0xc3a00000, + 0x7805c020, + 0x38a5029c, + 0x28a10000, + 0x20210008, + 0x5c200028, + 0x34020001, + 0x7801c050, + 0x33020921, + 0x382101c8, + 0x28220000, + 0x7804c050, + 0xb8801800, + 0x78010700, + 0x38210000, + 0xa0411000, + 0x00420018, + 0x7801c050, + 0x33020111, + 0x38210118, + 0x28210000, + 0x386300e4, + 0x78020002, + 0x20210400, + 0x0021000a, + 0x384220dc, + 0x33010112, + 0x28610000, + 0xb7221000, + 0x2021007f, + 0x33010110, + 0x340100ff, + 0x78030002, + 0x58410000, + 0x386320d0, + 0xb7231000, + 0x34010001, + 0x58410000, + 0xb8a01000, + 0x28410000, + 0x20210008, + 0x4420fffe, + 0x388400e4, + 0x34010000, + 0x58810000, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20210004, + 0x4420004f, + 0x430100a0, + 0x5c200004, + 0x4301009e, + 0x20210002, + 0x44200002, + 0x34010001, + 0x3301091b, + 0x430100a1, + 0x5c200004, + 0x4301009f, + 0x20210002, + 0x44200002, + 0x34010001, + 0x3301091c, + 0x430200a2, + 0x7801c050, + 0x382100a4, + 0x204200ff, + 0x7805c050, + 0x58220000, + 0x38a501c8, + 0x28a30000, + 0x34028fff, + 0x7806c050, + 0x4301009e, + 0xa0621800, + 0x38c60118, + 0x3c21000c, + 0x3402ffef, + 0x20217000, + 0xb8611800, + 0x58a30000, + 0x28c30000, + 0x7804c050, + 0x3884009c, + 0x430100a0, + 0xa0621800, + 0x3802e3e0, + 0x3c210004, + 0xb7223800, + 0x20210010, + 0xb8611800, + 0x58c30000, + 0x430100a3, + 0x202100ff, + 0x58810000, + 0x28a30000, + 0x3401f1ff, + 0x4302009f, + 0xa0611800, + 0x3801e3e8, + 0x3c420009, + 0xb7212000, + 0x20420e00, + 0xb8621800, + 0x58a30000, + 0x28c30000, + 0x3402fff7, + 0x430100a1, + 0xa0621800, + 0x3c210003, + 0x20210008, + 0xb8611800, + 0x58c30000, + 0x340106ff, + 0x58e10000, + 0x28810000, + 0x64210010, + 0x4420fffe, + 0x3801e3ec, + 0xb7211000, + 0x28410000, + 0x64210010, + 0x4420fffe, + 0x3801e3f0, + 0xb7211000, + 0x34010000, + 0x58410000, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20210004, + 0x5c200036, + 0x3801e3f0, + 0xb7211000, + 0x34010001, + 0x58410000, + 0x3301091b, + 0x7806c050, + 0x3301091c, + 0x38c600a4, + 0x28c10000, + 0x7803c050, + 0x386301c8, + 0x2021007f, + 0x330100a2, + 0x28610000, + 0x7804c050, + 0x38840118, + 0x20217000, + 0x0021000c, + 0x7805c050, + 0x3301009e, + 0x28810000, + 0x38a5009c, + 0x34070000, + 0x20210010, + 0x00210004, + 0x3802e3e0, + 0x330100a0, + 0x28a10000, + 0xb7224000, + 0x3802e3e8, + 0x2021007f, + 0x330100a3, + 0x28610000, + 0xb7221000, + 0x20210e00, + 0x00210009, + 0x3301009f, + 0x28810000, + 0x20210008, + 0x00210003, + 0x330100a1, + 0x58c70000, + 0x58a70000, + 0x340105ff, + 0x59010000, + 0x28410000, + 0x64210012, + 0x4420fffe, + 0x3801e3ec, + 0xb7211000, + 0x28410000, + 0x64210012, + 0x4420fffe, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20210002, + 0x44200038, + 0x430100c7, + 0x5c200004, + 0x430100c6, + 0x20210002, + 0x44200002, + 0x34010001, + 0x3301091a, + 0x430200c8, + 0x7801c050, + 0x382100ac, + 0x204200ff, + 0x7804c050, + 0x58220000, + 0x388401c8, + 0x28830000, + 0x3401fff8, + 0x7805c050, + 0x430200c6, + 0xa0611800, + 0x38a50118, + 0x20420007, + 0xb8621800, + 0x58830000, + 0x28a30000, + 0x3401fffe, + 0x78040002, + 0x430200c7, + 0xa0611800, + 0x38841fe0, + 0x20420001, + 0xb8621800, + 0x58a30000, + 0x78060002, + 0xb7241000, + 0xb8c01800, + 0x340106ff, + 0x38631fe8, + 0x780400ff, + 0x58410000, + 0xb7231000, + 0x3884ffff, + 0x28410000, + 0xa0240800, + 0x64210010, + 0x4420fffd, + 0x78010002, + 0x38211ff0, + 0xb7211000, + 0x28410000, + 0x64210010, + 0x4420fffe, + 0x38c61fe8, + 0xb7261000, + 0x34010000, + 0x58410000, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20210002, + 0x5c20002e, + 0x34010001, + 0x3301091a, + 0x7805c050, + 0xb8a00800, + 0x382100ac, + 0x28210000, + 0x7802c050, + 0x384201c8, + 0x2021007f, + 0x330100c8, + 0x28410000, + 0x78040002, + 0x38841fe8, + 0x20210007, + 0x7802c050, + 0x330100c6, + 0x38420118, + 0x28410000, + 0x78030002, + 0x38631fe0, + 0x20210001, + 0x330100c7, + 0x78020100, + 0x38420000, + 0xb7240800, + 0x58220000, + 0xb7231000, + 0x340105ff, + 0x780300ff, + 0x58410000, + 0xb7241000, + 0x3863ffff, + 0x28410000, + 0xa0230800, + 0x64210012, + 0x4420fffd, + 0x78010002, + 0x38211ff0, + 0xb7211000, + 0x28410000, + 0x64210012, + 0x4420fffe, + 0x38a500ac, + 0x34010000, + 0x58a10000, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20214000, + 0x4420000a, + 0x3801d05c, + 0xb7211000, + 0x340106ff, + 0x58410000, + 0x3801d064, + 0xb7211000, + 0x28410000, + 0x64210010, + 0x4420fffe, + 0xc3a00000, + 0x7801c020, + 0x3821029c, + 0x28210000, + 0x20214000, + 0x5c20000a, + 0x3801d05c, + 0xb7211000, + 0x340105ff, + 0x58410000, + 0x3801d064, + 0xb7211000, + 0x28410000, + 0x64210012, + 0x4420fffe, + 0xc3a00000, + 0xc3a00000, + 0xc3a00000, + 0xc3a00000, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b900004, + 0x204affff, + 0x2026ffff, + 0xb8606000, + 0xb8806800, + 0xb9400800, + 0x45400049, + 0x3545ffff, + 0xb4ca0800, + 0x3421ffff, + 0x14a3001f, + 0x00c80005, + 0x1422001f, + 0x0063001b, + 0x3d040002, + 0x0042001b, + 0xb48c2000, + 0xb4a32800, + 0x14a50005, + 0xb4220800, + 0x28870000, + 0x14210005, + 0x20abffff, + 0x202fffff, + 0x20c4001f, + 0x34050000, + 0x50ab0017, + 0x34010020, + 0xfc858000, + 0xc8247000, + 0x35010001, + 0x2028ffff, + 0x3d010002, + 0x3ca60002, + 0xb42c0800, + 0x28290000, + 0x80e41000, + 0x34a50001, + 0xbd2e0800, + 0xb4cd1800, + 0xb8221000, + 0x5e000003, + 0x58670000, + 0xe0000002, + 0x58620000, + 0xb9203800, + 0x20a5ffff, + 0x50ab0002, + 0xe3ffffee, + 0x7c810000, + 0x2149001f, + 0x450f000b, + 0xb8e01800, + 0x4420000c, + 0x3de10002, + 0xc8041800, + 0xb42c0800, + 0x28210000, + 0x80e41000, + 0xbc230800, + 0xb8221800, + 0xe0000004, + 0xb8e01800, + 0x44200002, + 0x80e41800, + 0x3ca60002, + 0x2122ffff, + 0x35650001, + 0x44400008, + 0x3401ffff, + 0xbc220800, + 0xa4200800, + 0xb4cd1000, + 0xa0610800, + 0x58410000, + 0xe0000003, + 0xb4cd0800, + 0x58230000, + 0x20a1ffff, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b900004, + 0x379c0018, + 0xc3a00000, + 0x379cffe4, + 0x5b8b001c, + 0x5b8c0018, + 0x5b8d0014, + 0x5b8e0010, + 0x5b8f000c, + 0x5b900008, + 0x5b910004, + 0x2048ffff, + 0x2026ffff, + 0xb8606000, + 0xb8805800, + 0xb9000800, + 0x45000072, + 0xb4c88800, + 0x3624ffff, + 0x3503ffff, + 0x1482001f, + 0x1461001f, + 0x0042001b, + 0x0021001b, + 0xb4822000, + 0x14840005, + 0xb4611800, + 0x20c7001f, + 0x14630005, + 0x2085ffff, + 0x00c60005, + 0x7cf00000, + 0x206dffff, + 0x2104001f, + 0x340a0000, + 0x5e0a0024, + 0xb8e05000, + 0x50ed000d, + 0x3d410002, + 0x3cc20002, + 0xb42b0800, + 0x28210000, + 0xb44c1000, + 0x58410000, + 0x35410001, + 0x34c20001, + 0x202affff, + 0x2046ffff, + 0x514d0002, + 0xe3fffff5, + 0x3d420002, + 0x4480000e, + 0x3403ffff, + 0xbc641800, + 0xb44b0800, + 0x28240000, + 0x3ca50002, + 0xa4601000, + 0xb4ac2800, + 0x28a10000, + 0xa0822000, + 0xa0230800, + 0xb8240800, + 0x58a10000, + 0xe0000040, + 0xb44b1000, + 0x3cc10002, + 0x28420000, + 0xb42c0800, + 0x58220000, + 0xe000003a, + 0x29630000, + 0xb9401000, + 0x50c5001e, + 0x3401ffff, + 0xbc270800, + 0xa4207800, + 0x34010020, + 0xc8277000, + 0x3cc10002, + 0x804e1000, + 0xbc674800, + 0xb42c4000, + 0xb9221000, + 0x34c60001, + 0x35440001, + 0x5d400006, + 0x29010000, + 0xa02f0800, + 0xb8290800, + 0x59010000, + 0xe0000002, + 0x59020000, + 0x208affff, + 0x3d410002, + 0xb8601000, + 0x20c6ffff, + 0x34030000, + 0xb42b0800, + 0x554d0002, + 0x28230000, + 0x50c50002, + 0xe3ffffe9, + 0xc8070800, + 0x80410800, + 0xbc671800, + 0x2224001f, + 0x3402ffff, + 0xbc443000, + 0xb8614000, + 0x5c800002, + 0xb8803000, + 0x65410000, + 0xa0300800, + 0x64210000, + 0x5c200005, + 0xc8071000, + 0x3401ffff, + 0x80220800, + 0xb8c13000, + 0x3ca30002, + 0xa4c01000, + 0xb46c1800, + 0x28610000, + 0xa1021000, + 0xa0260800, + 0xb8220800, + 0x58610000, + 0x35a10001, + 0x2021ffff, + 0x2b8b001c, + 0x2b8c0018, + 0x2b8d0014, + 0x2b8e0010, + 0x2b8f000c, + 0x2b900008, + 0x2b910004, + 0x379c001c, + 0xc3a00000, + 0x2b2301cc, + 0x202500ff, + 0x34040000, + 0x20610001, + 0x5c250007, + 0x2b2301cc, + 0x34840001, + 0x20610001, + 0x5044fffc, + 0x34010001, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8205800, + 0x340c0000, + 0xb9601000, + 0xb9800800, + 0xfbffffeb, + 0xb9601000, + 0xb9805800, + 0x442c0002, + 0x340c0001, + 0x7d830000, + 0x34010001, + 0x5c600003, + 0xfbffffe3, + 0x44200002, + 0x340b0001, + 0xb9600800, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x2b2301cc, + 0x202500ff, + 0x34040000, + 0x00610001, + 0x20210001, + 0x5c250007, + 0x2b2301cc, + 0x34840001, + 0x00610001, + 0x5044fffb, + 0x34010001, + 0xc3a00000, + 0x34010000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xb8201000, + 0x34010000, + 0xfbffffee, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xb8201000, + 0x34010001, + 0xfbffffe6, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x780200ff, + 0x3842ffff, + 0x78030100, + 0xa0220800, + 0x38630000, + 0xb8230800, + 0x5b2101c0, + 0x34010258, + 0xfbffffbf, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x7c2f0000, + 0x780400ff, + 0x34010003, + 0xc82f0800, + 0x3884ffff, + 0x3445ffff, + 0x3c210018, + 0xa0441000, + 0x00a50005, + 0xb8220800, + 0x34040000, + 0x5b2101c0, + 0xb8607000, + 0x34ab0001, + 0xb8806000, + 0x4c8b0029, + 0x3d810002, + 0x3563ffff, + 0x5de00005, + 0x2b2201c4, + 0xb42e0800, + 0x58220000, + 0xe0000004, + 0xb42e0800, + 0x28210000, + 0x5b2101c8, + 0x5d830009, + 0x340b0000, + 0x5c8b0004, + 0x34010258, + 0xfbffff96, + 0x442b0002, + 0x340b0001, + 0xb9602000, + 0xe0000016, + 0x34010000, + 0x4c2c0009, + 0xb8206800, + 0x5c810005, + 0x34010001, + 0x34020258, + 0xfbffffa4, + 0x442d0002, + 0x340d0001, + 0xb9a02000, + 0x340d0000, + 0x5c8d0005, + 0xb8800800, + 0x34020258, + 0xfbffff9c, + 0x442d0002, + 0x340d0001, + 0xb9a02000, + 0x358c0001, + 0x4d8b0002, + 0xe3ffffd9, + 0xb8800800, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xb8401800, + 0xb8201000, + 0x34010001, + 0xfbffffb3, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xb8401800, + 0xb8201000, + 0x34010000, + 0xfbffffaa, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff8, + 0x5b9d0004, + 0x5b820008, + 0xb8201000, + 0x37830008, + 0x34010001, + 0xfbffffa0, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780bc030, + 0x396b0000, + 0x29610000, + 0x780c0003, + 0x398cf99c, + 0x29620004, + 0x202107ff, + 0x204207ff, + 0xfbffc84b, + 0x0f01080e, + 0x29610008, + 0x2f02080e, + 0x202107ff, + 0x2042ffff, + 0xfbffc845, + 0x0f01080e, + 0x2961000c, + 0x2f02080e, + 0x202107ff, + 0x2042ffff, + 0xfbffc83f, + 0x0f01080e, + 0x2f01080e, + 0x2021ffff, + 0x3421fe78, + 0x2b02081c, + 0x3c230005, + 0x4843000c, + 0x29810000, + 0x78020003, + 0x38428c00, + 0x20210001, + 0x5c20000f, + 0x4041002a, + 0x330102b9, + 0x29810000, + 0x38210001, + 0x59810000, + 0xe0000009, + 0x2b010820, + 0x34040000, + 0x4c610006, + 0x29810000, + 0x3402fffe, + 0xa0220800, + 0x59810000, + 0x330402b9, + 0x34010000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x78050003, + 0x38a58c00, + 0x40a1004b, + 0x78060003, + 0x78070003, + 0x78080003, + 0x78040003, + 0x78030003, + 0x38c6f82c, + 0x38e78ba8, + 0x3908f818, + 0x38848b24, + 0x3863056c, + 0x44200014, + 0x28c10000, + 0x40a2002b, + 0x58830050, + 0x00210008, + 0x34420068, + 0x30e10014, + 0x28c10000, + 0x3c420007, + 0x00210008, + 0x30e1002d, + 0x5b02081c, + 0x40a10029, + 0x2b02081c, + 0x3c210007, + 0xc8411000, + 0x5b020820, + 0x29010000, + 0x38210800, + 0x59010000, + 0xc3a00000, + 0x78040003, + 0x78030002, + 0x38634a68, + 0x78020003, + 0x38848b24, + 0x34010000, + 0x38428ba8, + 0x58830050, + 0x3041002d, + 0x30410014, + 0x78030003, + 0x330102b9, + 0x3863f818, + 0x28610000, + 0x3402f7ff, + 0xa0220800, + 0x58610000, + 0xc3a00000, + 0x379cffb0, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x780e0003, + 0x39cefa5c, + 0x29c10000, + 0x78030003, + 0x780c0003, + 0x00220001, + 0x780d0003, + 0x780b0003, + 0x396bfa58, + 0x3863fa4c, + 0x398cfa50, + 0x39adfa54, + 0x20420001, + 0x20210001, + 0x5c200002, + 0x44400032, + 0x28610000, + 0xf8001b4b, + 0x29c40000, + 0xb8207800, + 0x3781004c, + 0x20840001, + 0x7c840001, + 0x37820044, + 0x3783003c, + 0x5c80001e, + 0x29640000, + 0x34060000, + 0x00850010, + 0x2084ffff, + 0x48a40002, + 0x0d660002, + 0x298c0000, + 0x2d650002, + 0x34040000, + 0x5b8c004c, + 0x29ad0000, + 0x5b840044, + 0x5b850048, + 0x5b8d0050, + 0xf8000056, + 0x2d610002, + 0x3403000f, + 0x37870050, + 0x34210004, + 0x0d610002, + 0x2b820040, + 0x2b81003c, + 0x3784001c, + 0x2045001f, + 0xbc651800, + 0x20a6001c, + 0xb4e62800, + 0x58afffcc, + 0xf8000aac, + 0x29c50000, + 0xb9e02000, + 0x34010018, + 0x00a50001, + 0x34020003, + 0x20a50001, + 0x7ca50001, + 0x34030050, + 0x5ca00002, + 0xfbfff51b, + 0x34010000, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0050, + 0xc3a00000, + 0x78040003, + 0x3884fa5c, + 0x40810001, + 0x78020003, + 0x38428ba8, + 0x30410017, + 0x40840001, + 0x78030003, + 0x78010003, + 0x38638b24, + 0x38210720, + 0x30440030, + 0x5861005c, + 0xc3a00000, + 0x78030003, + 0x78020002, + 0x78010003, + 0x38218ba8, + 0x34040000, + 0x38638b24, + 0x38424a68, + 0x5862005c, + 0x30240030, + 0x30240017, + 0xc3a00000, + 0x379cfff0, + 0x00280010, + 0x2046ffff, + 0x2021ffff, + 0x88263800, + 0x00420010, + 0x89063000, + 0x88220800, + 0x00e40010, + 0x20c5ffff, + 0xb4852000, + 0x2025ffff, + 0xb4852000, + 0x3c850010, + 0x00c60010, + 0x00840010, + 0x89024000, + 0x00210010, + 0xb4862000, + 0xb4812000, + 0x20e7ffff, + 0xb4a72800, + 0xb4882000, + 0x58640000, + 0x58650004, + 0x379c0010, + 0xc3a00000, + 0x28240004, + 0x28450004, + 0x28280000, + 0x2084ffff, + 0x20a5ffff, + 0xb4852000, + 0x2087ffff, + 0x58670004, + 0x28250004, + 0x28460004, + 0x00840010, + 0x00a50010, + 0x00c60010, + 0x28420000, + 0xb4a62800, + 0xb4852000, + 0x3c810010, + 0x00840010, + 0xb8e13800, + 0xb4882000, + 0xb4822000, + 0x58640000, + 0x58670004, + 0xc3a00000, + 0x28240004, + 0x28230000, + 0x34050000, + 0x3406001f, + 0x6c810000, + 0x3c630001, + 0x64210000, + 0x3ca50001, + 0x34c6ffff, + 0xb4611800, + 0xb4842000, + 0x54430003, + 0x34a50001, + 0xc8621800, + 0x4cc0fff6, + 0xb8a00800, + 0xc3a00000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8206000, + 0x34210001, + 0xf8001ad2, + 0x3c2b0008, + 0xb9800800, + 0xf8001acf, + 0xb9615800, + 0x2161ffff, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xf8001aa1, + 0xb8202000, + 0x7801ff00, + 0x780200ff, + 0x38210000, + 0x38420000, + 0xa0810800, + 0xa0821000, + 0x00420008, + 0x2083ff00, + 0x00210018, + 0x3c630008, + 0xb8220800, + 0x3c840018, + 0xb8230800, + 0xb8240800, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0xb8205800, + 0x34210004, + 0x780dff00, + 0x780e00ff, + 0xf8001a84, + 0x39ad0000, + 0x39ce0000, + 0xa02d2000, + 0xa02e1800, + 0x00630008, + 0x2022ff00, + 0x00840018, + 0x3c420008, + 0xb8832000, + 0x3c210018, + 0xb8822000, + 0xb8812000, + 0xb9600800, + 0xb8805800, + 0xf8001a75, + 0xa02d6800, + 0xa02e7000, + 0x01ce0008, + 0x2022ff00, + 0x01ad0018, + 0x3c420008, + 0xb9ae6800, + 0x3c210018, + 0xb9a26800, + 0xb9a16800, + 0x340c0000, + 0xb96c1800, + 0xb98d2000, + 0xb8600800, + 0xb8801000, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x780e0003, + 0xb9c06800, + 0xb8205800, + 0x39ad8e38, + 0x340c0007, + 0xb9600800, + 0xf8001a52, + 0x7802ff00, + 0x780300ff, + 0x38420000, + 0x38630000, + 0xa0221000, + 0xa0231800, + 0x2024ff00, + 0x00420018, + 0x00630008, + 0x3c840008, + 0xb8431000, + 0x3c210018, + 0xb8441000, + 0xb8411000, + 0x59a20000, + 0x356b0004, + 0x358cffff, + 0x35ad0004, + 0x4d80ffec, + 0xb9c03000, + 0x38c68e38, + 0x2cc50014, + 0x2cc20016, + 0x34010000, + 0x20a300ff, + 0x204400ff, + 0x3c630008, + 0x3c840008, + 0x00a50008, + 0x00420008, + 0xb8a32800, + 0xb8441000, + 0x0cc20016, + 0x0cc50014, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0xb8405800, + 0xf8001a24, + 0x7802ff00, + 0x780300ff, + 0x38420000, + 0x38630000, + 0xa0221000, + 0xa0231800, + 0x00630008, + 0x2024ff00, + 0x00420018, + 0x3c840008, + 0xb8431000, + 0x3c210018, + 0xb8441000, + 0xb8411000, + 0x59620000, + 0x2d610000, + 0x78040003, + 0x38848c00, + 0x2021ffff, + 0x202200ff, + 0x3c420008, + 0x00210008, + 0x3403ffff, + 0xb8220800, + 0x0d610000, + 0x2d610000, + 0x2021ff00, + 0x64211600, + 0x4420000d, + 0x2d610000, + 0x40820013, + 0x3403fffe, + 0x2021000f, + 0x5c220008, + 0x41610002, + 0x40820048, + 0x202100ff, + 0xe4220800, + 0xc8010800, + 0x20230003, + 0x3463fffd, + 0xb8600800, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0xb8406800, + 0xb8607800, + 0xb8807000, + 0xb8205800, + 0x340c0000, + 0x518d0008, + 0xb9600800, + 0xb9c01000, + 0xfbffffbe, + 0xb56f5800, + 0x44200003, + 0x358c0001, + 0xe3fffff9, + 0xb9800800, + 0x55ac0002, + 0x3401ffff, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cffe4, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x78020003, + 0x38428e38, + 0x40420019, + 0xb8206000, + 0x370e01c4, + 0x34030068, + 0x37840018, + 0xfbffffd4, + 0x4c200003, + 0x3401ffff, + 0xe0000016, + 0x2f820018, + 0x08210068, + 0xb9c05800, + 0x0f0201c0, + 0x4382001a, + 0xb5810800, + 0x342c0004, + 0x330201c2, + 0x4382001b, + 0x340d0018, + 0x330201c3, + 0xb9800800, + 0xf80019b9, + 0x59610000, + 0x358c0004, + 0x35adffff, + 0x356b0004, + 0x4da0fffa, + 0x34010014, + 0x59c10010, + 0x34010000, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c001c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0xb8205800, + 0xfbffff47, + 0x3402ffff, + 0x4c200002, + 0xe0000008, + 0x5b0b01bc, + 0x2b0101bc, + 0x34210020, + 0xfbffffc8, + 0x6c210000, + 0x3c220001, + 0x3442fffe, + 0xb8400800, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x2b2201d0, + 0x3403ff80, + 0x340100d2, + 0xa0431000, + 0x3842040a, + 0x5b2201d0, + 0xfbfffd49, + 0x34020001, + 0x34010009, + 0xfbfffdae, + 0x34010002, + 0xb8201000, + 0xfbfffdab, + 0x34020000, + 0x34010009, + 0xfbfffda8, + 0x78020003, + 0x38428e58, + 0x34019f9f, + 0x7803000f, + 0x3863ffff, + 0x58410000, + 0x58430004, + 0x34010034, + 0xfbfffd8d, + 0x34020001, + 0x34010009, + 0xfbfffd9c, + 0x34020003, + 0x34010002, + 0xfbfffd99, + 0x34020050, + 0x34010009, + 0xfbfffd96, + 0x780b0003, + 0x396b8e60, + 0x34011000, + 0x340c0008, + 0x59610000, + 0xb9601000, + 0x596c0004, + 0x34010024, + 0xfbfffd7b, + 0x34020050, + 0x34010009, + 0xfbfffd8a, + 0x34011020, + 0x59610000, + 0x596c0004, + 0xb9601000, + 0x34010024, + 0xfbfffd72, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x2b2201d0, + 0x3403ff80, + 0x340100d2, + 0xa0431000, + 0x3842040a, + 0x5b2201d0, + 0xfbfffd0c, + 0x34020001, + 0x34010009, + 0xfbfffd71, + 0x34010002, + 0xb8201000, + 0xfbfffd6e, + 0x34020000, + 0x34010009, + 0xfbfffd6b, + 0x78020003, + 0x38428e58, + 0x34019f9f, + 0x7803000f, + 0x3863ffff, + 0x58410000, + 0x58430004, + 0x34010034, + 0xfbfffd50, + 0x34020001, + 0x34010009, + 0xfbfffd5f, + 0x34020003, + 0x34010002, + 0xfbfffd5c, + 0x34020050, + 0x34010009, + 0xfbfffd59, + 0x780b0003, + 0x396b8e60, + 0x34011000, + 0x340c0008, + 0x59610000, + 0xb9601000, + 0x596c0004, + 0x34010024, + 0xfbfffd3e, + 0x34020050, + 0x34010009, + 0xfbfffd4d, + 0x34010000, + 0x59610000, + 0x596c0004, + 0xb9601000, + 0x34010024, + 0xfbfffd35, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2b2201d0, + 0x3403ff80, + 0x340100d2, + 0xa0431000, + 0x3842040a, + 0x5b2201d0, + 0xfbfffcd1, + 0x34020001, + 0x34010009, + 0xfbfffd36, + 0x34010002, + 0xb8201000, + 0xfbfffd33, + 0x34020000, + 0x34010009, + 0xfbfffd30, + 0x78020003, + 0x38428e58, + 0x3401ffff, + 0x7803000c, + 0x3863020f, + 0x58410000, + 0x58430004, + 0x34010034, + 0xfbfffd15, + 0x34020001, + 0x34010009, + 0xfbfffd24, + 0x34020003, + 0x34010002, + 0xfbfffd21, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x2b2101d0, + 0x3402ff80, + 0xa0220800, + 0x3402fbff, + 0xa0220800, + 0x5b2101d0, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x78010002, + 0x38210000, + 0x3884dfe0, + 0x78020004, + 0xb8812000, + 0x38420000, + 0xb8822000, + 0x78010008, + 0x38210000, + 0x78020010, + 0xb8812000, + 0x38420000, + 0xb8822000, + 0x78010100, + 0x38210000, + 0x78020200, + 0x38420000, + 0xb8812000, + 0x78030400, + 0x38630000, + 0xb8822000, + 0x78010800, + 0xb8832000, + 0x38210000, + 0xb8812000, + 0x5b240e60, + 0xfbffffb5, + 0x34020051, + 0x34010009, + 0x780e0003, + 0xfbfffcf2, + 0xb9c05800, + 0x396b8e60, + 0x3401008e, + 0x340c0008, + 0x59610000, + 0xb9601000, + 0x596c0004, + 0x34010024, + 0xfbfffcd7, + 0x34020051, + 0x34010009, + 0xfbfffce6, + 0x780d0100, + 0xb9a00800, + 0x382103ae, + 0x59610000, + 0xb9601000, + 0x596c0004, + 0x34010024, + 0xfbfffccc, + 0x34020001, + 0x34010009, + 0xfbfffcdb, + 0x34010002, + 0xb8201000, + 0xfbfffcd8, + 0x34020000, + 0x34010009, + 0xfbfffcd5, + 0x7801c00c, + 0x38210000, + 0x28210000, + 0x78020003, + 0x78030008, + 0x20210002, + 0x44200005, + 0x7801a0f8, + 0x38428e58, + 0x38211405, + 0xe0000004, + 0x7801a0f8, + 0x38428e58, + 0x38217465, + 0x58410000, + 0x78020003, + 0x38630001, + 0x38428e58, + 0x58430004, + 0x34010034, + 0xfbfffcae, + 0x34020001, + 0x34010009, + 0xfbfffcbd, + 0x34020003, + 0x34010002, + 0xfbfffcba, + 0x34020050, + 0x34010009, + 0xfbfffcb7, + 0xb9c05800, + 0x396b8e60, + 0x3401008e, + 0x340c0008, + 0x59610000, + 0xb9601000, + 0x596c0004, + 0x34010024, + 0xfbfffc9c, + 0x34020050, + 0x34010009, + 0xfbfffcab, + 0x39ad03ae, + 0x596d0000, + 0x596c0004, + 0xb9601000, + 0x34010024, + 0xfbfffc93, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cffe4, + 0x5b8b001c, + 0x5b8c0018, + 0x5b8d0014, + 0x5b8e0010, + 0x5b8f000c, + 0x5b900008, + 0x5b9d0004, + 0xfbffff54, + 0x34020001, + 0x34010009, + 0xfbfffc92, + 0x34010002, + 0xb8201000, + 0xfbfffc8f, + 0x34020000, + 0x34010009, + 0xfbfffc8c, + 0x78020003, + 0x7801a0f8, + 0x38428e58, + 0x38217465, + 0x78030008, + 0x38630001, + 0x58410000, + 0x58430004, + 0x34010034, + 0xfbfffc70, + 0x34020001, + 0x34010009, + 0xfbfffc7f, + 0x34020003, + 0x34010002, + 0xfbfffc7c, + 0x34020050, + 0x34010009, + 0x780b0003, + 0x780e0100, + 0x396b8e60, + 0x340c0008, + 0xfbfffc75, + 0x39ce02ae, + 0xb9601000, + 0x596e0000, + 0x596c0004, + 0x34010024, + 0xfbfffc5d, + 0x34020050, + 0x34010009, + 0x780d0100, + 0xfbfffc6b, + 0x39ad00ae, + 0xb9601000, + 0x596d0000, + 0x596c0004, + 0x34010024, + 0xfbfffc53, + 0x34020050, + 0x34010009, + 0xfbfffc62, + 0x341000ae, + 0xb9601000, + 0x59700000, + 0x596c0004, + 0x34010024, + 0xfbfffc4a, + 0x34020050, + 0x34010009, + 0xfbfffc59, + 0x340f0000, + 0xb9601000, + 0x596f0000, + 0x596c0004, + 0x34010024, + 0xfbfffc41, + 0x34020051, + 0x34010009, + 0xfbfffc50, + 0xb9601000, + 0x596e0000, + 0x596c0004, + 0x34010024, + 0xfbfffc39, + 0x34020051, + 0x34010009, + 0xfbfffc48, + 0xb9601000, + 0x596d0000, + 0x596c0004, + 0x34010024, + 0xfbfffc31, + 0x34020051, + 0x34010009, + 0xfbfffc40, + 0xb9601000, + 0x59700000, + 0x596c0004, + 0x34010024, + 0xfbfffc29, + 0x34020051, + 0x34010009, + 0xfbfffc38, + 0x596c0004, + 0x596f0000, + 0xb9601000, + 0x34010024, + 0xfbfffc21, + 0x5b2f0e60, + 0x2b8b001c, + 0x2b8c0018, + 0x2b8d0014, + 0x2b8e0010, + 0x2b8f000c, + 0x2b900008, + 0x2b9d0004, + 0x379c001c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x78020003, + 0x3842f81c, + 0x28420000, + 0x780bc050, + 0x780c0130, + 0x2042ff00, + 0x00420008, + 0x396b00b4, + 0x34010064, + 0x398c8060, + 0x34030003, + 0x50620002, + 0xe0000012, + 0x296b0000, + 0xfbffd2d5, + 0xfbffd2c0, + 0xb9800800, + 0x34020001, + 0xf8000628, + 0xb9800800, + 0x34020001, + 0xf8000643, + 0xb9800800, + 0x34020004, + 0xf8000639, + 0x216b007f, + 0xb9600800, + 0x34020007, + 0x504b0002, + 0xfbffd2b2, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78010003, + 0x3821f81c, + 0x28210000, + 0x780bc210, + 0x396b0008, + 0x29620000, + 0x202100ff, + 0x08210064, + 0x38420002, + 0x59620000, + 0xf80006bf, + 0x29610000, + 0x3402fffd, + 0xa0220800, + 0x59610000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x78010140, + 0x38210011, + 0xf80005f4, + 0x3824000f, + 0x78010140, + 0xb8801000, + 0x38210011, + 0xf80005ea, + 0x78010130, + 0x38218062, + 0xf80005ec, + 0x3402f7ff, + 0xa0222000, + 0x78010130, + 0xb8801000, + 0x38218062, + 0xf80005e1, + 0x78010130, + 0x38210002, + 0xf80005e3, + 0x3402fff3, + 0xa0222000, + 0x78010130, + 0xb8801000, + 0x38210002, + 0xf80005d8, + 0x78010130, + 0x38218063, + 0xf80005da, + 0x780effff, + 0xb9c01000, + 0x38427fff, + 0xa0220800, + 0x780dfffe, + 0x38248000, + 0xb9a01000, + 0x3842ffff, + 0x78010001, + 0xa0821000, + 0x38210000, + 0xb8412000, + 0x780cffef, + 0xb9801000, + 0x3842ffff, + 0x78010010, + 0xa0821000, + 0x38210000, + 0x780bfeff, + 0xb8412000, + 0xb9601800, + 0x3863ffff, + 0x78020100, + 0xa0831800, + 0x38420000, + 0x78010130, + 0xb8621000, + 0x38218063, + 0xf80005b8, + 0x78010130, + 0x38218062, + 0xf80005ba, + 0x38240001, + 0x78010130, + 0xb8801000, + 0x38218062, + 0xf80005b0, + 0x78010130, + 0x38218060, + 0xf80005b2, + 0x38240001, + 0x78010130, + 0xb8801000, + 0x38218060, + 0xf80005a8, + 0x78010003, + 0x3821f900, + 0x28210000, + 0x34020064, + 0x0821000b, + 0x34210032, + 0x8c220800, + 0xf800065f, + 0x78010110, + 0x38210010, + 0xf80005a2, + 0x38240001, + 0x78010110, + 0x38210010, + 0xb8801000, + 0xf8000598, + 0x78010110, + 0x38210010, + 0xf800059a, + 0x20210001, + 0x4420fffc, + 0x78010130, + 0x38218060, + 0xf8000595, + 0x20240001, + 0x64810000, + 0x4420fffb, + 0x78010130, + 0x38218062, + 0xf800058f, + 0x3402fffe, + 0xa0222000, + 0x78010130, + 0x38820800, + 0x38218062, + 0xf8000584, + 0x78010130, + 0x38218063, + 0xf8000586, + 0x39ce7fff, + 0xa02e2000, + 0x39adffff, + 0xa08d2000, + 0x398cffff, + 0xa08c2000, + 0x396bffff, + 0x78010130, + 0xa08b1000, + 0x38218063, + 0xf8000576, + 0x78010120, + 0x38214460, + 0xf8000578, + 0x20210300, + 0x5c20fffc, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0xb8202800, + 0x34010000, + 0xb8405800, + 0xb8201000, + 0xb8201800, + 0x340400b0, + 0x3406000f, + 0xf80017e5, + 0x34010000, + 0xb9602800, + 0xb8201000, + 0xb8201800, + 0x340400b4, + 0x3406000f, + 0xf80017de, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x340b0001, + 0x3d620011, + 0x34010000, + 0x3842e807, + 0xfbffffe3, + 0x34010003, + 0x34020010, + 0xfbffffe0, + 0x34010007, + 0x340200ff, + 0xfbffffdd, + 0xb9601000, + 0x34010008, + 0xfbffffda, + 0x7801c201, + 0x7802003c, + 0x3821c51c, + 0x38420000, + 0xfbfff101, + 0x34020058, + 0x5b02083c, + 0x34010ace, + 0x5b01084c, + 0x0f020852, + 0x34040000, + 0x3304085c, + 0x7803c020, + 0x3304085d, + 0x38630130, + 0x28620000, + 0x7801fffe, + 0x3821ffff, + 0xa0411000, + 0x58620000, + 0x330b0830, + 0x78030003, + 0x33040831, + 0x3863f900, + 0x2861003c, + 0x78048000, + 0x38848000, + 0x3c21000a, + 0x5b010834, + 0x34010000, + 0x5b010838, + 0x2862002c, + 0x34010008, + 0x5b020844, + 0x28620030, + 0x5b020840, + 0x34020100, + 0x58820050, + 0xfbffbf77, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x34010008, + 0xfbffbf9c, + 0x34010000, + 0x33010830, + 0x2b010838, + 0x3403ffff, + 0x37040848, + 0x5b010858, + 0x2b010844, + 0x2b020840, + 0xf800065f, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x340b0001, + 0x3d620011, + 0x34010000, + 0x3842e807, + 0xfbffff97, + 0x34010003, + 0x34020010, + 0xfbffff94, + 0x34010007, + 0x340200ff, + 0xfbffff91, + 0xb9601000, + 0x34010008, + 0xfbffff8e, + 0x7801c201, + 0x7802003c, + 0x3821c51c, + 0x38420000, + 0xfbfff0b5, + 0x34020018, + 0x5b02083c, + 0x34010ace, + 0x5b01084c, + 0x0f020852, + 0x330b085c, + 0x7803c020, + 0x330b085d, + 0x38630130, + 0x28620000, + 0x7801fffe, + 0x3821ffff, + 0xa0411000, + 0x58620000, + 0x330b0830, + 0x78020003, + 0x330b0831, + 0x3842f900, + 0x2841003c, + 0x3c21000a, + 0x5b010834, + 0x34010000, + 0x5b010838, + 0x2841002c, + 0x5b010844, + 0x28410030, + 0x5b010840, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x34010000, + 0x33010830, + 0x2b010838, + 0x3403ffff, + 0x37040848, + 0x5b010858, + 0x2b010844, + 0x2b020840, + 0xf800061c, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x2b03083c, + 0xb8207800, + 0xb8407000, + 0x2b010838, + 0x340b0000, + 0x88611800, + 0x2b010834, + 0x54230002, + 0xe0000026, + 0x2b01083c, + 0x2b030838, + 0x2b020840, + 0x88230800, + 0x2b0d0844, + 0x3c210002, + 0x2b030840, + 0xb4411000, + 0x344c0020, + 0x51830003, + 0x2b010844, + 0x342d0001, + 0x516e000a, + 0x3d620005, + 0xb9a00800, + 0xb5e22000, + 0xb5821000, + 0x3403ffff, + 0xf80005f6, + 0x35610001, + 0x202b00ff, + 0xe3fffff7, + 0x2b010838, + 0x34210001, + 0x5b010838, + 0x2b020838, + 0x2b010834, + 0x5422000a, + 0x34010000, + 0x5b010854, + 0x2b010838, + 0x3403ffff, + 0x37040848, + 0x5b010858, + 0x2b010844, + 0x2b020840, + 0xf80005e4, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x90002000, + 0x34010000, + 0xd0010000, + 0x7803c020, + 0x38630130, + 0x28620000, + 0x78010001, + 0x38210000, + 0x98411000, + 0x58620000, + 0xd0040000, + 0xc3a00000, + 0x2f020240, + 0x7808c030, + 0x34070000, + 0x2f050230, + 0x2042ffff, + 0x58220000, + 0x2f060234, + 0x39080000, + 0x20a5ffff, + 0x2f040238, + 0x20c6ffff, + 0x58250004, + 0x2f030244, + 0x2084ffff, + 0x58260008, + 0x2f020248, + 0x2063ffff, + 0x5824000c, + 0x2042ffff, + 0x58220028, + 0x58270020, + 0x58230024, + 0x58270010, + 0x58270014, + 0x58270018, + 0x5827001c, + 0x35020010, + 0x28420000, + 0x35080014, + 0x29020000, + 0x204207ff, + 0x3442fe28, + 0x3c42000d, + 0x5822005c, + 0xc3a00000, + 0x379cff98, + 0x5b8b0008, + 0x5b9d0004, + 0x378b000c, + 0xb9600800, + 0xfbffffd8, + 0x2b02083c, + 0xb9600800, + 0x00420003, + 0xfbffff8b, + 0xfbffffc7, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0068, + 0xc3a00000, + 0xc3a00000, + 0x379cff4c, + 0x5b9d0004, + 0x2b02083c, + 0x37810008, + 0x00420003, + 0xfbffff7f, + 0xfbffffbb, + 0x2b9d0004, + 0x379c00b4, + 0xc3a00000, + 0xb8203000, + 0x34050000, + 0x50a3000c, + 0x3c810002, + 0xb4260800, + 0x34210004, + 0x28460000, + 0x34840001, + 0x34a50001, + 0x58260000, + 0x34210004, + 0x34420004, + 0x50a30002, + 0xe3fffff9, + 0xb8800800, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x7802c040, + 0xb8205800, + 0x38420e10, + 0x34030024, + 0x34040000, + 0xfbffffe8, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38420ed0, + 0x34030002, + 0xfbffffe2, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38420eec, + 0x34030004, + 0xfbffffdc, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38421760, + 0x34030006, + 0xfbffffd6, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38421e34, + 0x34030002, + 0xfbffffd0, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38421e50, + 0x34030002, + 0xfbffffca, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38421e80, + 0x34030002, + 0xfbffffc4, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38421ef0, + 0x34030003, + 0xfbffffbe, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38422ef0, + 0x34030003, + 0xfbffffb8, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38423400, + 0x34030008, + 0xfbffffb2, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x3842381c, + 0x34030002, + 0xfbffffac, + 0xb8202000, + 0x7802c040, + 0xb9600800, + 0x38423a3c, + 0x3403000c, + 0xfbffffa6, + 0x7801c030, + 0x38210000, + 0x34220010, + 0x28420000, + 0x34210014, + 0x28210000, + 0x202107ff, + 0x3421fe28, + 0x3c21000d, + 0x59610000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfe98, + 0x5b8b0008, + 0x5b9d0004, + 0x378b000c, + 0xb9600800, + 0xfbffffa2, + 0x2b02083c, + 0xb9600800, + 0x00420003, + 0xfbffff08, + 0xfbffff44, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0168, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2f01080c, + 0x2b020868, + 0x2021ffff, + 0xfbffc211, + 0x5b010868, + 0x2f01080c, + 0x2b02086c, + 0x2021ffff, + 0xb4411000, + 0x5b02086c, + 0x2f01080e, + 0x2b020870, + 0x2021ffff, + 0xfbffc207, + 0x5b010870, + 0x2f01080e, + 0x2b020874, + 0x2021ffff, + 0xb4411000, + 0x5b020874, + 0x2f0102ee, + 0x2b020884, + 0x2021ffff, + 0xb4411000, + 0x5b020884, + 0x2b010888, + 0x2f0202b2, + 0x2042ffff, + 0xfbffc1f8, + 0x5b010888, + 0x2f0102b2, + 0x2b02088c, + 0x2021ffff, + 0xb4411000, + 0x5b02088c, + 0x2b010890, + 0x2b020198, + 0xb4220800, + 0x5b010890, + 0x2b010894, + 0x2f0206a0, + 0x2042ffff, + 0xfbffc1ea, + 0x5b010894, + 0x2f0102c4, + 0x2b020898, + 0x2021ffff, + 0xb4411000, + 0x5b020898, + 0x2b01089c, + 0x2f02015e, + 0x2042ffff, + 0xfbffc1e0, + 0x5b01089c, + 0x2f01015e, + 0x2b0208a0, + 0x2021ffff, + 0xb4411000, + 0x5b0208a0, + 0x2b0108a4, + 0x2f02015a, + 0x2042ffff, + 0xfbffc1d6, + 0x5b0108a4, + 0x2f02015a, + 0x78040003, + 0x3884fa64, + 0x2b0108a8, + 0x2042ffff, + 0x7803001e, + 0xb4220800, + 0x5b0108a8, + 0x2f02024c, + 0x38630000, + 0x2b0108ac, + 0x2042ffff, + 0xb4220800, + 0x5b0108ac, + 0x2f010248, + 0x2b0208b0, + 0x2021ffff, + 0xb4411000, + 0x5b0208b0, + 0x2b0108bc, + 0x5b0108bc, + 0x2b0108c0, + 0x5b0108c0, + 0x2b0108c4, + 0x5b0108c4, + 0x2b0108c8, + 0x5b0108c8, + 0x430106e8, + 0xb0200800, + 0xb4210800, + 0xb4380800, + 0x342108c8, + 0x2c220004, + 0x34420001, + 0x0c220004, + 0x4301008a, + 0x202100ff, + 0xb4210800, + 0xb4380800, + 0x342108d8, + 0x2c220004, + 0x34420001, + 0x0c220004, + 0x43010779, + 0x2b0208ec, + 0x18210001, + 0x202100ff, + 0xb4411000, + 0x5b0208ec, + 0x2b0108f0, + 0x5b0108f0, + 0x2b0108f4, + 0x5b0108f4, + 0x2b0108f8, + 0x5b0108f8, + 0x430102bf, + 0x2b0208fc, + 0x202100ff, + 0x3c210008, + 0xb4411000, + 0x5b0208fc, + 0x2b010900, + 0x2b02018c, + 0xb4220800, + 0x5b010900, + 0x28810000, + 0x2b020904, + 0xa0230800, + 0x00210011, + 0xb4411000, + 0x5b020904, + 0x2f01016e, + 0x2b020908, + 0x2021ffff, + 0xfbffc18a, + 0x5b010908, + 0x2f01016e, + 0x2b02090c, + 0x2021ffff, + 0xb4411000, + 0x5b02090c, + 0x2b010910, + 0x34210001, + 0x5b010910, + 0x2b020910, + 0x3801ffff, + 0x5c410003, + 0x34010001, + 0x33010832, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x34030000, + 0x37010868, + 0x3402002b, + 0x58230000, + 0x3442ffff, + 0x34210004, + 0x4c40fffd, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0xfbfffff6, + 0x34010010, + 0x33010831, + 0x34010001, + 0x33010830, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x2b010910, + 0x442000c1, + 0x2f010804, + 0x78080003, + 0x3908fe00, + 0xdc200800, + 0x3421fe78, + 0x3c210005, + 0x78020003, + 0x59010000, + 0x2b010868, + 0x38428c00, + 0x2c430082, + 0x3421fe78, + 0x3c210005, + 0x34040000, + 0x59010004, + 0x2b01086c, + 0x2b020910, + 0x8c220800, + 0x3421fe78, + 0x3c210005, + 0x59010008, + 0x2b01081c, + 0x59010030, + 0x2b010870, + 0x3421fe78, + 0x3c210005, + 0x59010034, + 0x2b010874, + 0x2b020910, + 0x8c220800, + 0x3421fe78, + 0x3c210005, + 0x59010038, + 0x2b010884, + 0x2b020910, + 0x8c220800, + 0x59010024, + 0x2b010888, + 0x59010028, + 0x2b01088c, + 0x2b020910, + 0x8c220800, + 0x5901002c, + 0x2b010890, + 0x88230800, + 0x2b020910, + 0x00210002, + 0x8c220800, + 0x59010050, + 0x2b010894, + 0x59010054, + 0x2b020898, + 0x2b010910, + 0x8c411000, + 0x2f010164, + 0x59020058, + 0x2021ffff, + 0x5901008c, + 0x2b01089c, + 0x59010090, + 0x2b0108a0, + 0x2b020910, + 0x8c220800, + 0x59010094, + 0x2b0108ac, + 0x2b020910, + 0x8c220800, + 0x59010098, + 0x2b0208b0, + 0x2b010910, + 0x8c411000, + 0x2f010162, + 0x5902009c, + 0x2021ffff, + 0x590100b0, + 0x2b0108a4, + 0x590100b4, + 0x2b0108a8, + 0x2b020910, + 0x8c220800, + 0x590400bc, + 0x590100b8, + 0x2b010914, + 0x44240006, + 0x2b0108b8, + 0x2b020914, + 0x8c220800, + 0x3c210003, + 0x590100c0, + 0x781d0003, + 0x59040134, + 0x5904013c, + 0x59040140, + 0xb8804800, + 0x3bbdf000, + 0xb5291000, + 0xb4581000, + 0x344108c8, + 0x2c230004, + 0x3d260002, + 0x3d250004, + 0x2063ffff, + 0x2b040910, + 0x08636400, + 0x3d210003, + 0xb4c83000, + 0x8c641800, + 0xc8290800, + 0x3c210002, + 0x344208d8, + 0xb43d0800, + 0x2c420004, + 0xb4bd2800, + 0x2042ffff, + 0x08426400, + 0x35240001, + 0x58c300d4, + 0x208900ff, + 0x28240058, + 0x75270007, + 0x29010134, + 0x88641800, + 0xb4230800, + 0x59010134, + 0x2b010910, + 0x8c411000, + 0x58c20114, + 0x28a10148, + 0x2903013c, + 0x29040140, + 0x88411000, + 0xb4625000, + 0x590a013c, + 0x28c10114, + 0x28a2014c, + 0x88220800, + 0xb4811800, + 0x59030140, + 0x44e0ffd5, + 0x29020134, + 0x34016400, + 0x8c611800, + 0x34040000, + 0x59040144, + 0x59040148, + 0x8c411000, + 0x59030140, + 0x8d410800, + 0x59020134, + 0x5901013c, + 0x2b0108f0, + 0x2b020910, + 0x8c220800, + 0x5901014c, + 0x2b0108f4, + 0x2b020910, + 0x8c220800, + 0x59010150, + 0x2b0108f8, + 0x2b020910, + 0x8c220800, + 0x59010154, + 0x2b0108ec, + 0x2b020910, + 0x08216400, + 0x5904015c, + 0x8c220800, + 0x59040160, + 0x59010158, + 0x2b010900, + 0x2b020910, + 0x8c220800, + 0x59010164, + 0x2b010904, + 0x2b020910, + 0x8c220800, + 0x5904016c, + 0x59010168, + 0x2b0208fc, + 0x2b010910, + 0x8c411000, + 0x2f010170, + 0x59020170, + 0x2021ffff, + 0x59010174, + 0x2b010908, + 0x59010178, + 0x2b01090c, + 0x2b020910, + 0x8c220800, + 0x5901017c, + 0xfbffff2b, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x2f020240, + 0x34030000, + 0x2f010242, + 0x2042ffff, + 0x2021ffff, + 0x54410002, + 0x34030001, + 0x2f0202c4, + 0xb4630800, + 0xb4380800, + 0x2c210240, + 0x780c0003, + 0x398c8c00, + 0xb4411000, + 0x0f02016c, + 0x2f01016c, + 0x418300bf, + 0x34040008, + 0x2f02016e, + 0x2021ffff, + 0x2042ffff, + 0xfbffbfc1, + 0x0f01016e, + 0x2f02016e, + 0x2f010170, + 0x50220013, + 0x43010174, + 0x7c210001, + 0x5c200009, + 0x2d810032, + 0x2f0b02ee, + 0x340203e8, + 0x3c210008, + 0x216bffff, + 0xf800151a, + 0x5d610004, + 0xe0000006, + 0x430102bc, + 0x5c200004, + 0x418100c4, + 0x330102bc, + 0xe000000f, + 0x2d810036, + 0xe0000009, + 0x2f02016e, + 0x2f010172, + 0x2042ffff, + 0x2021ffff, + 0x50410008, + 0x34010000, + 0x330102bc, + 0x2d810032, + 0x3c210008, + 0x340203e8, + 0xf8001506, + 0x0f0102ee, + 0xfbffc071, + 0x34010000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x90005800, + 0x34010000, + 0xd0010000, + 0x78040003, + 0x38848c00, + 0x2c830082, + 0x2c8100c6, + 0x340203e8, + 0x88230800, + 0x14210002, + 0x3803fd71, + 0x0f010170, + 0x2f010170, + 0x2021ffff, + 0x88230800, + 0x14210010, + 0x0f010172, + 0x2c810032, + 0x3c210008, + 0xf80014e7, + 0x78020003, + 0x0f0102ee, + 0x3842f824, + 0x28420000, + 0x780100ff, + 0x38210000, + 0xa0411000, + 0x00420010, + 0x78010003, + 0x38218ba8, + 0x78050003, + 0x30220015, + 0x3022002e, + 0x38a5f818, + 0x28a40000, + 0x7801ff7f, + 0x3821ffff, + 0xa0812000, + 0x78020080, + 0x38420000, + 0x78030003, + 0x78010003, + 0xb8822000, + 0x38638b24, + 0x38212438, + 0x58610054, + 0x58a40000, + 0xd00b0000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x90003000, + 0x34010000, + 0xd0010000, + 0x34020000, + 0x330202bc, + 0x78010003, + 0x330206e4, + 0x38218ba8, + 0x78050003, + 0x3022002e, + 0x30220015, + 0x38a5f818, + 0x28a40000, + 0x7801ff7f, + 0x3821ffff, + 0x78030003, + 0x78020002, + 0xa0812000, + 0x38638b24, + 0x38424a68, + 0x58620054, + 0x58a40000, + 0xd0060000, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x430202b8, + 0x78050003, + 0x7801c201, + 0x38a58acc, + 0x3821c43c, + 0x204200ff, + 0x340b0000, + 0x51620003, + 0x430202b8, + 0x204b00ff, + 0x430202bc, + 0x204200ff, + 0x51620003, + 0x430202bc, + 0x204b00ff, + 0x430202b9, + 0x204200ff, + 0x51620003, + 0x430202b9, + 0x204b00ff, + 0x430202bf, + 0x21640007, + 0x204200ff, + 0x444b0009, + 0x28a20020, + 0x3c840001, + 0x3403fff1, + 0xa0431000, + 0xb8441000, + 0x38420001, + 0x58a20020, + 0xfbffed5e, + 0x34010000, + 0x330b02bf, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0xb8203000, + 0x44600021, + 0x20610003, + 0x5c200005, + 0x20c10003, + 0x5c200003, + 0x20410003, + 0x4420000e, + 0x3463ffff, + 0x6461ffff, + 0xb8402800, + 0xb8c02000, + 0x5c200016, + 0x40a10000, + 0x3463ffff, + 0x6462ffff, + 0x30810000, + 0x34a50001, + 0x34840001, + 0x4440fffa, + 0xe000000e, + 0x00630002, + 0xb8402800, + 0x3463ffff, + 0x6461ffff, + 0xb8c02000, + 0x5c200008, + 0x28a10000, + 0x3463ffff, + 0x6462ffff, + 0x58810000, + 0x34a50004, + 0x34840004, + 0x4440fffa, + 0xb8c00800, + 0xc3a00000, + 0x78030003, + 0xb8201000, + 0x3863861c, + 0x34040000, + 0x2021000f, + 0x5c240003, + 0x00420004, + 0x34040004, + 0x2041000f, + 0xb4230800, + 0x40210000, + 0xb4810800, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b98d8, + 0x29610008, + 0x5c200019, + 0x2961000c, + 0xfbffffeb, + 0x3c220002, + 0x74210007, + 0xb44b1000, + 0x5c200013, + 0x28430014, + 0x78048000, + 0x78068000, + 0x78058000, + 0x38848000, + 0x38c68004, + 0x38a50420, + 0x4460000b, + 0x28620020, + 0x29610034, + 0x59630000, + 0xa0220800, + 0x58810000, + 0x29610038, + 0x28620024, + 0xa0220800, + 0x58c10000, + 0x58a30000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x90001800, + 0x34010000, + 0xd0010000, + 0x78020003, + 0x384298d8, + 0x28410008, + 0x34210001, + 0x58410008, + 0xd0030000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x90002000, + 0x34010000, + 0xd0010000, + 0x78050003, + 0xb8a01800, + 0x386398d8, + 0x28610008, + 0x3422ffff, + 0x44200002, + 0x58620008, + 0xd0040000, + 0xb8a01000, + 0x384298d8, + 0x28410008, + 0x5c200004, + 0x28410004, + 0x5c200002, + 0xfbffb6f6, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b8d0004, + 0x780c0003, + 0xb9805800, + 0x396b98d8, + 0x34080000, + 0x340d0001, + 0x35690014, + 0xbda82800, + 0x75020007, + 0x29610010, + 0x35080001, + 0x750a0007, + 0xa0250800, + 0x44200019, + 0x5c400018, + 0x29240000, + 0x44800016, + 0x2881000c, + 0xb9803000, + 0x38c698d8, + 0x3423ffff, + 0xa4a03800, + 0x5883000c, + 0x5c60000f, + 0x28c10010, + 0x28820010, + 0xa0270800, + 0x58c10010, + 0x44400005, + 0x28410000, + 0x58830010, + 0xa0270800, + 0x58410000, + 0x28c1000c, + 0xb8250800, + 0x58c1000c, + 0x34010001, + 0x5881001c, + 0x35290004, + 0x4540ffe0, + 0x2b8b000c, + 0x2b8c0008, + 0x2b8d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78050003, + 0xb8a02000, + 0x388498d8, + 0x28820004, + 0xb8201800, + 0x3401ffff, + 0x5c400018, + 0xb8400800, + 0x44600016, + 0x28810000, + 0x5823000c, + 0x90003800, + 0xd0020000, + 0x38a598d8, + 0x28a60000, + 0x28a30010, + 0x34020001, + 0x28c10008, + 0x28a4000c, + 0xbc410800, + 0xb8611800, + 0x58a30010, + 0x28c10008, + 0xbc411000, + 0xa4401000, + 0xa0822000, + 0x58a4000c, + 0xd0070000, + 0xfbffb6a4, + 0x34010000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8205800, + 0x90006000, + 0x34010000, + 0xd0010000, + 0x29610000, + 0xfbffff53, + 0x34020001, + 0xbc412800, + 0x78030003, + 0x3c220002, + 0x386398d8, + 0x74210007, + 0xa4a02000, + 0xb4431000, + 0x5c200016, + 0x29610000, + 0x28420014, + 0x34060000, + 0xa0240800, + 0x59610000, + 0x28610010, + 0xa0240800, + 0x58610010, + 0x44460006, + 0x5846001c, + 0x2861000c, + 0x58460010, + 0xb8250800, + 0x5861000c, + 0xd00c0000, + 0x78010003, + 0x382198d8, + 0x28210004, + 0x5c20000c, + 0xfbffb679, + 0xe000000a, + 0x29610004, + 0x29620008, + 0x34230001, + 0x54410004, + 0xd00c0000, + 0x3401fffb, + 0xe0000004, + 0x59630004, + 0xd00c0000, + 0x34010000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0xb9601800, + 0x386398d8, + 0x28640004, + 0xb8202800, + 0xb8404000, + 0x3401ffff, + 0x5c800027, + 0x90003000, + 0xd0040000, + 0x28a10004, + 0xb9602000, + 0x388498d8, + 0x34070001, + 0x3422ffff, + 0x44200005, + 0x58a20004, + 0xd0060000, + 0x34010000, + 0xe000001b, + 0x28830000, + 0x28a20000, + 0x28610008, + 0x58650010, + 0xbce10800, + 0xb8411000, + 0x58a20000, + 0x28610008, + 0x2882000c, + 0xbce10800, + 0xa4200800, + 0xa0411000, + 0x5882000c, + 0x45000007, + 0x28620008, + 0x5868000c, + 0x28810010, + 0xbce21000, + 0xb8220800, + 0x58810010, + 0xd0060000, + 0xfbffb63c, + 0x396b98d8, + 0x29610000, + 0x2821001c, + 0x7c210000, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0xb8202000, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x28810004, + 0x3423ffff, + 0x44200005, + 0x58830004, + 0xd0020000, + 0x34010000, + 0xc3a00000, + 0xd0020000, + 0x34010001, + 0xc3a00000, + 0xb8202000, + 0x90001800, + 0x34010000, + 0xd0010000, + 0x28810008, + 0x50220004, + 0xd0030000, + 0x3401fffb, + 0xc3a00000, + 0x58820004, + 0xd0030000, + 0x34010000, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x382198d8, + 0x28220000, + 0x28410018, + 0x28420014, + 0xd8400000, + 0x90002800, + 0x34010000, + 0xd0010000, + 0x78020003, + 0x384298d8, + 0x28410000, + 0x2843000c, + 0x28240008, + 0x34010001, + 0xbc240800, + 0xa4200800, + 0xa0611800, + 0x5843000c, + 0xd0050000, + 0xfbffb602, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b8d0004, + 0x3c470002, + 0xb8404800, + 0x34020001, + 0x780b0003, + 0x396b98d8, + 0xbc496000, + 0xb4eb3800, + 0x28e20014, + 0x340dffff, + 0x3408fffd, + 0x5c400014, + 0x780a0002, + 0x3488ff78, + 0x58250014, + 0x58260018, + 0x58230004, + 0x58290008, + 0x394a04f4, + 0x44800005, + 0x58280000, + 0x59040070, + 0x590a0078, + 0x59020074, + 0x582d0024, + 0x582d0020, + 0x58e10014, + 0x2961000c, + 0xb8404000, + 0xb82c0800, + 0x5961000c, + 0xb9000800, + 0x2b8b000c, + 0x2b8c0008, + 0x2b8d0004, + 0x379c000c, + 0xc3a00000, + 0x78198008, + 0x3b390000, + 0xc3a00000, + 0x78038008, + 0x38630000, + 0x586100a0, + 0x586200a4, + 0xc3a00000, + 0x78028008, + 0x38420000, + 0x584100a0, + 0x284100a4, + 0xc3a00000, + 0x78038008, + 0x38630000, + 0x586100a0, + 0x286100a4, + 0xb8220800, + 0x586100a4, + 0xc3a00000, + 0x78038008, + 0x38630000, + 0x586100a0, + 0x286100a4, + 0xa0220800, + 0x586100a4, + 0xc3a00000, + 0x78048008, + 0x38840000, + 0x588100a0, + 0x288100a4, + 0xa4601800, + 0xa0230800, + 0xb8220800, + 0x588100a4, + 0xc3a00000, + 0x78038008, + 0x38630000, + 0x586100a0, + 0x286100a4, + 0xa0410800, + 0x5c22fffe, + 0xc3a00000, + 0x78038008, + 0x38630000, + 0x586100a0, + 0x286100a4, + 0xa0410800, + 0x4422fffe, + 0xc3a00000, + 0x78048008, + 0x38840000, + 0x3803ca00, + 0xb4831800, + 0x58610000, + 0x3801ca04, + 0xb4812000, + 0x58820000, + 0xc3a00000, + 0x78038008, + 0x38630000, + 0x3802ca00, + 0xb4621000, + 0x58410000, + 0x3801ca04, + 0xb4611800, + 0x28610000, + 0xc3a00000, + 0x78048008, + 0x38840000, + 0x3803ca00, + 0xb4831800, + 0x58610000, + 0x3801ca04, + 0xb4812000, + 0x28810000, + 0xb8220800, + 0x58810000, + 0xc3a00000, + 0x78048008, + 0x38840000, + 0x3803ca00, + 0xb4831800, + 0x58610000, + 0x3801ca04, + 0xb4812000, + 0x28810000, + 0xa0220800, + 0x58810000, + 0xc3a00000, + 0x78058008, + 0x38a50000, + 0x3804ca00, + 0xb4a42000, + 0x58810000, + 0x3801ca04, + 0xb4a12800, + 0x28a10000, + 0xa4601800, + 0xa0230800, + 0xb8220800, + 0x58a10000, + 0xc3a00000, + 0x78058001, + 0x34030001, + 0x38a50800, + 0x78048001, + 0x30a30002, + 0x38840824, + 0x78028001, + 0x30830002, + 0x38420848, + 0x30430002, + 0x58a3000c, + 0x5883000c, + 0x5843000c, + 0x30a30005, + 0x30830005, + 0x30430005, + 0xc3a00000, + 0x3c220003, + 0x78038001, + 0xb4411000, + 0x3c420002, + 0x38630800, + 0xb4431000, + 0x34030001, + 0x30430002, + 0x5843000c, + 0x30430005, + 0xc3a00000, + 0x3c220003, + 0x78038001, + 0xb4411000, + 0x3c420002, + 0x38630800, + 0xb4431000, + 0x34010000, + 0x30410000, + 0x5841000c, + 0xc3a00000, + 0xb8201800, + 0x78048001, + 0x64210001, + 0x38840800, + 0x5c20000a, + 0x64650002, + 0x4460000c, + 0x78048001, + 0x64610007, + 0x38840848, + 0x5ca00008, + 0x78048001, + 0x5c200005, + 0xc3a00000, + 0x78048001, + 0x38840824, + 0xe0000002, + 0x388408fc, + 0x58820010, + 0x34010001, + 0x30810001, + 0x30810000, + 0xc3a00000, + 0x90001800, + 0x34010000, + 0xd0010000, + 0x7801c020, + 0x382100c8, + 0x28220000, + 0x7801c020, + 0x382100cc, + 0x28210000, + 0xd0030000, + 0x00420004, + 0x3c21001c, + 0xb8220800, + 0xc3a00000, + 0x90001000, + 0x34010000, + 0xd0010000, + 0x7801c020, + 0x382100c8, + 0x28240000, + 0x7801c020, + 0x382100cc, + 0x28230000, + 0xd0020000, + 0x34010000, + 0xb8242000, + 0xb8611800, + 0xb8600800, + 0xb8801000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8205800, + 0x44200010, + 0xfbffffea, + 0xb8402000, + 0xb44b1000, + 0xb8201800, + 0x34050000, + 0xf4823800, + 0xb4650800, + 0xb4e13800, + 0xb8e05800, + 0xb8406000, + 0xfbffffe0, + 0xb8201800, + 0x5563fffe, + 0x5d630002, + 0x5582fffc, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x780a8002, + 0x394a8000, + 0x29480000, + 0x3c21000a, + 0x3409c3ff, + 0x20213c00, + 0xa1094000, + 0xb9014000, + 0x59480000, + 0x29410000, + 0x3c42000e, + 0x3408bfff, + 0x20424000, + 0xa0280800, + 0xb8220800, + 0x59410000, + 0x29420000, + 0x3c63000f, + 0x7801ffff, + 0x38217fff, + 0xa0411000, + 0x20638000, + 0xb8431000, + 0x59420000, + 0x29430000, + 0x3c840010, + 0x7801ff00, + 0x780200ff, + 0x3821ffff, + 0x38420000, + 0xa0611800, + 0xa0822000, + 0xb8641800, + 0x59430000, + 0x29430000, + 0x3ca5001a, + 0x7801e3ff, + 0x78021c00, + 0x3821ffff, + 0x38420000, + 0xa0611800, + 0xa0a22800, + 0xb8651800, + 0x59430000, + 0x29430000, + 0x3cc60018, + 0x7801fcff, + 0x78020300, + 0x3821ffff, + 0x38420000, + 0xa0611800, + 0xa0c23000, + 0xb8661800, + 0x59430000, + 0x29430000, + 0x3ce7001d, + 0x7801dfff, + 0x78022000, + 0x3821ffff, + 0x38420000, + 0xa0611800, + 0xa0e23800, + 0xb8671800, + 0x59430000, + 0xc3a00000, + 0x780a8002, + 0x394a8048, + 0x29480000, + 0x3409fff0, + 0x2021000f, + 0xa1094000, + 0xb9014000, + 0x59480000, + 0x29410000, + 0x3c420004, + 0x3408ffef, + 0x20420010, + 0xa0280800, + 0xb8220800, + 0x59410000, + 0x29410000, + 0x3c630005, + 0x3402ffdf, + 0xa0220800, + 0x20630020, + 0xb8230800, + 0x59410000, + 0x29420000, + 0x3c840008, + 0x7801ffff, + 0x382100ff, + 0xa0411000, + 0x2084ff00, + 0xb8441000, + 0x59420000, + 0x29430000, + 0x3ca50010, + 0x7801fff8, + 0x78020007, + 0x3821ffff, + 0x38420000, + 0xa0611800, + 0xa0a22800, + 0xb8651800, + 0x59430000, + 0x29410000, + 0x3cc60006, + 0x3402ff3f, + 0xa0220800, + 0x20c600c0, + 0xb8260800, + 0x59410000, + 0x29430000, + 0x3ce70013, + 0x7801fff7, + 0x78020008, + 0x3821ffff, + 0x38420000, + 0xa0611800, + 0xa0e23800, + 0xb8671800, + 0x59430000, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b8c0004, + 0x780a0003, + 0xb9402800, + 0x38a58dd4, + 0x28a60000, + 0x78080003, + 0x39088dae, + 0x34c60001, + 0x20c6ffff, + 0x41070000, + 0x58a60000, + 0xb8204800, + 0xb8402800, + 0xb8605800, + 0xb8806000, + 0x5ce00007, + 0x78028002, + 0x38428000, + 0x28410030, + 0x20210001, + 0x4420fffe, + 0xe0000003, + 0x34010000, + 0x31010000, + 0xb9400800, + 0x38218dd4, + 0x78028002, + 0x38428000, + 0x28240000, + 0x28430000, + 0x00a50005, + 0x3401fc00, + 0xa0611800, + 0x208403ff, + 0x3d26001b, + 0xb8641800, + 0x01210005, + 0x58430000, + 0xb8a62800, + 0x58450004, + 0x20210007, + 0x58410008, + 0x584b000c, + 0xb8402800, + 0x34040000, + 0x3c820002, + 0xb44c0800, + 0x28230000, + 0x34840001, + 0xb4451000, + 0x68810007, + 0x58430010, + 0x4420fff9, + 0x394a8dd4, + 0x29410000, + 0x2b8b0008, + 0x2b8c0004, + 0x379c0008, + 0xc3a00000, + 0x78020003, + 0x78040003, + 0x38428de0, + 0x38848e28, + 0x34030001, + 0x3043000f, + 0x58810000, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0xb8206000, + 0xb8405800, + 0x7801c201, + 0x3821c530, + 0x34020026, + 0xfbffea21, + 0x7801c201, + 0xb9601000, + 0x3821c534, + 0xfbffea1d, + 0x7801c201, + 0x3821c538, + 0xb9801000, + 0xfbffea19, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x78038008, + 0x38630000, + 0x28650194, + 0x34040125, + 0x38a60001, + 0x58660194, + 0x58640190, + 0x58610198, + 0x38a10005, + 0x58610194, + 0x58660194, + 0x58620198, + 0x38a50003, + 0x58650194, + 0x58660194, + 0xc3a00000, + 0x78060003, + 0x38c6f320, + 0x28c60000, + 0x7807c020, + 0x38e7012c, + 0x20c60080, + 0x00ca0007, + 0x208400ff, + 0xb8a14800, + 0xb8404000, + 0x44c0000f, + 0x78010002, + 0x38210000, + 0xb8a31800, + 0x78020001, + 0xb8611800, + 0xb8a80800, + 0x38420000, + 0x58e90000, + 0xb8220800, + 0x51440002, + 0x58e10000, + 0x34010002, + 0x50240002, + 0x58e30000, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x3422ffff, + 0x340c0000, + 0x74410004, + 0xb9801800, + 0x340d0001, + 0xb9802000, + 0xb9805800, + 0x5c2c0022, + 0x3c410002, + 0x78020003, + 0x3842862c, + 0xb4220800, + 0x28210000, + 0xc0200000, + 0x78010003, + 0x3821f334, + 0x28220000, + 0x780b0002, + 0x396b0000, + 0x78018000, + 0x38210000, + 0xa0411000, + 0x34030001, + 0x4c400012, + 0xe0000004, + 0x780b0001, + 0x34030001, + 0x396b0000, + 0xb8602000, + 0xe000000c, + 0x780b0100, + 0x396b0000, + 0x340c0002, + 0xe0000008, + 0x780b0008, + 0x396b0000, + 0xe0000003, + 0x780b0004, + 0x396b0000, + 0x340d0000, + 0x340c0001, + 0x78010003, + 0x3821f330, + 0x28220000, + 0x64630000, + 0xb9625800, + 0x582b0000, + 0x5c600006, + 0x78020003, + 0x3842f320, + 0x28410000, + 0x38210010, + 0x58410000, + 0x64810000, + 0x5c200009, + 0x78020003, + 0x38428de0, + 0x34030001, + 0x78010003, + 0x3043000d, + 0x38218eac, + 0xfbfffd18, + 0x340d0000, + 0x45800005, + 0x78010003, + 0x3821f300, + 0x28220000, + 0x58220000, + 0x01610010, + 0x34020000, + 0x78050090, + 0x38a50000, + 0xb8401800, + 0x34040001, + 0xfbffff97, + 0xb9a00800, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x7801c201, + 0x34020065, + 0x3821c530, + 0xfbffe98d, + 0x7801c201, + 0x3821c534, + 0xfbffe9a4, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x78038008, + 0x38630000, + 0x28610194, + 0x3402ffc0, + 0xa0220800, + 0x38210001, + 0x58610194, + 0x34010124, + 0x58610190, + 0x28610198, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78030003, + 0x38638acc, + 0x28620048, + 0x78010001, + 0x38210000, + 0xb8411000, + 0x38420001, + 0x7801c201, + 0x58620048, + 0x3821c50c, + 0xfbffe96f, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x34060000, + 0x78070003, + 0x202900ff, + 0x204800ff, + 0x38e7f000, + 0xb8c02800, + 0x340a00ff, + 0xb5051000, + 0x204200ff, + 0x2041001f, + 0x00210004, + 0x2043000c, + 0x34210001, + 0xb5210800, + 0x3c210004, + 0x20420003, + 0xb8270800, + 0xb4230800, + 0xc8451000, + 0x28240000, + 0x3ca30003, + 0x3c420003, + 0x34a10001, + 0x80822000, + 0xbd431800, + 0x202500ff, + 0xa0832000, + 0x74a10003, + 0xb8c43000, + 0x4420ffea, + 0xb8c00800, + 0xc3a00000, + 0x28240004, + 0x28450004, + 0x28280000, + 0x2084ffff, + 0x20a5ffff, + 0xb4852000, + 0x2087ffff, + 0x58670004, + 0x28250004, + 0x28460004, + 0x00840010, + 0x00a50010, + 0x00c60010, + 0x28420000, + 0xb4a62800, + 0xb4852000, + 0x3c810010, + 0x00840010, + 0xb8e13800, + 0xb4882000, + 0xb4822000, + 0x58640000, + 0x58670004, + 0xc3a00000, + 0x34060000, + 0x204700ff, + 0x202300ff, + 0xb8c02000, + 0xbce42800, + 0x34820004, + 0x20610001, + 0x204400ff, + 0x00630001, + 0x64210000, + 0x7482001f, + 0x5c200002, + 0xb8c53000, + 0x4440fff7, + 0xb8c00800, + 0xc3a00000, + 0x00660002, + 0x34080000, + 0x20630003, + 0x3cc40002, + 0x3c630003, + 0xb8205000, + 0xb4812000, + 0xb9003800, + 0x28850000, + 0x80a32800, + 0x20a100ff, + 0xbc272800, + 0x34630008, + 0x34e70008, + 0x74e9001f, + 0x7c610020, + 0xb9054000, + 0x5c200007, + 0x34c60001, + 0x34840004, + 0x34030000, + 0x5cc20003, + 0xb8603000, + 0xb9402000, + 0x4520fff0, + 0xb9000800, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x78060003, + 0x38c68dd8, + 0x28c70000, + 0x780c8002, + 0x398c8000, + 0x34e70001, + 0x20e5ffff, + 0x58c50000, + 0x004e0005, + 0x29850000, + 0xb8205800, + 0x3d62001b, + 0x016d0005, + 0x3401fc00, + 0xa0a12800, + 0x20e703ff, + 0x016b0008, + 0xb8a72800, + 0x208400ff, + 0x34010000, + 0xb8607800, + 0xb9c27000, + 0x59850000, + 0xb8803800, + 0x216b00ff, + 0xb8201000, + 0xb8201800, + 0x34040037, + 0xb8202800, + 0xb8203000, + 0x3d6b0003, + 0xfbfffdf8, + 0x21ad0007, + 0x598e0004, + 0xb9ab6800, + 0x598d0008, + 0x598f000c, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b8c0004, + 0x20640003, + 0x780a8002, + 0xb8406000, + 0x3c840003, + 0x00630002, + 0xb8205800, + 0x394a8000, + 0x34020000, + 0x3c610002, + 0x34080000, + 0xb42b3000, + 0xb9003800, + 0x28c50000, + 0x80a42800, + 0x20a100ff, + 0xbc272800, + 0x34840008, + 0x34e70008, + 0x74e9001f, + 0x7c810020, + 0xb9054000, + 0x5c200007, + 0x34630001, + 0x34c60004, + 0x34040000, + 0x5c6c0003, + 0xb8801800, + 0xb9603000, + 0x4520fff0, + 0x34420001, + 0x59480010, + 0x74410007, + 0x354a0004, + 0x4420ffe7, + 0x2b8b0008, + 0x2b8c0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b8d0004, + 0x20a500ff, + 0x00a60001, + 0xb8406000, + 0x208400ff, + 0x20a50001, + 0x206200ff, + 0x3c840002, + 0x7ca80001, + 0x202d00ff, + 0x20c60001, + 0x340b0000, + 0x7807c210, + 0x7809c210, + 0x21830004, + 0x780ac210, + 0x5ccb0004, + 0x38e70008, + 0x58eb0000, + 0xe0000007, + 0x38e70008, + 0x34010002, + 0x58e10000, + 0x34050001, + 0x5d000002, + 0xb8a05800, + 0xbc431800, + 0x3401fff8, + 0x3ca20001, + 0xa1810800, + 0xb8220800, + 0x206200ff, + 0xb8242000, + 0x39290014, + 0x3c420008, + 0x59240000, + 0x394a0018, + 0xb9a22000, + 0xb9600800, + 0x59440000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b8d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffe4, + 0x5b8b001c, + 0x5b8c0018, + 0x5b8d0014, + 0x5b8e0010, + 0x5b8f000c, + 0x5b900008, + 0x5b9d0004, + 0x7803c210, + 0x7810c210, + 0x3863001c, + 0xba002000, + 0x58610000, + 0x38840008, + 0x28810000, + 0x780f0003, + 0xb9e01800, + 0x38210001, + 0x58810000, + 0x3863f334, + 0x28630000, + 0x78017f00, + 0x38210000, + 0xa0611800, + 0x006d0018, + 0x204e00ff, + 0x65ab0000, + 0x340c0000, + 0xe58d1800, + 0x3d840010, + 0x65620000, + 0x7801007f, + 0x38210000, + 0xa0431000, + 0xa0812000, + 0xb9e03800, + 0xba003000, + 0x7805ff80, + 0x64420000, + 0x7d610000, + 0x38e7f334, + 0x38c60008, + 0x38a5ffff, + 0x358c0001, + 0x5c200005, + 0x28e10000, + 0xa0250800, + 0xb8240800, + 0x58e10000, + 0x28c10000, + 0x20210010, + 0x5c200011, + 0x28c10000, + 0x3402fffe, + 0xa0220800, + 0x58c10000, + 0x5dc00005, + 0x28c10000, + 0x3402fffd, + 0xa0220800, + 0x58c10000, + 0x78010003, + 0x3821f320, + 0x28220000, + 0x3403ffef, + 0xa0431000, + 0x58220000, + 0xe0000006, + 0x5c40ffd8, + 0x340b0001, + 0xb9600800, + 0xfbfffe4b, + 0x5c20ffd4, + 0x2b8b001c, + 0x2b8c0018, + 0x2b8d0014, + 0x2b8e0010, + 0x2b8f000c, + 0x2b900008, + 0x2b9d0004, + 0x379c001c, + 0xc3a00000, + 0x379cffe0, + 0x5b8b0020, + 0x5b8c001c, + 0x5b8d0018, + 0x5b8e0014, + 0x5b8f0010, + 0x5b90000c, + 0x5b910008, + 0x5b9d0004, + 0x78060003, + 0x38c68de0, + 0x40c4000c, + 0xb8202800, + 0xb8404000, + 0x206f00ff, + 0xb8800800, + 0x44800062, + 0xb5e60800, + 0x4027001c, + 0x5ce0000e, + 0x3de10002, + 0x20a2ffff, + 0xb4261800, + 0x28610040, + 0x44410002, + 0x34070001, + 0x28620038, + 0x3401f000, + 0xa1010800, + 0x44220003, + 0x38e70001, + 0xe0000002, + 0x20e700ff, + 0x3401f000, + 0xa1010800, + 0x78110003, + 0xba204000, + 0x20a5ffff, + 0x39088de0, + 0x3df00002, + 0x00260018, + 0x3ca30008, + 0x29040030, + 0xb6081000, + 0x58410038, + 0xb8c33000, + 0x58450040, + 0x54860005, + 0x29010034, + 0x54c10003, + 0x34010000, + 0xe000003f, + 0x44e00038, + 0xba206000, + 0x398c8de0, + 0xb60c0800, + 0x282b0038, + 0x282d0040, + 0x29820020, + 0x016b000c, + 0x3de10003, + 0x3d6b000c, + 0x202e00ff, + 0x34010000, + 0xb44e1000, + 0x3403000f, + 0xb8202000, + 0xb8202800, + 0xfbffff3a, + 0x396b0067, + 0xb9600800, + 0x34020000, + 0xfbffff66, + 0x29820020, + 0x35c10004, + 0x202e00ff, + 0x34010000, + 0xb44e1000, + 0x3403000f, + 0xb8202000, + 0xb8202800, + 0xfbffff2d, + 0x21ad00ff, + 0xb9a00800, + 0x34020000, + 0xfbffff59, + 0x78018008, + 0x38210000, + 0x34020001, + 0x5822147c, + 0x58221478, + 0xb8201000, + 0x2841147c, + 0x20210001, + 0x64210000, + 0x5c20fffd, + 0x3a318de0, + 0xb6111000, + 0x28410038, + 0x28430040, + 0x780500e0, + 0x38a50000, + 0x00220010, + 0x2063ffff, + 0x2021ffff, + 0xb82f0800, + 0x34040003, + 0xfbfffdbb, + 0x78010003, + 0x38218de0, + 0xb5e10800, + 0x34020000, + 0x3022001c, + 0x34010001, + 0x2b8b0020, + 0x2b8c001c, + 0x2b8d0018, + 0x2b8e0014, + 0x2b8f0010, + 0x2b90000c, + 0x2b910008, + 0x2b9d0004, + 0x379c0020, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x206300ff, + 0x7c650000, + 0xb8403000, + 0x202700ff, + 0x34040002, + 0x5087000e, + 0x5ca00006, + 0x78010003, + 0x3821f320, + 0x28210000, + 0x20210080, + 0x44200028, + 0x00c20010, + 0x78050080, + 0x38a50000, + 0x20c1ffff, + 0x34030000, + 0xfbfffd95, + 0xe0000021, + 0x44a00020, + 0x34040000, + 0xb8802800, + 0x34a10001, + 0x202500ff, + 0x3c620001, + 0x20610008, + 0x74a80003, + 0x3c840008, + 0x204300ff, + 0x44200002, + 0x388400ff, + 0x4500fff7, + 0x3cec0002, + 0x78010003, + 0x3821f324, + 0xb5816000, + 0x298b0000, + 0xa4800800, + 0xa0c43000, + 0xa1615800, + 0x3ce10014, + 0x78050020, + 0xb9665800, + 0x38a50000, + 0xb4252800, + 0x01620010, + 0x2161ffff, + 0x34030000, + 0x34040002, + 0xfbfffd75, + 0x598b0000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x202b00ff, + 0x3d610014, + 0x780500a0, + 0x204cffff, + 0x38a50000, + 0x34020000, + 0xb4252800, + 0xb9800800, + 0xb8401800, + 0x34040001, + 0xfbfffd60, + 0x3d6b0002, + 0x78010003, + 0x3821f330, + 0xb5615800, + 0x29620000, + 0x7801ffff, + 0x38210000, + 0xa0411000, + 0xb84c1000, + 0x59620000, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x34230003, + 0x34040000, + 0x3406fffc, + 0x34050003, + 0xa0660800, + 0x28220000, + 0x3c840008, + 0x34a5ffff, + 0x20610003, + 0x3c210003, + 0x3463ffff, + 0x80411000, + 0x204200ff, + 0xb8822000, + 0x4ca0fff6, + 0xb8800800, + 0xc3a00000, + 0xb8403000, + 0x206500ff, + 0xb8202000, + 0x340afffc, + 0x340900ff, + 0x34070003, + 0x20810003, + 0x3c210003, + 0x20c200ff, + 0xbd211800, + 0xbc411000, + 0xa08a4000, + 0x20a10001, + 0x00c60008, + 0x00a50001, + 0x64210000, + 0xa4601800, + 0x34840001, + 0x34e7ffff, + 0x5c200005, + 0x29010000, + 0xa0230800, + 0xb8220800, + 0x59010000, + 0x4ce0ffee, + 0xc3a00000, + 0x7803c210, + 0x38630008, + 0x28620000, + 0x202100ff, + 0x38420001, + 0x58620000, + 0x5c200005, + 0x28610000, + 0x3402fffd, + 0xa0220800, + 0x58610000, + 0xc3a00000, + 0x202100ff, + 0x3c210004, + 0x78020003, + 0x3842f00c, + 0xb8220800, + 0x28230000, + 0x78020100, + 0x78040400, + 0x78010200, + 0x38210000, + 0xa0610800, + 0x38420000, + 0x38840000, + 0xa0621000, + 0x00210019, + 0xa0641800, + 0x0063001a, + 0x00420018, + 0x64260001, + 0x64420001, + 0x7c610001, + 0x78040003, + 0x34050000, + 0x5c250004, + 0x38848de0, + 0x30830018, + 0xe0000003, + 0x38848de0, + 0x30850018, + 0xa0c20800, + 0x34030000, + 0xe4230800, + 0x34020001, + 0x78040003, + 0x5c230004, + 0x38848de0, + 0x30830017, + 0xc3a00000, + 0x38848de0, + 0x30820017, + 0xc3a00000, + 0x379cff8c, + 0x5b8b003c, + 0x5b8c0038, + 0x5b8d0034, + 0x5b8e0030, + 0x5b8f002c, + 0x5b900028, + 0x5b910024, + 0x5b920020, + 0x5b93001c, + 0x5b940018, + 0x5b950014, + 0x5b960010, + 0x5b97000c, + 0x5b9b0008, + 0x5b9d0004, + 0x78100003, + 0xba000800, + 0x38218de0, + 0x40210001, + 0x5b81004c, + 0x2b82004c, + 0x78010003, + 0x3821f004, + 0x3c5b0004, + 0xbb610800, + 0x28230000, + 0x78020003, + 0x5b820040, + 0xb8400800, + 0x3821f008, + 0xbb610800, + 0x28350000, + 0x78020003, + 0x3842f00c, + 0x78010100, + 0xbb621000, + 0x38210000, + 0x284b0000, + 0xa2a10800, + 0x00210018, + 0x22a200ff, + 0x7c210001, + 0x5b820070, + 0x5b830074, + 0x5c200014, + 0x20630003, + 0x34010002, + 0xf0230800, + 0x78020003, + 0xc8010800, + 0xa0611800, + 0x3c630002, + 0x3842f324, + 0xb4621000, + 0x28410000, + 0x22a22000, + 0x5b810074, + 0x44400007, + 0x78010003, + 0x3821f330, + 0xb4610800, + 0x28210000, + 0x2021ffff, + 0x5b810070, + 0x78010400, + 0x38210000, + 0xa1610800, + 0x0021001a, + 0x7c210001, + 0x5c200010, + 0x78010003, + 0x3821f30c, + 0x28220000, + 0x37830058, + 0x78010fff, + 0x3821ffff, + 0xa0411000, + 0x3c420002, + 0x34010000, + 0x5b82006c, + 0x5b810068, + 0x37810070, + 0x37820068, + 0xfbfffd54, + 0xe0000005, + 0x2b810074, + 0x2b820070, + 0x5b81005c, + 0x5b820058, + 0x78010200, + 0x38210000, + 0xa1610800, + 0x00210019, + 0x78020003, + 0x64370001, + 0x38420000, + 0xa1621000, + 0x22a10f00, + 0x00330008, + 0x7806000c, + 0x00420010, + 0xba003800, + 0x38c60000, + 0xa1663000, + 0x38e78de0, + 0x204200ff, + 0x34010000, + 0x78030800, + 0x78050030, + 0x00cd0010, + 0x5b820048, + 0x38630000, + 0x40e80019, + 0x780400c0, + 0x38a50000, + 0x5b810060, + 0xa1631800, + 0xa1652800, + 0x2b810048, + 0x38840000, + 0xa1642000, + 0x0063001b, + 0x40e60002, + 0x00a50014, + 0x00840016, + 0x65120000, + 0x66f40000, + 0x21a200fc, + 0xb8416800, + 0x20a500ff, + 0x64760001, + 0x5b860064, + 0x208b00ff, + 0x5b850044, + 0xba608800, + 0xba540800, + 0x5c200003, + 0x7ec10000, + 0x4420000d, + 0x78030003, + 0x3863f30c, + 0x28620000, + 0x78011fff, + 0x3821ffff, + 0xa0411000, + 0x58620000, + 0x2b82005c, + 0x2b810058, + 0x5b820054, + 0x5b810050, + 0xe000002d, + 0x75a1000c, + 0x5c200027, + 0x78010003, + 0x3da20002, + 0x38218640, + 0xb4411000, + 0x28410000, + 0x78030003, + 0x78041fff, + 0xc0200000, + 0x2b810064, + 0x3863f30c, + 0x7802c000, + 0x3c210002, + 0x3884ffff, + 0x5b810064, + 0x28610000, + 0x38420000, + 0xe0000009, + 0x2b810064, + 0x3863f30c, + 0x78026000, + 0x3c210005, + 0x3884ffff, + 0x5b810064, + 0x28610000, + 0x38420000, + 0xa0240800, + 0xb8220800, + 0x58610000, + 0xe000000a, + 0xb8600800, + 0x3821f30c, + 0x28220000, + 0x3884ffff, + 0x34030000, + 0xa0441000, + 0x58220000, + 0x5b830060, + 0x5b830064, + 0x37810058, + 0x37820060, + 0x37830050, + 0xfbfffce5, + 0x65610003, + 0x7eee0000, + 0x2b820054, + 0xa02e0800, + 0x64210000, + 0x204c001f, + 0x5c200003, + 0x340b0000, + 0xe0000008, + 0x7d610003, + 0x5c200006, + 0x2b81004c, + 0xb9801000, + 0xfbfffcb7, + 0xb8207800, + 0xe0000006, + 0x3d620002, + 0x78010003, + 0x3821f324, + 0xb4411000, + 0x284f0000, + 0x22a11000, + 0x7c350000, + 0x75a1000c, + 0x5c200101, + 0x3da10002, + 0x78020003, + 0x38428674, + 0xb4220800, + 0x28210000, + 0xc0200000, + 0x2b810054, + 0x3402fffc, + 0x7803c200, + 0xa0220800, + 0x38630000, + 0xb8230800, + 0xb9e01000, + 0xfbffe609, + 0xe0000018, + 0x2b810054, + 0x78028008, + 0x38420000, + 0x00210002, + 0x78040003, + 0x3c210002, + 0x78030003, + 0xb4220800, + 0x582f0000, + 0x3a108de0, + 0x34010001, + 0x38845250, + 0x38638e28, + 0x3201000f, + 0xe0000087, + 0x78020003, + 0x3842f340, + 0x2b810054, + 0xba601800, + 0x202101ff, + 0xb4220800, + 0xb9e01000, + 0xfbfffeaf, + 0x78030003, + 0x78020003, + 0x38635250, + 0xe0000010, + 0x78020003, + 0x3842f540, + 0xe3fffff4, + 0x2b820054, + 0x2b850048, + 0x2b810050, + 0xba601800, + 0x34040000, + 0xfbfffd39, + 0xb8201000, + 0xb9e00800, + 0xfbfffd66, + 0x78030003, + 0x78020003, + 0x38634fc8, + 0x3a108de0, + 0x38428e28, + 0x34010001, + 0x3201000f, + 0x58430000, + 0xe00000c2, + 0x66c10000, + 0xa1c10800, + 0x64210000, + 0x5c200016, + 0x5e400015, + 0xba406800, + 0xba401000, + 0x34410001, + 0xb9b16800, + 0x202200ff, + 0x3e310004, + 0x74410007, + 0x4420fffb, + 0x2b830054, + 0x2b8c0064, + 0x780b8002, + 0x2063001f, + 0x396b8058, + 0x340e0040, + 0xb5831800, + 0xb9600800, + 0xb9c01000, + 0xfbfffc9e, + 0xb8207800, + 0xe000002d, + 0x65610003, + 0xa2810800, + 0x64210000, + 0x5c20001b, + 0x2b820040, + 0x340e0008, + 0x3842f008, + 0xbb620800, + 0x28210000, + 0x780200ff, + 0x38420000, + 0xa0220800, + 0x00210010, + 0xba601000, + 0x202100ff, + 0xfbfffc7c, + 0xb8206800, + 0x2b81004c, + 0xb9801800, + 0x340c0000, + 0x34220001, + 0x3c420004, + 0x78010003, + 0x3821f000, + 0xb8415800, + 0xb9600800, + 0xb9c01000, + 0xfbfffc80, + 0xb8207800, + 0xe000000f, + 0xbe6c6800, + 0x3401001c, + 0x502c0004, + 0xc80c0800, + 0x82610800, + 0xb9a16800, + 0x21820003, + 0x3d630002, + 0x78010003, + 0x3821f324, + 0xc8021000, + 0xb4615800, + 0x204c0003, + 0x340e0001, + 0x2b810050, + 0x2b820054, + 0x34030001, + 0xfbfffd66, + 0x4420000b, + 0xba000800, + 0x38218de0, + 0x28220028, + 0x2821002c, + 0x5b810050, + 0x2b810054, + 0x20210fff, + 0xb4411000, + 0x34421000, + 0x5b820054, + 0x2b810050, + 0x2b820054, + 0xbaa02000, + 0xb9a01800, + 0xfbfffc77, + 0xb9600800, + 0xb9c01000, + 0xb9801800, + 0xfbfffca7, + 0x78020003, + 0x78040003, + 0x78030003, + 0x38428de0, + 0x34010001, + 0x38845314, + 0x38638e28, + 0x3041000f, + 0x58640000, + 0xe000005b, + 0x78010003, + 0x3821f000, + 0xbb610800, + 0x28220000, + 0x34060000, + 0x7801001f, + 0x3821ffff, + 0xa0413800, + 0x5e86001a, + 0x2b850054, + 0xe6c60800, + 0x78038008, + 0x78020003, + 0x78040003, + 0x5c260008, + 0x38630000, + 0x38420198, + 0x3401fffc, + 0xb4621000, + 0xa0a10800, + 0x58410000, + 0xe0000005, + 0x38630000, + 0x38420198, + 0xb4620800, + 0x58250000, + 0x2b810050, + 0x78028008, + 0x38420000, + 0x3884019c, + 0xb4441000, + 0x2021ffff, + 0x58410000, + 0xe000001b, + 0x78038008, + 0x78020003, + 0x38630000, + 0x38420190, + 0x78010003, + 0xb4621000, + 0x38210194, + 0x584f0000, + 0xb4610800, + 0x58370000, + 0x2b810054, + 0x78020003, + 0x3404fffc, + 0x38420198, + 0xa0240800, + 0xb4621000, + 0x58410000, + 0x78010003, + 0x3821019c, + 0xb4611800, + 0x2b810050, + 0x78064000, + 0xa0e43800, + 0x2021ffff, + 0x58610000, + 0x38c60000, + 0x3ea10018, + 0x78058008, + 0x78020003, + 0x38a50000, + 0x3842018c, + 0xb8c13000, + 0xb4a21000, + 0xa1d61800, + 0x58460000, + 0x64630000, + 0x78060003, + 0x78020003, + 0x78040003, + 0x5c600008, + 0x78012000, + 0x384203a0, + 0x38210000, + 0xb4a21000, + 0xb8e10800, + 0x58410000, + 0xe0000004, + 0x384203a0, + 0xb4a20800, + 0x58270000, + 0x38845530, + 0x3a108de0, + 0x38c68e28, + 0x34010001, + 0x3201000f, + 0x58c40000, + 0x2b810044, + 0xb9e01000, + 0xba601800, + 0xfbfffd66, + 0x2b81004c, + 0xfbfffdf5, + 0x78010003, + 0x38218eac, + 0xfbfff87f, + 0x2b8b003c, + 0x2b8c0038, + 0x2b8d0034, + 0x2b8e0030, + 0x2b8f002c, + 0x2b900028, + 0x2b910024, + 0x2b920020, + 0x2b93001c, + 0x2b940018, + 0x2b950014, + 0x2b960010, + 0x2b97000c, + 0x2b9b0008, + 0x2b9d0004, + 0x379c0074, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x00240008, + 0xb8206000, + 0x78060003, + 0x780100ff, + 0x38c68ddc, + 0x3821ffff, + 0x28c50000, + 0x3c840018, + 0xa0e13800, + 0x7801ffff, + 0xb8e43800, + 0x38210000, + 0xa0e13800, + 0x34a50001, + 0x20a5ffff, + 0x780100ff, + 0xb8e53800, + 0x38210000, + 0xb8e13800, + 0x780b8002, + 0x58c50000, + 0x396b8000, + 0x340100ff, + 0x59610050, + 0x00420008, + 0x3d8c0018, + 0x59670044, + 0x206300ff, + 0x34010000, + 0xb9826000, + 0xb8603800, + 0xb8201000, + 0xb8201800, + 0x34040037, + 0xb8202800, + 0xb8203000, + 0xfbfffa2b, + 0x596c004c, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffc4, + 0x5b8b0024, + 0x5b8c0020, + 0x5b8d001c, + 0x5b8e0018, + 0x5b8f0014, + 0x5b900010, + 0x5b91000c, + 0x5b920008, + 0x5b9d0004, + 0x78110003, + 0xba200800, + 0x38218de0, + 0x40320001, + 0x78020003, + 0x3842f008, + 0x3e430004, + 0x78010003, + 0x3821f004, + 0xb8610800, + 0x28240000, + 0xb8621000, + 0x284c0000, + 0x78010100, + 0x38210000, + 0x78020003, + 0x3842f00c, + 0xb8621800, + 0xa1810800, + 0x286b0000, + 0x00210018, + 0x218200ff, + 0x7c210001, + 0x5b820038, + 0x5b84003c, + 0x5c200014, + 0x20830003, + 0x34010002, + 0xf0230800, + 0x78020003, + 0xc8010800, + 0xa0611800, + 0x3c630002, + 0x3842f324, + 0xb4621000, + 0x28410000, + 0x21822000, + 0x5b81003c, + 0x44400007, + 0x78010003, + 0x3821f330, + 0xb4610800, + 0x28210000, + 0x2021ffff, + 0x5b810038, + 0x78010400, + 0x38210000, + 0xa1610800, + 0x0021001a, + 0x7c210001, + 0x5c200010, + 0x78010003, + 0x3821f304, + 0x28220000, + 0x37830028, + 0x78010fff, + 0x3821ffff, + 0xa0411000, + 0x3c420002, + 0x34010000, + 0x5b820034, + 0x5b810030, + 0x37810038, + 0x37820030, + 0xfbfffb38, + 0xe0000005, + 0x2b81003c, + 0x2b830038, + 0x5b81002c, + 0x5b830028, + 0x78020200, + 0x7803000c, + 0x38420000, + 0x38630000, + 0xa1621000, + 0x00420019, + 0xa1631800, + 0x00630012, + 0x78010003, + 0x644f0001, + 0x38210000, + 0x206300ff, + 0xa1610800, + 0x00210010, + 0x7c620002, + 0x78040030, + 0x38840000, + 0x202600ff, + 0xa1642000, + 0x3c630002, + 0x00840014, + 0x21851000, + 0xa1e21000, + 0x21810f00, + 0xb8661800, + 0x002e0008, + 0x7cb00000, + 0x64420000, + 0x206300ff, + 0x208d00ff, + 0x5c400004, + 0x3a318de0, + 0x34010000, + 0x32210019, + 0x7461000c, + 0x5c20007e, + 0x3c610002, + 0x78020003, + 0x384286a8, + 0xb4220800, + 0x28210000, + 0x780b0003, + 0x780c0003, + 0xc0200000, + 0x2b81002c, + 0x3402fffc, + 0x7803c200, + 0xa0220800, + 0x38630000, + 0xb8230800, + 0xfbffe465, + 0xe0000019, + 0x2b82002c, + 0x78048008, + 0x38840000, + 0x00420002, + 0xb9a00800, + 0x3c420002, + 0xb9c01800, + 0xb4441000, + 0x28420000, + 0x396b8de0, + 0x398c8e28, + 0xfbfffc91, + 0x78010003, + 0x382159c8, + 0x34020001, + 0x3162000f, + 0x59810000, + 0xe000005c, + 0x78020003, + 0x3842f340, + 0x2b81002c, + 0x202101ff, + 0xb4220800, + 0xfbfffcdf, + 0xb8201000, + 0xb9a00800, + 0xb9c01800, + 0xfbfffc81, + 0x78020003, + 0x384259c8, + 0xe000000d, + 0x78020003, + 0x3842f540, + 0xe3fffff3, + 0x2b82002c, + 0x2b810028, + 0xb9c01800, + 0xb8c02800, + 0x34040001, + 0xfbfffb77, + 0xfbfffcf9, + 0x78020003, + 0x38425074, + 0x396b8de0, + 0x398c8e28, + 0x34010001, + 0x3161000f, + 0x59820000, + 0xe000003d, + 0x2b82002c, + 0x2b810028, + 0x396b8de0, + 0x31620000, + 0x34030000, + 0xfbfffbea, + 0x44200008, + 0x2961002c, + 0x29620028, + 0x5b810028, + 0x2b81002c, + 0x20210fff, + 0xb4411000, + 0x5b82002c, + 0x2b810028, + 0x2b82002c, + 0xba001800, + 0xfbffff0b, + 0x78010003, + 0x78020003, + 0x382157e4, + 0x38428e28, + 0x34040001, + 0x65e30000, + 0x58410000, + 0x3164000f, + 0x5c600022, + 0x31640019, + 0xe0000020, + 0x65e10000, + 0x5c20000e, + 0x2b83002c, + 0x78028008, + 0x78010003, + 0x38420000, + 0x38210190, + 0xb4410800, + 0x58230000, + 0x78010003, + 0x38210194, + 0xb4411000, + 0x2b810028, + 0x2021ffff, + 0x58410000, + 0x78028008, + 0x78010003, + 0x3821018c, + 0x38420000, + 0x3e06000c, + 0xb4411000, + 0x78050003, + 0x78030003, + 0x78040003, + 0x58460000, + 0x38a55484, + 0x38638de0, + 0x38848e28, + 0x34010001, + 0x3061000f, + 0x58850000, + 0xba400800, + 0xfbfffcbf, + 0x78010003, + 0x38218eac, + 0xfbfff749, + 0x2b8b0024, + 0x2b8c0020, + 0x2b8d001c, + 0x2b8e0018, + 0x2b8f0014, + 0x2b900010, + 0x2b91000c, + 0x2b920008, + 0x2b9d0004, + 0x379c003c, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x284b0000, + 0xb8403800, + 0x202100ff, + 0x3c210004, + 0x78020003, + 0x3842f000, + 0xb8220800, + 0x282c0000, + 0x7804f000, + 0x38840000, + 0xa1840800, + 0x0021001c, + 0x28e30000, + 0x78060fff, + 0x34020001, + 0x38c6ffff, + 0xbc411000, + 0xa1665800, + 0xb5625800, + 0xa0641800, + 0xa1662000, + 0xb8641800, + 0x3d610002, + 0x0162000e, + 0x58e30000, + 0x780500d0, + 0xa1866000, + 0x2021fffc, + 0x2042ffff, + 0x38a50000, + 0x34030000, + 0x34040002, + 0xfbfff9a5, + 0xf16c0800, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8de0, + 0x41630018, + 0x78020003, + 0x3842f304, + 0x202100ff, + 0x4460000a, + 0xfbffffcb, + 0x78020003, + 0x3842f320, + 0x34030000, + 0x44230004, + 0x28410000, + 0x38210004, + 0x58410000, + 0x31630018, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8de0, + 0x41630018, + 0x78020003, + 0x3842f30c, + 0x202100ff, + 0x4460000a, + 0xfbffffb4, + 0x78020003, + 0x3842f320, + 0x34030000, + 0x44230004, + 0x28410000, + 0x38210008, + 0x58410000, + 0x31630018, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8de0, + 0x41630013, + 0x34010000, + 0x34020002, + 0x44610004, + 0xfbfff940, + 0x34010000, + 0x31610013, + 0x41630014, + 0x34010000, + 0x34020002, + 0x44610004, + 0xfbfff950, + 0x34010000, + 0x31610014, + 0x41610017, + 0x78050003, + 0x78040003, + 0x38a56938, + 0x34060001, + 0x388440b4, + 0x78020003, + 0x44200005, + 0x38428e28, + 0x3166000f, + 0x58450000, + 0xe0000004, + 0x38428e28, + 0x3166000f, + 0x58440000, + 0x78010003, + 0x38218eac, + 0xfbfff6c0, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78020003, + 0x3842f30c, + 0x28430000, + 0x78040003, + 0x38848de0, + 0x7802e000, + 0x38420000, + 0xa0621800, + 0x0063001d, + 0x40820002, + 0x34060001, + 0xbcc31800, + 0xb4461000, + 0x34050000, + 0x204200ff, + 0x202100ff, + 0x206300ff, + 0x54620005, + 0x30850002, + 0x30860017, + 0xfbffffaa, + 0xe0000002, + 0x30820002, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8de0, + 0x41610001, + 0xfbffffde, + 0x41630013, + 0x34010000, + 0x34020002, + 0x44610004, + 0xfbfff8f9, + 0x34010000, + 0x31610013, + 0x41630014, + 0x34010000, + 0x34020002, + 0x44610004, + 0xfbfff909, + 0x34010000, + 0x31610014, + 0x41610017, + 0x78050003, + 0x78040003, + 0x38a56938, + 0x34060001, + 0x388440b4, + 0x78020003, + 0x44200005, + 0x38428e28, + 0x3166000f, + 0x58450000, + 0xe0000004, + 0x38428e28, + 0x3166000f, + 0x58440000, + 0x78010003, + 0x38218eac, + 0xfbfff679, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cffe4, + 0x5b8b001c, + 0x5b8c0018, + 0x5b8d0014, + 0x5b8e0010, + 0x5b8f000c, + 0x5b900008, + 0x5b9d0004, + 0x780f0003, + 0xb9e00800, + 0x3821f334, + 0x28220000, + 0x78100003, + 0x340c0000, + 0x78017f00, + 0x38210000, + 0xa0411000, + 0xba000800, + 0x38218de0, + 0x004d0018, + 0x402e0001, + 0x65ab0000, + 0xb9c00800, + 0xfbffff4b, + 0xe58d1800, + 0x3d840010, + 0x65620000, + 0x7801007f, + 0x38210000, + 0xa0431000, + 0xa0812000, + 0x7806c210, + 0xb9e03800, + 0x7805ff80, + 0x64420000, + 0x7d610000, + 0x38e7f334, + 0x38c60008, + 0x38a5ffff, + 0x358c0001, + 0x5c200005, + 0x28e10000, + 0xa0250800, + 0xb8240800, + 0x58e10000, + 0x28c10000, + 0x20210008, + 0x4420003a, + 0x3dc30004, + 0x78010003, + 0x3821f00c, + 0xb8610800, + 0x28210000, + 0x78020003, + 0x3842f008, + 0xb8621800, + 0x28630000, + 0x78020030, + 0x38420000, + 0x7804c210, + 0xa0220800, + 0x3884000c, + 0x28820000, + 0x00210014, + 0x20630f00, + 0x00630008, + 0x202100ff, + 0xfbfffb13, + 0x78030003, + 0x3863f320, + 0x28610000, + 0x3402ffef, + 0xba005800, + 0xa0220800, + 0x396b8de0, + 0x58610000, + 0x41610013, + 0x44200006, + 0x34010000, + 0x34020002, + 0xfbfff889, + 0x34010000, + 0x31610013, + 0x41610014, + 0x44200006, + 0x34010000, + 0x34020002, + 0xfbfff899, + 0x34010000, + 0x31610014, + 0x41610017, + 0x78020003, + 0x78030003, + 0x38426938, + 0x5c200003, + 0x78020003, + 0x384240b4, + 0x34010001, + 0x3161000f, + 0x38638e28, + 0x78010003, + 0x58620000, + 0x38218eac, + 0xfbfff60d, + 0xe0000006, + 0x5c40ffaf, + 0x340b0001, + 0xb9600800, + 0xfbfff8ae, + 0x5c20ffab, + 0x2b8b001c, + 0x2b8c0018, + 0x2b8d0014, + 0x2b8e0010, + 0x2b8f000c, + 0x2b900008, + 0x2b9d0004, + 0x379c001c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8de0, + 0x41610001, + 0xfbffff3c, + 0x78040003, + 0x3884f320, + 0x28820000, + 0x3403ffef, + 0x34010000, + 0xa0431000, + 0x58820000, + 0x41630013, + 0x34020002, + 0x44610004, + 0xfbfff851, + 0x34010000, + 0x31610013, + 0x41630014, + 0x34010000, + 0x34020002, + 0x44610004, + 0xfbfff861, + 0x34010000, + 0x31610014, + 0x41610017, + 0x78050003, + 0x78040003, + 0x38a56938, + 0x34060001, + 0x388440b4, + 0x78020003, + 0x44200005, + 0x38428e28, + 0x3166000f, + 0x58450000, + 0xe0000004, + 0x38428e28, + 0x3166000f, + 0x58440000, + 0x78010003, + 0x38218eac, + 0xfbfff5d1, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x780e0003, + 0xb9c00800, + 0x3821f334, + 0x28220000, + 0x340c0000, + 0x78017f00, + 0x38210000, + 0xa0411000, + 0x004d0018, + 0xe5ac5800, + 0xe58d1800, + 0x3d840010, + 0x65620000, + 0x7801007f, + 0x38210000, + 0xa0431000, + 0xa0812000, + 0x78068002, + 0xb9c03800, + 0x7805ff80, + 0x64420000, + 0x7d610000, + 0x38c68000, + 0x38e7f334, + 0x38a5ffff, + 0x358c0001, + 0x5c200005, + 0x28e10000, + 0xa0250800, + 0xb8240800, + 0x58e10000, + 0x28c10030, + 0x20210001, + 0x64210000, + 0x5c200028, + 0x780b0003, + 0x396b8de0, + 0x41610001, + 0xfbfffee5, + 0x78020003, + 0x3842f320, + 0x28410000, + 0x3403ffef, + 0xa0230800, + 0x58410000, + 0x41610013, + 0x44200006, + 0x34010000, + 0x34020002, + 0xfbfff7fa, + 0x34010000, + 0x31610013, + 0x41610014, + 0x44200006, + 0x34010000, + 0x34020002, + 0xfbfff80a, + 0x34010000, + 0x31610014, + 0x41610017, + 0x78020003, + 0x78030003, + 0x38426938, + 0x5c200003, + 0x78020003, + 0x384240b4, + 0x34010001, + 0x3161000f, + 0x38638e28, + 0x78010003, + 0x58620000, + 0x38218eac, + 0xfbfff57e, + 0xe0000006, + 0x5c40ffc0, + 0x340b0001, + 0xb9600800, + 0xfbfff81f, + 0x5c20ffbc, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8de0, + 0x41610001, + 0xfbfffe58, + 0x41630013, + 0x34010000, + 0x34020002, + 0x44610004, + 0xfbfff7ca, + 0x34010000, + 0x31610013, + 0x41630014, + 0x34010000, + 0x34020002, + 0x44610004, + 0xfbfff7da, + 0x34010000, + 0x31610014, + 0x41610017, + 0x78050003, + 0x78040003, + 0x38a56938, + 0x34060001, + 0x388440b4, + 0x78020003, + 0x44200005, + 0x38428e28, + 0x3166000f, + 0x58450000, + 0xe0000004, + 0x38428e28, + 0x3166000f, + 0x58440000, + 0x78010003, + 0x38218eac, + 0xfbfff54a, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cffe0, + 0x5b8b0020, + 0x5b8c001c, + 0x5b8d0018, + 0x5b8e0014, + 0x5b8f0010, + 0x5b90000c, + 0x5b910008, + 0x5b9d0004, + 0x780e0003, + 0xb9c00800, + 0x38218de0, + 0x40210001, + 0x78100003, + 0x340d0000, + 0xfbfffe7b, + 0xba000800, + 0x3821f334, + 0x28220000, + 0xb9c08800, + 0x78017f00, + 0x38210000, + 0xa0411000, + 0x004f0018, + 0xe5ed6000, + 0x3da20010, + 0x7803007f, + 0x38630000, + 0xa0433000, + 0x78053ffe, + 0xba004000, + 0x781d0003, + 0x7804ff80, + 0x7803c001, + 0xb8a03800, + 0x7d820000, + 0x3908f334, + 0x3bbdf740, + 0x3884ffff, + 0x34010002, + 0x3863c001, + 0x38e73ffe, + 0x5c400005, + 0x29020000, + 0xa0441000, + 0xb8461000, + 0x59020000, + 0x2bab0000, + 0x5d630049, + 0x78048008, + 0x78090003, + 0x38840000, + 0x38a53ffe, + 0x3929018c, + 0x780a4000, + 0x78080003, + 0x5ba50000, + 0xb4894800, + 0x394a0000, + 0x39080190, + 0x78070003, + 0x592a0000, + 0xb4884000, + 0x38e70194, + 0x78060003, + 0x591d0000, + 0x340c0000, + 0xb4873800, + 0x38c60198, + 0x78030003, + 0x58ec0000, + 0xb4863000, + 0x34010230, + 0x3863019c, + 0x78020003, + 0x58c10000, + 0xb4831800, + 0x384203a0, + 0x78054800, + 0x586c0000, + 0xb4822000, + 0x38a50004, + 0x58850000, + 0x592a0000, + 0x590b0000, + 0x58ec0000, + 0x34010234, + 0x58c10000, + 0x586c0000, + 0x78030003, + 0x58850000, + 0x3863f320, + 0x28610000, + 0x3402ffef, + 0xba205800, + 0xa0220800, + 0x58610000, + 0x396b8de0, + 0x41610013, + 0x442c0005, + 0xb9800800, + 0x34020002, + 0xfbfff744, + 0x316c0013, + 0x41610014, + 0x44200005, + 0xb9800800, + 0x34020002, + 0xfbfff755, + 0x316c0014, + 0x41610017, + 0x78020003, + 0x78030003, + 0x38426938, + 0x5c200003, + 0x78020003, + 0x384240b4, + 0x34010001, + 0x38638e28, + 0x3161000f, + 0xe000001c, + 0x45670020, + 0xfbfff771, + 0xb8205800, + 0x5c20001d, + 0xb9c06000, + 0x398c8de0, + 0x41820013, + 0x44400004, + 0x34020002, + 0xfbfff728, + 0x318b0013, + 0x41810014, + 0x44200005, + 0xb9600800, + 0x34020002, + 0xfbfff739, + 0x318b0014, + 0x41810017, + 0x78020003, + 0x78030003, + 0x38426938, + 0x5c200003, + 0x78020003, + 0x384240b4, + 0x34010001, + 0x38638e28, + 0x3181000f, + 0x78010003, + 0x58620000, + 0x38218eac, + 0xfbfff4ae, + 0xe000000b, + 0xe5af1000, + 0x65810000, + 0x35ad0001, + 0xa0220800, + 0x64210000, + 0x5c20ff7b, + 0x340c0001, + 0xb9800800, + 0xfbfff74a, + 0x5c20ff77, + 0x2b8b0020, + 0x2b8c001c, + 0x2b8d0018, + 0x2b8e0014, + 0x2b8f0010, + 0x2b90000c, + 0x2b910008, + 0x2b9d0004, + 0x379c0020, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x780f0003, + 0xb9e00800, + 0x38218de0, + 0x40210001, + 0x780e0003, + 0x340c0000, + 0xfbfffd79, + 0xb9c00800, + 0x3821f334, + 0x28220000, + 0x78017f00, + 0x38210000, + 0xa0411000, + 0x004d0018, + 0xe5ac5800, + 0xe58d1800, + 0x3d840010, + 0x65620000, + 0x7801007f, + 0x38210000, + 0xa0431000, + 0xa0812000, + 0x78068002, + 0xb9c03800, + 0x7805ff80, + 0x64420000, + 0x7d610000, + 0x38c68000, + 0x38e7f334, + 0x38a5ffff, + 0x358c0001, + 0x5c200005, + 0x28e10000, + 0xa0250800, + 0xb8240800, + 0x58e10000, + 0x28c10050, + 0x202100ff, + 0x7c2100ff, + 0x5c20003e, + 0xb9e05800, + 0x396b8de0, + 0x41630000, + 0x78018002, + 0x34020040, + 0x38218058, + 0xfbfff7cf, + 0x41640001, + 0xb8201000, + 0x78010003, + 0x3c840004, + 0x3821f00c, + 0xb8810800, + 0x28210000, + 0x78030003, + 0x3863f008, + 0xb8832000, + 0x28830000, + 0x78040030, + 0x38840000, + 0xa0240800, + 0x00210014, + 0x20630f00, + 0x00630008, + 0x202100ff, + 0xfbfff932, + 0x78020003, + 0x3842f320, + 0x28410000, + 0x3403ffef, + 0xa0230800, + 0x58410000, + 0x41610013, + 0x44200006, + 0x34010000, + 0x34020002, + 0xfbfff6aa, + 0x34010000, + 0x31610013, + 0x41610014, + 0x44200006, + 0x34010000, + 0x34020002, + 0xfbfff6ba, + 0x34010000, + 0x31610014, + 0x41610017, + 0x78020003, + 0x78030003, + 0x38426938, + 0x5c200003, + 0x78020003, + 0x384240b4, + 0x34010001, + 0x3161000f, + 0x38638e28, + 0x78010003, + 0x58620000, + 0x38218eac, + 0xfbfff42e, + 0xe0000006, + 0x5c40ffaa, + 0x340b0001, + 0xb9600800, + 0xfbfff6cf, + 0x5c20ffa6, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8de0, + 0x41610001, + 0xfbfffd07, + 0x78040003, + 0x3884f320, + 0x28820000, + 0x3403ffef, + 0x34010000, + 0xa0431000, + 0x58820000, + 0x41630013, + 0x34020002, + 0x44610004, + 0xfbfff673, + 0x34010000, + 0x31610013, + 0x41630014, + 0x34010000, + 0x34020002, + 0x44610004, + 0xfbfff683, + 0x34010000, + 0x31610014, + 0x41610017, + 0x78050003, + 0x78040003, + 0x38a56938, + 0x34060001, + 0x388440b4, + 0x78020003, + 0x44200005, + 0x38428e28, + 0x3166000f, + 0x58450000, + 0xe0000004, + 0x38428e28, + 0x3166000f, + 0x58440000, + 0x78010003, + 0x38218eac, + 0xfbfff3f3, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x202400ff, + 0x34070000, + 0x7481000f, + 0xb8403000, + 0xb8602800, + 0xb8e04000, + 0xb8e05000, + 0x5c270055, + 0x3c810002, + 0x78020003, + 0x384286dc, + 0xb4220800, + 0x28210000, + 0xc0200000, + 0xb8c03800, + 0xe000005b, + 0xa0c33800, + 0xe000004a, + 0xa0c30800, + 0xe0000006, + 0xb8c33800, + 0xe0000046, + 0x98c33800, + 0xe0000044, + 0xb8c30800, + 0xa4203800, + 0xe0000040, + 0x206500ff, + 0x34a2ffff, + 0xbcc21000, + 0x78018000, + 0x38210000, + 0xa0411000, + 0x0042001f, + 0xbcc53800, + 0x204800ff, + 0xe0000037, + 0x206500ff, + 0x34a1ffff, + 0x80c10800, + 0x80c53800, + 0x20280001, + 0xe0000031, + 0x206500ff, + 0xc8051000, + 0x80c21000, + 0xbcc53800, + 0xe0000005, + 0x206500ff, + 0xc8051000, + 0xbcc21000, + 0x80c53800, + 0x78018000, + 0xb8e23800, + 0x38210000, + 0xa0e10800, + 0x0021001f, + 0x202800ff, + 0xe0000021, + 0x0063001c, + 0x00c2001c, + 0x78010fff, + 0xb4431000, + 0x3821ffff, + 0xa0a11800, + 0x7c44000f, + 0x7449000f, + 0xa0c10800, + 0xb4230800, + 0xb4c53800, + 0x34020000, + 0x5c820005, + 0x0023001c, + 0x7c610001, + 0x5c220002, + 0xb8601000, + 0xb9220800, + 0x4420000e, + 0xe000000c, + 0x8cc30800, + 0x34020001, + 0xc4c33800, + 0x50410009, + 0xb8404000, + 0xe0000007, + 0xc8c33800, + 0x50c30005, + 0xe0000003, + 0xc8663800, + 0x50660002, + 0x34080001, + 0x5ce00002, + 0x340a0001, + 0x78030003, + 0x3863f320, + 0x28610000, + 0x3402fffe, + 0x3d040001, + 0xa0220800, + 0xb82a0800, + 0x58610000, + 0x28610000, + 0x3402fffd, + 0xa0220800, + 0xb8240800, + 0x58610000, + 0xb8e00800, + 0xc3a00000, + 0x379cffe0, + 0x5b8b0020, + 0x5b8c001c, + 0x5b8d0018, + 0x5b8e0014, + 0x5b8f0010, + 0x5b90000c, + 0x5b910008, + 0x5b9d0004, + 0x780e0003, + 0xb9c00800, + 0x38218de0, + 0x40240001, + 0x78030003, + 0x3863f000, + 0x3c840004, + 0x78010003, + 0x3821f00c, + 0xb8810800, + 0x28290000, + 0xb8831800, + 0x78020003, + 0x28250000, + 0x38420000, + 0x0126000d, + 0x286a0000, + 0x78010003, + 0x3821f004, + 0xb8810800, + 0x282c0000, + 0xa0a22800, + 0x00a50010, + 0x78010003, + 0x3821f008, + 0xb8812000, + 0x288b0000, + 0x0122000c, + 0x20a500ff, + 0x00a80001, + 0x20420001, + 0x01210004, + 0x01230008, + 0x0124000f, + 0x0127000e, + 0x7c420001, + 0x202f000f, + 0x2070000f, + 0x21080001, + 0x20840001, + 0x20c60001, + 0x20e70001, + 0x213d000f, + 0x20b10001, + 0x5c400012, + 0x214a0003, + 0x7d410003, + 0x7c820001, + 0xc8010800, + 0xa1415000, + 0x3d430002, + 0x5c400007, + 0x78010003, + 0x3821f330, + 0xb4610800, + 0x28210000, + 0x202affff, + 0xe0000005, + 0x78010003, + 0x3821f324, + 0xb4610800, + 0x282a0000, + 0x7cc10001, + 0x5c200012, + 0x218c0003, + 0x7d810003, + 0x7c820001, + 0xc8010800, + 0xa1816000, + 0x3d830002, + 0x5c400007, + 0x78010003, + 0x3821f330, + 0xb4610800, + 0x28210000, + 0x202cffff, + 0xe0000005, + 0x78010003, + 0x3821f324, + 0xb4610800, + 0x282c0000, + 0x7ce10001, + 0x5c200012, + 0x216b0003, + 0x7d610003, + 0x7c820001, + 0xc8010800, + 0xa1615800, + 0x3d630002, + 0x5c400007, + 0x78010003, + 0x3821f330, + 0xb4610800, + 0x28210000, + 0x202bffff, + 0xe0000005, + 0x78010003, + 0x3821f324, + 0xb4610800, + 0x282b0000, + 0x780100c0, + 0x38210000, + 0xa1210800, + 0x78020030, + 0x00210016, + 0x38420000, + 0xa1221000, + 0x202300ff, + 0x00420014, + 0x7c610003, + 0x204d00ff, + 0x5c200006, + 0x78010003, + 0x3821f320, + 0x28210000, + 0x202200ff, + 0xe000000e, + 0x65010000, + 0x3c620002, + 0x5c200007, + 0x78010003, + 0x3821f330, + 0xb4410800, + 0x28210000, + 0x2022ffff, + 0xe0000005, + 0x78010003, + 0x3821f324, + 0xb4410800, + 0x28220000, + 0xb9401800, + 0xbba00800, + 0xfbffff07, + 0xb8201000, + 0xb9801800, + 0xb9e00800, + 0xfbffff03, + 0xb8201000, + 0xba000800, + 0xb9601800, + 0xfbfffeff, + 0xb8201000, + 0x7da10003, + 0x5c20000a, + 0x78030003, + 0x3863f320, + 0x28610000, + 0x204400ff, + 0x3402ff00, + 0xa0220800, + 0xb8240800, + 0x58610000, + 0xe0000009, + 0x66210000, + 0x5c200004, + 0xb9a00800, + 0xfbfff7fb, + 0xe0000004, + 0xb9a00800, + 0x3403000f, + 0xfbfff7bb, + 0x78020003, + 0x78030003, + 0x38426938, + 0x38638e28, + 0x34040001, + 0x39ce8de0, + 0x78010003, + 0x31c4000f, + 0x58620000, + 0x38218eac, + 0xfbfff2ce, + 0x2b8b0020, + 0x2b8c001c, + 0x2b8d0018, + 0x2b8e0014, + 0x2b8f0010, + 0x2b90000c, + 0x2b910008, + 0x2b9d0004, + 0x379c0020, + 0xc3a00000, + 0x379cffd4, + 0x5b8b002c, + 0x5b8c0028, + 0x5b8d0024, + 0x5b8e0020, + 0x5b8f001c, + 0x5b900018, + 0x5b910014, + 0x5b920010, + 0x5b93000c, + 0x5b940008, + 0x5b9d0004, + 0x78110003, + 0xba208000, + 0x3a108de0, + 0x42130001, + 0x78010003, + 0x3821f008, + 0x3e6f0004, + 0x78140003, + 0xb9e10800, + 0x28230000, + 0xba806800, + 0x39adf320, + 0x29a10000, + 0x006c0010, + 0x34020000, + 0x78050070, + 0x202b00ff, + 0x2072ffff, + 0xb9600800, + 0x38a50000, + 0xb8401800, + 0x34040001, + 0xfbfff52d, + 0x218effff, + 0x21810300, + 0x4420000e, + 0x7801c201, + 0x34020065, + 0x3821c530, + 0xfbffdf29, + 0x7801c201, + 0x3821c534, + 0xfbffdf40, + 0x00220008, + 0x00210004, + 0x20420100, + 0xb9625800, + 0x20210200, + 0xb9615800, + 0x21810c00, + 0x44200011, + 0x78038008, + 0x38630000, + 0x28610194, + 0x3402ffc0, + 0xa0220800, + 0x38210001, + 0x58610194, + 0x34010124, + 0x58610190, + 0x28620198, + 0x00410006, + 0x00420002, + 0x20210400, + 0xb9615800, + 0x20420800, + 0xb9625800, + 0xa24e1000, + 0xa16e0800, + 0x4422000a, + 0x78020003, + 0x78030003, + 0x38426938, + 0x38638e28, + 0x34040001, + 0x78010003, + 0x3204000f, + 0x58620000, + 0xe0000058, + 0x78010003, + 0x3821f004, + 0xb9e12000, + 0x288b0000, + 0x21634000, + 0x44600005, + 0x34020001, + 0x78010003, + 0x3202000d, + 0xe000004e, + 0x21610800, + 0x44200006, + 0x29a10000, + 0x34020001, + 0x32020010, + 0x38210040, + 0x59a10000, + 0x21610400, + 0x44200006, + 0x29a10000, + 0x3402ffbf, + 0x32030010, + 0xa0220800, + 0x59a10000, + 0x21610200, + 0x44200015, + 0x28810000, + 0x202100ff, + 0x5c200003, + 0x3401001f, + 0xe0000003, + 0x3421ffff, + 0x202100ff, + 0x34230034, + 0x3a318de0, + 0xba802000, + 0x32230001, + 0x3884f320, + 0x28820000, + 0x206300ff, + 0x7801ff00, + 0x3821ffff, + 0x3c630010, + 0xa0411000, + 0xb8431000, + 0x58820000, + 0x21610100, + 0x44200007, + 0x78020003, + 0x38428de0, + 0x34030001, + 0x78010003, + 0x3043000e, + 0xe0000022, + 0x21611000, + 0x4420000a, + 0x78010003, + 0x3821f000, + 0xb9e10800, + 0x28230000, + 0x78021fff, + 0x3842ffff, + 0x0061001d, + 0xa0621000, + 0xfbfff497, + 0x21612000, + 0x4420000b, + 0x3e620004, + 0x78010003, + 0x3821f000, + 0xb8411000, + 0x28430000, + 0x78021fff, + 0x3842ffff, + 0x0061001d, + 0xa0621000, + 0xfbfff4a2, + 0x78050003, + 0x78020003, + 0x78030003, + 0x38a56938, + 0x38428de0, + 0x38638e28, + 0x34040001, + 0x78010003, + 0x3044000f, + 0x58650000, + 0x38218eac, + 0xfbfff21a, + 0x2b8b002c, + 0x2b8c0028, + 0x2b8d0024, + 0x2b8e0020, + 0x2b8f001c, + 0x2b900018, + 0x2b910014, + 0x2b920010, + 0x2b93000c, + 0x2b940008, + 0x2b9d0004, + 0x379c002c, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78080003, + 0xb9000800, + 0x38218de0, + 0x40220001, + 0x78050003, + 0x78030030, + 0x3c470004, + 0x78010003, + 0x3821f00c, + 0xb8e10800, + 0x28240000, + 0x78020003, + 0x38420000, + 0x780100c0, + 0x38210000, + 0xa0821000, + 0xa0810800, + 0x00210016, + 0x00420010, + 0x38630000, + 0x38a5f004, + 0x204200ff, + 0xa0832000, + 0x202600ff, + 0xb8e52800, + 0x00410001, + 0x00840014, + 0x28a50000, + 0x7cc30003, + 0x208400ff, + 0x20210001, + 0x20420001, + 0x5c600005, + 0x78010003, + 0x3821f000, + 0xb8e10800, + 0xe000000d, + 0x64210000, + 0x3cc30002, + 0x5c200007, + 0x78010003, + 0x3821f330, + 0xb4610800, + 0x28210000, + 0x2023ffff, + 0xe0000005, + 0x78010003, + 0x3821f324, + 0xb4610800, + 0x28230000, + 0x7c810003, + 0x5c200005, + 0x78010003, + 0x3821f000, + 0xb8e10800, + 0xe000000d, + 0x64410000, + 0x3c840002, + 0x5c200007, + 0x78010003, + 0x3821f330, + 0xb4810800, + 0x28210000, + 0x2021ffff, + 0xe0000005, + 0x78010003, + 0x3821f324, + 0xb4810800, + 0x28210000, + 0xa0250800, + 0xa0651800, + 0xe4612000, + 0x34050000, + 0x50230002, + 0x34050001, + 0x78030003, + 0x3863f320, + 0x28610000, + 0x3402fffe, + 0x3ca50001, + 0xa0220800, + 0xb8240800, + 0x58610000, + 0x28610000, + 0x3402fffd, + 0x78040003, + 0xa0220800, + 0xb8250800, + 0x58610000, + 0x78020003, + 0x38846938, + 0x39088de0, + 0x38428e28, + 0x34030001, + 0x78010003, + 0x3103000f, + 0x58440000, + 0x38218eac, + 0xfbfff1a8, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x202100ff, + 0x3c210004, + 0x78020003, + 0x3842f008, + 0xb8221000, + 0x28450000, + 0x7804f000, + 0x38840000, + 0x78020200, + 0x38420000, + 0xa0a21000, + 0x78030003, + 0xa0a42800, + 0x3863f00c, + 0x00a5001c, + 0xb8233000, + 0x00420019, + 0x20a30003, + 0x34010002, + 0x78070003, + 0x7c420001, + 0xf0230800, + 0x38e7f324, + 0x5c40000a, + 0xc8010800, + 0xa0611800, + 0x3c610002, + 0xb4270800, + 0x28210000, + 0x00220004, + 0x2025000f, + 0x204bffff, + 0xe0000003, + 0x28c10000, + 0x202bffff, + 0xbd655800, + 0x78020003, + 0x34030001, + 0x38428de0, + 0x3043001a, + 0x584b0004, + 0x34010007, + 0xfbfff2c3, + 0x34010007, + 0xfbfff2b6, + 0xb9601000, + 0x34010007, + 0xfbfff2c8, + 0x34010001, + 0x3c21001c, + 0x78028000, + 0x38428000, + 0x58410054, + 0x3401003c, + 0xfbffac92, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x78010003, + 0x34030000, + 0x38218de0, + 0x58230004, + 0x3023001a, + 0x3401003c, + 0xfbffacb2, + 0x34010007, + 0xfbfff2a8, + 0x34010001, + 0x3c21001c, + 0x78028000, + 0x38428000, + 0x58410054, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x202200ff, + 0x34010001, + 0x78040003, + 0x78060003, + 0xbc221800, + 0x3884f320, + 0x38c68de0, + 0x34050000, + 0x3409001f, + 0x3408ffdf, + 0x34a50001, + 0x34410001, + 0x68a7001f, + 0x3c630001, + 0x202200ff, + 0x51220007, + 0x28810000, + 0x34020000, + 0x34030001, + 0xa0280800, + 0x38210020, + 0x58810000, + 0x28c10008, + 0xa0230800, + 0x44200003, + 0xb8400800, + 0xc3a00000, + 0x44e0ffef, + 0x34010020, + 0xc3a00000, + 0x379cffec, + 0x5b8b0014, + 0x5b8c0010, + 0x5b8d000c, + 0x5b8e0008, + 0x5b9d0004, + 0x780d0003, + 0xb9a02800, + 0x38a58de0, + 0x40a80001, + 0x78010003, + 0x3821f00c, + 0x3d030004, + 0x78027000, + 0xb8613000, + 0x28c10000, + 0x38420000, + 0xb9a03800, + 0xa0220800, + 0x0024001c, + 0x44800020, + 0x64810002, + 0x5c20000e, + 0x68810002, + 0x5c200004, + 0x64810001, + 0x5c200005, + 0xe0000013, + 0x64810004, + 0x5c20000c, + 0xe0000010, + 0x78020003, + 0x78010003, + 0x38428e28, + 0x38216214, + 0xe000000a, + 0x78020003, + 0x78010003, + 0x38428e28, + 0x38215c3c, + 0xe0000005, + 0x78020003, + 0x78010003, + 0x38428e28, + 0x38215f38, + 0x58410000, + 0xb8e01000, + 0x38428de0, + 0x34030001, + 0x78010003, + 0x3043000f, + 0xe00000b6, + 0x40a10010, + 0x44200009, + 0x78010003, + 0x3821f300, + 0x28220000, + 0x78010002, + 0x38210000, + 0xa0411000, + 0x00420011, + 0x5c40000c, + 0x78030003, + 0x30a40010, + 0x3863f320, + 0x28610000, + 0x3402ffbf, + 0x34040001, + 0xa0220800, + 0x58610000, + 0x30a4000f, + 0x30a40011, + 0xe00000a3, + 0x78010003, + 0x3821f008, + 0xb8610800, + 0x28240000, + 0x78030400, + 0x38630000, + 0x28c50000, + 0x78010c00, + 0x38210000, + 0x28c20000, + 0xa0812000, + 0x78010100, + 0x38210000, + 0x0084001a, + 0xa0431000, + 0xa0a12800, + 0x0042001a, + 0x00810001, + 0x00ae0018, + 0x7c420001, + 0x20290001, + 0x5c400044, + 0x78010003, + 0x78020003, + 0x5dc0001e, + 0xb8403800, + 0x38e7f31c, + 0x28e20000, + 0xb8202800, + 0x38a5f320, + 0x7806ff00, + 0x38c60000, + 0x28a10000, + 0xa0461000, + 0x00420018, + 0x20210004, + 0x5c200002, + 0x44480033, + 0x28a10000, + 0x3402fffb, + 0x78030003, + 0xa0220800, + 0x58a10000, + 0x3863f304, + 0x28620000, + 0x7801f000, + 0x38210000, + 0xa0411000, + 0x58620000, + 0x28e30000, + 0x780100ff, + 0x3d020018, + 0x3821ffff, + 0xe000001e, + 0xb8403800, + 0x38e7f31c, + 0x28e20000, + 0xb8202800, + 0x780600ff, + 0x38c60000, + 0x38a5f320, + 0xa0461000, + 0x28a10000, + 0x00420010, + 0x20210008, + 0x204200ff, + 0x5c200002, + 0x44480015, + 0x28a10000, + 0x3402fff7, + 0x78030003, + 0xa0220800, + 0x58a10000, + 0x3863f30c, + 0x28620000, + 0x7801f000, + 0x38210000, + 0xa0411000, + 0x58620000, + 0x28e30000, + 0x7801ff00, + 0x3d020010, + 0x3821ffff, + 0xa0611800, + 0xa0461000, + 0xb8621800, + 0x58e30000, + 0xe0000002, + 0x20890001, + 0xb9a01800, + 0x34020000, + 0x38638de0, + 0x7d210001, + 0x30620017, + 0xb8406000, + 0x5c22000e, + 0x90005800, + 0xd0020000, + 0xb9000800, + 0xfbfffee5, + 0xb9a00800, + 0x38218de0, + 0x34030000, + 0x34020001, + 0x30230014, + 0x30220016, + 0x30230013, + 0xd00b0000, + 0xe000001e, + 0x3062001a, + 0x58620004, + 0x3401003c, + 0xfbffabd0, + 0x34010007, + 0xfbfff1c6, + 0x34010001, + 0x3c21001c, + 0x78028000, + 0x38428000, + 0x58410054, + 0x90005800, + 0xd00c0000, + 0xb9a01000, + 0x38428de0, + 0x40430012, + 0x44600006, + 0x34010000, + 0x30410015, + 0x30410012, + 0x340c0001, + 0xe0000004, + 0x34010001, + 0x30410015, + 0xb8606000, + 0xd00b0000, + 0x34010000, + 0x39ad8de0, + 0x31a10012, + 0x78040003, + 0xb8801000, + 0x38428de0, + 0x34010000, + 0x30410011, + 0x7dc30001, + 0x65850000, + 0x78020003, + 0x5c610005, + 0x78010003, + 0x38428e28, + 0x382140b4, + 0xe0000004, + 0x78010003, + 0x38428e28, + 0x3821494c, + 0x58410000, + 0x5ca00007, + 0x38848de0, + 0x34020001, + 0x78010003, + 0x3082000f, + 0x38218eac, + 0xfbfff04b, + 0x2b8b0014, + 0x2b8c0010, + 0x2b8d000c, + 0x2b8e0008, + 0x2b9d0004, + 0x379c0014, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x780b0003, + 0x396b8de0, + 0x416c0001, + 0x3581ffcc, + 0x202100ff, + 0xfbfffee7, + 0x78060003, + 0x38c6f320, + 0x34210034, + 0x202c00ff, + 0x28c40000, + 0x3d830010, + 0x7802ff00, + 0x780100ff, + 0x3842ffff, + 0x38210000, + 0xa0611800, + 0xa0822000, + 0xb8832000, + 0x34020000, + 0x58c40000, + 0x78050010, + 0x38a50000, + 0xb9800800, + 0xb8401800, + 0x34040001, + 0xfbfff2b1, + 0x316c0001, + 0xfbfffeee, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cffcc, + 0x5b8b0034, + 0x5b8c0030, + 0x5b8d002c, + 0x5b8e0028, + 0x5b8f0024, + 0x5b900020, + 0x5b91001c, + 0x5b920018, + 0x5b930014, + 0x5b940010, + 0x5b95000c, + 0x5b960008, + 0x5b970004, + 0x340a0000, + 0x202100ff, + 0x78140003, + 0x78138000, + 0x78127000, + 0x78110200, + 0x78100100, + 0x780f00c0, + 0x780e000c, + 0x780d0003, + 0xe42ab800, + 0xb9406000, + 0x205600ff, + 0x3a94f34c, + 0x3a730000, + 0x3a520000, + 0x3a310000, + 0x3a100000, + 0x39ef0000, + 0x39ce0000, + 0x39adf348, + 0x34070001, + 0xb9404000, + 0x3d050004, + 0x34150000, + 0xb4b41800, + 0x28660000, + 0xb4ad2800, + 0x28610000, + 0xa0d33000, + 0x00c6001f, + 0x28620000, + 0xa0320800, + 0x002b001c, + 0xa0511000, + 0x28610000, + 0x00420019, + 0x20c600ff, + 0x28640000, + 0xa0300800, + 0x00210018, + 0x28630000, + 0x64290001, + 0x7c420001, + 0x28a10000, + 0xa08f2000, + 0xa06e1800, + 0x20210f00, + 0x00840016, + 0x00630012, + 0xa1221000, + 0x00250008, + 0xe4551000, + 0x208100ff, + 0x206300ff, + 0x5c550007, + 0x64210003, + 0xe5751000, + 0xa0220800, + 0xe4350800, + 0x5c350002, + 0x34150001, + 0x7ec10000, + 0x34040000, + 0xa1210800, + 0xe4240800, + 0x5c240007, + 0xe4a41000, + 0x64610002, + 0xa0220800, + 0xe4240800, + 0x5c240002, + 0x34040001, + 0x64610002, + 0x7cc20001, + 0xa2e11800, + 0x5c400013, + 0x66a10000, + 0x5c200008, + 0x35080002, + 0x3401001f, + 0x4c280002, + 0xe000000e, + 0xb9475000, + 0x3ce70003, + 0xe000000b, + 0x64810000, + 0x5c200002, + 0x398c0002, + 0x64610000, + 0x5c200004, + 0x3ce70001, + 0x398c0001, + 0xe0000003, + 0xb9475000, + 0x3ce70001, + 0x35080001, + 0x6901001f, + 0x4420ffb5, + 0x78010003, + 0x38218de0, + 0x78020003, + 0x582a0008, + 0x3842f318, + 0x28410000, + 0xb9800800, + 0x584a0000, + 0x2b8b0034, + 0x2b8c0030, + 0x2b8d002c, + 0x2b8e0028, + 0x2b8f0024, + 0x2b900020, + 0x2b91001c, + 0x2b920018, + 0x2b930014, + 0x2b940010, + 0x2b95000c, + 0x2b960008, + 0x2b970004, + 0x379c0034, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0x90006800, + 0x34010000, + 0xd0010000, + 0x78010003, + 0x3821f300, + 0x28250000, + 0x78040002, + 0x78020004, + 0x28270000, + 0x38840000, + 0x38420000, + 0x28260000, + 0xa0e43800, + 0x78030001, + 0xa0c23000, + 0x38630000, + 0x00c60012, + 0x00e70011, + 0xa0a32800, + 0x34080001, + 0x20cb00ff, + 0x00a50010, + 0x20e700ff, + 0x78030003, + 0x78010003, + 0xfd686000, + 0xfce83000, + 0x38638de0, + 0x38218eac, + 0x20a500ff, + 0x78040003, + 0x78020003, + 0x5ca00003, + 0x3068000d, + 0xe000001b, + 0xb8802800, + 0x78010003, + 0x38a5f320, + 0x34030000, + 0x38218eac, + 0x5cc30008, + 0x38428de0, + 0x30470010, + 0x28a20000, + 0x38420040, + 0x58a20000, + 0xfbffef62, + 0xe0000007, + 0x38428de0, + 0x30430010, + 0x28a10000, + 0x3402ffbf, + 0xa0220800, + 0x58a10000, + 0x78020003, + 0x78010003, + 0x38428de0, + 0x5d800005, + 0x304b001b, + 0x304b000e, + 0x38218eac, + 0xfbffef53, + 0xd00d0000, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x379cffe8, + 0x5b8b0018, + 0x5b8c0014, + 0x5b8d0010, + 0x5b8e000c, + 0x5b8f0008, + 0x5b9d0004, + 0x3401003c, + 0xfbffaa97, + 0x34010007, + 0xfbfff08d, + 0x340d0001, + 0x3da1001c, + 0x780b8000, + 0x396b8000, + 0x780c0003, + 0x59610054, + 0x340e0000, + 0x398c8de0, + 0x3401001a, + 0x598e0004, + 0x318e001a, + 0xfbffaa89, + 0x3da2001a, + 0x34010019, + 0x59620050, + 0xfbffaa85, + 0x3da10019, + 0x78040003, + 0x59610050, + 0x3884f334, + 0x28820000, + 0x7801ff80, + 0x3821ffff, + 0xa0411000, + 0x78030003, + 0x58820000, + 0x3863f330, + 0x28610000, + 0x780bc210, + 0x780f0003, + 0x2021ffff, + 0x58610000, + 0x396b0008, + 0xb9e00800, + 0x596e0000, + 0x3821f300, + 0x28210000, + 0x20210004, + 0xfc2e0800, + 0xe42e1000, + 0x3181000c, + 0x5c4e003a, + 0x7802fe00, + 0xb9a02000, + 0x38420810, + 0x3403000f, + 0xb9a02800, + 0x340100fd, + 0xfbfff2f4, + 0xb9c00800, + 0xfbfff475, + 0x7804c210, + 0xb9601000, + 0x3884000c, + 0x28410000, + 0x20210008, + 0x4420fffe, + 0x28840000, + 0x3401fff0, + 0xa0812000, + 0x78050003, + 0x78080003, + 0x3908f33c, + 0x29020000, + 0x7801ffff, + 0x38210000, + 0xa0411000, + 0x00420010, + 0x38a58de0, + 0x78010003, + 0x58a20030, + 0x3821f314, + 0x28270000, + 0x78068008, + 0x38c60000, + 0x28c1153c, + 0x3c43000c, + 0xb4872000, + 0xc8230800, + 0x3c21000c, + 0x3ce70009, + 0xb4812000, + 0x58a40020, + 0x29010000, + 0x34030001, + 0x202100ff, + 0xb4411000, + 0x3442ffff, + 0x58a20034, + 0x28c1155c, + 0x3c21000c, + 0xb4270800, + 0x58a10028, + 0x28c1155c, + 0x00210014, + 0x30a3001d, + 0x58a1002c, + 0x30a3001c, + 0xe0000003, + 0x3181001d, + 0x3181001c, + 0x7802fe00, + 0x3403000f, + 0x34040000, + 0x34050001, + 0x38420094, + 0x340100fd, + 0xfbfff2b9, + 0x34010007, + 0x34020000, + 0xfbfff2e6, + 0x34040001, + 0x7802fe00, + 0x38420098, + 0x3403000f, + 0xb8802800, + 0x340100fd, + 0xfbfff2af, + 0x34010000, + 0xfbfff430, + 0x7803c210, + 0x7802c210, + 0x38630008, + 0x3842000c, + 0x28610000, + 0x20210008, + 0x4420fffe, + 0x28420000, + 0x0042000f, + 0x78018000, + 0x382100a4, + 0x28210000, + 0x20420001, + 0x780d0003, + 0x20210001, + 0xfbfffe9c, + 0xb9e01800, + 0x3863f300, + 0x28620000, + 0xb8205800, + 0x7801ffff, + 0x38217fff, + 0xa0411000, + 0x58620000, + 0x28610000, + 0x3402bfff, + 0xb9a02000, + 0xa0220800, + 0x58610000, + 0x3884f320, + 0x28810000, + 0x3402ff80, + 0x21630002, + 0xa0220800, + 0x58810000, + 0x44600005, + 0x34010003, + 0xfbfff149, + 0xb8201000, + 0x44200055, + 0x21610001, + 0x64210000, + 0x5c200005, + 0x34010004, + 0xfbfff142, + 0xb8201000, + 0x4420004e, + 0x34010020, + 0xfbfffd45, + 0xb8206000, + 0x7c210020, + 0x5c200005, + 0x34010005, + 0xfbfff139, + 0xb8201000, + 0x44200045, + 0x78020003, + 0x7801c001, + 0x3842f740, + 0x3821c001, + 0x358c0034, + 0x780e0003, + 0x39ce8de0, + 0x58410000, + 0x218300ff, + 0xb9a02000, + 0x31c30001, + 0x3884f320, + 0x28820000, + 0x7801ff00, + 0x3821ffff, + 0x3c630010, + 0xa0411000, + 0xb8431000, + 0x78030003, + 0x58820000, + 0x38638acc, + 0x28620048, + 0x7801fffe, + 0x3821ffff, + 0xa0411000, + 0x38420001, + 0x7801c201, + 0x58620048, + 0x3821c50c, + 0xfbffdb02, + 0x3401001a, + 0xfbffa998, + 0x340d0001, + 0x3da1001a, + 0x780b8000, + 0x396b8000, + 0x59610050, + 0x34010019, + 0xfbffa991, + 0x3da10019, + 0x34040000, + 0x59610050, + 0x78030003, + 0x31cc0001, + 0x31c4000f, + 0x31c40012, + 0x31c40013, + 0x31c40014, + 0x31c40015, + 0x31c40016, + 0x31c40017, + 0x31c40018, + 0x31c40019, + 0x3863f31c, + 0x28610000, + 0x2021ffff, + 0x58610000, + 0x41c1001b, + 0x44240008, + 0xb9e01800, + 0x3863f300, + 0x28620000, + 0x7801fffb, + 0x3821ffff, + 0xa0411000, + 0x58620000, + 0x31c4001b, + 0xb9a01000, + 0xb8400800, + 0x2b8b0018, + 0x2b8c0014, + 0x2b8d0010, + 0x2b8e000c, + 0x2b8f0008, + 0x2b9d0004, + 0x379c0018, + 0xc3a00000, + 0x379cfff4, + 0x5b8b000c, + 0x5b8c0008, + 0x5b9d0004, + 0x3401003c, + 0xfbffa992, + 0x340c0001, + 0x3d81001c, + 0x780b8000, + 0x396b8000, + 0x59610054, + 0x34010007, + 0xfbffef83, + 0x3401001a, + 0xfbffa989, + 0x3d82001a, + 0x34010019, + 0x59620050, + 0xfbffa985, + 0x3d810019, + 0x7803c210, + 0x59610050, + 0x34020000, + 0x38630008, + 0x78010003, + 0x58620000, + 0x38218de0, + 0x78050003, + 0x302c0011, + 0x3022000c, + 0x3022000f, + 0x3022001b, + 0x30220010, + 0x38a5f320, + 0x28a30000, + 0x3404ffbf, + 0xa0641800, + 0x58a30000, + 0x3022000d, + 0x30220012, + 0x30220013, + 0x30220014, + 0x30220015, + 0x30220016, + 0x30220017, + 0x30220018, + 0x30220019, + 0x3022000e, + 0x3022001a, + 0x58220004, + 0x2b8b000c, + 0x2b8c0008, + 0x2b9d0004, + 0x379c000c, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0x78010003, + 0x34020000, + 0x38218eac, + 0xfbffee3d, + 0x90002000, + 0x34010000, + 0xd0010000, + 0x780b0003, + 0xb9601000, + 0x38428de0, + 0x4043000d, + 0x3041000d, + 0xd0040000, + 0x44600003, + 0xfbffffb8, + 0xe3fffff1, + 0x90002000, + 0xd0030000, + 0xb9601000, + 0x38428de0, + 0x4043000e, + 0x34010000, + 0x3041000e, + 0xd0040000, + 0x4460000f, + 0xfbfffea5, + 0x78030003, + 0x78020003, + 0x396b8de0, + 0x38638e28, + 0x38426570, + 0x34040001, + 0x4420ffe0, + 0x78010003, + 0x58620000, + 0x3164000f, + 0x38218eac, + 0xfbffede4, + 0xe3ffffda, + 0x90002000, + 0xd0030000, + 0xb9600800, + 0x38218de0, + 0x4023000f, + 0x34020000, + 0x3022000f, + 0xd0040000, + 0x78010003, + 0x38218e28, + 0x396b8de0, + 0x4462ffce, + 0x28210000, + 0x3162000f, + 0xd8200000, + 0xe3ffffca, + 0x78050003, + 0x78020003, + 0xb8a00800, + 0x3842f4ff, + 0x3821f300, + 0x34070000, + 0x58270000, + 0x34210001, + 0x54220002, + 0xe3fffffd, + 0x78048008, + 0x78020003, + 0x38840000, + 0x3842ffff, + 0x78030003, + 0x7801c001, + 0x5882202c, + 0x3863f740, + 0x3821c001, + 0x58610000, + 0x38a5f300, + 0x28a10000, + 0x3402f00f, + 0x3404cfff, + 0xa0220800, + 0x38210090, + 0x58a10000, + 0x28a20000, + 0x78010003, + 0x38218de0, + 0x38420008, + 0x58a20000, + 0x28a20000, + 0x34030000, + 0x34060001, + 0xa0441000, + 0x38421000, + 0x58a20000, + 0x3027000d, + 0x30260011, + 0x3023001a, + 0x3027000c, + 0x3023000e, + 0x3023000f, + 0x3023001b, + 0x30230010, + 0x30230012, + 0x30230013, + 0x30230014, + 0x30230015, + 0x30230016, + 0x30230017, + 0x30230018, + 0x30230019, + 0x58270004, + 0xc3a00000, + 0x7801c210, + 0x38210008, + 0x28220000, + 0x38420001, + 0x58220000, + 0x28210000, + 0xc3a00000, + 0x7802c210, + 0x38420008, + 0x28410000, + 0x00210004, + 0x20210001, + 0x7c210001, + 0x4420fffc, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x20230004, + 0x00210003, + 0x64630000, + 0x3c210003, + 0x20c60007, + 0xb8c13000, + 0x3401fffb, + 0xc8031800, + 0xa0c13000, + 0x2063001f, + 0x3401ff00, + 0x3463fff0, + 0x7804ffff, + 0xa0e13800, + 0x388400ff, + 0x206300ff, + 0x3c630008, + 0x3401fffd, + 0xa0e43800, + 0x7805c210, + 0xa0c13000, + 0x38a50014, + 0x7804c210, + 0x58a60000, + 0xb8e33800, + 0x38840018, + 0x7801c210, + 0x58870000, + 0x3821001c, + 0x58220000, + 0xfbffffd1, + 0xfbffffd7, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x20220004, + 0x00210003, + 0x64420000, + 0x3c210003, + 0x20a50007, + 0xb8a12800, + 0xc8021000, + 0x3401ff00, + 0x2042001f, + 0xa0c13000, + 0x3442fff0, + 0x3401fffd, + 0x204200ff, + 0x7804ffff, + 0x38a50004, + 0xa0a12800, + 0x3c420008, + 0x388400ff, + 0x7803c210, + 0xa0c43000, + 0x38630014, + 0x7801c210, + 0x58650000, + 0xb8c23000, + 0x38210018, + 0x58260000, + 0xfbffffb0, + 0xfbffffb6, + 0x7801c210, + 0x3821000c, + 0x28210000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfff8, + 0x5b8b0008, + 0x5b9d0004, + 0xb8205800, + 0x00210003, + 0x20a50007, + 0x3c210003, + 0x21620007, + 0xb8a12800, + 0x34030001, + 0xbc621800, + 0x3401ff00, + 0xa0c13000, + 0x3401fffd, + 0x206300ff, + 0x7804ffff, + 0x38a50004, + 0xa0a12800, + 0x3c630008, + 0x388400ff, + 0x7802c210, + 0xa0c43000, + 0x38420014, + 0x7801c210, + 0x58450000, + 0xb8c33000, + 0x38210018, + 0x58260000, + 0xfbffff8c, + 0xfbffff92, + 0x7801c210, + 0x3821000c, + 0x28210000, + 0x216b0003, + 0x3d6b0003, + 0x802b0800, + 0x202100ff, + 0x2b8b0008, + 0x2b9d0004, + 0x379c0008, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x20430004, + 0x00420003, + 0x64630000, + 0x3c420003, + 0x20a50007, + 0xb8a22800, + 0x3402ff00, + 0xc8031800, + 0xa0c23000, + 0x202100ff, + 0x2063001f, + 0xb8c13000, + 0x3463fff0, + 0x3401fffd, + 0x206300ff, + 0x7804ffff, + 0x38a50004, + 0xa0a12800, + 0x3c630008, + 0x388400ff, + 0x7802c210, + 0xa0c43000, + 0x38420014, + 0x7801c210, + 0x58450000, + 0xb8c33000, + 0x38210018, + 0x58260000, + 0xfbffff61, + 0xfbffff67, + 0x7801c210, + 0x3821000c, + 0x28210000, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x379cfffc, + 0x5b9d0004, + 0x20440004, + 0x00420003, + 0x64840000, + 0x3c420003, + 0x20c60007, + 0xb8c23000, + 0x3402ff00, + 0xc8042000, + 0xa0e23800, + 0x202100ff, + 0x2084001f, + 0x3402fffb, + 0xb8e13800, + 0x3484fff0, + 0xa0c23000, + 0x208400ff, + 0x7805ffff, + 0x7801c210, + 0x3c840008, + 0x38a500ff, + 0x38c60002, + 0x38210014, + 0x58260000, + 0xa0e53800, + 0x7802c210, + 0xb8e43800, + 0x38420018, + 0x7801c210, + 0x58470000, + 0x3821001c, + 0x58230000, + 0xfbffff38, + 0xfbffff3e, + 0x2b9d0004, + 0x379c0004, + 0xc3a00000, + 0x7801c210, + 0x38210008, + 0x34020000, + 0x58220000, + 0xc3a00000, + 0x7803c210, + 0x38630008, + 0x28620000, + 0x38420002, + 0x00410007, + 0x58620000, + 0x20210001, + 0x5c200004, + 0x28620000, + 0x00410007, + 0xe3fffffc, + 0xc3a00000, + 0x7803c210, + 0x38630008, + 0x28620000, + 0x3401fffd, + 0xa0411000, + 0x00410007, + 0x58620000, + 0x20210001, + 0x7c210001, + 0x5c200004, + 0x28620000, + 0x00410007, + 0xe3fffffb, + 0xc3a00000, + 0x379cfff0, + 0x3c42000b, + 0x3c210010, + 0x3c630008, + 0xb8220800, + 0x20870004, + 0xb8230800, + 0x34e70008, + 0x208400f8, + 0x7802fe00, + 0x38420002, + 0xb8240800, + 0xbcc73000, + 0xb8220800, + 0x5b810010, + 0x38c600fd, + 0x5b86000c, + 0x5b850008, + 0x2b820010, + 0x7801c210, + 0x38210014, + 0x58220000, + 0x2b82000c, + 0x7801c210, + 0x38210018, + 0x58220000, + 0x2b830008, + 0x7801c210, + 0x3821001c, + 0x7802c210, + 0x58230000, + 0x38420008, + 0x28410000, + 0xb8401800, + 0x5b810004, + 0x43810007, + 0x38210001, + 0x33810007, + 0x2b810004, + 0x58410000, + 0x28610000, + 0x5b810004, + 0x43810007, + 0x00210004, + 0x20210001, + 0x7c210001, + 0x4420fffa, + 0x43810007, + 0x3402fffe, + 0xa0220800, + 0x33810007, + 0x2b810004, + 0x58610000, + 0x379c0010, + 0xc3a00000, + 0x379cfff4, + 0x3c42000b, + 0x3c210010, + 0x3c630008, + 0xb8220800, + 0x20860004, + 0xb8230800, + 0x208400f8, + 0x34c60008, + 0x7802fe00, + 0xb8240800, + 0x38420004, + 0xbca62800, + 0xb8220800, + 0x5b81000c, + 0x38a500fd, + 0x5b850008, + 0x2b82000c, + 0x7801c210, + 0x38210014, + 0x58220000, + 0x2b830008, + 0x7801c210, + 0x38210018, + 0x7802c210, + 0x58230000, + 0x38420008, + 0x28410000, + 0xb8402000, + 0x5b810004, + 0x43810007, + 0x38210001, + 0x33810007, + 0x2b810004, + 0x58410000, + 0x28810000, + 0x5b810004, + 0x43810007, + 0x00210003, + 0x20210001, + 0x4420fffb, + 0x43810007, + 0x3402fffe, + 0x7803c210, + 0xa0220800, + 0x33810007, + 0x2b810004, + 0x3863000c, + 0x58810000, + 0x28610000, + 0x379c000c, + 0xc3a00000, + 0x379cfff0, + 0x5b8b0010, + 0x5b8c000c, + 0x5b8d0008, + 0x5b9d0004, + 0xb8205800, + 0xb8406000, + 0x340d0000, + 0x5c4d000a, + 0x90000800, + 0x34020001, + 0x20210001, + 0xf8000031, + 0xd0010000, + 0x90e00800, + 0x342100a0, + 0xbba0f000, + 0xc0200000, + 0xb96c0800, + 0x7421000f, + 0x5c200010, + 0xb9600800, + 0x34020004, + 0x780b0003, + 0xf8000025, + 0x396b871c, + 0xb42b0800, + 0xb42c0800, + 0x40220000, + 0xb8400800, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0x4d600003, + 0xc80b5800, + 0x340d0001, + 0x4d800003, + 0x65ad0000, + 0xc80c6000, + 0x90c00800, + 0x20230002, + 0x8d6c1000, + 0x4460000b, + 0x65a10000, + 0x5c20ffee, + 0xc8021000, + 0xb8400800, + 0x2b8b0010, + 0x2b8c000c, + 0x2b8d0008, + 0x2b9d0004, + 0x379c0010, + 0xc3a00000, + 0xb9801000, + 0xb9600800, + 0xf800007b, + 0xb8201000, + 0xe3fffff2, + 0x2042001f, + 0x78030003, + 0x3863881c, + 0xb4421000, + 0xb4421000, + 0xb4621800, + 0x28630000, + 0xc0600000, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xb4210800, + 0xc3a00000, + 0x2042001f, + 0x78030003, + 0x3863889c, + 0xb4421000, + 0xb4421000, + 0xb4621800, + 0x28630000, + 0xc0600000, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0x00210001, + 0xc3a00000, + 0x2042001f, + 0x78030003, + 0x3863891c, + 0xb4421000, + 0xb4421000, + 0xb4621800, + 0x28630000, + 0xc0600000, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0x14210001, + 0xc3a00000, + 0x379cffe4, + 0x5b8b001c, + 0x5b8c0018, + 0x5b8d0014, + 0x5b8e0010, + 0x5b8f000c, + 0x5b900008, + 0x5b9d0004, + 0x340f0000, + 0xb8206800, + 0xb8405800, + 0xb8608000, + 0x340c0001, + 0xb9e07000, + 0xe000000a, + 0x49cb001c, + 0xb9600800, + 0x34020001, + 0xfbffff76, + 0xb8205800, + 0xb9800800, + 0x34020001, + 0xfbffff72, + 0xb8206000, + 0xf16d0800, + 0x7d830000, + 0x34020001, + 0xc8410800, + 0xa0230800, + 0x64210000, + 0x4420fff1, + 0x4580000d, + 0xb9800800, + 0x34020001, + 0x556d0003, + 0xc9ab6800, + 0xb9ec7800, + 0xfbffff8b, + 0xb8206000, + 0xb9600800, + 0x34020001, + 0xfbffff87, + 0xb8205800, + 0x5d80fff5, + 0xb9a00800, + 0x5e000002, + 0xb9e00800, + 0x2b8b001c, + 0x2b8c0018, + 0x2b8d0014, + 0x2b8e0010, + 0x2b8f000c, + 0x2b900008, + 0x2b9d0004, + 0x379c001c, + 0xc3a00000, + 0x00040100, + 0x01040100, + 0x02050100, + 0x03040200, + 0x04010100, + 0x05050200, + 0x06060100, + 0x07090200, + 0x00040100, + 0x01040100, + 0x02050100, + 0x03040200, + 0x04010100, + 0x05050200, + 0x06060100, + 0x07090100, + 0x08040100, + 0x09020100, + 0x0a030100, + 0x0b060100, + 0x0c080100, + 0x0d010100, + 0x0e020100, + 0x0f030100, + 0x10010100, + 0x11040100, + 0x12030100, + 0x13010100, + 0x14080100, + 0x15050100, + 0x16010100, + 0x17010100, + 0x18040100, + 0x1b060100, + 0x1c010100, + 0x00040100, + 0x8000001c, + 0x80000024, + 0x8000003c, + 0x80000044, + 0x8000004c, + 0x80000054, + 0x8000005c, + 0x80000064, + 0x80000124, + 0xc2100004, + 0x00029070, + 0x00029070, + 0x000293b8, + 0x000294e0, + 0x00029704, + 0x000298d0, + 0x0002a4e4, + 0x00029a74, + 0x0002a4a4, + 0x0002a1a8, + 0x000282ac, + 0x000282ac, + 0x00029364, + 0x000293c0, + 0x00029544, + 0x00029780, + 0x0002a4e4, + 0x00029908, + 0x0002a35c, + 0x00029b0c, + 0x000282f8, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00028300, + 0x00028308, + 0x00028310, + 0x00028318, + 0x00028320, + 0x00028328, + 0x0002904c, + 0x0002904c, + 0x00028330, + 0x00028338, + 0x00028340, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00028348, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00028350, + 0x00028358, + 0x00028360, + 0x00028398, + 0x000283a0, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x000283a8, + 0x000283b4, + 0x000283c0, + 0x000283e4, + 0x00028408, + 0x00028410, + 0x00028418, + 0x00028420, + 0x00028428, + 0x00028430, + 0x0002904c, + 0x0002904c, + 0x00028444, + 0x0002844c, + 0x0002904c, + 0x00028458, + 0x00028460, + 0x00028548, + 0x00028564, + 0x00028580, + 0x00028588, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00028590, + 0x00028598, + 0x000285a0, + 0x000285a8, + 0x000285b0, + 0x000285b8, + 0x000285c0, + 0x000285c8, + 0x000285d0, + 0x000285d8, + 0x000285e0, + 0x000285e8, + 0x000285f0, + 0x000285f8, + 0x00028600, + 0x00028608, + 0x00028610, + 0x00028618, + 0x00028620, + 0x00028628, + 0x00028630, + 0x00028638, + 0x00028640, + 0x0002864c, + 0x00028668, + 0x00028670, + 0x00028678, + 0x00028680, + 0x00028688, + 0x0002904c, + 0x0002904c, + 0x00028690, + 0x00028698, + 0x000286a0, + 0x000286a8, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x000286b0, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x000286b8, + 0x000286cc, + 0x00028714, + 0x00028dec, + 0x00028df4, + 0x00028e4c, + 0x00028e54, + 0x00028e5c, + 0x00028e64, + 0x0002904c, + 0x0002904c, + 0x00028ea0, + 0x0002904c, + 0x0002904c, + 0x000284a0, + 0x000284a8, + 0x00028ee4, + 0x00028eec, + 0x00028ef4, + 0x00028efc, + 0x00028f04, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00028f0c, + 0x00028f14, + 0x00028f1c, + 0x00028f24, + 0x00028f2c, + 0x00028f34, + 0x00028f3c, + 0x0002904c, + 0x0002904c, + 0x000287a0, + 0x00028e6c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00028a74, + 0x00028cc4, + 0x0002904c, + 0x00028b9c, + 0x00028b10, + 0x00028d60, + 0x0002904c, + 0x00028c38, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002843c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x000284e8, + 0x000284f0, + 0x00028508, + 0x00028510, + 0x0002904c, + 0x00028518, + 0x00028530, + 0x00028f44, + 0x00028f64, + 0x00028f88, + 0x00028fa4, + 0x00028fc0, + 0x00028954, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00029054, + 0x00029054, + 0x00028738, + 0x0002876c, + 0x0002904c, + 0x0002904c, + 0x000287d4, + 0x00028808, + 0x00028aa8, + 0x00028adc, + 0x00028bd0, + 0x00028c04, + 0x0002904c, + 0x0002904c, + 0x00028cf8, + 0x00028d2c, + 0x0002883c, + 0x00028a14, + 0x00028a3c, + 0x0002904c, + 0x0002904c, + 0x000288ec, + 0x000289fc, + 0x00028b70, + 0x00028c98, + 0x0002904c, + 0x00028dc0, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00029010, + 0x0002901c, + 0x00029024, + 0x00029030, + 0x00029000, + 0x00029008, + 0x00028a60, + 0x0002904c, + 0x00028940, + 0x00028b88, + 0x00028cb0, + 0x0002904c, + 0x00028dd8, + 0x0002904c, + 0x000286d8, + 0x000286f8, + 0x00029038, + 0x00028fe0, + 0x00028fe8, + 0x00028ff0, + 0x00028ff8, + 0x0002904c, + 0x0002904c, + 0x0002904c, + 0x00029040, + 0x00800092, + 0x00a300b6, + 0x00c800da, + 0x00ec0100, + 0x00029884, + 0x0002989c, + 0x000297b8, + 0x000298b8, + 0x000297cc, + 0x00029814, + 0x000298b4, + 0x00029b4c, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x00029da4, + 0x0002a184, + 0x0002a184, + 0x00029bd0, + 0x0002a184, + 0x00029cac, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a18c, + 0x0002a184, + 0x0002a184, + 0x00029b54, + 0x00029bb8, + 0x00029b6c, + 0x00029e04, + 0x00029e58, + 0x00029dc4, + 0x00029de4, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a140, + 0x0002a18c, + 0x0002a18c, + 0x0002a18c, + 0x0002a18c, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x00029c54, + 0x00029c74, + 0x00029b84, + 0x00029b9c, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x00029fd8, + 0x0002a018, + 0x00029fa8, + 0x00029f48, + 0x00029f78, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a18c, + 0x0002a05c, + 0x0002a078, + 0x00029bf8, + 0x00029c10, + 0x0002a184, + 0x0002a184, + 0x0002a110, + 0x0002a128, + 0x00029e8c, + 0x0002a184, + 0x0002a184, + 0x0002a184, + 0x0002a0e0, + 0x0002a094, + 0x0002a0b4, + 0x0002a0cc, + 0x0002a0d4, + 0x0002a148, + 0x0002a158, + 0x0002a17c, + 0x00029d04, + 0x00029d90, + 0x00029c28, + 0x0002c058, + 0x0002c148, + 0x0002c084, + 0x0002c148, + 0x0002c0b0, + 0x0002c148, + 0x0002c0dc, + 0x0002c148, + 0x0002c030, + 0x013014ab, + 0x013014b6, + 0x013014ac, + 0x013014be, + 0x010914e2, + 0x010914e1, + 0x01091507, + 0x00e70019, + 0xf6fcfe00, + 0x02040608, + 0x0002f430, + 0x0002f438, + 0x0002f440, + 0x0002f448, + 0x0002f450, + 0x0002f458, + 0x0002f460, + 0x0002f468, + 0x0002f470, + 0x0002f478, + 0x0002f480, + 0x0002f488, + 0x0002f490, + 0xff000100, + 0x02000100, + 0x03000100, + 0x02000100, + 0x00033528, + 0x00033554, + 0x00033568, + 0x00033578, + 0x00033584, + 0x0003433c, + 0x0003433c, + 0x0003433c, + 0x0003433c, + 0x0003433c, + 0x0003433c, + 0x0003433c, + 0x0003433c, + 0x00034360, + 0x00034360, + 0x00034360, + 0x00034360, + 0x00034390, + 0x00034440, + 0x00034464, + 0x000344a0, + 0x000344d0, + 0x000344dc, + 0x000344dc, + 0x000344dc, + 0x000344dc, + 0x00034524, + 0x00034524, + 0x00034524, + 0x00034524, + 0x000346c0, + 0x00034b3c, + 0x00034b5c, + 0x00034ba4, + 0x00034bd8, + 0x00034be4, + 0x00034be4, + 0x00034be4, + 0x00034be4, + 0x00034c20, + 0x00034c20, + 0x00034c20, + 0x00034c20, + 0x00034c94, + 0x00035ac4, + 0x00035ac4, + 0x00035acc, + 0x00035ad4, + 0x00035adc, + 0x00035ae4, + 0x00035aec, + 0x00035ac4, + 0x00035af8, + 0x00035b20, + 0x00035b38, + 0x00035b4c, + 0x00035b78, + 0x00035bc8, + 0x00035be0, + 0x00035bec, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00010000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00020100, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00030101, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00040201, + 0x01000000, + 0x00000000, + 0x00000000, + 0x00050201, + 0x01010000, + 0x00000000, + 0x00000000, + 0x00060302, + 0x01010100, + 0x00000000, + 0x00000000, + 0x00070302, + 0x01010101, + 0x00000000, + 0x00000000, + 0x00080402, + 0x02010101, + 0x01000000, + 0x00000000, + 0x00090403, + 0x02010101, + 0x01010000, + 0x00000000, + 0x000a0503, + 0x02020101, + 0x01010100, + 0x00000000, + 0x000b0503, + 0x02020101, + 0x01010101, + 0x00000000, + 0x000c0604, + 0x03020201, + 0x01010101, + 0x01000000, + 0x000d0604, + 0x03020201, + 0x01010101, + 0x01010000, + 0x000e0704, + 0x03020202, + 0x01010101, + 0x01010100, + 0x000f0705, + 0x03030202, + 0x01010101, + 0x01010101, + 0x00037ac8, + 0x00037ac4, + 0x00037ac0, + 0x00037abc, + 0x00037ab8, + 0x00037ab4, + 0x00037ab0, + 0x00037aac, + 0x00037aa8, + 0x00037aa4, + 0x00037aa0, + 0x00037a9c, + 0x00037a98, + 0x00037a94, + 0x00037a90, + 0x00037a8c, + 0x00037a88, + 0x00037a84, + 0x00037a80, + 0x00037a7c, + 0x00037a78, + 0x00037a74, + 0x00037a70, + 0x00037a6c, + 0x00037a68, + 0x00037a64, + 0x00037a60, + 0x00037a5c, + 0x00037a58, + 0x00037a54, + 0x00037a50, + 0x00037a4c, + 0x00037b68, + 0x00037b64, + 0x00037b60, + 0x00037b5c, + 0x00037b58, + 0x00037b54, + 0x00037b50, + 0x00037b4c, + 0x00037b48, + 0x00037b44, + 0x00037b40, + 0x00037b3c, + 0x00037b38, + 0x00037b34, + 0x00037b30, + 0x00037b2c, + 0x00037b28, + 0x00037b24, + 0x00037b20, + 0x00037b1c, + 0x00037b18, + 0x00037b14, + 0x00037b10, + 0x00037b0c, + 0x00037b08, + 0x00037b04, + 0x00037b00, + 0x00037afc, + 0x00037af8, + 0x00037af4, + 0x00037af0, + 0x00037aec, + 0x00037c08, + 0x00037c04, + 0x00037c00, + 0x00037bfc, + 0x00037bf8, + 0x00037bf4, + 0x00037bf0, + 0x00037bec, + 0x00037be8, + 0x00037be4, + 0x00037be0, + 0x00037bdc, + 0x00037bd8, + 0x00037bd4, + 0x00037bd0, + 0x00037bcc, + 0x00037bc8, + 0x00037bc4, + 0x00037bc0, + 0x00037bbc, + 0x00037bb8, + 0x00037bb4, + 0x00037bb0, + 0x00037bac, + 0x00037ba8, + 0x00037ba4, + 0x00037ba0, + 0x00037b9c, + 0x00037b98, + 0x00037b94, + 0x00037b90, + 0x00037b8c, + 0x24002800, + 0x3c002001, + 0x12010e01, + 0x13011101, + 0x0c010b01, + 0x17010601, + 0x07012201, + 0x23012601, + 0x27012a01, + 0x2b010800, + 0x2e010a01, + 0xff000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00021e74, + 0x00021ec4, + 0x00031e20, + 0x00000000, + 0x00021a70, + 0x0002daf0, + 0x0002cd24, + 0x00000000, + 0x0002c47c, + 0x00000000, + 0x00000000, + 0x0002cca4, + 0x0002bfc0, + 0x0002d9ec, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0002d814, + 0x00000000, + 0x00021cac, + 0x00021b1c, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00021a4c, + 0x00000000, + 0x00021f14, + 0x00021f64, + 0x00021adc, + 0x00000000, + 0x00021fb4, + 0x00022004, + 0x00021afc, + 0x00000000, + 0x00022054, + 0x000220a4, + 0x00000000, + 0x00000000, + 0x000220f4, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00021e2c, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0003f9e8, + 0x0003fd00, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00024a68, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x80402010, + 0x08040200, + 0x58606870, + 0x78808890, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000bb8, + 0x0bb8cccc, + 0x80000001, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000003ff, + 0x322d2823, + 0x1e19140f, + 0x342f2a25, + 0x201b1611, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x322d2823, + 0x1e19140f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000100, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xffffffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xffffffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xffffffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xffffffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x26000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000064, + 0x028e0000, + 0x01000005, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x04000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000050, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xe6000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00022fdc, + 0x00022fdc, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00010101, + 0x00000101, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000050, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00025000, + 0x00025000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000101, + 0x01010100, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x01000100, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000003ff, + 0xfffffc00, + 0x00000003, + 0x0000000a, + 0x00000400, + 0x00000007, + 0x000000ff, + 0x00000008, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08000000, + 0x00080000, + 0x00000190, + 0x00002710, + 0x00000050, + 0x0001011f, + 0x00010100, + 0x00000300, + 0x00000000, + 0x00000320, + 0x00004e20, + 0x00000050, + 0x0001001e, + 0x00010100, + 0x00000400, + 0x00000000, + 0x000004b0, + 0x00007530, + 0x00000050, + 0x0001001d, + 0x00010100, + 0x00000500, + 0x00000000, + 0x00000640, + 0x00009c40, + 0x00000050, + 0x0000001c, + 0x00010100, + 0x00000500, + 0x00000000, + 0x000007d0, + 0x0000c350, + 0x00000050, + 0x0000001b, + 0x01010100, + 0x00000500, + 0x00000000, + 0x00000960, + 0x0000ea60, + 0x00000050, + 0x0000001a, + 0x01010100, + 0x00000500, + 0x00000000, + 0x00000af0, + 0x00011170, + 0x00000050, + 0x00000019, + 0x01010100, + 0x00000500, + 0x00000000, + 0x00000c80, + 0x00013880, + 0x00000050, + 0x00000018, + 0x01010100, + 0x00000500, + 0x00000000, + 0x00000000, + 0x00000140, + 0x00000064, + 0x40010000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00002710, + 0x0e103000, + 0x00000000, + 0x00004e20, + 0x0e742d00, + 0x00000000, + 0x00007530, + 0x0ed82a00, + 0x00000000, + 0x00009c40, + 0x0f3c2700, + 0x00000000, + 0x0000c350, + 0x0fa02400, + 0x00000000, + 0x0000ea60, + 0x10042100, + 0x00000000, + 0x00011170, + 0x10681e00, + 0x00000000, + 0x00013880, + 0x10cc1b00, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000000, + 0x00600000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00002710, + 0x000003e8, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + SMU_FIRMWARE_PADS_1K + SMU_FIRMWARE_PADS_1K + SMU_FIRMWARE_PADS_1K + SMU_FIRMWARE_PADS_1K + SMU_FIRMWARE_PADS_1K + SMU_FIRMWARE_PADS_1K + SMU_FIRMWARE_PADS_1K + SMU_FIRMWARE_PADS_1K +}; +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbTablesKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbTablesKB.c new file mode 100644 index 0000000000..5c1fef2c20 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbTablesKB.c @@ -0,0 +1,499 @@ +/** + * @file + * + * GNB init tables + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86714 $ @e \$Date: 2013-01-24 17:51:46 -0600 (Thu, 24 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbTable.h" +#include "GnbRegistersKB.h" +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T A B L E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +GNB_TABLE ROMDATA GnbEarlierInitTableBeforeSmuKB [] = { + GNB_ENTRY_RMW ( + D0F0x98_x07_TYPE, + D0F0x98_x07_ADDRESS, + D0F0x98_x07_SMUCsrIsocEn_MASK, + (1 << D0F0x98_x07_SMUCsrIsocEn_OFFSET) + ), + GNB_ENTRY_RMW ( + D0F0x98_x1E_TYPE, + D0F0x98_x1E_ADDRESS, + D0F0x98_x1E_HiPriEn_MASK, + (1 << D0F0x98_x1E_HiPriEn_OFFSET) + ), + GNB_ENTRY_TERMINATE +}; + +GNB_TABLE ROMDATA GnbEarlyInitTableKB [] = { + // Set SVI2 + GNB_ENTRY_PROPERTY_RMW ( + TABLE_PROPERTY_SVI2, + 0x4, + 0x3F9D8, + 0x20000000, + (1 << 29) + ), + GNB_ENTRY_WR ( + D0F0x04_TYPE, + D0F0x04_ADDRESS, + (0x1 << D0F0x04_MemAccessEn_WIDTH) + ), + GNB_ENTRY_RMW ( + D0F0x64_x16_TYPE, + D0F0x64_x16_ADDRESS, + D0F0x64_x16_AerUrMsgEn_MASK, + 0x0 << D0F0x64_x16_AerUrMsgEn_OFFSET + ), + GNB_ENTRY_RMW ( + D0F0x98_x07_TYPE, + D0F0x98_x07_ADDRESS, + D0F0x98_x07_IocBwOptEn_MASK | D0F0x98_x07_DropZeroMaskWrEn_MASK, + (1 << D0F0x98_x07_IocBwOptEn_OFFSET) | (1 << D0F0x98_x07_DropZeroMaskWrEn_OFFSET) + ), + + GNB_ENTRY_RMW ( + D0F0x98_x0C_TYPE, + D0F0x98_x0C_ADDRESS, + D0F0x98_x0C_GcmWrrLenA_MASK | D0F0x98_x0C_GcmWrrLenB_MASK, + (0x8 << D0F0x98_x0C_GcmWrrLenA_OFFSET) | (0x8 << D0F0x98_x0C_GcmWrrLenB_OFFSET) + ), + + // Enable voltage controller + GNB_ENTRY_WR ( + SMU_MSG_TYPE, + SMC_MSG_VOLTAGE_CNTL_ENABLE, + 0 + ), +//--------------------------------------------------------------------------- + GNB_ENTRY_COPY ( + 0x9, + 0x49, + 0, + 32, + D0F0x64_x1F_TYPE, + D0F0x64_x1F_ADDRESS, + 0, + 32 + ), + // Enable VPC + // CSR_GNB_1.SviTrimValueVdd = Vdd Trim + GNB_ENTRY_COPY ( + 0x4, + 0x3F9F4, + 16, 8, + D18F5x12C_TYPE, + D18F5x12C_ADDRESS, + D18F5x12C_CoreLoadLineTrim_OFFSET, D18F5x12C_CoreLoadLineTrim_WIDTH + ), + // CSR_GNB_1.SviTrimValueVddNB = VddNB Trim + GNB_ENTRY_COPY ( + 0x4, + 0x3F9F4, + 24, 8, + D18F5x188_TYPE, + D18F5x188_ADDRESS, + D18F5x188_NbLoadLineTrim_OFFSET, D18F5x188_NbLoadLineTrim_WIDTH + ), + // CSR_GNB_3.SviLoadLineOffsetVdd = Vdd Offset + + GNB_ENTRY_COPY ( + 0x4, + 0x3F9F8, + 0, 8, + D18F5x12C_TYPE, + D18F5x12C_ADDRESS, + D18F5x12C_CoreOffsetTrim_OFFSET, D18F5x12C_CoreOffsetTrim_WIDTH + ), + // CSR_GNB_3.SviLoadLineOffsetVddNB = VddNB Offset + GNB_ENTRY_COPY ( + 0x4, + 0x3F9F8, + 8, 8, + D18F5x188_TYPE, + D18F5x188_ADDRESS, + D18F5x188_NbOffsetTrim_OFFSET, D18F5x188_NbOffsetTrim_WIDTH + ), + + // Set SRBM time out + GNB_ENTRY_RMW ( + 0x12, + 0xE40, + 0x1FFF, + (0x1FFF << 0) + ), + GNB_ENTRY_TERMINATE +}; + +GNB_TABLE ROMDATA GnbEnvInitTableKB [] = { + //--------------------------------------------------------------------------- + + // SMU Enable Thermal Controller + GNB_ENTRY_WR ( + SMU_MSG_TYPE, + 56, + 0 + ), + // Enable VPC + GNB_ENTRY_PROPERTY_RMW ( + 0x00040000ul, + 0x4, + 0x3F9D8, + 0x1, + (1 << 0) + ), + // Enable LHTC + GNB_ENTRY_PROPERTY_WR ( + TABLE_PROPERTY_LHTC, + SMU_MSG_TYPE, + 70, + 0 + ), + GNB_ENTRY_PROPERTY_WR ( + 0x00040000ul, + SMU_MSG_TYPE, + SMC_MSG_CONFIG_VPC_ACCUMULATOR, + 0 + ), + + // PM_CONFIG.f.enable_tdc_limit = 1; + GNB_ENTRY_PROPERTY_RMW ( + 0x00040000ul, + 0x4, + 0x3F9D8, + 0x4, + (1 << 2) + ), + GNB_ENTRY_PROPERTY_WR ( + 0x00040000ul, + SMU_MSG_TYPE, + 46, + 0 + ), + + // Enable Package Power Limit + GNB_ENTRY_PROPERTY_WR ( + 0x00080000ul, + SMU_MSG_TYPE, + SMC_MSG_ENABLE_PKGPWRLIMIT, + 0 + ), + + // Enable BAPM + // PM_CONFIG.f.enable_bapm = 1; + GNB_ENTRY_PROPERTY_RMW ( + TABLE_PROPERTY_BAPM, + 0x4, + 0x3F9D8, + 0x2, + (1 << 1) + ), + GNB_ENTRY_PROPERTY_WR ( + TABLE_PROPERTY_BAPM, + SMU_MSG_TYPE, + 48, + 0 + ), +//--------------------------------------------------------------------------- +// ORB Init + GNB_ENTRY_RMW ( + D0F0x98_x07_TYPE, + D0F0x98_x07_ADDRESS, + D0F0x98_x07_IocBwOptEn_MASK | D0F0x98_x07_DropZeroMaskWrEn_MASK, + (0x1 << D0F0x98_x07_IocBwOptEn_OFFSET) | (0x1 << D0F0x98_x07_DropZeroMaskWrEn_OFFSET) + ), + GNB_ENTRY_RMW ( + D0F0x98_x07_TYPE, + D0F0x98_x07_ADDRESS, + D0F0x98_x07_IommuBwOptEn_MASK | D0F0x98_x07_IommuIsocPassPWMode_MASK | D0F0x98_x07_DmaReqRespPassPWMode_MASK, + (0x1 << D0F0x98_x07_IommuBwOptEn_OFFSET) | (0x1 << D0F0x98_x07_IommuIsocPassPWMode_OFFSET) | (0 << D0F0x98_x07_DmaReqRespPassPWMode_OFFSET) + ), + GNB_ENTRY_RMW ( + D0F0x98_x08_TYPE, + D0F0x98_x08_ADDRESS, + D0F0x98_x08_NpWrrLenC_MASK, + 0x1 << D0F0x98_x08_NpWrrLenC_OFFSET + ), + GNB_ENTRY_RMW ( + D0F0x98_x28_TYPE, + D0F0x98_x28_ADDRESS, + D0F0x98_x28_ForceCoherentIntr_MASK, + 0x1 << D0F0x98_x28_ForceCoherentIntr_OFFSET + ), + GNB_ENTRY_RMW ( + D0F0x98_x2C_TYPE, + D0F0x98_x2C_ADDRESS, + D0F0x98_x2C_SBDmaActiveMask_MASK | D0F0x98_x2C_CgttLclkOverride_MASK, + (1 << D0F0x98_x2C_SBDmaActiveMask_OFFSET) | (1 << D0F0x98_x2C_CgttLclkOverride_OFFSET) + ), + // Enable gBIF UID Clumping [BIT 23:21 = 011b] + GNB_ENTRY_RMW ( + D0F0x98_x3A_TYPE, + D0F0x98_x3A_ADDRESS, + 0x00E00000, + 0x00600000 + ), + GNB_ENTRY_RMW ( + D18F0x110_TYPE, + D18F0x110_ADDRESS, + 0x00E00000, + 0x00600000 + ), + //NB P-state Configuration for Runtime + GNB_ENTRY_RMW ( + 0x4, + 0x3F9E8, + 0xFF | 0xFF00 | + 0xFF0000 | 0xFF000000, + (3 << 0) | (0 << 8) | + (2 << 16) | (1 << 24) + ), + // Programming a conservative watermark for NBP states + GNB_ENTRY_RMW ( + 0x12, + 0x6cd8, + 0x10 | + 0x100 | + 0xffff0000, + (1 << 4) | + (1 << 8) | + (0x7FFF << 16) + ), + + GNB_ENTRY_RMW ( + 0x12, + 0x6cc8, + 0x3 | + 0x30000, + (0x3 << 0) | + (0x3 << 16) + ), + + GNB_ENTRY_RMW ( + 0x12, + 0x6cd4, + 0xffff0000, + (0x7FFF << 16) + ), + + GNB_ENTRY_RMW ( + 0x12, + 0x6cd4, + 0x1, + (1 << 0) + ), + + GNB_ENTRY_RMW ( + 0x12, + 0x6cd8, + 0x1, + (1 << 0) + ), + + GNB_ENTRY_TERMINATE +}; + +GNB_TABLE ROMDATA GnbMidInitTableKB [] = { +//--------------------------------------------------------------------------- +// ORB clock gating + GNB_ENTRY_PROPERTY_RMW ( + 0x00000008ul, + D0F0x98_x49_TYPE, + D0F0x98_x49_ADDRESS, + D0F0x98_x49_SoftOverrideClk6_MASK | D0F0x98_x49_SoftOverrideClk5_MASK | D0F0x98_x49_SoftOverrideClk4_MASK | D0F0x98_x49_SoftOverrideClk3_MASK | D0F0x98_x49_SoftOverrideClk2_MASK | D0F0x98_x49_SoftOverrideClk1_MASK | D0F0x98_x49_SoftOverrideClk0_MASK, + 0x0 + ), + GNB_ENTRY_PROPERTY_RMW ( + 0x00000008ul, + D0F0x98_x4A_TYPE, + D0F0x98_x4A_ADDRESS, + D0F0x98_x4A_SoftOverrideClk6_MASK | D0F0x98_x4A_SoftOverrideClk5_MASK | D0F0x98_x4A_SoftOverrideClk4_MASK | D0F0x98_x4A_SoftOverrideClk3_MASK | D0F0x98_x4A_SoftOverrideClk2_MASK | D0F0x98_x4A_SoftOverrideClk1_MASK | D0F0x98_x4A_SoftOverrideClk0_MASK, + 0x0 + ), + GNB_ENTRY_PROPERTY_RMW ( + 0x00000008ul, + D0F0x98_x2C_TYPE, + D0F0x98_x2C_ADDRESS, + D0F0x98_x2C_CgttLclkOverride_MASK, + 0x0 + ), +//--------------------------------------------------------------------------- +// IOC clock gating + GNB_ENTRY_PROPERTY_RMW ( + 0x00000010ul, + D0F0x64_x22_TYPE, + D0F0x64_x22_ADDRESS, + 0x4000000 | 0x8000000 | 0x10000000 | 0x20000000 | 0x40000000, + 0x0 + ), + GNB_ENTRY_PROPERTY_RMW ( + 0x00000010ul, + D0F0x64_x23_TYPE, + D0F0x64_x23_ADDRESS, + 0x4000000 | 0x8000000 | 0x10000000 | 0x20000000 | 0x40000000, + 0x0 + ), + GNB_ENTRY_PROPERTY_RMW ( + 0x00000010ul, + D0F0x64_x46_TYPE, + D0F0x64_x46_ADDRESS, + 0x10000, + 0x0 + ), + //--------------------------------------------------------------------------- + GNB_ENTRY_RMW ( + 0x4, + 0xc0200110, + 0x18 | 0x1 | + 0x2 | 0x200 | + 0x400, + (0x3 << 3) | + (0 << 0) | + (0x0 << 1) | + (0x1 << 9) | + (0x1 << 10) + ), +//--------------------------------------------------------------------------- + GNB_ENTRY_PROPERTY_RMW ( + TABLE_PROPERTY_LCLK_DEEP_SLEEP, + 0x4, + 0xc0200310, + 0x20 | + 0x40 | + 0x80 | + 0x100 | + 0x200 | + 0x400 | + 0x800 | + 0x1000 | + 0x2000 | + 0x4000 | + 0x8000 | + 0x10000 | + 0x20000 | + 0x40000 | + 0x80000 | + 0x100000 | + 0x1 | + 0x2 | + 0x4, + ( 1 << 5) | + ( 0 << 6) | + ( 0 << 7) | + ( 0 << 8) | + ( 0 << 9) | + ( 1 << 10) | + ( 1 << 11) | + ( 1 << 12) | + ( 1 << 13) | + ( 1 << 14) | + ( 1 << 15) | + ( 1 << 16) | + ( 1 << 17) | + ( 1 << 18) | + ( 1 << 19) | + ( 1 << 20) | + ( 1 << 0) | + ( 1 << 1) | + ( 1 << 2) + ), + GNB_ENTRY_PROPERTY_RMW ( + TABLE_PROPERTY_LCLK_DEEP_SLEEP, + 0x4, + 0xc020008c, + 0x7 | + 0x8 | + 0xfff0, + ( 5 << 0) | + ( 0 << 3) | + ( 0xF << 4) + ), + GNB_ENTRY_PROPERTY_RMW ( + TABLE_PROPERTY_IGFX_DISABLED, + 0x4, + 0xc0200310, + 0x200000, + 0x0 + ), +// Reset : 0, Enable : 1 + GNB_ENTRY_PROPERTY_RMW ( + TABLE_PROPERTY_LCLK_DEEP_SLEEP, + 0x4, + 0xc020008c, + 0x80000000, + (0x1 << 31) + ), +//--------------------------------------------------------------------------- + GNB_ENTRY_TERMINATE +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraKB.c new file mode 100644 index 0000000000..c5eb8a1dc0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraKB.c @@ -0,0 +1,260 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Initialize PP/DPM fuse table. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbUra.h" +#include "GnbUraToken.h" +#include "GnbRegisterAccKB.h" +#include "GnbRegistersKB.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GNBURAKB_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GnbUraGetKB ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT VOID *Value + ); + +VOID +GnbUraSetKB ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT VOID *Value + ); + +VOID +GnbUraStreamSetKB ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT URA_TUPLE *UraTuple, + IN UINT32 CombinedCount + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb Unified Register Access method + * + * + * @param[in] Device Pointer to Device object + * @param[in] UraTokenInfo Pointer to URA_TOKEN_INFO structure + * @param[in, out] Value Pointer to Context + */ +VOID +GnbUraGetKB ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT VOID *Value + ) +{ + ACCESS_WIDTH Width; + UINT32 RegValue; + UINT32 FieldMask; + UINT32 TargetAddress; + + RegValue = 0; + Width = (UraTokenInfo->Flags == GNB_URA_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; + switch (UraTokenInfo->MethodType) { + case TYPE_GNB_INDIRECT_ACCESS: + TargetAddress = Device->DevPciAddress.AddressValue | UraTokenInfo->RegDomainType; + GnbLibPciIndirectRead ( TargetAddress, UraTokenInfo->RegAddress, Width, &RegValue, Device->StdHeader); + IDS_HDT_CONSOLE (NB_MISC, " Ura GET: RegDomainType = 0x%x IndirectAddress = 0x%08x, Value = 0x%08x\n", UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, RegValue); + break; + + case TYPE_GNB_PROTOCOL_ACCESS: + TargetAddress = UraTokenInfo->RegDomainType; + GnbRegisterReadKB (Device->GnbHandle, (UINT8)TargetAddress, UraTokenInfo->RegAddress, &RegValue, UraTokenInfo->Flags, Device->StdHeader); + IDS_HDT_CONSOLE (NB_MISC, " Ura GET: RegDomainType = %d, Address = 0x%08x, Value = 0x%08x\n", TargetAddress, UraTokenInfo->RegAddress, RegValue); + break; + + default: + ASSERT (FALSE); + return; + } + + if (UraTokenInfo->WholeRegAccess == TRUE) { + *(UINT32 *)Value = RegValue; + } else { + RegValue = RegValue >> UraTokenInfo->BfOffset; + FieldMask = (((UINT32)1 << UraTokenInfo->BfWidth) - 1); + *(UINT32 *)Value = RegValue & FieldMask; + } + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb Unified Register Access method + * + * + * @param[in] Device Pointer to Device object + * @param[in] UraTokenInfo Pointer to URA_TOKEN_INFO structure + * @param[in, out] Value Pointer to Context + */ +VOID +GnbUraSetKB ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT VOID *Value + ) +{ + ACCESS_WIDTH Width; + UINT32 RegValue; + UINT32 TargetValue; + UINT32 FieldMask; + UINT32 TempValue; + + Width = (UraTokenInfo->Flags == GNB_URA_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; + FieldMask = 0; + TempValue = *(UINT32 *)Value; + + switch (UraTokenInfo->MethodType) { + case TYPE_GNB_INDIRECT_ACCESS: + if (UraTokenInfo->WholeRegAccess == TRUE) { + TargetValue = TempValue; + } else { + GnbLibPciIndirectRead ( Device->DevPciAddress.AddressValue | UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, Width, &RegValue, Device->StdHeader); + FieldMask = (((UINT32)1 << UraTokenInfo->BfWidth) - 1); + TargetValue = RegValue & (~(FieldMask << UraTokenInfo->BfOffset)); + TargetValue |= (TempValue & FieldMask) << UraTokenInfo->BfOffset; + } + GnbLibPciIndirectWrite ( Device->DevPciAddress.AddressValue | UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, Width, &TargetValue, Device->StdHeader); + IDS_HDT_CONSOLE (NB_MISC, " Ura SET: RegDomainType = 0x%x IndirectAddress = 0x%08x, Value = 0x%08x\n", UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, TargetValue); + break; + + case TYPE_GNB_PROTOCOL_ACCESS: + if (UraTokenInfo->WholeRegAccess == TRUE) { + TargetValue = TempValue; + } else { + GnbRegisterReadKB (Device->GnbHandle, UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, &RegValue, UraTokenInfo->Flags, Device->StdHeader); + FieldMask = (((UINT32)1 << UraTokenInfo->BfWidth) - 1); + TargetValue = RegValue & (~(FieldMask << UraTokenInfo->BfOffset)); + TargetValue |= (TempValue & FieldMask) << UraTokenInfo->BfOffset; + } + GnbRegisterWriteKB (Device->GnbHandle, UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, &TargetValue, UraTokenInfo->Flags, Device->StdHeader); + IDS_HDT_CONSOLE (NB_MISC, " Ura SET: RegDomainType = %d, Address = 0x%08x, Value = 0x%08x\n", UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, TargetValue); + break; + + default: + ASSERT (FALSE); + break; + } + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb Unified Register Access method + * + * + * @param[in] Device Pointer to device object + * @param[in] UraTokenInfo Pointer to URA_TOKEN_INFO structure + * @param[in, out] UraTuple Pointer to structure URA_TUPLE + * @param[in] CombinedCount Token count + */ +VOID +GnbUraStreamSetKB ( + IN DEV_OBJECT *Device, + IN URA_TOKEN_INFO *UraTokenInfo, + IN OUT URA_TUPLE *UraTuple, + IN UINT32 CombinedCount + ) +{ + ACCESS_WIDTH Width; + UINT32 RegValue; + UINT32 Index; + UINT32 StreamSetAddress; + UINT32 StepLength; + UINT32 TargetAddress; + + Width = (UraTokenInfo->Flags == GNB_URA_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; + StreamSetAddress = UraTokenInfo->RegAddress; + StepLength = UraTuple->StepLength; + for (Index = 0; Index < CombinedCount; Index++) { + RegValue = *(((UINT32 *) ((UINTN)UraTuple->Value)) + Index); + switch (UraTokenInfo->MethodType) { + case TYPE_GNB_INDIRECT_ACCESS: + TargetAddress = Device->DevPciAddress.AddressValue | UraTokenInfo->RegDomainType; + //IDS_HDT_CONSOLE (NB_MISC, "0x%08x:0x%08x, \n", StreamSetAddress, RegValue); + GnbLibPciIndirectWrite (TargetAddress, StreamSetAddress, Width, &RegValue, Device->StdHeader); + break; + + case TYPE_GNB_PROTOCOL_ACCESS: + TargetAddress = UraTokenInfo->RegDomainType; + GnbRegisterWriteKB (Device->GnbHandle, (UINT8)TargetAddress, StreamSetAddress, &RegValue, UraTokenInfo->Flags, Device->StdHeader); + break; + + default: + ASSERT (FALSE); + return; + } + StreamSetAddress += StepLength; + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraTokenMapKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraTokenMapKB.c new file mode 100644 index 0000000000..2d75fcee51 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbUraTokenMapKB.c @@ -0,0 +1,122 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AGESA gnb file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ****************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbUra.h" +#include "GnbUraToken.h" +#include "GnbRegistersKB.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_GNBURATOKENMAPKB_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +VOID +GnbUraLocateRegTblKB ( + IN DEV_OBJECT *Device, + IN OUT UINT32 *UraTableAddress + ); +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +REG_FIELD_TABLE_STRUCT UraTableKB = { + {0xC2100000, 0x4, 0}, + {0, 1, FIELD_OFFSET(RxSmuIntReq ,BfxSmuIntToggle)}, + {1, 16, FIELD_OFFSET(RxSmuIntReq ,BfxSmuServiceIndex)}, + {0xC2100004, 0x4, 0}, + {0, 1, FIELD_OFFSET(RxSmuIntSts ,BfxSmuIntAck)}, + {1, 1, FIELD_OFFSET(RxSmuIntSts ,BfxSmuIntDone)}, + {0xE0003088, 0x4, 0}, + {0, 1, FIELD_OFFSET(RxSmuAuthSts ,BfxSmuAuthDone)}, + {1, 1, FIELD_OFFSET(RxSmuAuthSts ,BfxSmuAuthPass)}, + {0xE00030A4, 0x4, 0}, + {16, 1, FIELD_OFFSET(RxSmuFwAuth ,BfxSmuProtectedMode)}, + {0xC0000004, 0x4, 0}, + {7, 1, FIELD_OFFSET(REG_FIELD_TABLE_STRUCT_fld11 ,BfxSmuBootSeqDone)}, + {0x3F800, 0x4, 0}, + {0, 1, FIELD_OFFSET(RxSmuFwFlags ,BfxSmuInterruptsEnabled)}, + {0x80000000, 0x4, 0}, + {0, 1, FIELD_OFFSET(RxSmuResetCntl ,BfxSmuRstReg)}, + {0x80000004, 0x4, 0}, + {0, 1, FIELD_OFFSET(RxSmuClkCntl ,BfxSmuCkDisable)}, + {0x80008000, 0x4, 0}, + {D0F0xBC_x20000_ADDRESS, D0F0xBC_x20000_TYPE, 0}, + {D0F0xBC_x0_ADDRESS, D0F0xBC_x0_TYPE, 0}, + {D0F0xBC_xC210003C_ADDRESS, D0F0xBC_xC210003C_TYPE, 0}, + +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb Unified Register Access method to locate register table. + * + * + * @param[in] Device Standard configuration header + * @param[in, out] UraTableAddress Ura register table address + */ +VOID +GnbUraLocateRegTblKB ( + IN DEV_OBJECT *Device, + IN OUT UINT32 *UraTableAddress + ) +{ + *UraTableAddress = (UINT32)((UINTN)(&UraTableKB)); + return; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.c new file mode 100644 index 0000000000..5fd3cca0eb --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.c @@ -0,0 +1,447 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific PCIe configuration data + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "PcieComplexDataKB.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIECOMPLEXDATAKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PcieGetComplexDataLengthKB ( + IN UINT8 SocketId, + OUT UINTN *Length, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieBuildComplexConfigurationKB ( + IN UINT8 SocketId, + OUT VOID *Buffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +PcieGetNativePhyLaneBitmapKB ( + IN UINT32 PhyLaneBitmap, + IN PCIe_ENGINE_CONFIG *Engine + ); +// +// Complex configuration +// + +KB_COMPLEX_CONFIG ComplexDataKB = { + //Silicon + { + { + DESCRIPTOR_SILICON | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_GNB | DESCRIPTOR_TERMINATE_TOPOLOGY, + 0, + 0, + offsetof (KB_COMPLEX_CONFIG, GppWrapper) - offsetof (KB_COMPLEX_CONFIG, Silicon) + }, + 0, + 0xFF, + 0xFF + }, + //Gpp Wrapper + { + { + DESCRIPTOR_PCIE_WRAPPER, + offsetof (KB_COMPLEX_CONFIG, GppWrapper) - offsetof (KB_COMPLEX_CONFIG, Silicon), + offsetof (KB_COMPLEX_CONFIG, DdiWrapper) - offsetof (KB_COMPLEX_CONFIG, GppWrapper), + offsetof (KB_COMPLEX_CONFIG, PortPBR4) - offsetof (KB_COMPLEX_CONFIG, GppWrapper) + }, + GPP_WRAP_ID, + GPP_NUMBER_OF_PIFs, + GPP_START_PHY_LANE, + GPP_END_PHY_LANE, + GPP_CORE_ID, + GPP_CORE_ID, + GPP_END_PHY_LANE - GPP_START_PHY_LANE + 1, + { + 1, + 1, + 1, + 1, + 1, + 1, + 1 + }, + }, + //Virtual DDI Wrapper + { + { + DESCRIPTOR_DDI_WRAPPER | DESCRIPTOR_VIRTUAL | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_GNB | DESCRIPTOR_TERMINATE_TOPOLOGY, + offsetof (KB_COMPLEX_CONFIG, DdiWrapper) - offsetof (KB_COMPLEX_CONFIG, Silicon), + 0, + offsetof (KB_COMPLEX_CONFIG, Ddi1) - offsetof (KB_COMPLEX_CONFIG, DdiWrapper) + }, + DDI_WRAP_ID, + 0, + DDI_START_PHY_LANE, + DDI_END_PHY_LANE, + -1, + 0, + 0, + { + 1, + 1, + 1, + 1, + 1, + 0, + 1 + }, + }, +//------------------------------ GPP WRAPPER START------------------------------------- + //Port PBR4 + { + { + DESCRIPTOR_PCIE_ENGINE, + offsetof (KB_COMPLEX_CONFIG, PortPBR4) - offsetof (KB_COMPLEX_CONFIG, GppWrapper), + offsetof (KB_COMPLEX_CONFIG, PortPBR3) - offsetof (KB_COMPLEX_CONFIG, PortPBR4), + 0 + }, + { PciePortEngine, GPP_START_PHY_LANE, GPP_END_PHY_LANE }, + 0, //Initialization Status + 0xFF, //Scratch + { + { + {0}, + 7, + 7, + PBR4_NATIVE_PCI_DEV, + PBR4_NATIVE_PCI_FUN, + PBR4_CORE_ID, + PBR4_PORT_ID, + {(UINT32)PBR4_PCI_ADDRESS}, + LinkStateResetExit, + PBR4, + PBR4_UNIT_ID, + PBR4_NUM_UNIT_IDs + }, + }, + }, + //Port PBR3 + { + { + DESCRIPTOR_PCIE_ENGINE, + offsetof (KB_COMPLEX_CONFIG, PortPBR3) - offsetof (KB_COMPLEX_CONFIG, GppWrapper), + offsetof (KB_COMPLEX_CONFIG, PortPBR2) - offsetof (KB_COMPLEX_CONFIG, PortPBR3), + 0 + }, + { PciePortEngine, GPP_START_PHY_LANE, GPP_END_PHY_LANE }, + 0, //Initialization Status + 0xFF, //Scratch + { + { + {0}, + 6, + 6, + PBR3_NATIVE_PCI_DEV, + PBR3_NATIVE_PCI_FUN, + PBR3_CORE_ID, + PBR3_PORT_ID, + {(UINT32)PBR3_PCI_ADDRESS}, + LinkStateResetExit, + PBR3, + PBR3_UNIT_ID, + PBR3_NUM_UNIT_IDs + }, + }, + }, + //Port PBR2 + { + { + DESCRIPTOR_PCIE_ENGINE, + offsetof (KB_COMPLEX_CONFIG, PortPBR2) - offsetof (KB_COMPLEX_CONFIG, GppWrapper), + offsetof (KB_COMPLEX_CONFIG, PortPBR1) - offsetof (KB_COMPLEX_CONFIG, PortPBR2), + 0 + }, + { PciePortEngine, GPP_START_PHY_LANE, GPP_END_PHY_LANE}, + 0, //Initialization Status + 0xFF, //Scratch + { + { + {0}, + 5, + 5, + PBR2_NATIVE_PCI_DEV, + PBR2_NATIVE_PCI_FUN, + PBR2_CORE_ID, + PBR2_PORT_ID, + {(UINT32)PBR2_PCI_ADDRESS}, + LinkStateResetExit, + PBR2, + PBR2_UNIT_ID, + PBR2_NUM_UNIT_IDs + }, + }, + }, + //Port PBR1 + { + { + DESCRIPTOR_PCIE_ENGINE, + offsetof (KB_COMPLEX_CONFIG, PortPBR1) - offsetof (KB_COMPLEX_CONFIG, GppWrapper), + offsetof (KB_COMPLEX_CONFIG, PortPBR0) - offsetof (KB_COMPLEX_CONFIG, PortPBR1), + 0 + }, + { PciePortEngine, GPP_START_PHY_LANE, GPP_END_PHY_LANE }, + 0, //Initialization Status + 0xFF, //Scratch + { + { + {0}, + 4, + 4, + PBR1_NATIVE_PCI_DEV, + PBR1_NATIVE_PCI_FUN, + PBR1_CORE_ID, + PBR1_PORT_ID, + {(UINT32)PBR1_PCI_ADDRESS}, + LinkStateResetExit, + PBR1, + PBR1_UNIT_ID, + PBR1_NUM_UNIT_IDs + }, + }, + }, + //Port PBR0 + { + { + DESCRIPTOR_PCIE_ENGINE | DESCRIPTOR_TERMINATE_LIST, + offsetof (KB_COMPLEX_CONFIG, PortPBR0) - offsetof (KB_COMPLEX_CONFIG, GppWrapper), + offsetof (KB_COMPLEX_CONFIG, Ddi1) - offsetof (KB_COMPLEX_CONFIG, PortPBR0), + 0 + }, + { PciePortEngine, GPP_START_PHY_LANE, GPP_END_PHY_LANE }, + 0, //Initialization Status + 0xFF, //Scratch + { + { + {0}, + 0, + 3, + PBR0_NATIVE_PCI_DEV, + PBR0_NATIVE_PCI_FUN, + PBR0_CORE_ID, + PBR0_PORT_ID, + {(UINT32)PBR0_PCI_ADDRESS}, + LinkStateResetExit, + PBR0, + PBR0_UNIT_ID, + PBR0_NUM_UNIT_IDs + }, + }, + }, +//------------------------------ GPP WRAPPER END ------------------------------------- +//------------------------------ DDI WRAPPER START---------------------------------- + //Ddi1 + { + { + DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL, + offsetof (KB_COMPLEX_CONFIG, Ddi1) - offsetof (KB_COMPLEX_CONFIG, DdiWrapper), + offsetof (KB_COMPLEX_CONFIG, Ddi2) - offsetof (KB_COMPLEX_CONFIG, Ddi1), + 0 + }, + {PcieDdiEngine}, + 0, //Initialization Status + 0xFF //Scratch + }, + //Ddi2 + { + { + DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL, + offsetof (KB_COMPLEX_CONFIG, Ddi2) - offsetof (KB_COMPLEX_CONFIG, DdiWrapper), + offsetof (KB_COMPLEX_CONFIG, Vga) - offsetof (KB_COMPLEX_CONFIG, Ddi2), + 0 + }, + {PcieDdiEngine}, + 0, //Initialization Status + 0xFF //Scratch + }, + //Vga + { + { + DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_GNB | DESCRIPTOR_TERMINATE_TOPOLOGY, + offsetof (KB_COMPLEX_CONFIG, Vga) - offsetof (KB_COMPLEX_CONFIG, DdiWrapper), + 0, + 0 + }, + {PcieDdiEngine}, + 0, //Initialization Status + 0xFF //Scratch + }, + { + {0, 0, 0, 0, 0} + } +}; + +// +// PCIe lane allocation GPP +// +UINT8 ROMDATA GppPortLaneConfigurationTableKB [] = { + UNUSED_LANE_ID, UNUSED_LANE_ID, UNUSED_LANE_ID, UNUSED_LANE_ID, UNUSED_LANE_ID, UNUSED_LANE_ID, 4, 7, 0, 3, + UNUSED_LANE_ID, UNUSED_LANE_ID, UNUSED_LANE_ID, UNUSED_LANE_ID, 6, 7, 4, 5, 0, 3, + UNUSED_LANE_ID, UNUSED_LANE_ID, 7, 7, 6, 6, 4, 5, 0, 3, + 7, 7, 6, 6, 5, 5, 4, 4, 0, 3 +}; + +// +// DDI lane allocation DDI +// +UINT8 ROMDATA DdiLaneConfigurationTableKB [] = { + 0, 3, 4, 7, 8, 11 +}; + +// +// PCIe lane allocation desfriptors +// +PCIe_LANE_ALLOC_DESCRIPTOR ROMDATA PcieLaneAllocConfigurationKB[] = { + { + 0, + GPP_WRAP_ID, + PciePortEngine, + NUMBER_OF_GPP_PORTS, + sizeof (GppPortLaneConfigurationTableKB) / (NUMBER_OF_GPP_PORTS * 2), + &GppPortLaneConfigurationTableKB[0] + }, + { + DESCRIPTOR_TERMINATE_LIST, + DDI_WRAP_ID, + PcieDdiEngine, + NUMBER_OF_DDI_DDIS, + sizeof (DdiLaneConfigurationTableKB) / (NUMBER_OF_DDI_DDIS * 2), + &DdiLaneConfigurationTableKB[0] + } +}; + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get length of data block for complex + * + * + * + * @param[in] SocketId Socket ID. + * @param[out] Length Length of configuration info block + * @param[out] StdHeader Standard configuration header + * @retval AGESA_SUCCESS Configuration data length is correct + */ +AGESA_STATUS +PcieGetComplexDataLengthKB ( + IN UINT8 SocketId, + OUT UINTN *Length, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *Length = sizeof (KB_COMPLEX_CONFIG); + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Build configuration + * + * + * + * @param[in] SocketId Socket ID. + * @param[out] Buffer Pointer to buffer to build internal complex data structure + * @param[out] StdHeader Standard configuration header. + * @retval AGESA_SUCCESS Configuration data build successfully + */ +AGESA_STATUS +PcieBuildComplexConfigurationKB ( + IN UINT8 SocketId, + OUT VOID *Buffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LibAmdMemCopy (Buffer, &ComplexDataKB, sizeof (KB_COMPLEX_CONFIG), StdHeader); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * get native PHY lane bitmap + * + * + * @param[in] PhyLaneBitmap Package PHY lane bitmap + * @param[in] Engine Standard configuration header. + * @retval Native PHY lane bitmap + */ +UINT32 +PcieGetNativePhyLaneBitmapKB ( + IN UINT32 PhyLaneBitmap, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + + return PhyLaneBitmap; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.h new file mode 100644 index 0000000000..6663031ec4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieComplexDataKB.h @@ -0,0 +1,157 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific PCIe definitions + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIECOMPLEXDATAKB_H_ +#define _PCIECOMPLEXDATAKB_H_ + +#define MAX_NUM_PHYs 2 +#define MAX_NUM_LANE_PER_PHY 8 + +#define NUMBER_OF_GPP_PORTS 5 +#define NUMBER_OF_DDI_DDIS 3 + +#define NON_INITIALIZED_PCI_ADDRESS 0 + +#define GPP_WRAP_ID 0 +#define GPP_START_PHY_LANE 0 +#define GPP_END_PHY_LANE 7 +#define GPP_CORE_ID 0 +#define GPP_NUMBER_OF_PIFs 1 + +#define DDI_WRAP_ID 3 +#define DDI_START_PHY_LANE 8 +#define DDI_END_PHY_LANE 19 +#define DDI_NUMBER_OF_PIFs 1 + +// PBR0 +#define PBR0 0 +#define PBR0_NATIVE_PCI_DEV 2 +#define PBR0_NATIVE_PCI_FUN 1 +#define PBR0_CORE_ID GPP_CORE_ID +#define PBR0_PORT_ID 0 +#define PBR0_PCI_ADDRESS NON_INITIALIZED_PCI_ADDRESS +#define PBR0_UNIT_ID 0x4 +#define PBR0_NUM_UNIT_IDs 0x1 + +// PBR1 +#define PBR1 1 +#define PBR1_NATIVE_PCI_DEV 2 +#define PBR1_NATIVE_PCI_FUN 2 +#define PBR1_CORE_ID GPP_CORE_ID +#define PBR1_PORT_ID 1 +#define PBR1_PCI_ADDRESS NON_INITIALIZED_PCI_ADDRESS +#define PBR1_UNIT_ID 0x5 +#define PBR1_NUM_UNIT_IDs 0x1 + +// PBR2 +#define PBR2 2 +#define PBR2_NATIVE_PCI_DEV 2 +#define PBR2_NATIVE_PCI_FUN 3 +#define PBR2_CORE_ID GPP_CORE_ID +#define PBR2_PORT_ID 2 +#define PBR2_PCI_ADDRESS NON_INITIALIZED_PCI_ADDRESS +#define PBR2_UNIT_ID 0x6 +#define PBR2_NUM_UNIT_IDs 0x1 + +// PBR3 +#define PBR3 3 +#define PBR3_NATIVE_PCI_DEV 2 +#define PBR3_NATIVE_PCI_FUN 4 +#define PBR3_CORE_ID GPP_CORE_ID +#define PBR3_PORT_ID 3 +#define PBR3_PCI_ADDRESS NON_INITIALIZED_PCI_ADDRESS +#define PBR3_UNIT_ID 0x7 +#define PBR3_NUM_UNIT_IDs 0x1 + +// PBR4 +#define PBR4 4 +#define PBR4_NATIVE_PCI_DEV 2 +#define PBR4_NATIVE_PCI_FUN 5 +#define PBR4_CORE_ID GPP_CORE_ID +#define PBR4_PORT_ID 4 +#define PBR4_PCI_ADDRESS NON_INITIALIZED_PCI_ADDRESS +#define PBR4_UNIT_ID 0x8 +#define PBR4_NUM_UNIT_IDs 0x1 + +#define MaxDevNum 4 +#define MaxDevFunc 5 + +#define GPP_CORE_x4x4 ((4ull << 8) | (4ull << 0)) +#define GPP_CORE_x4x2x2 ((2ull << 16) | (2ull << 8) | (4ull << 0)) +#define GPP_CORE_x4x2x1x1 ((1ull << 24) | (1ull << 16) | (2ull << 8) | (4ull << 0)) +#define GPP_CORE_x4x1x1x1x1 ((1ull << 32) | (1ull << 24) | (1ull << 16) | (1ull << 8) | (4ull << 0)) + +///Family specific silicon configuration +typedef struct { + UINT8 PortDevMap [5]; ///< Device number that has beed allocated already +} KB_PCIe_SILICON_CONFIG; + + +/// Complex Configuration for silicon module +typedef struct { + PCIe_SILICON_CONFIG Silicon; ///< Silicon + + PCIe_WRAPPER_CONFIG GppWrapper; ///< GPP Wrapper + PCIe_WRAPPER_CONFIG DdiWrapper; ///< DDI Wrapper + + // GPP + PCIe_ENGINE_CONFIG PortPBR4; ///< Port PBR6 + PCIe_ENGINE_CONFIG PortPBR3; ///< Port PBR5 + PCIe_ENGINE_CONFIG PortPBR2; ///< Port PBR4 + PCIe_ENGINE_CONFIG PortPBR1; ///< Port PBR3 + PCIe_ENGINE_CONFIG PortPBR0; ///< Port PBR2 + + // DDI + PCIe_ENGINE_CONFIG Ddi1; ///< Ddi1 + PCIe_ENGINE_CONFIG Ddi2; ///< Ddi2 + PCIe_ENGINE_CONFIG Vga; ///< Vga + KB_PCIe_SILICON_CONFIG FmSilicon; ///< Fm silicon config +} KB_COMPLEX_CONFIG; + + +VOID +PcieSetPortPciAddressMapKB ( + IN PCIe_SILICON_CONFIG *Silicon + ); +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieConfigKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieConfigKB.c new file mode 100644 index 0000000000..bc87ddef3d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieConfigKB.c @@ -0,0 +1,626 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific PCIe wrapper configuration services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "PcieComplexDataKB.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIECONFIGKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +#define DEVFUNC(d, f) ((((UINT8) d) << 3) | ((UINT8) f)) + +extern PCIe_LANE_ALLOC_DESCRIPTOR ROMDATA PcieLaneAllocConfigurationKB[]; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +CONST CHAR8* +PcieDebugGetCoreConfigurationStringKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 ConfigurationValue + ); + +CONST CHAR8* +PcieDebugGetHostRegAddressSpaceStringKB ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT16 AddressFrame + ); + +BOOLEAN +PcieCheckPortPcieLaneCanBeMuxedKB ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +AGESA_STATUS +PcieMapPortPciAddressKB ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +CONST CHAR8* +PcieDebugGetWrapperNameStringKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +AGESA_STATUS +PcieConfigureEnginesLaneAllocationKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIE_ENGINE_TYPE EngineType, + IN UINT8 ConfigurationId + ); + +AGESA_STATUS +PcieGetCoreConfigurationValueKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId, + IN UINT64 ConfigurationSignature, + IN UINT8 *ConfigurationValue + ); + +BOOLEAN +PcieCheckPortPciDeviceMappingKB ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +AGESA_STATUS +PcieGetSbConfigInfoKB ( + IN UINT8 SocketId, + OUT PCIe_PORT_DESCRIPTOR *SbPort, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +// +// Default port dev map +// +UINT8 ROMDATA DefaultPortDevMap [] = { + DEVFUNC (2, 1), + DEVFUNC (2, 2), + DEVFUNC (2, 3), + DEVFUNC (2, 4), + DEVFUNC (2, 5) +}; + +// +// Default apic config +// +APIC_DEVICE_INFO ROMDATA DefaultIoapicConfig [] = { + {0, 0, 0x18}, + {1, 0, 0x19}, + {2, 0, 0x1A}, + {3, 0, 0x1B}, + {4, 0, 0x18} +}; + + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] PcieLaneConfig Lane configuration descriptor + * @param[in] ConfigurationId Configuration ID + * @retval AGESA_SUCCESS Configuration successfully applied + * @retval AGESA_ERROR Requested configuration not supported + */ +STATIC AGESA_STATUS +PcieConfigurePcieEnginesLaneAllocation ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_LANE_ALLOC_DESCRIPTOR *PcieLaneConfig, + IN UINT8 ConfigurationId + ) +{ + UINT8 CoreLaneIndex; + PCIe_ENGINE_CONFIG *EnginesList; + + if (ConfigurationId >= PcieLaneConfig->NumberOfConfigurations) { + return AGESA_ERROR; + } + EnginesList = PcieConfigGetChildEngine (Wrapper); + CoreLaneIndex = ConfigurationId * PcieLaneConfig->NumberOfEngines * 2; + + while (EnginesList != NULL) { + if (PcieLibIsPcieEngine (EnginesList)) { + PcieConfigResetDescriptorFlags (EnginesList, DESCRIPTOR_ALLOCATED); + EnginesList->Type.Port.StartCoreLane = PcieLaneConfig->ConfigTable[CoreLaneIndex++]; + EnginesList->Type.Port.EndCoreLane = PcieLaneConfig->ConfigTable[CoreLaneIndex++]; + } + EnginesList = PcieLibGetNextDescriptor (EnginesList); + } + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] DdiLaneConfig Lane configuration descriptor + * @param[in] ConfigurationId Configuration ID + * @retval AGESA_SUCCESS Configuration successfully applied + * @retval AGESA_ERROR Requested configuration not supported + */ +STATIC AGESA_STATUS +PcieConfigureDdiEnginesLaneAllocation ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_LANE_ALLOC_DESCRIPTOR *DdiLaneConfig, + IN UINT8 ConfigurationId + ) +{ + UINTN LaneIndex; + PCIe_ENGINE_CONFIG *EnginesList; + if (ConfigurationId >= DdiLaneConfig->NumberOfConfigurations) { + return AGESA_ERROR; + } + LaneIndex = ConfigurationId * DdiLaneConfig->NumberOfEngines * 2; + EnginesList = PcieConfigGetChildEngine (Wrapper); + while (EnginesList != NULL) { + if (PcieLibIsDdiEngine (EnginesList)) { + PcieConfigResetDescriptorFlags (EnginesList, DESCRIPTOR_ALLOCATED); + EnginesList->EngineData.StartLane = DdiLaneConfig->ConfigTable[LaneIndex++] + Wrapper->StartPhyLane; + EnginesList->EngineData.EndLane = DdiLaneConfig->ConfigTable[LaneIndex++] + Wrapper->StartPhyLane; + } + EnginesList = PcieLibGetNextDescriptor (EnginesList); + } + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] EngineType Engine Type + * @param[in] ConfigurationId Configuration ID + * @retval AGESA_SUCCESS Configuration successfully applied + * @retval AGESA_ERROR Requested configuration not supported + */ +AGESA_STATUS +PcieConfigureEnginesLaneAllocationKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIE_ENGINE_TYPE EngineType, + IN UINT8 ConfigurationId + ) +{ + AGESA_STATUS Status; + PCIe_LANE_ALLOC_DESCRIPTOR *LaneConfigDescriptor; + + Status = AGESA_ERROR; + LaneConfigDescriptor = PcieLaneAllocConfigurationKB; + while (LaneConfigDescriptor != NULL) { + if (LaneConfigDescriptor->WrapId == Wrapper->WrapId && LaneConfigDescriptor->EngineType == EngineType) { + switch (EngineType) { + case PciePortEngine: + Status = PcieConfigurePcieEnginesLaneAllocation (Wrapper, LaneConfigDescriptor, ConfigurationId); + break; + case PcieDdiEngine: + Status = PcieConfigureDdiEnginesLaneAllocation (Wrapper, LaneConfigDescriptor, ConfigurationId); + break; + default: + ASSERT (FALSE); + } + break; + } + LaneConfigDescriptor = PcieConfigGetNextDataDescriptor (LaneConfigDescriptor); + } + return Status; +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get core configuration value + * + * + * + * @param[in] Wrapper Pointer to internal configuration data area + * @param[in] CoreId Core ID + * @param[in] ConfigurationSignature Configuration signature + * @param[out] ConfigurationValue Configuration value (for core configuration) + * @retval AGESA_SUCCESS Configuration successfully applied + * @retval AGESA_ERROR Core configuration value can not be determined + */ +AGESA_STATUS +PcieGetCoreConfigurationValueKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId, + IN UINT64 ConfigurationSignature, + IN UINT8 *ConfigurationValue + ) +{ + AGESA_STATUS Status; + Status = AGESA_SUCCESS; + switch (ConfigurationSignature) { + case GPP_CORE_x4x1x1x1x1: + *ConfigurationValue = 0x4; + break; + case GPP_CORE_x4x2x1x1: + *ConfigurationValue = 0x3; + break; + case GPP_CORE_x4x2x2: + *ConfigurationValue = 0x2; + break; + case GPP_CORE_x4x4: + *ConfigurationValue = 0x1; + break; + default: + IDS_HDT_CONSOLE (PCIE_MISC, "ERROR!!![%s Wrapper] Unknown core config signature 0x%08x%08x\n", + PcieDebugGetWrapperNameStringKB (Wrapper), + ((UINT32 *) &ConfigurationSignature)[1], + ((UINT32 *) &ConfigurationSignature)[0] + ); + ASSERT (FALSE); + Status = AGESA_ERROR; + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if engine can be remapped to Device/function number requested by user + * defined engine descriptor + * + * Function only called if requested device/function does not much native device/function + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieCheckPortPciDeviceMappingKB ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT8 DevFunc; + UINT8 Index; + DevFunc = DEVFUNC (PortDescriptor->Port.DeviceNumber, PortDescriptor->Port.FunctionNumber); + if (DevFunc == 0) { + return TRUE; + } + for (Index = 0; Index < (sizeof (DefaultPortDevMap) / sizeof (DefaultPortDevMap[0])); Index++) { + if (DefaultPortDevMap[Index] == DevFunc) { + return TRUE; + } + } + return FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get core configuration string + * + * Debug function for logging configuration + * + * @param[in] Wrapper Pointer to internal configuration data area + * @param[in] ConfigurationValue Configuration value + * @retval Configuration string + */ + +CONST CHAR8* +PcieDebugGetCoreConfigurationStringKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 ConfigurationValue + ) +{ + switch (ConfigurationValue) { + case 0x4: + return "4:1:1:1:1"; + case 0x3: + return "4:2:1:1"; + case 0x2: + return "4:2:2"; + case 0x1: + return "4:4"; + default: + break; + } + return " !!! Something Wrong !!!"; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get wrapper name + * + * Debug function for logging wrapper name + * + * @param[in] Wrapper Pointer to internal configuration data area + * @retval Wrapper Name string + */ + +CONST CHAR8* +PcieDebugGetWrapperNameStringKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + switch (Wrapper->WrapId) { + case GPP_WRAP_ID: + return "GPP"; + case DDI_WRAP_ID: + return "Virtual DDI"; + default: + break; + } + return " !!! Something Wrong !!!"; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get register address name + * + * Debug function for logging register trace + * + * @param[in] Silicon Silicon config descriptor + * @param[in] AddressFrame Address Frame + * @retval Register address name + */ +CONST CHAR8* +PcieDebugGetHostRegAddressSpaceStringKB ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT16 AddressFrame + ) +{ + switch (AddressFrame) { + case 0x130: + return "GPP WRAP"; + case 0x110: + return "GPP PIF0"; + case 0x120: + return "GPP PHY0"; + case 0x140: + return "GPP CORE"; + default: + break; + } + return " !!! Something Wrong !!!"; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if the lane can be muxed by link width requested by user + * defined engine descriptor + * + * Check Engine StartCoreLane could be aligned by user requested link width(x1, x2, x4, x8, x16). + * Check Engine StartCoreLane could be aligned by user requested link width x2. + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Lane can be muxed + * @retval FALSE Lane can NOT be muxed + */ + +BOOLEAN +PcieCheckPortPcieLaneCanBeMuxedKB ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + PCIe_WRAPPER_CONFIG *Wrapper; + UINT16 NormalizedLoPhyLane; + BOOLEAN Result; + + Result = FALSE; + Wrapper = PcieConfigGetParentWrapper (Engine); + DescriptorLoLane = MIN (PortDescriptor->EngineData.StartLane, PortDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (PortDescriptor->EngineData.StartLane, PortDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + + NormalizedLoPhyLane = DescriptorLoLane - Wrapper->StartPhyLane; + + if (NormalizedLoPhyLane == Engine->Type.Port.StartCoreLane) { + Result = TRUE; + } else { + if (NormalizedLoPhyLane == 0) { + Result = TRUE; + } else { + if ((NormalizedLoPhyLane % DescriptorNumberOfLanes) == 0) { + Result = TRUE; + } + } + } + return Result; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Map engine to specific PCI device address + * + * + * + * @param[in] Engine Pointer to engine configuration + * @retval AGESA_ERROR Fail to map PCI device address + * @retval AGESA_SUCCESS Successfully allocate PCI address + */ + +AGESA_STATUS +PcieMapPortPciAddressKB ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + AGESA_STATUS Status; + KB_COMPLEX_CONFIG *ComplexConfig; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_PLATFORM_CONFIG *Pcie; + UINT8 DevFunc; + UINT8 Index; + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapPortPciAddressKB Enter\n"); + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header); + if (Engine->Type.Port.PortData.DeviceNumber == 0 && Engine->Type.Port.PortData.FunctionNumber == 0) { + Engine->Type.Port.PortData.DeviceNumber = Engine->Type.Port.NativeDevNumber; + Engine->Type.Port.PortData.FunctionNumber = Engine->Type.Port.NativeFunNumber; + } + ComplexConfig = (KB_COMPLEX_CONFIG *) PcieConfigGetParentSilicon (Engine); + IDS_OPTION_HOOK (IDS_GNB_PCIE_PORT_REMAP, &Engine->Type.Port, GnbLibGetHeader (Pcie)); + DevFunc = (Engine->Type.Port.PortData.DeviceNumber << 3) | Engine->Type.Port.PortData.FunctionNumber; + for (Index = 0; Index < sizeof (ComplexConfig->FmSilicon.PortDevMap); ++Index) { + if (ComplexConfig->FmSilicon.PortDevMap[Index] == DevFunc) { + Status = AGESA_ERROR; + break; + } + } + if (Status == AGESA_SUCCESS) { + ComplexConfig->FmSilicon.PortDevMap[Engine->Type.Port.PcieBridgeId] = DevFunc; + } + for (Index = 0; Index < sizeof (DefaultPortDevMap); ++Index) { + if (DevFunc == DefaultPortDevMap[Index]) { + Engine->Type.Port.LogicalBridgeId = Index; + // Get the configuration from the table or from "auto settings" + if (Engine->Type.Port.PortData.ApicDeviceInfo.GroupMap == 0x00) { + // If Group is 0, use "Auto" settings + Engine->Type.Port.PortData.ApicDeviceInfo = DefaultIoapicConfig[Index]; + } + break; + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapPortPciAddressKB Exit [0x%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Map engine to specific PCI device address + * + * + * @param[in] Silicon Silicon config descriptor + */ + +VOID +PcieSetPortPciAddressMapKB ( + IN PCIe_SILICON_CONFIG *Silicon + ) +{ + UINT8 Index; + UINT8 DevFuncIndex; + UINT8 PortDevMap [sizeof (DefaultPortDevMap)]; + PCIe_PLATFORM_CONFIG *Pcie; + D0F0x64_x30_STRUCT D0F0x64_x30; + + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Silicon->Header); + LibAmdMemCopy (&PortDevMap[0], &DefaultPortDevMap[0], sizeof (DefaultPortDevMap), GnbLibGetHeader (Pcie)); + for (Index = 0; Index < sizeof (((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap); ++Index) { + if (((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap[Index] != 0) { + for (DevFuncIndex = 0; DevFuncIndex < sizeof (((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap); ++DevFuncIndex) { + if (PortDevMap[DevFuncIndex] == ((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap[Index]) { + PortDevMap[DevFuncIndex] = 0; + break; + } + } + } + } + for (Index = 0; Index < sizeof (((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap); ++Index) { + if (((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap[Index] == 0) { + for (DevFuncIndex = 0; DevFuncIndex < sizeof (((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap); ++DevFuncIndex) { + if (PortDevMap[DevFuncIndex] != 0) { + ((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap[Index] = PortDevMap[DevFuncIndex]; + PortDevMap[DevFuncIndex] = 0; + break; + } + } + } + GnbRegisterReadKB ((GNB_HANDLE *) Silicon, D0F0x64_x30_TYPE, D0F0x64_x30_ADDRESS + Index, &D0F0x64_x30.Value, 0, GnbLibGetHeader (Pcie)); + D0F0x64_x30.Field.DevFnMap = ((KB_COMPLEX_CONFIG *) Silicon)->FmSilicon.PortDevMap[Index]; + GnbRegisterWriteKB ((GNB_HANDLE *) Silicon, D0F0x64_x30_TYPE, D0F0x64_x30_ADDRESS + Index, &D0F0x64_x30.Value, 0, GnbLibGetHeader (Pcie)); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build default SB configuration descriptor + * + * + * @param[in] SocketId Socket Id + * @param[out] SbPort Pointer to SB configuration descriptor + * @param[in] StdHeader Standard configuration header. + * @retval AGESA_SUCCESS Configuration data build successfully + */ +AGESA_STATUS +PcieGetSbConfigInfoKB ( + IN UINT8 SocketId, + OUT PCIe_PORT_DESCRIPTOR *SbPort, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return AGESA_UNSUPPORTED; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieEarlyInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieEarlyInitKB.c new file mode 100644 index 0000000000..2199796fd8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieEarlyInitKB.c @@ -0,0 +1,938 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe early post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87701 $ @e \$Date: 2013-02-07 12:58:51 -0600 (Thu, 07 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbUra.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieTrainingV2.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV4.h" +#include "GnbPcieInitLibV5.h" +#include "PcieLibKB.h" +#include "PcieComplexDataKB.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "OptionGnb.h" +#include "GnbSmuInitLibV7.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIEEARLYINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_BUILD_OPTIONS GnbBuildOptions; +extern BUILD_OPT_CFG UserOptions; +extern CONST PCIE_HOST_REGISTER_TABLE_HEADER ROMDATA PcieInitEarlyTableKB; +extern CONST PCIE_HOST_REGISTER_TABLE_HEADER ROMDATA CoreInitTableKB; +extern CONST PCIE_PORT_REGISTER_TABLE_HEADER ROMDATA PortInitEarlyTableKB; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PcieEarlyInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Set port device/function mapping + * + * + * + * @param[in] Descriptor Silicon descriptor + * @param[in] Buffer Pointer to buffer + * @param[in] Pcie Pointer to global PCIe configuration + */ +STATIC AGESA_STATUS +PciePortMapInitCallbackKB ( + IN PCIe_DESCRIPTOR_HEADER *Descriptor, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieSetPortPciAddressMapKB ((PCIe_SILICON_CONFIG *) Descriptor); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Static init for various registers. + * + * + * + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +STATIC +PcieEarlyStaticInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINTN Index; + + for (Index = 0; Index < PcieInitEarlyTableKB.Length; Index++) { + GnbLibPciIndirectRMW ( + MAKE_SBDFO (0,0,0,0, D0F0xE0_ADDRESS), + PcieInitEarlyTableKB.Table[Index].Reg, + AccessS3SaveWidth32, + (UINT32)~PcieInitEarlyTableKB.Table[Index].Mask, + PcieInitEarlyTableKB.Table[Index].Data, + GnbLibGetHeader (Pcie) + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init core registers. + * + * + * @param[in] Wrapper Pointer to wrapper configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +STATIC +PcieEarlyCoreInitKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 CoreId; + UINTN Index; + if (PcieLibIsPcieWrapper (Wrapper)) { + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyCoreInitKB Enter\n"); + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + for (Index = 0; Index < CoreInitTableKB.Length; Index++) { + UINT32 Value; + Value = PcieRegisterRead ( + Wrapper, + CORE_SPACE (CoreId, CoreInitTableKB.Table[Index].Reg), + Pcie + ); + Value &= (~CoreInitTableKB.Table[Index].Mask); + Value |= CoreInitTableKB.Table[Index].Data; + PcieRegisterWrite ( + Wrapper, + CORE_SPACE (CoreId, CoreInitTableKB.Table[Index].Reg), + Value, + FALSE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyCoreInitKB Exit\n"); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Pcie Phy Isolation + * + * + * @param[in] Wrapper Pointer to wrapper configuration descriptor + * @param[in] Pcie Pointer to PCIe configuration data area + */ +VOID +STATIC +PciePhyIsolationKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 ActiveLaneBitmap; + UINT32 PhyRxIsoDis; + D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; + UINT32 D0F0xE4_WRAP_8021; + UINT32 D0F0xE4_WRAP_8022; + UINT32 D0F0xE4_WRAP_8025; + UINT32 D0F0xE4_WRAP_8026; + + IDS_HDT_CONSOLE (GNB_TRACE, "PciePhyIsolationKB Enter\n"); + + // Apply lane mux + D0F0xE4_WRAP_8021 = 0x07060504; + D0F0xE4_WRAP_8022 = 0x03020100; + D0F0xE4_WRAP_8025 = 0x07060504; + D0F0xE4_WRAP_8026 = 0x03020100; + + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8021_ADDRESS), + D0F0xE4_WRAP_8021, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8022_ADDRESS), + D0F0xE4_WRAP_8022, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS), + D0F0xE4_WRAP_8025, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8026_ADDRESS), + D0F0xE4_WRAP_8026, + FALSE, + Pcie + ); + + PhyRxIsoDis = GnbBuildOptions.CfgPciePhyIsolationEnable ? 0 : 3; + ActiveLaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE, 0, Wrapper); + if ((ActiveLaneBitmap & 0xF0) != 0) { + PhyRxIsoDis = 3; + } + + IDS_OPTION_HOOK (IDS_GNB_PCIE_PHY_ISOLATION, &PhyRxIsoDis, GnbLibGetHeader (Pcie)); + + D0F0xE4_WRAP_8013.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8013.Field.PhyRxIsoDis = 3; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + D0F0xE4_WRAP_8013.Value, + FALSE, + Pcie + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "PciePhyIsolationKB Exit\n"); +} + +UINT8 LaneMuxSelectorArrayKB[] = { 7, 6, 5, 4, 3, 2, 1, 0 }; + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate mux array index + * + * + * + * @param[in, out] LaneMuxSelectorArrayPtr Pointer to mux selector array + * @param[in] LaneMuxValue The value that match to array + * @retval Index Index successfully mapped + */ +STATIC UINT8 +PcieTopologyLocateMuxIndexKB ( + IN OUT UINT8 *LaneMuxSelectorArrayPtr, + IN UINT8 LaneMuxValue + ) +{ + UINT8 Index; + for (Index = 0; Index < sizeof (LaneMuxSelectorArrayKB); Index++ ) { + if (LaneMuxSelectorArrayPtr [Index] == LaneMuxValue) { + return Index; + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Apply lane mux + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +STATIC VOID +PcieTopologyApplyLaneMuxKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT32 Index; + UINT8 RxLaneMuxSelectorArray [sizeof (LaneMuxSelectorArrayKB)]; + UINT8 TxLaneMuxSelectorArray [sizeof (LaneMuxSelectorArrayKB)]; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMuxKB Enter\n"); + if (PcieLibIsPcieWrapper (Wrapper)) { + LibAmdMemCopy ( + &TxLaneMuxSelectorArray[0], + &LaneMuxSelectorArrayKB[0], + sizeof (LaneMuxSelectorArrayKB), + GnbLibGetHeader (Pcie) + ); + LibAmdMemCopy ( + &RxLaneMuxSelectorArray[0], + &LaneMuxSelectorArrayKB[0], + sizeof (LaneMuxSelectorArrayKB), + GnbLibGetHeader (Pcie) + ); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { + UINT32 CoreLaneBitmap; + UINT32 PifLaneBitmap; + UINT8 CurrentCoreLane; + UINT8 CurrentPifLane; + + CoreLaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_CORE_ALLOC, 0, EngineList); + PifLaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, EngineList); + + while (CoreLaneBitmap != 0) { + CurrentCoreLane = LibAmdBitScanForward (CoreLaneBitmap); + CurrentPifLane = LibAmdBitScanForward (PifLaneBitmap); + + if (TxLaneMuxSelectorArray[CurrentPifLane] != CurrentCoreLane) { + TxLaneMuxSelectorArray[PcieTopologyLocateMuxIndexKB (TxLaneMuxSelectorArray, CurrentCoreLane)] = TxLaneMuxSelectorArray[CurrentPifLane]; + TxLaneMuxSelectorArray[CurrentPifLane] = CurrentCoreLane; + } + + if (RxLaneMuxSelectorArray[CurrentCoreLane] != CurrentPifLane) { + RxLaneMuxSelectorArray[PcieTopologyLocateMuxIndexKB (RxLaneMuxSelectorArray, CurrentPifLane)] = RxLaneMuxSelectorArray[CurrentCoreLane]; + RxLaneMuxSelectorArray[CurrentCoreLane] = CurrentPifLane; + } + + CoreLaneBitmap &= (~ (1 << CurrentCoreLane)); + PifLaneBitmap &= (~ (1 << CurrentPifLane)); + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + for (Index = 0; Index < 2; ++Index) { + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8021_ADDRESS + Index), + ((UINT32 *) TxLaneMuxSelectorArray) [Index], + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS + Index), + ((UINT32 *) RxLaneMuxSelectorArray) [Index], + FALSE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMuxKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute/clean up reconfiguration + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +STATIC VOID +PcieTopologyExecuteReconfigKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; + PCIe_SILICON_CONFIG *Silicon; + DEV_OBJECT DevObject; + + if (PcieLibIsPcieWrapper (Wrapper)) { + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigKB Enter\n"); + + D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x1; + D0F0xE4_WRAP_8062.Field.ResetPeriod = 0x2; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + + Silicon = PcieConfigGetParentSilicon (Wrapper); + + GnbLibPciIndirectRMW ( + Silicon->Address.AddressValue | D0F0xB8_ADDRESS, + 0x3f81c, + AccessWidth32, + (UINT32) ~0xff00, + Wrapper->WrapId << 8, + GnbLibGetHeader (Pcie) + ); + + DevObject.StdHeader = GnbLibGetHeader (Pcie); + DevObject.GnbHandle = GnbGetHandle (GnbLibGetHeader (Pcie)); + DevObject.DevPciAddress.AddressValue = Silicon->Address.AddressValue; + GnbSmuServiceRequestV7 ( + &DevObject, + 25, //SMC_MSG_RECONFIGURE, + 0, + 0 + ); + + D0F0xE4_WRAP_8062.Field.ConfigXferMode = 0x1; + D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x0; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigKB Exit\n"); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Apply Misc settings for given wrapper + * + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ +STATIC VOID +PcieMiscInitKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8011_STRUCT D0F0xE4_WRAP_8011; + GnbRegistersKB4915_STRUCT GnbRegistersKB4915; + GnbRegistersKB4940_STRUCT GnbRegistersKB4940; + GnbRegistersKB4965_STRUCT GnbRegistersKB4965; + GnbRegistersKB4990_STRUCT GnbRegistersKB4990; + GnbRegistersKB5015_STRUCT GnbRegistersKB5015; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMiscInitKB Enter\n"); + D0F0xE4_WRAP_8011.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8011_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8011.Field.Bitfield_23_23 = 0; + + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8011_ADDRESS), + D0F0xE4_WRAP_8011.Value, + TRUE, + Pcie + ); + + GnbRegistersKB4915.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x805), + Pcie + ); + + GnbRegistersKB4940.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x905), + Pcie + ); + + GnbRegistersKB4965.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x0A05), + Pcie + ); + GnbRegistersKB4990.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x0B05), + Pcie + ); + + GnbRegistersKB5015.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x0C05), + Pcie + ); + + GnbRegistersKB4915.Field.bit_31_24 = 0x40; + GnbRegistersKB4940.Field.bit_31_24 = 0x40; + GnbRegistersKB4965.Field.bit_31_24 = 0x40; + GnbRegistersKB4990.Field.bit_31_24 = 0x40; + GnbRegistersKB5015.Field.bit_31_24 = 0x40; + + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x805), + GnbRegistersKB4915.Value, + TRUE, + Pcie + ); + + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x905), + GnbRegistersKB4940.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x0A05), + GnbRegistersKB4965.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x0B05), + GnbRegistersKB4990.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x0C05), + GnbRegistersKB5015.Value, + TRUE, + Pcie + ); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMiscInitKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Switch to PCIe Native Gen1 PLL. + * + * + * @param[in] Pcie Pointer to global PCIe configuration + */ +AGESA_STATUS +STATIC +PcieNativeGen1PLLSwitchKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_LINK_SPEED_CAP GlobalSpeedCap; + UINT32 ParamValue; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieNativeGen1PLLSwitchKB Enter\n"); + + GlobalSpeedCap = PcieUtilGlobalGenCapability ( + PCIE_PORT_GEN_CAP_MAX | PCIE_GLOBAL_GEN_CAP_TRAINED_PORTS | PCIE_GLOBAL_GEN_CAP_HOTPLUG_PORTS, + Pcie + ); + + ParamValue = 0; + if (GlobalSpeedCap == PcieGen1) { + GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), TYPE_SMU_MSG, 87, &ParamValue, 0, GnbLibGetHeader (Pcie)); + } + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieNativeGen1PLLSwitchKB Exit\n"); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Per wrapper Pcie Init prior training. + * + * + * @param[in] Wrapper Pointer to wrapper configuration descriptor + * @param[in] Buffer Pointer buffer + * @param[in] Pcie Pointer to global PCIe configuration + */ +AGESA_STATUS +STATIC +PcieEarlyInitCallbackKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + BOOLEAN CoreConfigChanged; + BOOLEAN PllConfigChanged; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInitCallbackKB Enter\n"); + CoreConfigChanged = FALSE; + PllConfigChanged = FALSE; + IDS_OPTION_HOOK (IDS_BEFORE_RECONFIGURATION, Pcie, GnbLibGetHeader (Pcie)); + PcieTopologyPrepareForReconfig (Wrapper, Pcie); + Status = PcieTopologySetCoreConfig (Wrapper, &CoreConfigChanged, Pcie); + ASSERT (Status == AGESA_SUCCESS); + PciePhyIsolationKB (Wrapper, Pcie); + PcieTopologyApplyLaneMuxKB (Wrapper, Pcie); + PciePifSetRxDetectPowerMode (Wrapper, Pcie); + PciePifSetLs2ExitTimeV5 (Wrapper, Pcie); + PciePifApplyGanging (Wrapper, Pcie); + PcieTopologySelectMasterPllKB (Wrapper, &PllConfigChanged, Pcie); + PcieMiscInitKB (Wrapper, Pcie); + PcieTopologyExecuteReconfigKB (Wrapper, Pcie); + PcieTopologyCleanUpReconfig (Wrapper, Pcie); + PcieTopologySetLinkReversalV4 (Wrapper, Pcie); + PciePifPllConfigureKB (Wrapper, Pcie); + PcieTopologyLaneControlV5 ( + DisableLanes, + PcieUtilGetWrapperLaneBitMap (LANE_TYPE_CORE_ALL, LANE_TYPE_PCIE_CORE_ALLOC, Wrapper), + Wrapper, + Pcie + ); + + PciePollPifForCompeletion (Wrapper, Pcie); + PcieEarlyCoreInitKB (Wrapper, Pcie); + PcieSetSsidV4 (UserOptions.CfgGnbPcieSSID, Wrapper, Pcie); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInitCallbackKB Exit [%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Pcie Init + * + * + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ + +AGESA_STATUS +STATIC +PcieEarlyInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + BOOLEAN NativeGen1PLL; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInitKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + NativeGen1PLL = GnbBuildOptions.CfgNativeGen1PLL; + + Status = PcieConfigRunProcForAllDescriptors (DESCRIPTOR_SILICON, 0, DESCRIPTOR_TERMINATE_TOPOLOGY, PciePortMapInitCallbackKB, NULL, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + IDS_OPTION_HOOK (IDS_GNB_PMM_NATIVEGEN1PLL, &NativeGen1PLL, GnbLibGetHeader (Pcie)); + + if (NativeGen1PLL == TRUE) { + Status = PcieNativeGen1PLLSwitchKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + + Status = PcieConfigRunProcForAllWrappers (DESCRIPTOR_ALL_WRAPPERS, PcieEarlyInitCallbackKB, NULL, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + PcieEarlyStaticInitKB (Pcie); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInitKB Exit [%x]\n", AgesaStatus); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set misc slot capability + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieLinkSetSlotCapKB ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 IntPin; + PCIe_WRAPPER_CONFIG *Wrapper; + + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | DxF0x58_ADDRESS, + AccessWidth32, + 0xffffffff, + 1 << DxF0x58_SlotImplemented_OFFSET, + GnbLibGetHeader (Pcie) + ); + + if (Engine->Type.Port.Address.Address.Function < 5) { + IntPin = Engine->Type.Port.Address.Address.Function; + } else { + IntPin = Engine->Type.Port.Address.Address.Function - 4; + } + + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | DxF0x3C_ADDRESS, + AccessWidth32, + 0xffffffff, + IntPin << DxF0x3C_IntPin_OFFSET, + GnbLibGetHeader (Pcie) + ); + + // Set MaxPayload straps for port + if (Engine->EngineData.StartLane == Engine->EngineData.EndLane) { + IDS_HDT_CONSOLE (GNB_TRACE, "Set MaxPayload strap for StartLane = %d and EndLane = %d\n", Engine->EngineData.StartLane, Engine->EngineData.EndLane); + Wrapper = PcieConfigGetParentWrapper (Engine); + PcieRegisterRMW ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x804 + (Engine->Type.Port.PortId) * 0x100), + 0xe, + MAX_PAYLOAD_256 << 1, + FALSE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init various features on all active ports + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieEarlyPortInitCallbackKB ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyPortInitCallbackKB Enter\n"); + ASSERT (Engine->EngineData.EngineType == PciePortEngine); + PciePortProgramRegisterTable (PortInitEarlyTableKB.Table, PortInitEarlyTableKB.Length, Engine, FALSE, Pcie); + PcieSetLinkSpeedCapV4 (PcieGen1, Engine, Pcie); + PcieSetLinkWidthCap (Engine, Pcie); + PcieCompletionTimeout (Engine, Pcie); + PcieLinkSetSlotCapKB (Engine, Pcie); + PcieLinkInitHotplugV5 (Engine, Pcie); + PciePhyChannelCharacteristicV5 (Engine, Pcie); + if (Engine->Type.Port.PortData.PortPresent == PortDisabled || + (Engine->Type.Port.PortData.EndpointStatus == EndpointNotPresent && + Engine->Type.Port.PortData.LinkHotplug != HotplugEnhanced && + Engine->Type.Port.PortData.LinkHotplug != HotplugServer)) { + ASSERT (!PcieConfigIsSbPcieEngine (Engine)); + // + // Pass endpoint status in scratch + // + PciePortRegisterRMW ( + Engine, + 0x1, + 0x1, + 0x1, + FALSE, + Pcie + ); + PcieTrainingSetPortState (Engine, LinkStateDeviceNotPresent, FALSE, Pcie); + } + if (PcieConfigIsSbPcieEngine (Engine)) { + PcieTrainingSetPortState (Engine, LinkStateTrainingSuccess, FALSE, Pcie); + } + if (Engine->Type.Port.PortData.MiscControls.LinkComplianceMode == 0x1) { + PcieTrainingSetPortState (Engine, LinkStateTrainingCompleted, FALSE, Pcie); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyPortInitCallbackKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init various features on all active ports + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +DdiEarlyPortInitCallbackKB ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 GMMx6464; + UINT32 GMMx5C6C; + UINT32 GMMx5C90; + + IDS_HDT_CONSOLE (GNB_TRACE, "DdiEarlyPortInitCallbackKB Enter\n"); + if ((Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDP) || + (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDpToLvds) || + (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvds) || + (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvdsSwInit)) { + + IDS_HDT_CONSOLE (GNB_TRACE, "Found eDP/LVDS Connector\n"); + + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x6464, &GMMx6464, 0, GnbLibGetHeader (Pcie)); + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x5c90, &GMMx5C90, 0, GnbLibGetHeader (Pcie)); + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x5c6c, &GMMx5C6C, 0, GnbLibGetHeader (Pcie)); + GMMx6464 |= 1; + GMMx6464 |= 1 << 4; + GMMx6464 |= 1 << 25; + GMMx5C90 &= ~0x3f00; GMMx5C90 |= 1 << 8; + GMMx5C6C &= ~0x1800; GMMx5C6C |= 1 << 13; + GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x6464, &GMMx6464, 0, GnbLibGetHeader (Pcie)); + GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x5c90, &GMMx5C90, 0, GnbLibGetHeader (Pcie)); + GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x12, 0x5c6c, &GMMx5C6C, 0, GnbLibGetHeader (Pcie)); + } + + IDS_HDT_CONSOLE (GNB_TRACE, "DdiEarlyPortInitCallbackKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Master procedure to init various features on all active ports + * + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_STATUS + * + */ +AGESA_STATUS +STATIC +PcieEarlyPortInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + Status = AGESA_SUCCESS; + // Leave all device in Presence Detect Presence state for distributed training will be completed at PciePortPostEarlyInit + if (Pcie->TrainingAlgorithm == PcieTrainingDistributed) { + Pcie->TrainingExitState = LinkStateResetExit; + } + + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieEarlyPortInitCallbackKB, + NULL, + Pcie + ); + + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL, + DdiEarlyPortInitCallbackKB, + NULL, + Pcie + ); + + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe Early Post Init + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +PcieEarlyInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + PCIe_PLATFORM_CONFIG *Pcie; + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInterfaceKB Enter\n"); + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + PciePortsVisibilityControlV5 (UnhidePorts, Pcie); + + Status = PcieEarlyInitKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + Status = PcieEarlyPortInitKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + Status = PcieTraining (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_PCIE_PHY_CONFIG, Pcie, StdHeader); + PciePortsVisibilityControlV5 (HidePorts, Pcie); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEarlyInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieEnvInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieEnvInitKB.c new file mode 100644 index 0000000000..9656f26d9e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieEnvInitKB.c @@ -0,0 +1,94 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe env post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "S3SaveState.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIEENVINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PcieEnvInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe Env Init + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ +AGESA_STATUS +PcieEnvInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + S3_SAVE_DISPATCH (StdHeader, PcieLateRestoreKBS3Script_ID, 0, NULL); + return AGESA_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c new file mode 100644 index 0000000000..61b07250a6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.c @@ -0,0 +1,463 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * KB specific PCIe services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87645 $ @e \$Date: 2013-02-06 13:08:17 -0600 (Wed, 06 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV5.h" +#include "GnbPcieConfig.h" +#include "GnbPcieTrainingV2.h" +#include "GnbNbInitLibV4.h" +#include "GnbNbInitLibV1.h" +#include "GnbNbInitLibV5.h" +#include "PcieComplexDataKB.h" +#include "PcieLibKB.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "GnbF1Table.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIELIBKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +PCIE_LINK_SPEED_CAP +PcieGetLinkSpeedCapKB ( + IN UINT32 Flags, + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT32 +GnbTimeStampKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +PcieMaxPayloadKB ( + IN PCIe_ENGINE_CONFIG *Engine + ); +/*----------------------------------------------------------------------------------------*/ +/** + * PLL powerdown + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifPllConfigureKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllConfigureKB Enter\n"); + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS), + Pcie + ); + + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x0; + + if (Wrapper->Features.PowerOffUnusedPlls != 0) { + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + } else { + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateL0; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateL0; + } + + if (Wrapper->Features.PllOffInL1 != 0) { + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateLS2; + } else { + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateL0; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateL0; + } + + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + 1), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllConfigureKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Power down unused lanes and plls + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePwrPowerDownUnusedLanesKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 UnusedLanes; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrPowerDownUnusedLanesKB Enter\n"); + if (Wrapper->Features.PowerOffUnusedLanes != 0) { + UnusedLanes = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_CORE_ALL, LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE, Wrapper); + PcieTopologyLaneControlV5 ( + DisableLanes, + UnusedLanes, + Wrapper, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrPowerDownUnusedLanesKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Request boot up voltage + * + * + * + * @param[in] LinkCap Global GEN capability + * @param[in] Pcie Pointer to PCIe configuration data area + */ +VOID +PcieSetVoltageKB ( + IN PCIE_LINK_SPEED_CAP LinkCap, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 TargetVid; + UINT8 MinVidIndex; + UINT8 PP_FUSE_ARRAY_V2_fld32[5]; + UINT8 Index; + PP_F1_ARRAY_V2 *PpF1Array; + UINT32 Millivolt; + UINT32 D0F0xBC_xC0104007; + UINT32 D0F0xBC_xC0104008; + UINT32 D0F0xBC_xC010407C; + UINT32 D0F0xBC_xC0107064; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetVoltageKB Enter\n"); + PpF1Array = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, GnbLibGetHeader (Pcie)); + if (PpF1Array == NULL) { + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0104007, &D0F0xBC_xC0104007, 0, GnbLibGetHeader (Pcie)); + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0104008, &D0F0xBC_xC0104008, 0, GnbLibGetHeader (Pcie)); + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC010407C, &D0F0xBC_xC010407C, 0, GnbLibGetHeader (Pcie)); + GnbRegisterReadKB (GnbGetHandle (GnbLibGetHeader (Pcie)), 0x4, 0xC0107064, &D0F0xBC_xC0107064, 0, GnbLibGetHeader (Pcie)); + PP_FUSE_ARRAY_V2_fld32[0] = (UINT8) ((D0F0xBC_xC0104007 >> 5) & 0xFF); + PP_FUSE_ARRAY_V2_fld32[1] = (UINT8) ((D0F0xBC_xC0104008 >> 5) & 0xFF); + PP_FUSE_ARRAY_V2_fld32[2] = (UINT8) ((D0F0xBC_xC0104008 >> 13) & 0xFF); + PP_FUSE_ARRAY_V2_fld32[3] = (UINT8) ((D0F0xBC_xC0104008 >> 21) & 0xFF); + PP_FUSE_ARRAY_V2_fld32[4] = (UINT8) ((D0F0xBC_xC010407C >> 20) & 0xFF); + Index = (UINT8) ((D0F0xBC_xC0107064 >> 11) & 7); + } else { + PP_FUSE_ARRAY_V2_fld32[0] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[0]; + PP_FUSE_ARRAY_V2_fld32[1] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[1]; + PP_FUSE_ARRAY_V2_fld32[2] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[2]; + PP_FUSE_ARRAY_V2_fld32[3] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[3]; + PP_FUSE_ARRAY_V2_fld32[4] = PpF1Array->PP_FUSE_ARRAY_V2_fld32[4]; + Index = PpF1Array->PcieGen2Vid; + } + if (LinkCap > PcieGen1) { + ASSERT (PP_FUSE_ARRAY_V2_fld32[Index] != 0); + TargetVid = PP_FUSE_ARRAY_V2_fld32[Index]; + } else { + + MinVidIndex = 0; + for (Index = 0; Index < 5; Index++) { + if (PP_FUSE_ARRAY_V2_fld32[Index] > PP_FUSE_ARRAY_V2_fld32[MinVidIndex]) { + MinVidIndex = (UINT8) Index; + } + } + ASSERT (PP_FUSE_ARRAY_V2_fld32[MinVidIndex] != 0); + TargetVid = PP_FUSE_ARRAY_V2_fld32[MinVidIndex]; + } + + IDS_HDT_CONSOLE (PCIE_MISC, " Set Voltage for Gen %d, Vid code %d\n", LinkCap, TargetVid); + Millivolt = GnbTranslateVidCodeToMillivoltV5 (TargetVid, GnbLibGetHeader (Pcie)) * 4 / 100; + GnbRegisterWriteKB (GnbGetHandle (GnbLibGetHeader (Pcie)), TYPE_SMU_MSG, SMC_MSG_VDDNB_REQUEST, &Millivolt, 0, GnbLibGetHeader (Pcie)); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetVoltageKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PLL power up latency + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + * @retval Pll wake up latency in us + */ +UINT8 +PciePifGetPllPowerUpLatencyKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + return 35; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get max link speed capability supported by this port + * + * + * + * @param[in] Flags See Flags PCIE_PORT_GEN_CAP_BOOT / PCIE_PORT_GEN_CAP_MAX + * @param[in] Engine Pointer to engine config descriptor + * @retval PcieGen1/PcieGen2 Max supported link gen capability + */ +PCIE_LINK_SPEED_CAP +PcieGetLinkSpeedCapKB ( + IN UINT32 Flags, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + PCIE_LINK_SPEED_CAP LinkSpeedCapability; + PCIe_WRAPPER_CONFIG *Wrapper; + PCIe_PLATFORM_CONFIG *Pcie; + + Wrapper = PcieConfigGetParentWrapper (Engine); + Pcie = PcieConfigGetPlatform (Wrapper); + + LinkSpeedCapability = PcieGen2; + + if (Engine->Type.Port.PortData.LinkSpeedCapability == PcieGenMaxSupported) { + Engine->Type.Port.PortData.LinkSpeedCapability = (UINT8) LinkSpeedCapability; + } + if (Pcie->PsppPolicy == PsppPowerSaving) { + LinkSpeedCapability = PcieGen1; + } + if (Engine->Type.Port.PortData.LinkSpeedCapability < LinkSpeedCapability) { + LinkSpeedCapability = Engine->Type.Port.PortData.LinkSpeedCapability; + } + if ((Flags & PCIE_PORT_GEN_CAP_BOOT) != 0) { + + if (( Pcie->PsppPolicy == PsppBalanceLow || + Engine->Type.Port.PortData.MiscControls.LinkSafeMode == PcieGen1) + && !PcieConfigIsSbPcieEngine (Engine)) { + + LinkSpeedCapability = PcieGen1; + } + } + return LinkSpeedCapability; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Family specific time stamp function + * + * + * @param[in] StdHeader Standard configuration header + * @retval Count + */ +UINT32 +GnbTimeStampKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TimeStamp; + + TimeStamp = 0; + + GnbLibPciIndirectRead ( + MAKE_SBDFO (0, 0, 0, 0, 0xE0), + 0x13080F0, + AccessWidth32, + &TimeStamp, + StdHeader + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbTsKb: %08x\n", TimeStamp); + return TimeStamp; + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Limit MaxPayload to 256 for x1 ports + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @retval MaxPayload MaxPayloadSupport + */ +UINT8 +PcieMaxPayloadKB ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT8 MaxPayload; + + MaxPayload = MAX_PAYLOAD_512; + if (Engine->EngineData.StartLane == Engine->EngineData.EndLane) { + MaxPayload = MAX_PAYLOAD_256; + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMaxPayloadKB Exit with MaxPayload = %d for StartLane = %d and EndLane = %d\n", MaxPayload, Engine->EngineData.StartLane, Engine->EngineData.EndLane); + return MaxPayload; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Select master PLL + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[out] ConfigChanged Pointer to boolean indicator that configuration was changed + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieTopologySelectMasterPllKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + OUT BOOLEAN *ConfigChanged, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT16 MasterLane; + UINT16 MasterHotplugLane; + UINT16 EngineMasterLane; + D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; + D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013_BASE; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); + MasterLane = 0xFFFF; + MasterHotplugLane = 0xFFFF; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieConfigIsEngineAllocated (EngineList) && EngineList->Type.Port.PortData.PortPresent != PortDisabled && PcieConfigIsPcieEngine (EngineList)) { + EngineMasterLane = PcieConfigGetPcieEngineMasterLane (EngineList); + if (EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + MasterHotplugLane = (EngineMasterLane < MasterHotplugLane) ? EngineMasterLane : MasterHotplugLane; + } else { + MasterLane = (EngineMasterLane < MasterLane) ? EngineMasterLane : MasterLane; + if (PcieConfigIsSbPcieEngine (EngineList)) { + break; + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + + if (MasterLane == 0xffff) { + if (MasterHotplugLane != 0xffff) { + MasterLane = MasterHotplugLane; + } else { + MasterLane = 0x0; + } + } + + D0F0xE4_WRAP_8013.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8013_BASE.Value = D0F0xE4_WRAP_8013.Value; + + if (MasterLane <= 3 ) { + Wrapper->MasterPll = GNB_PCIE_MASTERPLL_A; + } else { + Wrapper->MasterPll = GNB_PCIE_MASTERPLL_B; + } + + IDS_OPTION_HOOK (IDS_GNB_PCIE_MASTERPLL_SELECTION, &(Wrapper->MasterPll), GnbLibGetHeader (Pcie)); + + if (Wrapper->MasterPll == GNB_PCIE_MASTERPLL_A) { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x1; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; + } else { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x1; + } + + if (ConfigChanged != NULL) { + *ConfigChanged = (D0F0xE4_WRAP_8013.Value == D0F0xE4_WRAP_8013_BASE.Value) ? FALSE : TRUE; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + D0F0xE4_WRAP_8013.Value, + FALSE, + Pcie + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Exit\n"); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.h new file mode 100644 index 0000000000..0434b7886e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieLibKB.h @@ -0,0 +1,80 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * KB specific PCIe configuration data services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84519 $ @e \$Date: 2012-12-17 11:20:40 -0600 (Mon, 17 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIELIBKB_H_ +#define _PCIELIBKB_H_ + +VOID +PciePifPllConfigureKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePwrPowerDownUnusedLanesKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSetVoltageKB ( + IN PCIE_LINK_SPEED_CAP LinkCap, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT8 +PciePifGetPllPowerUpLatencyKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologySelectMasterPllKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + OUT BOOLEAN *ConfigChanged, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieMidInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieMidInitKB.c new file mode 100644 index 0000000000..ef076477ea --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieMidInitKB.c @@ -0,0 +1,392 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe mid post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 88079 $ @e \$Date: 2013-02-15 15:28:53 -0600 (Fri, 15 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV4.h" +#include "GnbPcieInitLibV5.h" +#include "GnbFamServices.h" +#include "PcieLibKB.h" +#include "PciePortServicesV4.h" +#include "GnbRegistersKB.h" +#include "Filecode.h" + +#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIEMIDINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern CONST PCIE_PORT_REGISTER_TABLE_HEADER ROMDATA PortInitMidTableKB; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PcieMidInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init various features on all active ports + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieMidPortInitCallbackKB ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PciePortProgramRegisterTable (PortInitMidTableKB.Table, PortInitMidTableKB.Length, Engine, TRUE, Pcie); + if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS) || Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + PcieEnableSlotPowerLimitV5 (Engine, Pcie); + } + // If StartLane == 4/7 and EndLane == 7/4, this is GFX port + if (!(((Engine->EngineData.StartLane == 4) && (Engine->EngineData.EndLane == 7)) || + ((Engine->EngineData.StartLane == 7) && (Engine->EngineData.EndLane == 4)))) { + // For GPP ports only set STRAP_MED_yTSx_COUNT=2 + PciePortRegisterRMW ( + Engine, + 0xC0, + 0x30, + 0x2 << 4, + TRUE, + Pcie + ); + } + PcieEnableAspm (Engine, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Master procedure to init various features on all active ports + * + * + * + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_STATUS + * + */ + +AGESA_STATUS +STATIC +PcieMidPortInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + PCIE_LINK_SPEED_CAP GlobalSpeedCap; + Status = AGESA_SUCCESS; + + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieMidPortInitCallbackKB, + NULL, + Pcie + ); + + GlobalSpeedCap = PcieUtilGlobalGenCapability ( + PCIE_PORT_GEN_CAP_BOOT | PCIE_GLOBAL_GEN_CAP_TRAINED_PORTS | PCIE_GLOBAL_GEN_CAP_HOTPLUG_PORTS, + Pcie + ); + + + PcieSetVoltageKB (GlobalSpeedCap, Pcie); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Clock gating + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +STATIC VOID +PciePwrClockGatingKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8011_STRUCT D0F0xE4_WRAP_8011; + D0F0xE4_WRAP_8012_STRUCT D0F0xE4_WRAP_8012; + D0F0xE4_WRAP_8014_STRUCT D0F0xE4_WRAP_8014; + D0F0xE4_WRAP_8015_STRUCT D0F0xE4_WRAP_8015; + D0F0xE4_WRAP_8016_STRUCT D0F0xE4_WRAP_8016; + UINT8 CoreId; + + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrClockGatingKB Enter\n"); + D0F0xE4_WRAP_8014.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8014_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8015.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8015_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8012.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8012_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8011.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8011_ADDRESS), + Pcie + ); + + if (Wrapper->Features.ClkGating == 0x1) { + D0F0xE4_WRAP_8011.Field.TxclkPermGateLatency = 0; + D0F0xE4_WRAP_8011.Field.Reserved_16_16 = 0x1; + D0F0xE4_WRAP_8011.Field.TxclkPermGateEven = 0x1; + D0F0xE4_WRAP_8011.Field.TxclkPermStop = 0; + D0F0xE4_WRAP_8011.Field.TxclkDynGateEnable = 0x1; + D0F0xE4_WRAP_8011.Field.TxclkDynGateLatency = 0; + D0F0xE4_WRAP_8011.Field.TxclkRegsGateEnable = 0x1; + D0F0xE4_WRAP_8011.Field.TxclkRegsGateLatency = 0; + D0F0xE4_WRAP_8011.Field.TxclkLcntGateEnable = 0x1; + + D0F0xE4_WRAP_8012.Field.Pif1xIdleResumeLatency = 0x7; + D0F0xE4_WRAP_8012.Field.Pif1xIdleGateEnable = 0x1; + D0F0xE4_WRAP_8012.Field.Pif1xIdleGateLatency = 0; + + D0F0xE4_WRAP_8014.Field.TxclkPermGateEnable = 0x1; + D0F0xE4_WRAP_8014.Field.TxclkPrbsGateEnable = 0x1; + D0F0xE4_WRAP_8014.Field.PcieGatePifA1xEnable = 0x1; + D0F0xE4_WRAP_8014.Field.PcieGatePifB1xEnable = 0x1; + + } + + if (Wrapper->Features.TxclkGatingPllPowerDown == 0x1) { + D0F0xE4_WRAP_8014.Field.TxclkPermGateOnlyWhenPllPwrDn = 0x1; + } + + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8014_ADDRESS), + D0F0xE4_WRAP_8014.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8015_ADDRESS), + D0F0xE4_WRAP_8015.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8012_ADDRESS), + D0F0xE4_WRAP_8012.Value, + TRUE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8011_ADDRESS), + D0F0xE4_WRAP_8011.Value, + TRUE, + Pcie + ); + + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + PcieRegisterWriteField ( + Wrapper, + CORE_SPACE (CoreId, D0F0xE4_CORE_0011_ADDRESS), + D0F0xE4_CORE_0011_DynClkLatency_OFFSET, + D0F0xE4_CORE_0011_DynClkLatency_WIDTH, + 0xf, + TRUE, + Pcie + ); + } + + if (Wrapper->Features.LclkGating == 0x1) { + D0F0xE4_WRAP_8016.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8016_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8016.Field.LclkDynGateEnable = 0x1; + D0F0xE4_WRAP_8016.Field.LclkGateFree = 0x1; + D0F0xE4_WRAP_8016.Field.LclkDynGateLatency = 0x3F; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8016_ADDRESS), + D0F0xE4_WRAP_8016.Value, + TRUE, + Pcie + ); + } + + IDS_HDT_CONSOLE (GNB_TRACE, "PciePwrClockGatingKB Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Per wrapper Pcie Late Init. + * + * + * @param[in] Wrapper Pointer to wrapper configuration descriptor + * @param[in] Buffer Pointer buffer + * @param[in] Pcie Pointer to global PCIe configuration + */ +AGESA_STATUS +STATIC +PcieMidInitCallbackKB ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PciePwrPowerDownUnusedLanesKB (Wrapper, Pcie); + PciePwrClockGatingKB (Wrapper, Pcie); + PcieLockRegisters (Wrapper, Pcie); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Pcie Late Init + * + * Late PCIe initialization + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ + +AGESA_STATUS +STATIC +PcieMidInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMidInitKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + + Status = PcieConfigRunProcForAllWrappers (DESCRIPTOR_ALL_WRAPPERS, PcieMidInitCallbackKB, NULL, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMidInitKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe Mid Init + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ +AGESA_STATUS +PcieMidInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMidInterfaceKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + PciePortsVisibilityControlV5 (UnhidePorts, Pcie); + + Status = PcieMidPortInitKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + Status = PcieMidInitKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + PciePortsVisibilityControlV5 (HidePorts, Pcie); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMidInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PciePostInitKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PciePostInitKB.c new file mode 100644 index 0000000000..77fb825982 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PciePostInitKB.c @@ -0,0 +1,470 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe post initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbPcieConfig.h" +#include "GnbPcieTrainingV2.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV4.h" +#include "GnbPcieInitLibV5.h" +#include "PcieLibKB.h" +#include "GnbRegistersKB.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBINITKB_PCIEPOSTINITKB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PciePostEarlyInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PciePostInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieLateRestoreInitKBS3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID* Context + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init various features on all ports + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PciePostPortInitCallbackKB ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_LINK_SPEED_CAP LinkSpeedCapability; + ASSERT (Engine->EngineData.EngineType == PciePortEngine); + if (Engine->Type.Port.PortData.MiscControls.LinkSafeMode == PcieGen1) { + PcieLinkSafeMode (Engine, Pcie); + } + LinkSpeedCapability = PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_BOOT, Engine); + PcieSetLinkSpeedCapV4 (LinkSpeedCapability, Engine, Pcie); + if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS) && (LinkSpeedCapability > PcieGen1) && !PcieConfigIsSbPcieEngine (Engine)) { + PcieTrainingSetPortState (Engine, LinkStateRetrain, FALSE, Pcie); + PcieConfigUpdatePortStatus (Engine, 0, INIT_STATUS_PCIE_TRAINING_SUCCESS); + } + if (Engine->Type.Port.PortData.MiscControls.LinkComplianceMode == 0x1) { + PcieForceCompliance (Engine, Pcie); + PcieTrainingSetPortState (Engine, LinkStateResetExit, FALSE, Pcie); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init various features on all ports + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PciePostS3PortInitCallbackKB ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_LINK_SPEED_CAP LinkSpeedCapability; + PCIE_LINK_TRAINING_STATE State; + + ASSERT (Engine->EngineData.EngineType == PciePortEngine); + + LinkSpeedCapability = PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_BOOT, Engine); + PcieSetLinkSpeedCapV4 (LinkSpeedCapability, Engine, Pcie); + + if (Engine->Type.Port.PortData.MiscControls.LinkSafeMode == PcieGen1) { + PcieLinkSafeMode (Engine, Pcie); + } + + if (!PcieConfigIsSbPcieEngine (Engine)) { + // + // General Port + // + State = LinkStateDeviceNotPresent; + if (Engine->Type.Port.PortData.LinkHotplug == HotplugDisabled || Engine->Type.Port.PortData.LinkHotplug == HotplugInboard) { + // + // Non hotplug device: we only check status from previous boot + // + if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + State = LinkStateResetExit; + } + } else { + UINT32 PcieScratch; + // + // Get endpoint staus from scratch + // + PcieScratch = PciePortRegisterRead (Engine, 0x1, Pcie); + // + // Hotplug device: we check ep status if reported + // + if ((PcieScratch & 0x1) == 0) { + State = LinkStateResetExit; + } + } + // + // For compliance we always leave link in enabled state + // + if (Engine->Type.Port.PortData.MiscControls.LinkComplianceMode) { + State = LinkStateResetExit; + } + PcieConfigUpdatePortStatus (Engine, 0, INIT_STATUS_PCIE_TRAINING_SUCCESS); + } else { + // + // SB port + // + State = LinkStateTrainingSuccess; + } + PcieTrainingSetPortState (Engine, State, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Master procedure to init various features on all active ports + * + * + * + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_STATUS + * + */ + +AGESA_STATUS +STATIC +PciePostEarlyPortInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + Status = AGESA_SUCCESS; + // Distributed Training started at PciePortInit complete it now to get access to PCIe devices + if (Pcie->TrainingAlgorithm == PcieTrainingDistributed) { + Pcie->TrainingExitState = LinkStateTrainingCompleted; + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Master procedure to init various features on all active ports + * + * + * + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_STATUS + * + */ + +AGESA_STATUS +STATIC +PciePostPortInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + Status = AGESA_SUCCESS; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PciePostPortInitCallbackKB, + NULL, + Pcie + ); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Master procedure to init various features on all active ports + * + * + * + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_STATUS + * + */ + +AGESA_STATUS +STATIC +PciePostS3PortInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + Status = AGESA_SUCCESS; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PciePostS3PortInitCallbackKB, + NULL, + Pcie + ); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Pcie Init + * + * + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ + +AGESA_STATUS +STATIC +PciePostInitKB ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_LINK_SPEED_CAP GlobalSpeedCap; + + GlobalSpeedCap = PcieUtilGlobalGenCapability ( + PCIE_PORT_GEN_CAP_BOOT | PCIE_GLOBAL_GEN_CAP_TRAINED_PORTS | PCIE_GLOBAL_GEN_CAP_HOTPLUG_PORTS, + Pcie + ); + + + PcieSetVoltageKB (GlobalSpeedCap, Pcie); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe Post Init + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ +AGESA_STATUS +PciePostEarlyInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePostEarlyInterfaceKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + IDS_OPTION_HOOK (IDS_BEFORE_GPP_TRAINING, Pcie, StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + PciePortsVisibilityControlV5 (UnhidePorts, Pcie); + + Status = PciePostEarlyPortInitKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + Status = PcieTraining (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + PciePortsVisibilityControlV5 (HidePorts, Pcie); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePostEarlyInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe Post Init + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ +AGESA_STATUS +PciePostInterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePostInterfaceKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + IDS_OPTION_HOOK (IDS_BEFORE_GEN2_INIT, Pcie, StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + PciePortsVisibilityControlV5 (UnhidePorts, Pcie); + + Status = PciePostInitKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + Status = PciePostPortInitKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + Status = PcieTraining (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + PciePortsVisibilityControlV5 (HidePorts, Pcie); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePostInterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe Post Init + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ +STATIC AGESA_STATUS +PciePostS3InterfaceKB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePostS3InterfaceKB Enter\n"); + AgesaStatus = AGESA_SUCCESS; + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + PciePortsVisibilityControlV5 (UnhidePorts, Pcie); + + Status = PciePostInitKB (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + if (Pcie->TrainingAlgorithm == PcieTrainingDistributed) { + Status = PciePostS3PortInitKB (Pcie); + } else { + Status = PciePostPortInitKB (Pcie); + } + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + Status = PcieTraining (Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + ASSERT (Status == AGESA_SUCCESS); + + PciePortsVisibilityControlV5 (HidePorts, Pcie); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePostS3InterfaceKB Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIe S3 restore + * + * + * + * @param[in] StdHeader Standard configuration header + * @param[in] ContextLength Context Length (not used) + * @param[in] Context Context pointer (not used) + */ +VOID +PcieLateRestoreInitKBS3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID* Context + ) +{ + PciePostS3InterfaceKB (StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieTablesKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieTablesKB.c new file mode 100644 index 0000000000..10f882808a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/PcieTablesKB.c @@ -0,0 +1,225 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe init tables. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85361 $ @e \$Date: 2013-01-07 11:15:28 -0600 (Mon, 07 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbRegistersKB.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T A B L E S + *---------------------------------------------------------------------------------------- + */ + +STATIC PCIE_HOST_REGISTER_ENTRY PcieInitEarlyTable ROMDATA[] = { + { + PHY_SPACE (0, 0, D0F0xE4_PHY_4440_ADDRESS), + D0F0xE4_PHY_4440_PllDbgRoIPFDResetCntrl_MASK, + 0x2 << D0F0xE4_PHY_4440_PllDbgRoIPFDResetCntrl_OFFSET + }, + { + PHY_SPACE (0, 0, D0F0xE4_PHY_4450_ADDRESS), + D0F0xE4_PHY_4450_PllCfgROVTOIBiasCntrlOvrdVal0_MASK | + D0F0xE4_PHY_4450_PllCfgROBWCntrlOvrdVal0_MASK, + (0x0 << D0F0xE4_PHY_4450_PllCfgROVTOIBiasCntrlOvrdVal0_OFFSET) | (0x90 << D0F0xE4_PHY_4450_PllCfgROBWCntrlOvrdVal0_OFFSET) + }, + { + PHY_SPACE (0, 0, D0F0xE4_PHY_0004_ADDRESS), + D0F0xE4_PHY_0004_CfgIdleDetTh_MASK, + 0x0 << D0F0xE4_PHY_0004_CfgIdleDetTh_OFFSET + } + }; + +CONST PCIE_HOST_REGISTER_TABLE_HEADER ROMDATA PcieInitEarlyTableKB = { + &PcieInitEarlyTable[0], + sizeof (PcieInitEarlyTable) / sizeof (PCIE_HOST_REGISTER_ENTRY) +}; + +STATIC PCIE_HOST_REGISTER_ENTRY ROMDATA CoreInitTable [] = { + { + D0F0xE4_CORE_0020_ADDRESS, + D0F0xE4_CORE_0020_CiRcOrderingDis_MASK | + D0F0xE4_CORE_0020_CiSlvOrderingDis_MASK, + (0x1 << D0F0xE4_CORE_0020_CiRcOrderingDis_OFFSET) + }, + { + D0F0xE4_CORE_0010_ADDRESS, + D0F0xE4_CORE_0010_RxUmiAdjPayloadSize_MASK, + (0x4 << D0F0xE4_CORE_0010_RxUmiAdjPayloadSize_OFFSET) + }, + { + D0F0xE4_CORE_001C_ADDRESS, + D0F0xE4_CORE_001C_TxArbRoundRobinEn_MASK | + D0F0xE4_CORE_001C_TxArbSlvLimit_MASK | + D0F0xE4_CORE_001C_TxArbMstLimit_MASK, + (0x1 << D0F0xE4_CORE_001C_TxArbRoundRobinEn_OFFSET) | + (0x4 << D0F0xE4_CORE_001C_TxArbSlvLimit_OFFSET) | + (0x4 << D0F0xE4_CORE_001C_TxArbMstLimit_OFFSET) + }, + { + D0F0xE4_CORE_0040_ADDRESS, + D0F0xE4_CORE_0040_PElecIdleMode_MASK, + (0x1 << D0F0xE4_CORE_0040_PElecIdleMode_OFFSET) + }, + { + D0F0xE4_CORE_0002_ADDRESS, + D0F0xE4_CORE_0002_HwDebug_0_MASK, + (0x1 << D0F0xE4_CORE_0002_HwDebug_0_OFFSET) + }, + { + D0F0xE4_CORE_00C1_ADDRESS, + D0F0xE4_CORE_00C1_StrapLinkBwNotificationCapEn_MASK | + D0F0xE4_CORE_00C1_StrapGen2Compliance_MASK, + (0x1 << D0F0xE4_CORE_00C1_StrapLinkBwNotificationCapEn_OFFSET) | + (0x1 << D0F0xE4_CORE_00C1_StrapGen2Compliance_OFFSET) + }, + { + D0F0xE4_CORE_00B0_ADDRESS, + D0F0xE4_CORE_00B0_StrapF0MsiEn_MASK | + D0F0xE4_CORE_00B0_StrapF0AerEn_MASK, + (0x1 << D0F0xE4_CORE_00B0_StrapF0MsiEn_OFFSET) | (0x0 << D0F0xE4_CORE_00B0_StrapF0AerEn_OFFSET) + } +}; + +CONST PCIE_HOST_REGISTER_TABLE_HEADER ROMDATA CoreInitTableKB = { + &CoreInitTable[0], + sizeof (CoreInitTable) / sizeof (PCIE_HOST_REGISTER_ENTRY) +}; + + +STATIC PCIE_PORT_REGISTER_ENTRY ROMDATA PortInitEarlyTable [] = { + { + DxFxxE4_x70_ADDRESS, + DxFxxE4_x70_RxRcbCplTimeoutMode_MASK, + (0x1 << DxFxxE4_x70_RxRcbCplTimeoutMode_OFFSET) + }, + { + DxFxxE4_xA0_ADDRESS, + DxFxxE4_xA0_Lc16xClearTxPipe_MASK | DxFxxE4_xA0_LcL1ImmediateAck_MASK | DxFxxE4_xA0_LcL0sInactivity_MASK, + (0x1 << DxFxxE4_xA0_Lc16xClearTxPipe_OFFSET) | + (0x1 << DxFxxE4_xA0_LcL1ImmediateAck_OFFSET) | + (0x6 << DxFxxE4_xA0_LcL0sInactivity_OFFSET) + }, + { + DxFxxE4_xA1_ADDRESS, + DxFxxE4_xA1_LcDontGotoL0sifL1Armed_MASK, + (0x1 << DxFxxE4_xA1_LcDontGotoL0sifL1Armed_OFFSET) + }, + { + DxFxxE4_xA2_ADDRESS, + DxFxxE4_xA2_LcRenegotiateEn_MASK | DxFxxE4_xA2_LcUpconfigureSupport_MASK, + (0x1 << DxFxxE4_xA2_LcRenegotiateEn_OFFSET) | + (0x1 << DxFxxE4_xA2_LcUpconfigureSupport_OFFSET) + }, + { + DxFxxE4_xA3_ADDRESS, + DxFxxE4_xA3_LcXmitFtsBeforeRecovery_MASK, + (0x1 << DxFxxE4_xA3_LcXmitFtsBeforeRecovery_OFFSET) + }, + { + DxFxxE4_xB1_ADDRESS, + DxFxxE4_xB1_LcElecIdleMode_MASK | + DxFxxE4_xB1_LcDeassertRxEnInL0s_MASK | + DxFxxE4_xB1_LcBlockElIdleinL0_MASK, + (0x1 << DxFxxE4_xB1_LcElecIdleMode_OFFSET) | + (0x1 << DxFxxE4_xB1_LcDeassertRxEnInL0s_OFFSET) | + (0x1 << DxFxxE4_xB1_LcBlockElIdleinL0_OFFSET) + }, + { + 0xC0, + 0x70000, + (0x1 << 16) + } +}; + +CONST PCIE_PORT_REGISTER_TABLE_HEADER ROMDATA PortInitEarlyTableKB = { + &PortInitEarlyTable[0], + sizeof (PortInitEarlyTable) / sizeof (PCIE_PORT_REGISTER_ENTRY) +}; + + +STATIC PCIE_PORT_REGISTER_ENTRY ROMDATA PortInitMidTable [] = { + { + DxFxxE4_xA2_ADDRESS, + DxFxxE4_xA2_LcDynLanesPwrState_MASK, + (0x3 << DxFxxE4_xA2_LcDynLanesPwrState_OFFSET) + }, + { + DxFxxE4_x6A_ADDRESS, + DxFxxE4_x6A_ErrReportingDis_MASK, + (0x1 << DxFxxE4_x6A_ErrReportingDis_OFFSET) + }, +// { +// 0xC0, +// DxFxxE4_xC0_StrapAutoRcSpeedNegotiationDis_MASK, +// (0x1 << DxFxxE4_xC0_StrapAutoRcSpeedNegotiationDis_OFFSET) +// } +}; + +CONST PCIE_PORT_REGISTER_TABLE_HEADER ROMDATA PortInitMidTableKB = { + &PortInitMidTable[0], + sizeof (PortInitMidTable) / sizeof (PCIE_PORT_REGISTER_ENTRY) +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/excel925.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/excel925.h new file mode 100644 index 0000000000..1d9fc9fe5c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/excel925.h @@ -0,0 +1,113 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * SCS Binary + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85201 $ @e \$Date: 2013-01-03 14:13:50 -0600 (Thu, 03 Jan 2013) $ + * + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +#ifndef _EXCEL925_H_ +#define _EXCEL925_H_ + +UINT8 excel925[] = { + 0x21, 0x53, 0x43, 0x53, 0x4B, 0x41, 0x42, 0x49, 0x4E, 0x49, 0x20, 0x20, 0x56, 0x30, 0x2E, 0x30, + 0x2E, 0x30, 0x2E, 0x31, 0x1 , 0x00, 0x00, 0x4 , 0x00, 0x3 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x16, 0x2 , 0x1 , 0xA5, 0xF7, 0x2D, 0x83, 0x4E, 0xC3, 0xC3, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0x3F, 0x2 , 0x1 , 0x80, 0x00, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB8, 0x59, 0x00, 0x00, 0x92, 0x00, 0x96, 0xB8, 0x00, 0xC3, 0x00, 0xB5, 0x54, 0xB4, 0x8B, 0x62, + 0xB5, 0x00, 0xC4, 0xC1, 0x00, 0xA6, 0x55, 0x00, 0x00, 0xC7, 0x00, 0x38, 0x3C, 0x71, 0x4C, 0xB0, + 0x00, 0x00, 0xB7, 0xC4, 0x00, 0xB5, 0x86, 0xA4, 0x00, 0xC4, 0x00, 0x9B, 0xCB, 0x9D, 0x85, 0xC2, + 0xFF, 0x86, 0xD4, 0xC0, 0x00, 0x00, 0xB0, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x3 , 0x1 , 0xC7, 0x50, 0x7A, 0x3F, + 0x4A, 0xBE, 0x9E, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x2 , 0x1 , 0x80, 0x00, + 0x00, 0x91, 0x00, 0x70, 0x00, 0x00, 0x98, 0x98, 0x9F, 0x9F, 0x00, 0x00, 0x43, 0x43, 0x43, 0x43, + 0x97, 0x00, 0xB4, 0x00, 0x00, 0x00, 0xAE, 0x00, 0x00, 0x00, 0x9E, 0x93, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x00, 0xA5, 0xA5, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xA2, 0xA2, 0xA2, 0x00, 0x90, 0xDA, 0x96, + 0x8D, 0x8D, 0x8D, 0x8D, 0x90, 0x00, 0xFF, 0x00, 0xE6, 0x00, 0xDA, 0x4E, 0x00, 0x89, 0x89, 0x00, + 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x99, 0xA9, 0x91, 0x98, 0xC9, 0x00, 0x00, + 0x00, 0x16, 0x4 , 0x1 , 0xCC, 0xBF, 0x86, 0xAD, 0x43, 0x3A, 0x9D, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0x3F, 0x2 , 0x1 , 0x80, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xB2, + 0x7E, 0x7E, 0x00, 0x00, 0x97, 0x97, 0x97, 0x97, 0xA0, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xBA, 0x00, + 0x00, 0x00, 0x9D, 0x57, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0xA8, 0xA8, 0x00, 0x00, 0x4 , 0x4 , + 0xAB, 0xAB, 0xAB, 0xAB, 0x00, 0x00, 0xDE, 0x00, 0x75, 0x75, 0x75, 0x75, 0x64, 0x91, 0xFF, 0x00, + 0xE0, 0xE4, 0x95, 0x00, 0x00, 0x80, 0x80, 0xE9, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x95, 0xA5, 0xB5, 0xDE, 0x00, 0xB9, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif // _EXCEL925_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbIoapic/GnbIoapic.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbIoapic/GnbIoapic.c new file mode 100644 index 0000000000..3a7c6ac8b2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbIoapic/GnbIoapic.c @@ -0,0 +1,224 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB IOAPIC Initialization + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "PcieConfigLib.h" +#include "Filecode.h" +#include "GnbRegistersCommonV2.h" +#define FILECODE PROC_GNB_MODULES_GNBIOAPIC_GNBIOAPIC_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GnbNbIoapicInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init IOAPIC on GNB port + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +IoapicInitCallbackV5 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCI_ADDR GnbPciAddress; + D0F0xFC_x10_STRUCT D0F0xFC_x10; + + GnbPciAddress = GnbGetHostPciAddress ((GNB_HANDLE *) PcieConfigGetParent (DESCRIPTOR_SILICON, &Engine->Header)); + D0F0xFC_x10.Value = 0x0; + + // Bounds check values - make sure the value is small enough to fit the field size + ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.GroupMap < (1 << D0F0xFC_x10_BrExtIntrGrp_WIDTH)); + ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.Swizzle < (1 << D0F0xFC_x10_BrExtIntrSwz_WIDTH)); + ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.BridgeInt < (1 << D0F0xFC_x10_BrIntIntrMap_WIDTH)); + + // Get the configuration from the PCIe_PORT_DATA APIC_DEVICE_INFO struct + D0F0xFC_x10.Field.BrExtIntrGrp = Engine->Type.Port.PortData.ApicDeviceInfo.GroupMap; + D0F0xFC_x10.Field.BrExtIntrSwz = Engine->Type.Port.PortData.ApicDeviceInfo.Swizzle; + D0F0xFC_x10.Field.BrIntIntrMap = Engine->Type.Port.PortData.ApicDeviceInfo.BridgeInt; + + // Write the register + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, + D0F0xFC_x10_ADDRESS + Engine->Type.Port.LogicalBridgeId, + AccessS3SaveWidth32, + &D0F0xFC_x10.Value, + GnbLibGetHeader (Pcie) + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to Enable IOAPIC on GNB + * + * + * + * @param[in] Descriptor Silicon descriptor + * @param[in] Buffer Pointer to buffer + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_STATUS + */ +STATIC AGESA_STATUS +IoapicEnableCallbackV5 ( + IN PCIe_DESCRIPTOR_HEADER *Descriptor, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCI_ADDR GnbPciAddress; + D0F0xFC_x00_STRUCT D0F0xFC_x00; + UINT32 *AddressPtr; + UINT32 AddressLow; + UINT32 AddressHigh; + + D0F0xFC_x00.Value = 0x0; + D0F0xFC_x00.Field.IoapicEnable = 1; + // Set the extended ID enable (default) + D0F0xFC_x00.Field.IoapicIdExtEn = 1; + // Enable SB feature for every APIC. ACPI OS may disable this once the OS boots + D0F0xFC_x00.Field.IoapicSbFeatureEn = 1; + AddressPtr = (UINT32*) Buffer; + AddressLow = AddressPtr[0] & 0xFFFFFF00; + AddressHigh = AddressPtr[1]; + // Get the PCI address of the GNB + GnbPciAddress = GnbGetHostPciAddress (GnbGetHandle (GnbLibGetHeader (Pcie))); + // If the BLDCFG base address is null, assume that the base address of the APIC has already been programmed + // If base address is defined in BLDCFG, program it here + if ((AddressLow != 0) || (AddressHigh != 0)) { + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, + D0F0xFC_x01_ADDRESS, + AccessS3SaveWidth32, + &AddressLow, + GnbLibGetHeader (Pcie) + ); + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, + D0F0xFC_x02_ADDRESS, + AccessS3SaveWidth32, + &AddressHigh, + GnbLibGetHeader (Pcie) + ); + } + // Enable the IOAPIC. + GnbLibPciIndirectWrite ( + GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, + D0F0xFC_x00_ADDRESS, + AccessS3SaveWidth32, + &D0F0xFC_x00.Value, + GnbLibGetHeader (Pcie) + ); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init NB IOAPIC + * + * + * + * @param[in] StdHeader Standard Configuration Header + */ + +AGESA_STATUS +GnbNbIoapicInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_MID_PARAMS *MidParamsPtr; + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + UINT64 GnbNbIoapicAddress; + IDS_HDT_CONSOLE (GNB_TRACE, "GnbNbIoapicInterface Enter\n"); + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + if (Status == AGESA_SUCCESS) { + MidParamsPtr = (AMD_MID_PARAMS *) StdHeader; + GnbNbIoapicAddress = MidParamsPtr->GnbMidConfiguration.GnbIoapicAddress; + // For each ENGINE, configure the group, swizzle, and pin per APIC_DEVICE_INFO + PcieConfigRunProcForAllEngines (DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, IoapicInitCallbackV5, NULL, Pcie); + + // For each GNB, configure the IOAPIC Enable, ID Size, and SB Feature Enable + Status = PcieConfigRunProcForAllDescriptors (DESCRIPTOR_SILICON, 0, DESCRIPTOR_TERMINATE_TOPOLOGY, IoapicEnableCallbackV5, &GnbNbIoapicAddress, Pcie); + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbNbIoapicInterface Exit\n"); + return Status; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.h new file mode 100644 index 0000000000..42956570b7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV1/GnbNbInitLibV1.h @@ -0,0 +1,99 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBNBINITLIBV1_H_ +#define _GNBNBINITLIBV1_H_ + + +AGESA_STATUS +GnbSetTom ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLpcDmaDeadlockPrevention ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbOrbDynamicWake ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLock ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbClumpUnitID ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +UINT8 +GnbLocateLowestVidIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidCode ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateLowestVidCode ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.c new file mode 100644 index 0000000000..b26679bb49 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.c @@ -0,0 +1,386 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "S3SaveState.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbNbInitLibV4.h" +#include "GnbRegistersCommonV2.h" +#include "heapManager.h" +#include "GnbFamServices.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBNBINITLIBV4_GNBNBINITLIBV4_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +#define SMC_RAM_START_ADDR 0x10000ul + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +typedef struct { + GNB_PCI_SCAN_DATA ScanData; + GNB_TOPOLOGY_INFO *TopologyInfo; +} GNB_TOPOLOGY_INFO_DATA; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GnbSmuServiceRequestV4S3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID *Context + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Check a PCIE device to see if it supports phantom functions + * + * @param[in] Device Device pci address + * @param[in] StdHeader Standard configuration header + * @return TRUE Current device supports phantom functions + */ +STATIC BOOLEAN +GnbCheckPhantomFuncSupport ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PcieCapPtr; + UINT32 Value; + Value = 0; + + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr != 0) { + GnbLibPciRead (Device.AddressValue | (PcieCapPtr + 4), AccessWidth32, &Value, StdHeader); + } + return ((Value & (BIT3 | BIT4)) != 0) ? TRUE : FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Evaluate device + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status + */ + +SCAN_STATUS +STATIC +GnbTopologyInfoScanCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + SCAN_STATUS ScanStatus; + GNB_TOPOLOGY_INFO_DATA *GnbTopologyInfo; + PCIE_DEVICE_TYPE DeviceType; + ScanStatus = SCAN_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, " GnbIommuInfoScanCallback for Device = %d:%d:%d\n", + Device.Address.Bus, + Device.Address.Device, + Device.Address.Function + ); + GnbTopologyInfo = (GNB_TOPOLOGY_INFO_DATA *)ScanData; + ScanStatus = SCAN_SUCCESS; + DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader); + switch (DeviceType) { + case PcieDeviceRootComplex: + case PcieDeviceDownstreamPort: + GnbLibPciScanSecondaryBus (Device, &GnbTopologyInfo->ScanData); + break; + case PcieDeviceUpstreamPort: + GnbLibPciScanSecondaryBus (Device, &GnbTopologyInfo->ScanData); + ScanStatus = SCAN_SKIP_FUNCTIONS | SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + case PcieDevicePcieToPcix: + GnbTopologyInfo->TopologyInfo->PcieToPciexBridge = TRUE; + ScanStatus = SCAN_SKIP_FUNCTIONS | SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + case PcieDeviceEndPoint: + case PcieDeviceLegacyEndPoint: + if (GnbCheckPhantomFuncSupport (Device, ScanData->StdHeader)) { + GnbTopologyInfo->TopologyInfo->PhantomFunction = TRUE; + } + ScanStatus = SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + default: + break; + } + return ScanStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get IOMMU topology info + * + * + * + * @param[in] StartPciAddress Start PCI address + * @param[in] EndPciAddress End PCI address + * @param[in] TopologyInfo Topology info structure + * @param[in] StdHeader Standard Configuration Header + */ + +AGESA_STATUS +GnbGetTopologyInfoV4 ( + IN PCI_ADDR StartPciAddress, + IN PCI_ADDR EndPciAddress, + OUT GNB_TOPOLOGY_INFO *TopologyInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GNB_TOPOLOGY_INFO_DATA GnbTopologyInfo; + IDS_HDT_CONSOLE (GNB_TRACE, "GnbGetTopologyInfoV4 Enter\n"); + GnbTopologyInfo.ScanData.GnbScanCallback = GnbTopologyInfoScanCallback; + GnbTopologyInfo.ScanData.StdHeader = StdHeader; + GnbTopologyInfo.TopologyInfo = TopologyInfo; + GnbLibPciScan (StartPciAddress, EndPciAddress, &GnbTopologyInfo.ScanData); + IDS_HDT_CONSOLE (GNB_TRACE, "GnbGetTopologyInfoV4 Exit\n"); + return AGESA_SUCCESS; +} + + + +/*----------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------*/ +/** + * SMU firmware download + * + * + * @param[in] GnbPciAddress GNB Pci Address + * @param[in] Firmware Pointer tp firmware + * @param[in] StdHeader Standard configuration header + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get IOMMU PCI address + * + * + * @param[in] GnbHandle GNB handle + * @param[in] StdHeader Standard configuration header + */ + +PCI_ADDR +GnbGetIommuPciAddressV4 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR GnbIommuPciAddress; + GnbIommuPciAddress = GnbGetHostPciAddress (GnbHandle); + GnbIommuPciAddress.Address.Function = 0x2; + return GnbIommuPciAddress; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * UnitID Clumping + * + * + * @param[in] GnbHandle GNB handle + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbClumpUnitIdV4 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + PCIe_ENGINE_CONFIG *EngineList; + UINT32 Value; + + Value = 0; + EngineList = (PCIe_ENGINE_CONFIG *) PcieConfigGetChild (DESCRIPTOR_PCIE_ENGINE, &GnbHandle->Header); + while (EngineList != NULL) { + if (EngineList->Type.Port.NumberOfUnitId != 0) { + if (!PcieConfigIsActivePcieEngine (EngineList)) { + Value |= (((1 << EngineList->Type.Port.NumberOfUnitId) - 1) << EngineList->Type.Port.UnitId); + } else { + if (EngineList->Type.Port.NumberOfUnitId > 1) { + Value |= (((1 << (EngineList->Type.Port.NumberOfUnitId - 1)) - 1) << (EngineList->Type.Port.UnitId + 1)); + } + } + } + EngineList = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (EngineList, DESCRIPTOR_TERMINATE_GNB); + } + // Set GNB + GnbLibPciIndirectRMW ( + GnbHandle->Address.AddressValue | D0F0x94_ADDRESS, + D0F0x98_x3A_ADDRESS, + AccessS3SaveWidth32, + (UINT32) ~Value, + Value, + StdHeader + ); + //Set UNB + GnbLibPciRMW ( + MAKE_SBDFO (0, 0, GnbHandle->NodeId + 0x18, 0, D18F0x110_ADDRESS + GnbHandle->LinkId * 4), + AccessS3SaveWidth32, + (UINT32) ~Value, + Value, + StdHeader + ); +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Config GNB to prevent LPC deadlock scenario + * + * + * @param[in] GnbHandle GNB handle + * @param[in] StdHeader Standard configuration header + */ + +VOID +GnbLpcDmaDeadlockPreventionV4 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_ENGINE_CONFIG *EngineList; + + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &GnbHandle->Header); + EngineList = (PCIe_ENGINE_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_ENGINES, &GnbHandle->Header); + while (EngineList != NULL) { + if (PcieConfigIsPcieEngine (EngineList) && PcieConfigIsSbPcieEngine (EngineList)) { + PcieRegisterRMW ( + PcieConfigGetParentWrapper (EngineList), + CORE_SPACE (EngineList->Type.Port.CoreId, D0F0xE4_CORE_0010_ADDRESS), + D0F0xE4_CORE_0010_UmiNpMemWrite_MASK, + 1 << D0F0xE4_CORE_0010_UmiNpMemWrite_OFFSET, + TRUE, + Pcie + ); + //Enable special NP memory write protocol in ORB + GnbLibPciIndirectRMW ( + GnbHandle->Address.AddressValue | D0F0x94_ADDRESS, + D0F0x98_x06_ADDRESS, + AccessS3SaveWidth32, + 0xFFFFFFFF, + 1 << D0F0x98_x06_UmiNpMemWrEn_OFFSET, + StdHeader + ); + break; + } + EngineList = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (EngineList, DESCRIPTOR_TERMINATE_GNB); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable IOMMU base address. (MMIO space ) + * + * + * @param[in] GnbHandle GNB handle + * @param[in] StdHeader Standard Configuration Header + * @retval AGESA_SUCCESS + * @retval AGESA_ERROR + */ + +AGESA_STATUS +GnbEnableIommuMmioV4 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + UINT16 CapabilityOffset; + UINT64 BaseAddress; + UINT32 Value; + PCI_ADDR GnbIommuPciAddress; + + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GnbEnableIommuMmio Enter\n"); + + if (GnbFmCheckIommuPresent (GnbHandle, StdHeader)) { + GnbIommuPciAddress = GnbGetIommuPciAddressV4 (GnbHandle, StdHeader); + CapabilityOffset = GnbLibFindPciCapability (GnbIommuPciAddress.AddressValue, IOMMU_CAP_ID, StdHeader); + + GnbLibPciRead (GnbIommuPciAddress.AddressValue | (CapabilityOffset + 0x4), AccessWidth32, &Value, StdHeader); + BaseAddress = (UINT64) Value << 32; + GnbLibPciRead (GnbIommuPciAddress.AddressValue | (CapabilityOffset + 0x8), AccessWidth32, &Value, StdHeader); + BaseAddress |= Value; + + if ((BaseAddress & 0xfffffffffffffffe) != 0x0) { + IDS_HDT_CONSOLE (GNB_TRACE, " Enable IOMMU MMIO at address %x for Socket %d Silicon %d\n", BaseAddress, GnbGetSocketId (GnbHandle) , GnbGetSiliconId (GnbHandle)); + GnbLibPciRMW (GnbIommuPciAddress.AddressValue | (CapabilityOffset + 0x8), AccessS3SaveWidth32, 0xFFFFFFFF, 0x0, StdHeader); + GnbLibPciRMW (GnbIommuPciAddress.AddressValue | (CapabilityOffset + 0x4), AccessS3SaveWidth32, 0xFFFFFFFE, 0x1, StdHeader); + } else { + ASSERT (FALSE); + Status = AGESA_ERROR; + } + } + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbEnableIommuMmio Exit\n"); + return Status; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.h new file mode 100644 index 0000000000..522a42e665 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV4/GnbNbInitLibV4.h @@ -0,0 +1,122 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBNBINITLIBV4_H_ +#define _GNBNBINITLIBV4_H_ + +#pragma pack (push, 1) + +/// Firmware header +typedef struct { + UINT32 Version; ///< Version + UINT32 HeaderLength; ///< Header length + UINT32 FirmwareLength; ///< Firmware length + UINT32 EntryPoint; ///< Entry point + UINT32 MessageDigest[5]; ///< Message digest + UINT32 Reserved_A[3]; ///< Reserved + UINT32 CurrentSystemState; ///< Current system state + UINT32 DpmCacHistory; ///< DpmCac History + UINT32 DpmResidencyCounters; ///< DPM recidency counters + UINT32 Reserved_B[16]; ///< Reserved + UINT32 Reserved_C[16]; ///< Reserved + UINT32 Reserved_D[16]; ///< Reserved + UINT32 HeaderEnd; ///< Header end signature +} FIRMWARE_HEADER_V4; + +/// SMU service request contect +typedef struct { + PCI_ADDR GnbPciAddress; ///< PCIe address of GNB + UINT8 RequestId; ///< Request/Msg ID +} SMU_MSG_CONTEXT; + +#pragma pack (pop) + +AGESA_STATUS +GnbGetTopologyInfoV4 ( + IN PCI_ADDR StartPciAddress, + IN PCI_ADDR EndPciAddress, + OUT GNB_TOPOLOGY_INFO *TopologyInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbSmuServiceRequestV4 ( + IN PCI_ADDR GnbPciAddress, + IN UINT8 RequestId, + IN UINT32 AccessFlags, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbSmuFirmwareLoadV4 ( + IN PCI_ADDR GnbPciAddress, + IN FIRMWARE_HEADER_V4 *Firmware, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +PCI_ADDR +GnbGetIommuPciAddressV4 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbClumpUnitIdV4 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +GnbLpcDmaDeadlockPreventionV4 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbEnableIommuMmioV4 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c new file mode 100644 index 0000000000..516739aa3c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c @@ -0,0 +1,348 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "Filecode.h" +#include "GnbRegistersCommonV2.h" +#include "GnbF1Table.h" +#define FILECODE PROC_GNB_MODULES_GNBNBINITLIBV5_GNBNBINITLIBV5_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +GnbSetTomV5 ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +UINT8 +GnbLocateLowestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GnbTranslateVidCodeToMillivoltV5 ( + IN UINT8 Vid, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidIndexV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Init NB set top of memory + * + * + * + * @param[in] NbPciAddress Gnb PCI address + * @param[in] StdHeader Standard Configuration Header + */ + +AGESA_STATUS +GnbSetTomV5 ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + UINT64 MsrData; + UINT64 GnbTom2; + UINT64 GnbTom3; + UINT32 Value; + + Status = AGESA_SUCCESS; + //Read memory size below 4G from MSR C001_001A + LibAmdMsrRead (TOP_MEM, &MsrData, StdHeader); + //Write to NB register 0x90 + Value = (UINT32)MsrData & 0xFF800000; //Keep bits 31:23 + GnbLibPciRMW ( + NbPciAddress.AddressValue | D0F0x90_ADDRESS, + AccessS3SaveWidth32, + 0x007FFFFF, + Value, + StdHeader + ); + if (Value == 0) { + Status = AGESA_WARNING; + } + + GnbTom2 = 0; + GnbTom3 = 0; + LibAmdMsrRead (SYS_CFG, &MsrData, StdHeader); + if ((MsrData & BIT21) != 0) { + //If SYS_CFG(MtrrTom2En) then configure GNB TOM2 and TOM3 + //Read memory size above 4G from TOP_MEM2 (MSR C001_001D) + LibAmdMsrRead (TOP_MEM2, &MsrData, StdHeader); + if ((MsrData & (UINT64)0x0000FFFFFFC00000) > ((UINT64)0x0000010000000000)) { + // If TOP_MEM2 is above 1TB, enable GNB TOM2 and TOM3 + // Set TOM2 for below 1TB limit + GnbTom2 = 0x000000FD00000000; + // TOM3 is INCLUSIVE, so set it to TOM - 1 using bits 47:22 + GnbTom3 = (MsrData - 1) & (UINT64)0x0000FFFFFFC00000; + } else { + // If TOP_MEM2 is below 1TB, set TOM2 using bits 39:22 + GnbTom2 = MsrData & (UINT64)0x000000FFFFC00000; //Keep bits 39:22 + // If TOP_MEM2 is below 1TB, disable GNB TOM3 + GnbTom3 = 0; + } + } + + if (GnbTom2 != 0) { + // Write memory size[39:32] to indirect register 1A[7:0] + Value = (UINT32) ((GnbTom2 >> 32) & 0xFF); + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x1A_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0xFFFFFF00, + Value, + StdHeader + ); + // Write memory size[31:23] to indirect register 19[31:23] and enable memory through bit 0 + Value = (UINT32)GnbTom2 & 0xFF800000; //Keep bits 31:23 + Value |= BIT0; // Enable top of memory + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x19_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0x007FFFFF, + Value, + StdHeader + ); + } + + if (GnbTom3 != 0) { + // Above 1TB addressing TOM3 if MSR TOM is above 1TB + // Write memory size[47:22] to indirect register 4E[25:0] and enable memory through bit 31 + Value = (UINT32) (GnbTom3 >> 22); + Value |= BIT31; + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + 0x4e | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0x83FFFFFF, + Value, + StdHeader + ); + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the index of highest SCLK VID + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID index + */ +UINT8 +GnbLocateHighestVidIndexV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxVid; + UINT8 MaxVidIndex; + UINTN Index; + PP_F1_ARRAY_V2 *PpF1Array; + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + if (PpF1Array == NULL) { + IDS_HDT_CONSOLE (GNB_TRACE, " ERROR!!! Heap Location\n"); + return 0; + } + + MaxVidIndex = 0; + MaxVid = 0xff; + for (Index = 0; Index < 5; Index++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index] != 0 && PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index] < MaxVid) { + MaxVid = PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index]; + MaxVidIndex = (UINT8) Index; + } + } + ASSERT (PpF1Array->PP_FUSE_ARRAY_V2_fld32[MaxVidIndex] != 0); + return MaxVidIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the index of lowest SCLK VID + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID index + */ +STATIC UINT8 +GnbLocateLowestVidIndexV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MinVidIndex; + UINTN Index; + PP_F1_ARRAY_V2 *PpF1Array; + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + if (PpF1Array == NULL) { + IDS_HDT_CONSOLE (GNB_TRACE, " ERROR!!! Heap Location\n"); + return 0; + } + + MinVidIndex = 0; + + for (Index = 0; Index < 5; Index++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index] > PpF1Array->PP_FUSE_ARRAY_V2_fld32[MinVidIndex]) { + MinVidIndex = (UINT8) Index; + } + } + ASSERT (PpF1Array->PP_FUSE_ARRAY_V2_fld32[MinVidIndex] != 0); + return MinVidIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the highest SCLK VID (high voltage) + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID + */ +UINT8 +GnbLocateHighestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxVidIndex; + PP_F1_ARRAY_V2 *PpF1Array; + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + + MaxVidIndex = GnbLocateHighestVidIndexV5 (StdHeader); + ASSERT (PpF1Array->PP_FUSE_ARRAY_V2_fld32[MaxVidIndex] != 0); + return PpF1Array->PP_FUSE_ARRAY_V2_fld32[MaxVidIndex]; + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the lowest SCLK VID (low voltage) + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID + */ +UINT8 +GnbLocateLowestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MinVidIndex; + PP_F1_ARRAY_V2 *PpF1Array; + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + MinVidIndex = GnbLocateLowestVidIndexV5 (StdHeader); + ASSERT (PpF1Array->PP_FUSE_ARRAY_V2_fld32[MinVidIndex] != 0); + return PpF1Array->PP_FUSE_ARRAY_V2_fld32[MinVidIndex]; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Translate VID code to millivolt with two fraction bits + * + * + * @param[in] Vid VID code + * @param[in] StdHeader Standard configuration header + * @retval 100 millivolt with two fraction bits + */ + +UINT32 +GnbTranslateVidCodeToMillivoltV5 ( + IN UINT8 Vid, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Millivolt; + + // According to SVI2 spec, Vid Code 0xF7 is 6.25mv. 6.25mv is one boundary value. + if (Vid > 0xF7) { + Vid = 0xF7; + ASSERT (FALSE); + } + + // Equation: VID code increase/decrease 1, there is one 6.25mv change. + // 6.25mv could be described using integer 625 with two fraction bits. + Millivolt = (0xF7 - Vid + 1) * 625; + + return Millivolt; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.h new file mode 100644 index 0000000000..df1eaa9d3f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.h @@ -0,0 +1,80 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBNBINITLIBV5_H_ +#define _GNBNBINITLIBV5_H_ + +AGESA_STATUS +GnbSetTomV5 ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidIndexV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +UINT8 +GnbLocateLowestVidIndexV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateLowestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GnbTranslateVidCodeToMillivoltV5 ( + IN UINT8 Vid, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c new file mode 100644 index 0000000000..0fb763b33a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.c @@ -0,0 +1,463 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87263 $ @e \$Date: 2013-01-31 09:18:06 -0600 (Thu, 31 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbNbInitLibV1.h" +#include "OptionGnb.h" +#include "PcieAlibV2.h" +#include "GnbF1Table.h" +#include "Filecode.h" + +#define FILECODE PROC_GNB_MODULES_GNBPCIEALIBV2_PCIEALIBV2_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern F_ALIB_GET *AlibGetBaseTableV2; +extern F_ALIB_UPDATE *AlibDispatchTableV2[]; +extern GNB_BUILD_OPTIONS ROMDATA GnbBuildOptions; + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +AGESA_STATUS +PcieAlibUpdateGnbData ( + IN OUT VOID *SsdtBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +PcieAlibUpdatePciePortDataCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieAlibBuildAcpiTableV2 ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **AlibSsdtPtr + ); + +AGESA_STATUS +PcieAlibUpdateVoltageData ( + IN OUT VOID *DataBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieAlibUpdatePcieData ( + IN OUT VOID *DataBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Create ACPI ALIB SSDT table + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +PcieAlibV2Feature ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_LATE_PARAMS *LateParamsPtr; + LateParamsPtr = (AMD_LATE_PARAMS*) StdHeader; + return PcieAlibBuildAcpiTableV2 (StdHeader, &LateParamsPtr->AcpiAlib); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build ALIB ACPI table + * + * + * + * @param[in] StdHeader Standard Configuration Header + * @param[in,out] AlibSsdtPtr Pointer to pointer to ALIB SSDT table + * @retval AGESA_SUCCESS + * @retval AGESA_ERROR + */ + +AGESA_STATUS +PcieAlibBuildAcpiTableV2 ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT VOID **AlibSsdtPtr + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + UINTN Index; + VOID *AlibSsdtBuffer; + VOID *AlibSsdtTable; + UINTN AlibSsdtlength; + UINT32 AmlObjName; + VOID *AmlObjPtr; + + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibBuildAcpiTableV2 Enter\n"); + AgesaStatus = AGESA_SUCCESS; + AlibSsdtTable = AlibGetBaseTableV2 (StdHeader); + AlibSsdtlength = ((ACPI_TABLE_HEADER*) AlibSsdtTable)->TableLength; + if (*AlibSsdtPtr == NULL) { + AlibSsdtBuffer = GnbAllocateHeapBuffer ( + AMD_ACPI_ALIB_BUFFER_HANDLE, + AlibSsdtlength, + StdHeader + ); + ASSERT (AlibSsdtBuffer != NULL); + if (AlibSsdtBuffer == NULL) { + return AGESA_ERROR; + } + *AlibSsdtPtr = AlibSsdtBuffer; + } else { + AlibSsdtBuffer = *AlibSsdtPtr; + } + // Check length of port data + ASSERT (sizeof (_ALIB_PORT_DATA) <= 20); + // Check length of global data + ASSERT (sizeof (_ALIB_GLOBAL_DATA) <= 32); + // Copy template to buffer + LibAmdMemCopy (AlibSsdtBuffer, AlibSsdtTable, AlibSsdtlength, StdHeader); + // Update table OEM fields. + LibAmdMemCopy ( + (VOID *) &((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->OemId, + (VOID *) &GnbBuildOptions.OemIdString, + sizeof (GnbBuildOptions.OemIdString), + StdHeader); + LibAmdMemCopy ( + (VOID *) &((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->OemTableId, + (VOID *) &GnbBuildOptions.OemTableIdString, + sizeof (GnbBuildOptions.OemTableIdString), + StdHeader); + // + // Update register base base + // + PcieAlibUpdateGnbData (AlibSsdtBuffer, StdHeader); + // + // Update transfer block + // + AmlObjName = STRING_TO_UINT32 ('A', 'D', 'A', 'T'); + AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); + if (AmlObjPtr != NULL) { + AmlObjPtr = (UINT8 *) AmlObjPtr + 10; + } + // Dispatch function from table + Index = 0; + while (AlibDispatchTableV2[Index] != NULL) { + Status = AlibDispatchTableV2[Index] (AmlObjPtr, StdHeader); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + Index++; + } + if (AgesaStatus != AGESA_SUCCESS) { + //Shrink table length to size of the header + ((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->TableLength = sizeof (ACPI_TABLE_HEADER); + } + ChecksumAcpiTable ((ACPI_TABLE_HEADER*) AlibSsdtBuffer, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibBuildAcpiTableV2 Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Update MMIO info + * + * + * + * + * @param[in] SsdtBuffer Pointer to SSDT table + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +PcieAlibUpdateGnbData ( + IN OUT VOID *SsdtBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 LocalMsrRegister; + UINT32 AmlObjName; + VOID *AmlObjPtr; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdateGnbData Enter\n"); + // + // Locate Base address variable + // + AmlObjName = STRING_TO_UINT32 ('A', 'G', 'R', 'B'); + AmlObjPtr = GnbLibFind ( + SsdtBuffer, + ((ACPI_TABLE_HEADER*) SsdtBuffer)->TableLength, + (UINT8*) &AmlObjName, + sizeof (AmlObjName) + ); + /// @todo + // ASSERT (AmlObjPtr != NULL); + if (AmlObjPtr == NULL) { + return AGESA_ERROR; + } + // + // Update PCIe MMIO base + // + LibAmdMsrRead (MSR_MMIO_Cfg_Base, &LocalMsrRegister, StdHeader); + if ((LocalMsrRegister & BIT0) != 0 && (LocalMsrRegister & 0xFFFFFFFF00000000) == 0) { + *(UINT32*)((UINT8*) AmlObjPtr + 5) = (UINT32) (LocalMsrRegister & 0xFFFFF00000); + } else { + ASSERT (FALSE); + return AGESA_ERROR; + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdateGnbData Exit\n"); + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Update MMIO info + * + * + * + * + * @param[in] DataBuffer Pointer to data buffer + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +PcieAlibUpdateVoltageData ( + IN OUT VOID *DataBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PP_F1_ARRAY_V2 *PpF1Array; + AGESA_STATUS Status; + ALIB_DATA *AlibData; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdateVoltageData Enter\n"); + Status = AGESA_SUCCESS; + ASSERT (DataBuffer != NULL); + AlibData = (ALIB_DATA *) DataBuffer; + // + // Locate F1 table + // + PpF1Array = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + if (PpF1Array != NULL) { + // + // Update GEN1 Vid + // + AlibData->Data.Data.PcieVidGen1 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[0]; + // + // Update GEN2 Vid + // + AlibData->Data.Data.PcieVidGen2 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[PpF1Array->PcieGen2Vid]; + // + // Update DPM Mask + // + AlibData->Data.Data.DpmMask = (PpF1Array->PP_FUSE_ARRAY_V2_fld37 + 1); + IDS_HDT_CONSOLE (GNB_TRACE, " DpmMask = %02x\n", AlibData->Data.Data.DpmMask); + // + // Update Boost data + // + AlibData->Data.Data.NumBoostStates = (PpF1Array->PP_FUSE_ARRAY_V2_fld36); + IDS_HDT_CONSOLE (GNB_TRACE, " NumBoost = %02x\n", AlibData->Data.Data.NumBoostStates); + } else { + Status = AGESA_ERROR; + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdateVoltageData Exit\n"); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Update PCIe info + * + * + * + * + * @param[in] DataBuffer Ponter to data buffer + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +PcieAlibUpdatePcieData ( + IN OUT VOID *DataBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIe_PLATFORM_CONFIG *Pcie; + AMD_LATE_PARAMS *LateParamsPtr; + AGESA_STATUS Status; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdatePcieData Enter\n"); + ASSERT (DataBuffer != NULL); + Status = AGESA_SUCCESS; + // + // Locate PCIe platform config + // + if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) { + // + // Update policy data + // + ((ALIB_DATA *) DataBuffer)->Data.Data.PsppPolicy = Pcie->PsppPolicy; + // + // Update data for each port + // + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_PCIE_ENGINE, + PcieAlibUpdatePciePortDataCallback, + DataBuffer, + Pcie + ); + } else { + ASSERT (FALSE); + Status = AGESA_FATAL; + } + + LateParamsPtr = (AMD_LATE_PARAMS *) StdHeader; + ((ALIB_DATA *) DataBuffer)->Data.Data.DockedTdpHeadroom = + LateParamsPtr->GnbLateConfiguration.DockedTdpHeadroom; + IDS_HDT_CONSOLE (GNB_TRACE, " DockedTdpHeadroom = %02x\n", + LateParamsPtr->GnbLateConfiguration.DockedTdpHeadroom); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibUpdatePcieData Exit\n"); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to update PCIe port data + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieAlibUpdatePciePortDataCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + _ALIB_PORT_DATA *PortData; + + PortData = &((ALIB_DATA *) Buffer)->PortData[Engine->Type.Port.PcieBridgeId].PortData; + + if (PcieConfigIsEngineAllocated (Engine) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS))) { + // + // Various speed capability + // + PortData->PciePortMaxSpeed = (UINT8) PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_MAX, Engine); + PortData->PciePortCurSpeed = (UINT8) PcieFmGetLinkSpeedCap (PCIE_PORT_GEN_CAP_BOOT, Engine); + PortData->PciePortDcSpeed = PcieGen1; + PortData->PciePortAcSpeed = PortData->PciePortMaxSpeed; + if (Pcie->PsppPolicy == PsppBalanceLow) { + PortData->PciePortAcSpeed = PcieGen1; + } + if (PcieConfigIsSbPcieEngine (Engine)) { + PortData->PcieSbPort = 0x1; + PortData->PciePortAcSpeed = PortData->PciePortMaxSpeed; + } + if (Engine->Type.Port.PortData.MiscControls.LinkSafeMode != 0) { + PortData->PcieLinkSafeMode = 0x1; + PortData->PcieLocalOverrideSpeed = Engine->Type.Port.PortData.MiscControls.LinkSafeMode; + } + // + // various port capability + // + PortData->StartPhyLane = (UINT8) Engine->EngineData.StartLane; + PortData->EndPhyLane = (UINT8) Engine->EngineData.EndLane; + PortData->StartCoreLane = (UINT8) Engine->Type.Port.StartCoreLane; + PortData->EndCoreLane = (UINT8) Engine->Type.Port.EndCoreLane; + PortData->PortId = Engine->Type.Port.PortId; + PortData->LinkHotplug = Engine->Type.Port.PortData.LinkHotplug; + PortData->PciDev = (UINT8) Engine->Type.Port.Address.Address.Device; + PortData->PciFun = (UINT8) Engine->Type.Port.Address.Address.Function; + } else { + PortData->PciePortMaxSpeed = PcieGen1; + PortData->PciePortCurSpeed = PcieGen1; + PortData->PciePortDcSpeed = PcieGen1; + PortData->PciePortAcSpeed = PcieGen1; + PortData->PcieLocalOverrideSpeed = PcieGen1; + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.h new file mode 100644 index 0000000000..322d7c43c8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAlibV2/PcieAlibV2.h @@ -0,0 +1,107 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe ALIB + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84514 $ @e \$Date: 2012-12-17 10:44:17 -0600 (Mon, 17 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIEALIBV2_H_ +#define _PCIEALIBV2_H_ + +#pragma pack (push, 1) + +/// _ALIB_PORT_DATA structure +typedef struct { + UINT8 PciePortMaxSpeed; ///< Maximum speed for PCIe Port + UINT8 PciePortAcSpeed; ///< AC power speed for PCIe Port + UINT8 PciePortDcSpeed; ///< DC power speed for PCIe Port + UINT8 PciePortCurSpeed; ///< Current speed for PCIe Port + UINT8 PcieSbPort; ///< Sb Port + UINT8 PcieLinkSafeMode; ///< Link Safe Mode + UINT8 PcieLocalOverrideSpeed; ///< Local Override Speed + UINT8 StartPhyLane; ///< Start PHY lane + UINT8 EndPhyLane; ///< End PHY lane + UINT8 StartCoreLane; ///< Start CORE lane + UINT8 EndCoreLane; ///< End Core lane + UINT8 PortId; ///< Logical Port ID + UINT8 LinkHotplug; ///< Hotplug Flags + UINT8 PciDev; ///< PCI Device Number + UINT8 PciFun; ///< PCI Function Number +} _ALIB_PORT_DATA; + +/// Set size for Port Data +typedef union { + _ALIB_PORT_DATA PortData; ///< Port data for ALIB + UINT8 Padding[20]; ///< Padding size +} ALIB_PORT_DATA; + +/// _ALIB_GLOBAL_DATA structure +typedef struct { + UINT8 PsppPolicy; ///< PSPP Policy + UINT8 PcieVidGen1; ///< VID for Gen1 + UINT8 PcieVidGen2; ///< VID for Gen2 + UINT8 PcieVidGen3; ///< VID for Gen3 + UINT8 DpmMask; ///< DPM Mask + UINT8 NumBoostStates; ///< DPM States + UINT8 DockedTdpHeadroom; ///< Docked TDP Headroom +} _ALIB_GLOBAL_DATA; + +/// Set size for Global Data +typedef union { + _ALIB_GLOBAL_DATA Data; ///< Global data struct for ALIB + UINT8 Padding[32]; ///< Padding size +} ALIB_GLOBAL_DATA; + +/// ALIB_GLOBAL_DATA structure +typedef struct { + ALIB_GLOBAL_DATA Data; ///< Global data struct for ALIB + ALIB_PORT_DATA PortData[12]; ///< Padding size +} ALIB_DATA; + + +#pragma pack (pop) + +AGESA_STATUS +PcieAlibV2Feature ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.c new file mode 100644 index 0000000000..22339890dc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.c @@ -0,0 +1,374 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link ASPM + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "OptionGnb.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "PcieAspmBlackList.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEASPM_PCIEASPM_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern GNB_BUILD_OPTIONS GnbBuildOptions; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +typedef struct { + GNB_PCI_SCAN_DATA ScanData; + PCIE_ASPM_TYPE Aspm; + PCI_ADDR DownstreamPort; + BOOLEAN AspmL0sBlackList; +} PCIE_ASPM_DATA; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +SCAN_STATUS +PcieAspmCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +VOID +excel950_fun0 ( + IN PCI_ADDR Downstream, + IN PCI_ADDR Upstream, + IN PCIE_ASPM_TYPE Aspm, + IN OUT BOOLEAN *AspmL0sBlackList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +PCIE_ASPM_TYPE +excel950_fun1 ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +excel950_fun2 ( + IN PCI_ADDR DownstreamPort, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIE_ASPM_DATA PcieAspmData; + PcieAspmData.Aspm = Aspm; + PcieAspmData.ScanData.StdHeader = StdHeader; + PcieAspmData.ScanData.GnbScanCallback = PcieAspmCallback; + PcieAspmData.AspmL0sBlackList = FALSE; + GnbLibPciScan (DownstreamPort, DownstreamPort, &PcieAspmData.ScanData); +} + +AGESA_STATUS +PcieAspmInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Evaluate device + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status of 0 + */ + +SCAN_STATUS +PcieAspmCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + SCAN_STATUS ScanStatus; + PCIE_ASPM_DATA *PcieAspmData; + PCIE_DEVICE_TYPE DeviceType; + ScanStatus = SCAN_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, " PcieAspmCallback for Device = %d:%d:%d\n", + Device.Address.Bus, + Device.Address.Device, + Device.Address.Function + ); + PcieAspmData = (PCIE_ASPM_DATA *) ScanData; + ScanStatus = SCAN_SUCCESS; + DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader); + switch (DeviceType) { + case PcieDeviceRootComplex: + case PcieDeviceDownstreamPort: + PcieAspmData->DownstreamPort = Device; + //PcieExitLatencyData->LinkCount++; + GnbLibPciRMW (Device.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffffull, 0x0, ScanData->StdHeader); + GnbLibPciScanSecondaryBus (Device, &PcieAspmData->ScanData); + //PcieExitLatencyData->LinkCount--; + + //Pcie ASPM Black List for L0s with HW method change + if ((DeviceType == PcieDeviceRootComplex) && (PcieAspmData->AspmL0sBlackList == TRUE)) { + IDS_HDT_CONSOLE (GNB_TRACE, " Black List L0s disabled = %d:%d:%d\n", Device.Address.Bus, Device.Address.Device, Device.Address.Function); + GnbLibPciIndirectRMW (Device.AddressValue | 0xE0, 0xA0, AccessS3SaveWidth32, 0xfffff0ff, 0, ScanData->StdHeader); + } + break; + case PcieDeviceUpstreamPort: + excel950_fun0 ( + PcieAspmData->DownstreamPort, + Device, + PcieAspmData->Aspm, + &PcieAspmData->AspmL0sBlackList, + ScanData->StdHeader + ); + GnbLibPciRMW (Device.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffffull, 0x0, ScanData->StdHeader); + GnbLibPciScanSecondaryBus (Device, &PcieAspmData->ScanData); + ScanStatus = SCAN_SKIP_FUNCTIONS | SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + case PcieDeviceEndPoint: + case PcieDeviceLegacyEndPoint: + excel950_fun0 ( + PcieAspmData->DownstreamPort, + Device, + PcieAspmData->Aspm, + &PcieAspmData->AspmL0sBlackList, + ScanData->StdHeader + ); + ScanStatus = SCAN_SKIP_FUNCTIONS | SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + default: + break; + } + return ScanStatus; +} + +VOID +excel950_fun4 ( + IN PCI_ADDR Function, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PcieCapPtr; + PcieCapPtr = GnbLibFindPciCapability (Function.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr != 0) { + GnbLibPciRMW ( + Function.AddressValue | (PcieCapPtr + PCIE_LINK_CTRL_REGISTER) , + AccessS3SaveWidth8, + (UINT32)~(BIT0 | BIT1), + Aspm, + StdHeader + ); + } +} + +STATIC VOID +excel950_fun5 ( + IN PCI_ADDR Device, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxFunc; + UINT8 CurrentFunc; + MaxFunc = GnbLibPciIsMultiFunctionDevice (Device.AddressValue, StdHeader) ? 7 : 0; + for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) { + Device.Address.Function = CurrentFunc; + if (GnbLibPciIsDevicePresent (Device.AddressValue, StdHeader)) { + excel950_fun4 (Device, Aspm, StdHeader); + } + } +} + +VOID +excel950_fun0 ( + IN PCI_ADDR Downstream, + IN PCI_ADDR Upstream, + IN PCIE_ASPM_TYPE Aspm, + IN OUT BOOLEAN *AspmL0sBlackList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIe_LINK_ASPM LinkAsmp; + PCIE_ASPM_TYPE DownstreamCap; + PCIE_ASPM_TYPE UpstreamCap; + LinkAsmp.DownstreamPort = Downstream; + DownstreamCap = excel950_fun1 (Downstream, StdHeader); + LinkAsmp.UpstreamPort = Upstream; + UpstreamCap = excel950_fun1 (Upstream, StdHeader); + LinkAsmp.DownstreamAspm = DownstreamCap & UpstreamCap & Aspm & AspmL1; + LinkAsmp.UpstreamAspm = LinkAsmp.DownstreamAspm; + LinkAsmp.RequestedAspm = Aspm; + if ((UpstreamCap & Aspm & AspmL0s) != 0) { + LinkAsmp.UpstreamAspm |= AspmL0s; + } + if ((DownstreamCap & Aspm & AspmL0s) != 0) { + LinkAsmp.DownstreamAspm |= AspmL0s; + } + if (GnbBuildOptions.PcieAspmBlackListEnable == 1) { + PcieAspmBlackListFeature (&LinkAsmp, StdHeader); + if ((LinkAsmp.DownstreamAspm & AspmL0s) == 0) { + *AspmL0sBlackList = LinkAsmp.BlackList; + } + } + //AgesaPcieLinkAspm (&LinkAsmp, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, " Set ASPM [%d] for Device = %d:%d:%d\n", + (LinkAsmp.UpstreamAspm) , + LinkAsmp.UpstreamPort.Address.Bus, + LinkAsmp.UpstreamPort.Address.Device, + LinkAsmp.UpstreamPort.Address.Function + ); + IDS_HDT_CONSOLE (GNB_TRACE, " Set ASPM [%d] for Device = %d:%d:%d\n", + (LinkAsmp.DownstreamAspm) , + LinkAsmp.DownstreamPort.Address.Bus, + LinkAsmp.DownstreamPort.Address.Device, + LinkAsmp.DownstreamPort.Address.Function + ); + // Disable ASPM Upstream component + excel950_fun5 (Upstream, AspmDisabled, StdHeader); + // Enable ASPM Donstream component + excel950_fun4 (Downstream, LinkAsmp.DownstreamAspm, StdHeader); + // Enable ASPM Upstream component + excel950_fun5 (Upstream, LinkAsmp.UpstreamAspm, StdHeader); +} + + + +PCIE_ASPM_TYPE +excel950_fun1 ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PcieCapPtr; + UINT32 Value; + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr == 0) { + return 0; + } + GnbLibPciRead ( + Device.AddressValue | (PcieCapPtr + PCIE_LINK_CAP_REGISTER), + AccessWidth32, + &Value, + StdHeader + ); + return (Value >> 10) & 3; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init various features on all active ports + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieAspmPortInitCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if (Engine->Type.Port.PortData.LinkAspm != AspmDisabled && + !PcieConfigIsSbPcieEngine (Engine) && + PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + excel950_fun2 ( + Engine->Type.Port.Address, + Engine->Type.Port.PortData.LinkAspm, + GnbLibGetHeader (Pcie) + ); + } +} + + +/**----------------------------------------------------------------------------------------*/ +/** + * Interface to enable Clock Power Managment + * + * + * + * @param[in] StdHeader Standard configuration header + * + * @retval AGESA_STATUS + */ + /*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieAspmInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + PCIe_PLATFORM_CONFIG *Pcie; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAspmInterface Enter\n"); + AgesaStatus = PcieLocateConfigurationData (StdHeader, &Pcie); + if (AgesaStatus == AGESA_SUCCESS) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieAspmPortInitCallback, + NULL, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieAspmInterface Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.h new file mode 100644 index 0000000000..1424a907c3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieAspm/PcieAspm.h @@ -0,0 +1,63 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link ASPM + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIEASPM_H_ +#define _PCIEASPM_H_ + +VOID +excel950_fun2 ( + IN PCI_ADDR DownstreamPort, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +excel950_fun4 ( + IN PCI_ADDR Function, + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.c new file mode 100644 index 0000000000..64f01c0754 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.c @@ -0,0 +1,326 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe Clock Power Managment + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "PcieClkPm.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECLKPM_PCIECLKPM_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable Clock Power Managment on function of the device + * + * + * + * @param[in] Function PCI address of function. + * @param[in] StdHeader Standard configuration header + * + */ + /*----------------------------------------------------------------------------------------*/ +STATIC VOID +PcieClkPmEnableOnFunction ( + IN PCI_ADDR Function, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 PcieCapPtr; + PcieCapPtr = GnbLibFindPciCapability (Function.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr != 0) { + GnbLibPciRMW ( + Function.AddressValue | (PcieCapPtr + PCIE_LINK_CTRL_REGISTER), + AccessS3SaveWidth32, + (UINT32)~(BIT8), + BIT8, + StdHeader + ); + } +} + + +/**----------------------------------------------------------------------------------------*/ +/** + * check capability of intire device including its functions + * + * + * + * @param[in] Device PCI address of downstream port + * @param[in] StdHeader Standard configuration header + * + * @retval TRUE - Device support Clock Power Managment + */ + /*----------------------------------------------------------------------------------------*/ +STATIC BOOLEAN +PcieClkPmCheckDeviceCapability ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + UINT8 MaxFunc; + UINT8 CurrentFunc; + UINT8 PcieCapPtr; + UINT32 Value; + + MaxFunc = GnbLibPciIsMultiFunctionDevice (Device.AddressValue, StdHeader) ? 7 : 0; + + for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) { + Device.Address.Function = CurrentFunc; + if (GnbLibPciIsDevicePresent (Device.AddressValue, StdHeader)) { + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader); + if (PcieCapPtr == 0) { + return FALSE; + } + GnbLibPciRead ( + Device.AddressValue | (PcieCapPtr + PCIE_LINK_CAP_REGISTER), + AccessWidth32, + &Value, + StdHeader + ); + if ((Value & BIT18) == 0) { + return FALSE; + } + } + } + return TRUE; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Clock power managment on device + * + * + * + * @param[in] Device PCI address of device. + * @param[in] StdHeader Standard configuration header + * + */ + /*----------------------------------------------------------------------------------------*/ +STATIC VOID +PcieClkPmEnableOnDevice ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxFunc; + UINT8 CurrentFunc; + if (PcieClkPmCheckDeviceCapability (Device, StdHeader)) { + MaxFunc = GnbLibPciIsMultiFunctionDevice (Device.AddressValue, StdHeader) ? 7 : 0; + for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) { + Device.Address.Function = CurrentFunc; + if (GnbLibPciIsDevicePresent (Device.AddressValue, StdHeader)) { + IDS_HDT_CONSOLE (GNB_TRACE, " Enable Clock Power Managment for Device = %d:%d:%d\n", + Device.Address.Bus, + Device.Address.Device, + Device.Address.Function + ); + PcieClkPmEnableOnFunction (Device, StdHeader); + } + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Evaluate device + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status of 0 + */ + +STATIC SCAN_STATUS +PcieClkPmCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + SCAN_STATUS ScanStatus; + PCIE_DEVICE_TYPE DeviceType; + ScanStatus = SCAN_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, " PcieClkPmCallback for Device = %d:%d:%d\n", + Device.Address.Bus, + Device.Address.Device, + Device.Address.Function + ); + ScanStatus = SCAN_SUCCESS; + DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader); + switch (DeviceType) { + case PcieDeviceRootComplex: + case PcieDeviceDownstreamPort: + GnbLibPciRMW (Device.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffffull, 0x0, ScanData->StdHeader); + GnbLibPciScanSecondaryBus (Device, ScanData); + break; + case PcieDeviceUpstreamPort: + PcieClkPmEnableOnDevice (Device, ScanData->StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffffull, 0x0, ScanData->StdHeader); + GnbLibPciScanSecondaryBus (Device, ScanData); + ScanStatus = SCAN_SKIP_FUNCTIONS | SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + case PcieDeviceEndPoint: + case PcieDeviceLegacyEndPoint: + PcieClkPmEnableOnDevice (Device, ScanData->StdHeader); + ScanStatus = SCAN_SKIP_FUNCTIONS | SCAN_SKIP_DEVICES | SCAN_SKIP_BUSES; + break; + default: + break; + } + return ScanStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Confiugure Clock Power Managment + * + * + * + * + * @param[in] DownstreamPort Downstream port PCI address + * @param[in] StdHeader Standard configuration header + * + */ + +VOID +STATIC +PcieClkPmPortInitConfigure ( + IN PCI_ADDR DownstreamPort, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GNB_PCI_SCAN_DATA ScanData; + ScanData.StdHeader = StdHeader; + ScanData.GnbScanCallback = PcieClkPmCallback; + GnbLibPciScan (DownstreamPort, DownstreamPort, &ScanData); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init various features on all active ports + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieClkPmPortInitCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if (Engine->Type.Port.PortData.MiscControls.ClkPmSupport == 0x1 && + !PcieConfigIsSbPcieEngine (Engine) && + PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + PcieClkPmPortInitConfigure ( + Engine->Type.Port.Address, + GnbLibGetHeader (Pcie) + ); + } +} + +/**----------------------------------------------------------------------------------------*/ +/** + * Interface to enable Clock Power Managment + * + * + * + * @param[in] StdHeader Standard configuration header + * + * @retval AGESA_STATUS + */ + /*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieClkPmInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + PCIe_PLATFORM_CONFIG *Pcie; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieClkPmInterface Enter\n"); + AgesaStatus = PcieLocateConfigurationData (StdHeader, &Pcie); + if (AgesaStatus == AGESA_SUCCESS) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieClkPmPortInitCallback, + NULL, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieClkPmInterface Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.h new file mode 100644 index 0000000000..fe054f543a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieClkPm/PcieClkPm.h @@ -0,0 +1,54 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link ASPM + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIECLKPM_H_ +#define _PCIECLKPM_H_ + +AGESA_STATUS +PcieClkPmInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.c new file mode 100644 index 0000000000..d498ad00e0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.c @@ -0,0 +1,135 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB function to create/locate PCIe configuration data area + * + * Contain code that create/locate/manes GNB/PCIe configuration + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_GNBHANDLELIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get GNB handle + * + * + * @param[in] StdHeader Standard configuration header + */ +GNB_HANDLE * +GnbGetHandle ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIe_PLATFORM_CONFIG *Pcie; + GNB_HANDLE *GnbHandle; + AGESA_STATUS Status; + GnbHandle = NULL; + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + GnbHandle = (GNB_HANDLE *) PcieConfigGetChild (DESCRIPTOR_SILICON, &Pcie->Header); + } + return GnbHandle; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get GNB socket ID + * + * + * @param[in] GnbHandle Gnb handle + */ +UINT8 +GnbGetSocketId ( + IN GNB_HANDLE *GnbHandle + ) +{ + return PcieConfigGetParentComplex (GnbHandle)->SocketId; +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Get PCI_ADDR of GNB + * + * + * @param[in] Handle Pointer to GNB_HANDLE + * @retval PCI_ADDR PCI_ADDR of device + */ + +PCI_ADDR +GnbGetHostPciAddress ( + IN GNB_HANDLE *Handle + ) +{ + ASSERT (Handle != NULL); + return Handle->Address; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.h new file mode 100644 index 0000000000..8fc984764c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbHandleLib.h @@ -0,0 +1,74 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB function to create/locate PCIe configuration data area + * + * Contain code that create/locate and rebase configuration data area. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBHANDLELIB_H_ +#define _GNBHANDLELIB_H_ + + +GNB_HANDLE * +GnbGetHandle ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbGetSocketId ( + IN GNB_HANDLE *GnbHandle + ); + +PCI_ADDR +GnbGetHostPciAddress ( + IN GNB_HANDLE *Handle + ); + + +#define GnbGetNextHandle(Descriptor) (GNB_HANDLE *) PcieConfigGetNextTopologyDescriptor (Descriptor, DESCRIPTOR_TERMINATE_TOPOLOGY) + +#define GnbGetSiliconId(Handle) (Handle != NULL ? (Handle)->SiliconId : 0) +#define GnbGetNodeId(Handle) (Handle != NULL ? (Handle)->NodeId : 0) + +#define GnbIsGnbConnectedToSb(Handle) (Handle != NULL ? ((Handle)->Address.AddressValue == 0x0) : FALSE) + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbPcieConfig.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbPcieConfig.h new file mode 100644 index 0000000000..d216c79c8b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/GnbPcieConfig.h @@ -0,0 +1,54 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe configuration + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _GNBPCIECONFIG_H_ +#define _GNBPCIECONFIG_H_ + +#include "GnbPcie.h" +#include "PcieConfigData.h" +#include "PcieConfigLib.h" +#include "GnbHandleLib.h" + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c new file mode 100644 index 0000000000..5a25844884 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c @@ -0,0 +1,533 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB function to create/locate PCIe configuration data area + * + * Contain code that create/locate and rebase configuration data area. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "OptionGnb.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbFamServices.h" +#include "cpuServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "PcieMapTopology.h" +#include "PcieInputParser.h" +#include "PcieConfigLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIECONFIGDATA_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +extern GNB_BUILD_OPTIONS ROMDATA GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +#define PcieConfigAttachChild(P, C) (P)->Child = (UINT16) ((UINT8 *) C - (UINT8 *) P); +#define PcieConfigAttachParent(P, C) (C)->Parent = (UINT16) ((UINT8 *) C - (UINT8 *) P); + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +STATIC +PcieConfigAttachComplexes ( + IN OUT PCIe_COMPLEX_CONFIG *Base, + IN OUT PCIe_COMPLEX_CONFIG *New + ); + +AGESA_STATUS +PcieUpdateConfigurationData ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +PCIe_COMPLEX_DESCRIPTOR * +PcieConfigProcessUserConfig ( + IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieConfigurationInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieConfigurationMap ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Create internal PCIe configuration topology + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_SUCCESS Configuration data successfully allocated. + * @retval AGESA_FATAL Configuration data allocation failed. + */ + +AGESA_STATUS +PcieConfigurationInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_SILICON_CONFIG *Silicon; + UINT8 SocketId; + UINTN CurrentComplexesDataLength; + UINTN ComplexesDataLength; + UINT8 ComplexIndex; + VOID *Buffer; + ComplexesDataLength = 0; + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Enter\n"); + for (SocketId = 0; SocketId < GetPlatformNumberOfSockets (); SocketId++) { + if (IsProcessorPresent (SocketId, StdHeader)) { + Status = PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + ComplexesDataLength += CurrentComplexesDataLength; + } + } + ComplexIndex = 0; + Pcie = GnbAllocateHeapBufferAndClear (AMD_PCIE_COMPLEX_DATA_HANDLE, sizeof (PCIe_PLATFORM_CONFIG) + ComplexesDataLength, StdHeader); + ASSERT (Pcie != NULL); + if (Pcie != NULL) { + PcieConfigAttachChild (&Pcie->Header, &Pcie->ComplexList[ComplexIndex].Header); + PcieConfigSetDescriptorFlags (Pcie, DESCRIPTOR_PLATFORM | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_TOPOLOGY); + Buffer = (UINT8 *) (Pcie) + sizeof (PCIe_PLATFORM_CONFIG); + for (SocketId = 0; SocketId < GetPlatformNumberOfSockets (); SocketId++) { + if (IsProcessorPresent (SocketId, StdHeader)) { + Pcie->ComplexList[ComplexIndex].SocketId = SocketId; + //Attache Comples to Silicon which will be created by PcieFmBuildComplexConfiguration + PcieConfigAttachChild (&Pcie->ComplexList[ComplexIndex].Header, &((PCIe_SILICON_CONFIG *) Buffer)->Header); + //Attach Comples to Pcie + PcieConfigAttachParent (&Pcie->Header, &Pcie->ComplexList[ComplexIndex].Header); + PcieConfigSetDescriptorFlags (&Pcie->ComplexList[ComplexIndex], DESCRIPTOR_COMPLEX | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_GNB | DESCRIPTOR_TERMINATE_TOPOLOGY); + PcieFmBuildComplexConfiguration (SocketId, Buffer, StdHeader); + Silicon = PcieConfigGetChildSilicon (&Pcie->ComplexList[ComplexIndex]); + while (Silicon != NULL) { + PcieConfigAttachParent (&Pcie->ComplexList[ComplexIndex].Header, &Silicon->Header); + GetNodeId (SocketId, Silicon->SiliconId, &Silicon->NodeId, StdHeader); + GnbFmGetLinkId ((GNB_HANDLE*) Silicon, &Silicon->LinkId, StdHeader); + Silicon = (PCIe_SILICON_CONFIG *) PcieConfigGetNextTopologyDescriptor (Silicon, DESCRIPTOR_TERMINATE_TOPOLOGY); + } + + if (ComplexIndex > 0) { + PcieConfigAttachComplexes (&Pcie->ComplexList[ComplexIndex - 1], &Pcie->ComplexList[ComplexIndex]); + } + PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader); + Buffer = (VOID *) ((UINT8 *) Buffer + CurrentComplexesDataLength); + ComplexIndex++; + } + } + } else { + Status = AGESA_FATAL; + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Exit [0x%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Create internal PCIe configuration topology + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_SUCCESS Configuration data successfully allocated. + * @retval AGESA_FATAL Configuration data allocation failed. + */ + +AGESA_STATUS +PcieConfigurationMap ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_EARLY_PARAMS *EarlyParamsPtr; + PCIe_COMPLEX_DESCRIPTOR *PcieComplexList; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor; + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + UINTN Index; + UINTN NumberOfComplexes; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationMap Enter\n"); + AgesaStatus = AGESA_SUCCESS; + EarlyParamsPtr = (AMD_EARLY_PARAMS *) StdHeader; + PcieComplexList = PcieConfigProcessUserConfig (EarlyParamsPtr->GnbConfig.PcieComplexList, StdHeader); + GNB_DEBUG_CODE ( + if (PcieComplexList != NULL) { + PcieUserConfigConfigDump (PcieComplexList); + } + ); + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetChild (DESCRIPTOR_COMPLEX, &Pcie->Header); + NumberOfComplexes = PcieInputParserGetNumberOfComplexes (PcieComplexList); + while (Complex != NULL) { + for (Index = 0; Index < NumberOfComplexes; Index++) { + ComplexDescriptor = PcieInputParserGetComplexDescriptor (PcieComplexList, Index); + if (ComplexDescriptor->SocketId == Complex->SocketId) { + Status = PcieMapTopologyOnComplex (ComplexDescriptor, Complex, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + } + Complex = PcieLibGetNextDescriptor (Complex); + } + } + Pcie->LinkReceiverDetectionPooling = GnbBuildOptions.CfgGnbLinkReceiverDetectionPooling; + Pcie->LinkL0Pooling = GnbBuildOptions.CfgGnbLinkL0Pooling; + Pcie->LinkGpioResetAssertionTime = GnbBuildOptions.CfgGnbLinkGpioResetAssertionTime; + Pcie->LinkResetToTrainingTime = GnbBuildOptions.CfgGnbLinkResetToTrainingTime; + Pcie->GfxCardWorkaround = GfxWorkaroundEnable; + Pcie->TrainingExitState = LinkStateTrainingCompleted; + Pcie->TrainingAlgorithm = GnbBuildOptions.CfgGnbTrainingAlgorithm; + if ((UserOptions.CfgAmdPlatformType & AMD_PLATFORM_MOBILE) != 0) { + Pcie->GfxCardWorkaround = GfxWorkaroundDisable; + } + Pcie->PsppPolicy = EarlyParamsPtr->GnbConfig.PsppPolicy; + IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_PCIE_PLATFORM_CONFIG, Pcie, StdHeader); + GNB_DEBUG_CODE ( + PcieConfigDebugDump (Pcie); + ); + HeapDeallocateBuffer (AMD_GNB_TEMP_DATA_HANDLE, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationMap Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate global PCIe configuration data + * + * + * + * @param[in] PcieComplexList User PCIe topology configuration + * @param[out] StdHeader Standard configuration header + * @retval Updated topology configuration + */ +PCIe_COMPLEX_DESCRIPTOR * +PcieConfigProcessUserConfig ( + IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Node0SocketId; + UINT32 Node0SiliconId; + UINTN NumberOfComplexes; + UINTN NumberOfPorts; + UINTN Index; + UINT16 DescriptorLoLane; + UINT16 DescriptorHiLane; + PCIe_COMPLEX_DESCRIPTOR *ResultComplexConfig; + PCIe_COMPLEX_DESCRIPTOR *SbComplexDescriptor; + PCIe_PORT_DESCRIPTOR *SbPortDescriptor; + PCIe_PORT_DESCRIPTOR DefaultSbPortDescriptor; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + AGESA_STATUS Status; + SbPortDescriptor = NULL; + GetSocketModuleOfNode (0, &Node0SocketId, &Node0SiliconId, StdHeader); + Status = PcieFmGetSbConfigInfo ((UINT8) Node0SocketId, &DefaultSbPortDescriptor, StdHeader); + if (Status == AGESA_UNSUPPORTED) { + return PcieComplexList; + } + if (PcieComplexList == NULL) { + // No complex descriptor for any silicon was provided + // 1. Create complex descriptor + // 2. Create SB port descriptor + // 3. Attach SB descriptor to complex descriptor created in step #1 + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBufferAndClear ( + AMD_GNB_TEMP_DATA_HANDLE, + sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + SbComplexDescriptor = ResultComplexConfig; + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8 *) ResultComplexConfig + sizeof (PCIe_COMPLEX_DESCRIPTOR)); + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + SbPortDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + // Attach post array to complex descriptor + SbComplexDescriptor->PciePortList = SbPortDescriptor; + SbComplexDescriptor->SocketId = Node0SocketId; + SbComplexDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + } else { + NumberOfComplexes = PcieInputParserGetNumberOfComplexes (PcieComplexList); + SbComplexDescriptor = PcieInputParserGetComplexDescriptorOfSocket (PcieComplexList, Node0SocketId); + if (SbComplexDescriptor == NULL) { + // No complex descriptor for silicon that have SB attached. + // 1. Create complex descriptor. Will be first one in the list + // 2. Create SB port descriptor + // 3. Attach SB descriptor to complex descriptor created in step #1 + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBufferAndClear ( + AMD_GNB_TEMP_DATA_HANDLE, + (NumberOfComplexes + 1) * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + SbComplexDescriptor = ResultComplexConfig; + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8 *) ResultComplexConfig + (NumberOfComplexes + 1) * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + SbPortDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + // Attach post array to complex descriptor + SbComplexDescriptor->PciePortList = SbPortDescriptor; + SbComplexDescriptor->SocketId = Node0SocketId; + SbComplexDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + LibAmdMemCopy ( + (UINT8 *) ResultComplexConfig + sizeof (PCIe_COMPLEX_DESCRIPTOR), + PcieComplexList, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + StdHeader + ); + + } else { + // Complex descriptor that represent silicon that have SB attached exist + // 1. Determine if complex have descriptor for SB + // 2. Create new descriptor for SB if needed + NumberOfPorts = PcieInputParserGetLengthOfPcieEnginesList (SbComplexDescriptor); + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBuffer ( + AMD_GNB_TEMP_DATA_HANDLE, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + (NumberOfPorts + 1) * sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Copy complex descriptor array + LibAmdMemCopy ( + ResultComplexConfig, + PcieComplexList, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + StdHeader + ); + if (NumberOfPorts != 0) { + // Copy port descriptor array associated with complex with SB attached + LibAmdMemCopy ( + (UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + SbComplexDescriptor->PciePortList, + NumberOfPorts * sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Update SB complex pointer on in memory list + SbComplexDescriptor = PcieInputParserGetComplexDescriptorOfSocket ((PCIe_COMPLEX_DESCRIPTOR *) ResultComplexConfig, Node0SocketId); + // Attach port descriptor array to complex + SbComplexDescriptor->PciePortList = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR)); + for (Index = 0; Index < NumberOfPorts; ++Index) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (SbComplexDescriptor, Index); + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + if (DescriptorLoLane >= DefaultSbPortDescriptor.EngineData.StartLane && DescriptorLoLane <= DefaultSbPortDescriptor.EngineData.EndLane) { + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) EngineDescriptor; + } + } + } + } + if (SbPortDescriptor == NULL) { + // No descriptor that represent SB where found, create new one, will be first one in list + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + // Copy default config info + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + // Reattach descriptor list to complex + SbComplexDescriptor->PciePortList = SbPortDescriptor; + } else { + // Move SB descriptor to be first one in array + LibAmdMemCopy ( + (UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + SbPortDescriptor, + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Disable original SB descriptor + SbPortDescriptor->EngineData.EngineType = PcieUnusedEngine; + //Update pointer to new SB descriptor + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + //It is no longer a descriptor that terminates list + SbPortDescriptor->Flags &= (~ DESCRIPTOR_TERMINATE_LIST); + // Reattach descriptor list to complex + SbComplexDescriptor->PciePortList = SbPortDescriptor; + } + } + } + // Mark descriptor as SB link + SbPortDescriptor->Port.MiscControls.SbLink = 0x1; + return ResultComplexConfig; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate global PCIe configuration data + * + * + * + * @param[in] StdHeader Standard configuration header + * @param[out] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Configuration data successfully located + * @retval AGESA_FATAL Configuration can not be located. + */ +AGESA_STATUS +PcieLocateConfigurationData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT PCIe_PLATFORM_CONFIG **Pcie + ) +{ + *Pcie = GnbLocateHeapBuffer (AMD_PCIE_COMPLEX_DATA_HANDLE, StdHeader); + if (*Pcie == NULL) { + IDS_ERROR_TRAP; + return AGESA_FATAL; + } + (*Pcie)->StdHeader = (PVOID) StdHeader; + PcieUpdateConfigurationData (*Pcie); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attache descriptors + * + * + * @param[in] Type Descriptor type + * @param[in,out] Base Base descriptor + * @param[in,out] New New descriptor + */ +VOID +STATIC +PcieConfigAttachDescriptors ( + IN UINT32 Type, + IN OUT PCIe_DESCRIPTOR_HEADER *Base, + IN OUT PCIe_DESCRIPTOR_HEADER *New + ) +{ + PCIe_DESCRIPTOR_HEADER *Left; + PCIe_DESCRIPTOR_HEADER *Right; + + Left = PcieConfigGetPeer (DESCRIPTOR_TERMINATE_GNB, PcieConfigGetChild (Type, Base)); + ASSERT (Left != NULL); + Right = PcieConfigGetChild (Type, New); + Left->Peer = (UINT16) ((UINT8 *) Right - (UINT8 *) Left); + PcieConfigResetDescriptorFlags (Left, DESCRIPTOR_TERMINATE_TOPOLOGY); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach configurations of two GNB to each other. + * + * Function will link all data structure to linked lists + * + * @param[in,out] Base Base complex descriptor + * @param[in,out] New New complex descriptor + */ +VOID +STATIC +PcieConfigAttachComplexes ( + IN OUT PCIe_COMPLEX_CONFIG *Base, + IN OUT PCIe_COMPLEX_CONFIG *New + ) +{ + // Connect Complex + Base->Header.Peer = (UINT16) ((UINT8 *) New - (UINT8 *) Base); + PcieConfigResetDescriptorFlags (Base, DESCRIPTOR_TERMINATE_TOPOLOGY); + // Connect Silicon + PcieConfigAttachDescriptors (DESCRIPTOR_SILICON, &Base->Header, &New->Header); + // Connect Wrappers + PcieConfigAttachDescriptors (DESCRIPTOR_PCIE_WRAPPER | DESCRIPTOR_DDI_WRAPPER, &Base->Header, &New->Header); + // Connect Engines + PcieConfigAttachDescriptors (DESCRIPTOR_PCIE_ENGINE | DESCRIPTOR_DDI_ENGINE, &Base->Header, &New->Header); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Update configuration data + * + * Puprouse of this structure to update config data that base on programming of + * other silicon compoments. For instance PCI address of GNB and PCIe ports + * can change by AGESA or external agent + * + * + * @param[in,out] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Configuration data successfully update + * @retval AGESA_FATAL Failt to update configuration + */ +AGESA_STATUS +PcieUpdateConfigurationData ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *Silicon; + PCIe_ENGINE_CONFIG *Engine; + PCI_ADDR NewAddress; + // Update silicon configuration + Silicon = PcieConfigGetChildSilicon (Pcie); + while (Silicon != NULL) { + NewAddress = GnbFmGetPciAddress ((GNB_HANDLE *) PcieConfigGetParentComplex (Silicon), GnbLibGetHeader (Pcie)); + if (Silicon->Address.AddressValue != NewAddress.AddressValue) { + Silicon->Address.AddressValue = NewAddress.AddressValue; + Engine = PcieConfigGetChildEngine (Silicon); + while (Engine != NULL) { + if (PcieConfigIsPcieEngine (Engine)) { + Engine->Type.Port.Address.Address.Bus = Silicon->Address.Address.Bus; + } + Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (Engine, DESCRIPTOR_TERMINATE_GNB); + } + } + Silicon = (PCIe_SILICON_CONFIG *) PcieConfigGetNextTopologyDescriptor (Silicon, DESCRIPTOR_TERMINATE_TOPOLOGY); + } + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.h new file mode 100644 index 0000000000..b38287c569 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.h @@ -0,0 +1,57 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB function to create/locate PCIe configuration data area + * + * Contain code that create/locate and rebase configuration data area. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIECONFIGDATA_H_ +#define _PCIECONFIGDATA_H_ + + +AGESA_STATUS +PcieLocateConfigurationData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT PCIe_PLATFORM_CONFIG **Pcie + ); + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.c new file mode 100644 index 0000000000..8e5e3dd43a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.c @@ -0,0 +1,799 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB function to create/locate PCIe configuration data area + * + * Contain code that create/locate and rebase configuration data area. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "PcieMapTopology.h" +#include "PcieInputParser.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIECONFIGLIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * get Master Lane of PCIe port engine + * + * + * + * @param[in] Engine Pointer to engine descriptor + * @retval Master Engine Lane Number + */ +UINT8 +PcieConfigGetPcieEngineMasterLane ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT8 MasterLane; + PCIe_WRAPPER_CONFIG *Wrapper; + ASSERT (PcieConfigIsPcieEngine (Engine)); + + Wrapper = PcieConfigGetParentWrapper (Engine); + if (Engine->EngineData.StartLane <= Engine->EngineData.EndLane) { + MasterLane = (UINT8) (Engine->EngineData.StartLane - Wrapper->StartPhyLane); + } else { + MasterLane = (UINT8) (Engine->EngineData.EndLane - Wrapper->StartPhyLane); + } + return MasterLane; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of core lanes + * + * + * + * @param[in] Engine Pointer to engine descriptor + * @retval Number of core lane + */ +UINT8 +PcieConfigGetNumberOfCoreLane ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + if (Engine->Type.Port.StartCoreLane >= UNUSED_LANE_ID || Engine->Type.Port.EndCoreLane >= UNUSED_LANE_ID) { + return 0; + } + return (UINT8) (Engine->Type.Port.EndCoreLane - Engine->Type.Port.StartCoreLane + 1); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable engine + * + * + * + * @param[in] Engine Pointer to engine config descriptor + */ +VOID +PcieConfigDisableEngine ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + if (PcieConfigIsSbPcieEngine (Engine)) { + return; + } + PcieConfigResetDescriptorFlags (Engine, DESCRIPTOR_ALLOCATED); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable all engines on wrapper + * + * + * + * @param[in] EngineTypeMask Engine type bitmap. + * @param[in] Wrapper Pointer to wrapper config descriptor + */ +VOID +PcieConfigDisableAllEngines ( + IN UINTN EngineTypeMask, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if ((EngineList->EngineData.EngineType & EngineTypeMask) != 0) { + PcieConfigDisableEngine (EngineList); + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get engine PHY lanes bitmap + * + * + * + * @param[in] Engine Pointer to engine config descriptor + */ +UINT32 +PcieConfigGetEnginePhyLaneBitMap ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT32 LaneBitMap; + LaneBitMap = 0; + if (PcieLibIsEngineAllocated (Engine)) { + LaneBitMap = ((1 << PcieConfigGetNumberOfPhyLane (Engine)) - 1) << (PcieLibGetLoPhyLane (Engine) - PcieConfigGetParentWrapper (Engine)->StartPhyLane); + } + return LaneBitMap; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of phy lanes + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @retval Number of Phy lane + */ +UINT8 +PcieConfigGetNumberOfPhyLane ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + if (Engine->EngineData.StartLane >= UNUSED_LANE_ID || Engine->EngineData.StartLane >= UNUSED_LANE_ID) { + return 0; + } + if (Engine->EngineData.StartLane > Engine->EngineData.EndLane) { + return (UINT8) (Engine->EngineData.StartLane - Engine->EngineData.EndLane + 1); + } else { + return (UINT8) (Engine->EngineData.EndLane - Engine->EngineData.StartLane + 1); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get port configuration signature for given wrapper and core + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] CoreId Core ID + * @retval Configuration Signature + */ +UINT64 +PcieConfigGetConfigurationSignature ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId + ) +{ + UINT64 ConfigurationSignature; + PCIe_ENGINE_CONFIG *EngineList; + ConfigurationSignature = 0; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieConfigIsPcieEngine (EngineList) && EngineList->Type.Port.CoreId == CoreId) { + ConfigurationSignature = (ConfigurationSignature << 8) | PcieConfigGetNumberOfCoreLane (EngineList); + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + return ConfigurationSignature; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check Port Status + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] PortStatus Check if status asserted for port + * @retval TRUE if status asserted + */ +BOOLEAN +PcieConfigCheckPortStatus ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT32 PortStatus + ) +{ + return (Engine->InitStatus & PortStatus) == 0 ? FALSE : TRUE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set/Reset port status + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] SetStatus SetStatus + * @param[in] ResetStatus ResetStatus + * + */ +UINT16 +PcieConfigUpdatePortStatus ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_ENGINE_INIT_STATUS SetStatus, + IN PCIe_ENGINE_INIT_STATUS ResetStatus + ) +{ + Engine->InitStatus |= SetStatus; + Engine->InitStatus &= (~ResetStatus); + return Engine->InitStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute callback on all descriptor of specific type + * + * + * @param[in] InDescriptorFlags Include descriptor flags + * @param[in] OutDescriptorFlags Exlude descriptor flags + * @param[in] TerminationFlags Termination flags + * @param[in] Callback Pointer to callback function + * @param[in, out] Buffer Pointer to buffer to pass information to callback + * @param[in] Pcie Pointer to global PCIe configuration + */ + +AGESA_STATUS +PcieConfigRunProcForAllDescriptors ( + IN UINT32 InDescriptorFlags, + IN UINT32 OutDescriptorFlags, + IN UINT32 TerminationFlags, + IN PCIe_RUN_ON_DESCRIPTOR_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_DESCRIPTOR_HEADER *Descriptor; + + AgesaStatus = AGESA_SUCCESS; + Descriptor = PcieConfigGetChild (InDescriptorFlags & DESCRIPTOR_ALL_TYPES, &Pcie->Header); + while (Descriptor != NULL) { + if ((InDescriptorFlags & Descriptor->DescriptorFlags) != 0 && (OutDescriptorFlags && Descriptor->DescriptorFlags) == 0) { + Status = Callback (Descriptor, Buffer, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + Descriptor = (PCIe_DESCRIPTOR_HEADER *) PcieConfigGetNextTopologyDescriptor (Descriptor, TerminationFlags); + } + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute callback on all wrappers in topology + * + * + * @param[in] DescriptorFlags Wrapper Flags + * @param[in] Callback Pointer to callback function + * @param[in, out] Buffer Pointer to buffer to pass information to callback + * @param[in] Pcie Pointer to global PCIe configuration + */ + +AGESA_STATUS +PcieConfigRunProcForAllWrappers ( + IN UINT32 DescriptorFlags, + IN PCIe_RUN_ON_WRAPPER_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_WRAPPER_CONFIG *Wrapper; + + AgesaStatus = AGESA_SUCCESS; + Wrapper = (PCIe_WRAPPER_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_WRAPPERS, &Pcie->Header); + while (Wrapper != NULL) { + if (!(PcieLibIsVirtualDesciptor (Wrapper) && (DescriptorFlags & DESCRIPTOR_VIRTUAL) == 0)) { + if ((DescriptorFlags & DESCRIPTOR_ALL_WRAPPERS & Wrapper->Header.DescriptorFlags) != 0) { + Status = Callback (Wrapper, Buffer, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + } + Wrapper = (PCIe_WRAPPER_CONFIG *) PcieConfigGetNextTopologyDescriptor (Wrapper, DESCRIPTOR_TERMINATE_TOPOLOGY); + } + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute callback on all engine in topology + * + * + * @param[in] DescriptorFlags Engine flags. + * @param[in] Callback Pointer to callback function + * @param[in, out] Buffer Pointer to buffer to pass information to callback + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieConfigRunProcForAllEngines ( + IN UINT32 DescriptorFlags, + IN PCIe_RUN_ON_ENGINE_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + + PCIe_ENGINE_CONFIG *Engine; + Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_ENGINES, &Pcie->Header); + while (Engine != NULL) { + if (!(PcieLibIsVirtualDesciptor (Engine) && (DescriptorFlags & DESCRIPTOR_VIRTUAL) == 0)) { + if (!((DescriptorFlags & DESCRIPTOR_ALLOCATED) != 0 && !PcieLibIsEngineAllocated (Engine))) { + if ((Engine->Header.DescriptorFlags & DESCRIPTOR_ALL_ENGINES & DescriptorFlags) != 0) { + Callback (Engine, Buffer, Pcie); + } + } + } + Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (Engine, DESCRIPTOR_TERMINATE_TOPOLOGY); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get parent descriptor of specific type + * + * + * @param[in] Type Descriptor type + * @param[in] Descriptor Pointer to buffer to pass information to callback + */ +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetParent ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ) +{ + while ((Descriptor->DescriptorFlags & Type) == 0) { + if (Descriptor->Parent != 0) { + Descriptor = (PCIe_DESCRIPTOR_HEADER *) ((UINT8 *) Descriptor - Descriptor->Parent); + } else { + return NULL; + } + } + return Descriptor; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get child descriptor of specific type + * + * + * @param[in] Type Descriptor type + * @param[in] Descriptor Pointer to buffer to pass information to callback + */ +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetChild ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ) +{ + while ((Descriptor->DescriptorFlags & Type) == 0) { + if (Descriptor->Child != 0) { + Descriptor = (PCIe_DESCRIPTOR_HEADER *) ((UINT8 *) Descriptor + Descriptor->Child); + } else { + return NULL; + } + } + return Descriptor; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get peer descriptor of specific type + * + * + * @param[in] Type Descriptor type + * @param[in] Descriptor Pointer to buffer to pass information to callback + */ +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetPeer ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ) +{ + ASSERT (Descriptor != NULL); + while ((Descriptor->DescriptorFlags & Type) == 0) { + if (Descriptor->Peer != 0) { + Descriptor = (PCIe_DESCRIPTOR_HEADER *) ((UINT8 *) Descriptor + Descriptor->Peer); + } else { + return NULL; + } + } + return Descriptor; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check is engine is active or potentially active + * + * + * + * @param[in] Engine Pointer to engine descriptor + * @retval TRUE - engine active + * @retval FALSE - engine not active + */ +BOOLEAN +PcieConfigIsActivePcieEngine ( + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + BOOLEAN Result; + ASSERT (PcieConfigIsPcieEngine (Engine)); + Result = FALSE; + if (PcieConfigIsEngineAllocated (Engine)) { + if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS) || + (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled && Engine->Type.Port.PortData.LinkHotplug != HotplugInboard)) { + Result = TRUE; + } + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate SB engine on wrapper + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @retval SB engine pointer or NULL + */ +PCIe_ENGINE_CONFIG * +PcieConfigLocateSbEngine ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieConfigIsSbPcieEngine (EngineList)) { + return EngineList; + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + return NULL; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump engine configuration + * + * + * @param[in] EngineList Engine Configuration + */ +VOID +PcieConfigEngineDebugDump ( + IN PCIe_ENGINE_CONFIG *EngineList + ) +{ + IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", EngineList->Header.DescriptorFlags); + IDS_HDT_CONSOLE (PCIE_MISC, " Engine Type - %s\n Start Phy Lane - %d\n End Phy Lane - %d\n", + ((EngineList->EngineData.EngineType == PciePortEngine) ? "PCIe Port" : "DDI Link"), + EngineList->EngineData.StartLane, + EngineList->EngineData.EndLane + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Scrath - %d\n", EngineList->Scratch); + IDS_HDT_CONSOLE (PCIE_MISC, " Init Status - 0x%08x\n", EngineList->InitStatus); + if (PcieLibIsPcieEngine (EngineList)) { + IDS_HDT_CONSOLE (PCIE_MISC, " PCIe port configuration:\n"); + IDS_HDT_CONSOLE (PCIE_MISC, " Port Training - %s\n", + (EngineList->Type.Port.PortData.PortPresent == PortDisabled) ? "Disable" : "Enabled" + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Start Core Lane - %d\n", EngineList->Type.Port.StartCoreLane); + IDS_HDT_CONSOLE (PCIE_MISC, " End Core Lane - %d\n", EngineList->Type.Port.EndCoreLane); + IDS_HDT_CONSOLE (PCIE_MISC, " Requested PCI Dev Number - %d\n",EngineList->Type.Port.PortData.DeviceNumber); + IDS_HDT_CONSOLE (PCIE_MISC, " Requested PCI Func Number - %d\n",EngineList->Type.Port.PortData.FunctionNumber); + IDS_HDT_CONSOLE (PCIE_MISC, " PCI Address - %d:%d:%d\n", + EngineList->Type.Port.Address.Address.Bus, + EngineList->Type.Port.Address.Address.Device, + EngineList->Type.Port.Address.Address.Function + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Misc Control - 0x%02x\n", EngineList->Type.Port.PortData.MiscControls); + IDS_HDT_CONSOLE (PCIE_MISC, " Native PCI Dev Number - %d\n", EngineList->Type.Port.NativeDevNumber); + IDS_HDT_CONSOLE (PCIE_MISC, " Native PCI Func Number - %d\n", EngineList->Type.Port.NativeFunNumber); + IDS_HDT_CONSOLE (PCIE_MISC, " Hotplug - %s\n", + (EngineList->Type.Port.PortData.LinkHotplug == HotplugDisabled) ? "Disabled" : ( + (EngineList->Type.Port.PortData.LinkHotplug == HotplugBasic) ? "Basic" : ( + (EngineList->Type.Port.PortData.LinkHotplug == HotplugServer) ? "Server" : ( + (EngineList->Type.Port.PortData.LinkHotplug == HotplugEnhanced) ? "Enhanced" : ( + (EngineList->Type.Port.PortData.LinkHotplug == HotplugInboard) ? "Inboard" : "Unknown")))) + ); + ASSERT (EngineList->Type.Port.PortData.LinkHotplug < MaxHotplug); + IDS_HDT_CONSOLE (PCIE_MISC, " ASPM - %s\n", + (EngineList->Type.Port.PortData.LinkAspm == AspmDisabled) ? "Disabled" : ( + (EngineList->Type.Port.PortData.LinkAspm == AspmL0s) ? "L0s" : ( + (EngineList->Type.Port.PortData.LinkAspm == AspmL1) ? "L1" : ( + (EngineList->Type.Port.PortData.LinkAspm == AspmL0sL1) ? "L0s & L1" : "Unknown"))) + ); + ASSERT (EngineList->Type.Port.PortData.LinkAspm < MaxAspm); + IDS_HDT_CONSOLE (PCIE_MISC, " Speed - %d\n", + EngineList->Type.Port.PortData.LinkSpeedCapability + ); + } else { + IDS_HDT_CONSOLE (PCIE_MISC, " DDI configuration:\n"); + IDS_HDT_CONSOLE (PCIE_MISC, " Connector - %s\n", + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDP) ? "DP" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDP) ? "eDP" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeSingleLinkDVI) ? "Single Link DVI" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDualLinkDVI) ? "Dual Link DVI" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeHDMI) ? "HDMI" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDpToVga) ? "DP-to-VGA" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDpToLvds) ? "DP-to-LVDS" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeLvds) ? "LVDS" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeSingleLinkDviI) ? "Single Link DVI-I" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeCrt) ? "CRT" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvds) ? "eDP To Lvds - No SW Init Required" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvdsSwInit) ? "Third party eDP To Lvds - SW Init Required" : ( + (EngineList->Type.Ddi.DdiData.ConnectorType == ConnectorTypeAutoDetect) ? "Autodetect" : "Unknown")))))))))))) + ); + ASSERT (EngineList->Type.Ddi.DdiData.ConnectorType < MaxConnectorType); + IDS_HDT_CONSOLE (PCIE_MISC, " Aux - Aux%d\n", EngineList->Type.Ddi.DdiData.AuxIndex + 1); + ASSERT (EngineList->Type.Ddi.DdiData.AuxIndex < MaxAux); + IDS_HDT_CONSOLE (PCIE_MISC, " Hdp - Hdp%d\n", EngineList->Type.Ddi.DdiData.HdpIndex + 1); + ASSERT (EngineList->Type.Ddi.DdiData.HdpIndex < MaxHdp); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump wrapper configuration + * + * + * @param[in] WrapperList Wrapper Configuration + */ +VOID +PcieConfigWrapperDebugDump ( + IN PCIe_WRAPPER_CONFIG *WrapperList + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config -------->\n", + PcieFmDebugGetWrapperNameString (WrapperList) + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Start PHY lane - %02d\n", WrapperList->StartPhyLane); + IDS_HDT_CONSOLE (PCIE_MISC, " End PHY lane - %02d\n", WrapperList->EndPhyLane); + IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", WrapperList->Header.DescriptorFlags); + IDS_HDT_CONSOLE (PCIE_MISC, " PowerOffUnusedLanes - %x\n PowerOffUnusedPlls - %x\n ClkGating - %x\n" + " LclkGating - %x\n TxclkGatingPllPowerDown - %x\n PllOffInL1 - %x\n", + WrapperList->Features.PowerOffUnusedLanes, + WrapperList->Features.PowerOffUnusedPlls, + WrapperList->Features.ClkGating, + WrapperList->Features.LclkGating, + WrapperList->Features.TxclkGatingPllPowerDown, + WrapperList->Features.PllOffInL1 + ); + IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config End----->\n", + PcieFmDebugGetWrapperNameString (WrapperList) + ); + EngineList = PcieConfigGetChildEngine (WrapperList); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + PcieConfigEngineDebugDump (EngineList); + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump configuration to debug out + * + * + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieConfigDebugDump ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *SiliconList; + PCIe_WRAPPER_CONFIG *WrapperList; + PCIe_COMPLEX_CONFIG *ComplexList; + ComplexList = (PCIe_COMPLEX_CONFIG *) PcieConfigGetChild (DESCRIPTOR_COMPLEX, &Pcie->Header); + IDS_HDT_CONSOLE (PCIE_MISC, "<-------------- PCIe Config Start------------>\n"); + IDS_HDT_CONSOLE (PCIE_MISC, " PSPP Policy - %s\n", + (Pcie->PsppPolicy == PsppPowerSaving) ? "Power Saving" : + (Pcie->PsppPolicy == PsppBalanceHigh) ? "Balance-High" : ( + (Pcie->PsppPolicy == PsppBalanceLow) ? "Balance-Low" : ( + (Pcie->PsppPolicy == PsppPerformance) ? "Performance" : ( + (Pcie->PsppPolicy == PsppDisabled) ? "Disabled" : "Unknown"))) + ); + IDS_HDT_CONSOLE (PCIE_MISC, " GFX Workaround - %s\n", + (Pcie->GfxCardWorkaround == 0) ? "Disabled" : "Enabled" + ); + IDS_HDT_CONSOLE (PCIE_MISC, " LinkL0Pooling - %dus\n", + Pcie->LinkL0Pooling + ); + IDS_HDT_CONSOLE (PCIE_MISC, " LinkGpioResetAssertionTime - %dus\n", + Pcie->LinkGpioResetAssertionTime + ); + IDS_HDT_CONSOLE (PCIE_MISC, " LinkReceiverDetectionPooling - %dus\n", + Pcie->LinkReceiverDetectionPooling + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Training Algorythm - %s\n", + (Pcie->TrainingAlgorithm == PcieTrainingStandard) ? "PcieTrainingStandard" : ( + (Pcie->TrainingAlgorithm == PcieTrainingDistributed) ? "PcieTrainingDistributed" : "Unknown") + ); + while (ComplexList != NULL) { + IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Complex Config Start ---------->\n"); + IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", ComplexList->Header.DescriptorFlags); + IDS_HDT_CONSOLE (PCIE_MISC, " Socket ID - %d\n", ComplexList->SocketId); + SiliconList = PcieConfigGetChildSilicon (ComplexList); + while (SiliconList != NULL) { + IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Silicon Config Start -------->\n"); + IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", SiliconList->Header.DescriptorFlags); + IDS_HDT_CONSOLE (PCIE_MISC, " Silicon ID - %d\n", SiliconList->SiliconId); + IDS_HDT_CONSOLE (PCIE_MISC, " Node ID - %d\n", SiliconList->NodeId); + IDS_HDT_CONSOLE (PCIE_MISC, " Host PCI Address - %d:%d:%d\n", + SiliconList->Address.Address.Bus, + SiliconList->Address.Address.Device, + SiliconList->Address.Address.Function + ); + WrapperList = PcieConfigGetChildWrapper (SiliconList); + while (WrapperList != NULL) { + PcieConfigWrapperDebugDump (WrapperList); + WrapperList = PcieLibGetNextDescriptor (WrapperList); + } + IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Silicon Config End ---------->\n"); + SiliconList = PcieLibGetNextDescriptor (SiliconList); + } + IDS_HDT_CONSOLE (PCIE_MISC, " <---------- Complex Config End ------------>\n"); + ComplexList = PcieLibGetNextDescriptor (ComplexList); + } + IDS_HDT_CONSOLE (PCIE_MISC, "<-------------- PCIe Config End-------------->\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump input configuration to user engine descriptor + * + * + * @param[in] EngineDescriptor Pointer to engine descriptor + */ +VOID +PcieUserDescriptorConfigDump ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor + ) +{ + + IDS_HDT_CONSOLE (PCIE_MISC, " Engine Type - %s\n", + (EngineDescriptor->EngineData.EngineType == PciePortEngine) ? "PCIe Port" : ( + (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) ? "DDI Link" : ( + (EngineDescriptor->EngineData.EngineType == PcieUnusedEngine) ? "Unused" : "Invalid")) + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Start Phy Lane - %d\n End Phy Lane - %d\n", + EngineDescriptor->EngineData.StartLane, + EngineDescriptor->EngineData.EndLane + ); + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + IDS_HDT_CONSOLE (PCIE_MISC, " PortPresent - %d\n ChannelType - %d\n DeviceNumber - %d\n FunctionNumber - %d\n LinkSpeedCapability - %d\n LinkAspm - %d\n LinkHotplug - %d\n ResetId - %d\n SB link - %d\n MiscControls - 0x%02x\n" , + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.PortPresent, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.ChannelType, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.DeviceNumber, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.FunctionNumber, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkSpeedCapability, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkAspm, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkHotplug, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.ResetId, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.MiscControls.SbLink, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.MiscControls + ); + } + if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + IDS_HDT_CONSOLE (PCIE_MISC, " ConnectorType - %d\n AuxIndex - %d\n HdpIndex - %d\n" , + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.ConnectorType, + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.AuxIndex, + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.HdpIndex + ); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump input configuration to debug out + * + * + * @param[in] ComplexDescriptor Pointer to user defined complex descriptor + */ +VOID +PcieUserConfigConfigDump ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor + ) +{ + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + PCIe_COMPLEX_DESCRIPTOR *CurrentComplexDescriptor; + UINTN ComplexIndex; + UINTN Index; + UINTN NumberOfEngines; + UINTN NumberOfComplexes; + + IDS_HDT_CONSOLE (PCIE_MISC, "<---------- PCIe User Config Start------------->\n"); + + NumberOfComplexes = PcieInputParserGetNumberOfComplexes (ComplexDescriptor); + for (ComplexIndex = 0; ComplexIndex < NumberOfComplexes; ++ComplexIndex) { + CurrentComplexDescriptor = PcieInputParserGetComplexDescriptor (ComplexDescriptor, ComplexIndex); + NumberOfEngines = PcieInputParserGetNumberOfEngines (CurrentComplexDescriptor); + IDS_HDT_CONSOLE (PCIE_MISC, " ComplexDescriptor SocketId - %d\n NumberOfEngines - %d\n", + ComplexDescriptor->SocketId, + NumberOfEngines + ); + + for (Index = 0; Index < NumberOfEngines; Index++) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, Index); + PcieUserDescriptorConfigDump (EngineDescriptor); + } + } + IDS_HDT_CONSOLE (PCIE_MISC, "<---------- PCIe User Config End-------------->\n"); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.h new file mode 100644 index 0000000000..45e5e460df --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieConfigLib.h @@ -0,0 +1,221 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB function to create/locate PCIe configuration data area + * + * Contain code that create/locate and rebase configuration data area. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIECONFIGLIB_H_ +#define _PCIECONFIGLIB_H_ + +typedef VOID (*PCIe_RUN_ON_ENGINE_CALLBACK) ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +typedef AGESA_STATUS (*PCIe_RUN_ON_WRAPPER_CALLBACK) ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +typedef AGESA_STATUS (*PCIe_RUN_ON_DESCRIPTOR_CALLBACK) ( + IN PCIe_DESCRIPTOR_HEADER *Descriptor, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT8 +PcieConfigGetPcieEngineMasterLane ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT8 +PcieConfigGetNumberOfCoreLane ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +VOID +PcieConfigDisableAllEngines ( + IN UINTN EngineTypeMask, + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PcieConfigDisableEngine ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT32 +PcieConfigGetEnginePhyLaneBitMap ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT8 +PcieConfigGetNumberOfPhyLane ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT64 +PcieConfigGetConfigurationSignature ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT8 CoreId + ); + +BOOLEAN +PcieConfigCheckPortStatus ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT32 PortStatus + ); + +UINT16 +PcieConfigUpdatePortStatus ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_ENGINE_INIT_STATUS SetStatus, + IN PCIe_ENGINE_INIT_STATUS ResetStatus + ); + +VOID +PcieConfigRunProcForAllEngines ( + IN UINT32 DescriptorFlags, + IN PCIe_RUN_ON_ENGINE_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieConfigRunProcForAllWrappers ( + IN UINT32 DescriptorFlags, + IN PCIe_RUN_ON_WRAPPER_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieConfigRunProcForAllDescriptors ( + IN UINT32 InDescriptorFlags, + IN UINT32 OutDescriptorFlags, + IN UINT32 TerminationFlags, + IN PCIe_RUN_ON_DESCRIPTOR_CALLBACK Callback, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetParent ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ); + +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetChild ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ); + +PCIe_DESCRIPTOR_HEADER * +PcieConfigGetPeer ( + IN UINT32 Type, + IN PCIe_DESCRIPTOR_HEADER *Descriptor + ); + +BOOLEAN +PcieConfigIsActivePcieEngine ( + IN PCIe_ENGINE_CONFIG *Engine + ); + +PCIe_ENGINE_CONFIG * +PcieConfigLocateSbEngine ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PcieConfigDebugDump ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieConfigWrapperDebugDump ( + IN PCIe_WRAPPER_CONFIG *WrapperList + ); + +VOID +PcieConfigEngineDebugDump ( + IN PCIe_ENGINE_CONFIG *EngineList + ); + +VOID +PcieUserConfigConfigDump ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor + ); + +VOID +PcieUserDescriptorConfigDump ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor + ); + +#define PcieConfigGetParentWrapper(Descriptor) ((PCIe_WRAPPER_CONFIG *) PcieConfigGetParent (DESCRIPTOR_ALL_WRAPPERS, &((Descriptor)->Header))) +#define PcieConfigGetParentSilicon(Descriptor) ((PCIe_SILICON_CONFIG *) PcieConfigGetParent (DESCRIPTOR_SILICON, &((Descriptor)->Header))) +#define PcieConfigGetParentComplex(Descriptor) ((PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &((Descriptor)->Header))) +#define PcieConfigGetPlatform(Descriptor) ((PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &((Descriptor)->Header))) +#define PcieConfigGetChildWrapper(Descriptor) ((PCIe_WRAPPER_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_WRAPPERS, &((Descriptor)->Header))) +#define PcieConfigGetChildEngine(Descriptor) ((PCIe_ENGINE_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_ENGINES, &((Descriptor)->Header))) +#define PcieConfigGetChildSilicon(Descriptor) ((PCIe_SILICON_CONFIG *) PcieConfigGetChild (DESCRIPTOR_SILICON, &((Descriptor)->Header))) +#define PcieConfigGetNextDescriptor(Descriptor) ((((Descriptor->Header.DescriptorFlags & DESCRIPTOR_TERMINATE_LIST) != 0) ? NULL : (++Descriptor))) +#define PcieConfigIsPcieEngine(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_PCIE_ENGINE) != 0) : FALSE) +#define PcieConfigIsDdiEngine(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_DDI_ENGINE) != 0) : FALSE) +#define PcieConfigIsPcieWrapper(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_PCIE_WRAPPER) != 0) : FALSE) +#define PcieConfigIsSbPcieEngine(Engine) (Engine != NULL ? ((BOOLEAN) (Engine->Type.Port.PortData.MiscControls.SbLink)) : FALSE) +#define PcieConfigIsDdiWrapper(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_DDI_WRAPPER) != 0) : FALSE) +#define PcieConfigIsEngineAllocated(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_ALLOCATED) != 0) : FALSE) +#define PcieConfigIsVirtualDesciptor(Descriptor) (Descriptor != NULL ? ((Descriptor->Header.DescriptorFlags & DESCRIPTOR_VIRTUAL) != 0) : FALSE) +#define PcieConfigSetDescriptorFlags(Descriptor, SetDescriptorFlags) if (Descriptor != NULL) (Descriptor)->Header.DescriptorFlags |= SetDescriptorFlags +#define PcieConfigResetDescriptorFlags(Descriptor, ResetDescriptorFlags) if (Descriptor != NULL) ((PCIe_DESCRIPTOR_HEADER *) Descriptor)->DescriptorFlags &= (~(ResetDescriptorFlags)) +#define PcieInputParsetGetNextDescriptor(Descriptor) (Descriptor != NULL ? ((((Descriptor->Flags & DESCRIPTOR_TERMINATE_LIST) != 0) ? NULL : (Descriptor+1))) : NULL) +#define PcieConfigGetNextTopologyDescriptor(Descriptor, Termination) (Descriptor != NULL ? (((((PCIe_DESCRIPTOR_HEADER *) Descriptor)->DescriptorFlags & Termination) != 0) ? NULL : ((UINT8 *) Descriptor + ((PCIe_DESCRIPTOR_HEADER *) Descriptor)->Peer)) : NULL) +#define GnbGetNextHandle(Descriptor) (GNB_HANDLE *) PcieConfigGetNextTopologyDescriptor (Descriptor, DESCRIPTOR_TERMINATE_TOPOLOGY) +#define PcieConfigGetNextDataDescriptor(Descriptor) ((Descriptor->Flags & DESCRIPTOR_TERMINATE_LIST) != 0 ? NULL : Descriptor+1) + +#define PcieConfigGetStdHeader(Descriptor) ((AMD_CONFIG_PARAMS *)((PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &((Descriptor)->Header)))->StdHeader) + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.c new file mode 100644 index 0000000000..8a174b5344 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.c @@ -0,0 +1,277 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to parse PCIe input configuration data + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "PcieConfigLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIEINPUTPARSER_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINTN Index + ); + +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptorOfSocket ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINT32 SocketId + ); + +PCIe_ENGINE_DESCRIPTOR* +PcieInputParserGetEngineDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex, + IN UINTN Index + ); + +UINTN +PcieInputParserGetNumberOfEngines ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ); + +UINTN +PcieInputParserGetNumberOfComplexes ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList + ); + +UINTN +PcieInputParserGetLengthOfPcieEnginesList ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of complexes in platform topology configuration + * + * + * + * @param[in] ComplexList First complex configuration in complex configuration array + * @retval Number of Complexes + * + */ +UINTN +PcieInputParserGetNumberOfComplexes ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList + ) +{ + UINTN Result; + Result = 0; + while (ComplexList != NULL) { + Result++; + ComplexList = PcieInputParsetGetNextDescriptor (ComplexList); + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of PCIe engines in given complex + * + * + * + * @param[in] Complex Complex configuration + * @retval Number of Engines + */ +UINTN +PcieInputParserGetLengthOfPcieEnginesList ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ) +{ + UINTN Result; + PCIe_PORT_DESCRIPTOR *PciePortList; + Result = 0; + PciePortList = Complex->PciePortList; + while (PciePortList != NULL) { + Result++; + PciePortList = PcieInputParsetGetNextDescriptor (PciePortList); + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of DDI engines in given complex + * + * + * + * @param[in] Complex Complex configuration + * @retval Number of Engines + */ +STATIC UINTN +PcieInputParserGetLengthOfDdiEnginesList ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ) +{ + UINTN Result; + PCIe_DDI_DESCRIPTOR *DdiLinkList; + Result = 0; + DdiLinkList = Complex->DdiLinkList; + while (DdiLinkList != NULL) { + Result++; + DdiLinkList = PcieInputParsetGetNextDescriptor (DdiLinkList); + } + return Result; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get number of engines in given complex + * + * + * + * @param[in] Complex Complex configuration header + * @retval Number of Engines + */ +UINTN +PcieInputParserGetNumberOfEngines ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ) +{ + UINTN Result; + + Result = PcieInputParserGetLengthOfDdiEnginesList (Complex) + + PcieInputParserGetLengthOfPcieEnginesList (Complex); + return Result; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Complex descriptor by index from given Platform configuration + * + * + * + * @param[in] ComplexList Platform topology configuration + * @param[in] Index Complex descriptor Index + * @retval Pointer to Complex Descriptor + */ +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINTN Index + ) +{ + ASSERT (Index < (PcieInputParserGetNumberOfComplexes (ComplexList))); + return &ComplexList[Index]; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Complex descriptor by index from given Platform configuration + * + * + * + * @param[in] ComplexList Platform topology configuration + * @param[in] SocketId Socket Id + * @retval Pointer to Complex Descriptor + */ +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptorOfSocket ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINT32 SocketId + ) +{ + PCIe_COMPLEX_DESCRIPTOR *Result; + Result = NULL; + while (ComplexList != NULL) { + if (ComplexList->SocketId == SocketId) { + Result = ComplexList; + break; + } + ComplexList = PcieInputParsetGetNextDescriptor (ComplexList); + } + return Result; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Engine descriptor from given complex by index + * + * + * + * @param[in] Complex Complex descriptor + * @param[in] Index Engine descriptor index + * @retval Pointer to Engine Descriptor + */ +PCIe_ENGINE_DESCRIPTOR* +PcieInputParserGetEngineDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex, + IN UINTN Index + ) +{ + UINTN PcieListlength; + ASSERT (Index < (PcieInputParserGetNumberOfEngines (Complex))); + PcieListlength = PcieInputParserGetLengthOfPcieEnginesList (Complex); + if (Index < PcieListlength) { + return (PCIe_ENGINE_DESCRIPTOR*) &((Complex->PciePortList)[Index]); + } else { + return (PCIe_ENGINE_DESCRIPTOR*) &((Complex->DdiLinkList)[Index - PcieListlength]); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.h new file mode 100644 index 0000000000..488c514040 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieInputParser.h @@ -0,0 +1,83 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to parse PCIe input configuration data + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEINPUTPARSER_H_ +#define _PCIEINPUTPARSER_H_ + + +UINTN +PcieInputParserGetNumberOfComplexes ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList + ); + +UINTN +PcieInputParserGetNumberOfEngines ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ); + + +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINTN Index + ); + +PCIe_ENGINE_DESCRIPTOR* +PcieInputParserGetEngineDescriptor ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex, + IN UINTN Index + ); + +PCIe_COMPLEX_DESCRIPTOR* +PcieInputParserGetComplexDescriptorOfSocket ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexList, + IN UINT32 SocketId + ); + +UINTN +PcieInputParserGetLengthOfPcieEnginesList ( + IN PCIe_COMPLEX_DESCRIPTOR *Complex + ); +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c new file mode 100644 index 0000000000..cb24a9b284 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c @@ -0,0 +1,645 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to map user define topology to processor configuration + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GeneralServices.h" +#include "PcieInputParser.h" +#include "PcieMapTopology.h" +#include "GnbPcieConfig.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIEMAPTOPOLOGY_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +AGESA_STATUS +STATIC +PcieMapPortsPciAddresses ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieMapTopologyOnWrapper ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieMapInitializeEngineData ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +BOOLEAN +PcieCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +BOOLEAN +PcieIsDescriptorLinkWidthValid ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor + ); + +BOOLEAN +PcieCheckLanesMatch ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +BOOLEAN +PcieCheckDescriptorMapsToWrapper ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PcieAllocateEngine ( + IN UINT8 DescriptorIndex, + IN PCIe_ENGINE_CONFIG *Engine + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in] Complex Pointer to complex descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ + +AGESA_STATUS +PcieMapTopologyOnComplex ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_COMPLEX_CONFIG *Complex, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *Silicon; + PCIe_WRAPPER_CONFIG *Wrapper; + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnComplex Enter\n"); + Silicon = PcieConfigGetChildSilicon (Complex); + while (Silicon != NULL) { + Wrapper = PcieConfigGetChildWrapper (Silicon); + while (Wrapper != NULL) { + Status = PcieMapTopologyOnWrapper (ComplexDescriptor, Wrapper, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + PcieConfigDisableAllEngines (PciePortEngine | PcieDdiEngine, Wrapper); + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Fail to map topology on %s Wrapper\n", + PcieFmDebugGetWrapperNameString (Wrapper) + ); + ASSERT (FALSE); + } + Wrapper = PcieLibGetNextDescriptor (Wrapper); + } + Status = PcieMapPortsPciAddresses (Silicon, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + Silicon = PcieLibGetNextDescriptor (Silicon); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnComplex Exit [%x]\n", AgesaStatus); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] EngineType Engine type + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in] Wrapper Pointer to wrapper config descriptor + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ +STATIC AGESA_STATUS +PcieEnginesToWrapper ( + IN PCIE_ENGINE_TYPE EngineType, + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + AGESA_STATUS Status; + PCIe_ENGINE_CONFIG *EngineList; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + UINT8 ConfigurationId; + UINT8 Allocations; + UINTN Index; + UINTN NumberOfDescriptors; + + ConfigurationId = 0; + Allocations = 0; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEnginesToWrapper Enter\n"); + NumberOfDescriptors = PcieInputParserGetNumberOfEngines (ComplexDescriptor); + do { + Status = PcieFmConfigureEnginesLaneAllocation (Wrapper, EngineType, ConfigurationId++); + if (Status == AGESA_SUCCESS) { + Allocations = 0; + for (Index = 0; Index < NumberOfDescriptors; Index++) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, Index); + if (EngineDescriptor->EngineData.EngineType == EngineType) { + // Step 1, belongs to wrapper check. + if (PcieCheckDescriptorMapsToWrapper (EngineDescriptor, Wrapper)) { + ++Allocations; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (!PcieLibIsEngineAllocated (EngineList)) { + // Step 2.user descriptor less or equal to link width of engine + if (PcieCheckLanesMatch (EngineDescriptor, EngineList)) { + // Step 3, Check if link width is correct.x1, x2, x4, x8, x16. + if (!PcieIsDescriptorLinkWidthValid (EngineDescriptor)) { + PcieConfigDisableEngine (EngineList); + return AGESA_ERROR; + } + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + // Step 4, Family specifc, port device number match engine device + if (PcieCheckPortPciDeviceMapping ((PCIe_PORT_DESCRIPTOR*) EngineDescriptor, EngineList)) { + //Step 5, Family specifc, lanes can be muxed. + if (PcieFmCheckPortPcieLaneCanBeMuxed ((PCIe_PORT_DESCRIPTOR*) EngineDescriptor, EngineList)) { + PcieAllocateEngine ((UINT8) Index, EngineList); + --Allocations; + break; + } + } + } else { + PcieAllocateEngine ((UINT8) Index, EngineList); + --Allocations; + break; + } + } + } //end if PcieLibIsEngineAllocated + EngineList = PcieLibGetNextDescriptor (EngineList); + } + } //end if PcieCheckDescriptorMapsToWrapper + } // end if EngineType + } //end for + } + } while (Status == AGESA_SUCCESS && Allocations != 0); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEnginesToWrapper Exit [%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if lane from user port descriptor (PCIe_PORT_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * + * + * @param[in] EngineDescriptor Pointer to used define engine descriptor + * @param[in] Wrapper Pointer to PCIe_WRAPPER_CONFIG + * @retval TRUE Belongs to wrapper + * @retval FALSE Not belongs to wrapper + */ +BOOLEAN +PcieCheckDescriptorMapsToWrapper ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + Result = FALSE; + + if (Wrapper->StartPhyLane <= DescriptorLoLane && DescriptorHiLane <= Wrapper->EndPhyLane) { + // Lanes of descriptor belongs to wrapper + Result = TRUE; + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Engine to be allocated. + * + * + * @param[in] DescriptorIndex UINT8 index + * @param[in] Engine Pointer to engine config + */ +VOID +PcieAllocateEngine ( + IN UINT8 DescriptorIndex, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + PcieConfigSetDescriptorFlags (Engine, DESCRIPTOR_ALLOCATED); + Engine->Scratch = DescriptorIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * PCIE port + * + * + * 1 Check if lane from user port descriptor (PCIe_PORT_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * 2 Check if link width from user descriptor less or equal to link width of engine (PCIe_ENGINE_CONFIG) + * 3 Check if link width is correct. Correct link width for PCIe port x1, x2, x4, x8, x16, correct link width for DDI x4, x8 + * 4 Check if user port device number (PCIe_PORT_DESCRIPTOR) match engine port device number (PCIe_ENGINE_CONFIG) + * 5 Check if lane can be muxed + * + * + * DDI Link + * + * 1 Check if lane from user port descriptor (PCIe_DDI_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * 2 Check lane from (PCIe_DDI_DESCRIPTOR) match exactly phy lane (PCIe_ENGINE_CONFIG) + * + * + * + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in,out] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ +AGESA_STATUS +PcieMapTopologyOnWrapper ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_ENGINE_CONFIG *EngineList; + UINT32 WrapperPhyLaneBitMap; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnWrapper Enter\n"); + AgesaStatus = AGESA_SUCCESS; + if (PcieLibIsPcieWrapper (Wrapper)) { + Status = PcieEnginesToWrapper (PciePortEngine, ComplexDescriptor, Wrapper); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + // If we can not map topology on wrapper we can not enable any engines. + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_PCIE_TOPOLOGY_CONFIGURATION, + Wrapper->WrapId, + Wrapper->StartPhyLane, + Wrapper->EndPhyLane, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableAllEngines (PciePortEngine, Wrapper); + } + } + if (PcieLibIsDdiWrapper (Wrapper)) { + Status = PcieEnginesToWrapper (PcieDdiEngine, ComplexDescriptor, Wrapper); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + // If we can not map topology on wrapper we can not enable any engines. + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_DDI_TOPOLOGY_CONFIGURATION, + Wrapper->WrapId, + Wrapper->StartPhyLane, + Wrapper->EndPhyLane, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableAllEngines (PcieDdiEngine, Wrapper); + } + } + // Copy engine data + PcieMapInitializeEngineData (ComplexDescriptor, Wrapper, Pcie); + + EngineList = PcieConfigGetChildEngine (Wrapper); + // Verify if we oversubscribe lanes and PHY link width + WrapperPhyLaneBitMap = 0; + while (EngineList != NULL) { + UINT32 EnginePhyLaneBitMap; + if (PcieLibIsEngineAllocated (EngineList)) { + EnginePhyLaneBitMap = PcieConfigGetEnginePhyLaneBitMap (EngineList); + if ((WrapperPhyLaneBitMap & EnginePhyLaneBitMap) != 0) { + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Lanes double subscribe lanes [Engine Lanes %d..%d]\n", + EngineList->EngineData.StartLane, + EngineList->EngineData.EndLane + ); + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_LANES_CONFIGURATION, + EngineList->EngineData.StartLane, + EngineList->EngineData.EndLane, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableEngine (EngineList); + Status = AGESA_ERROR; + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } else { + WrapperPhyLaneBitMap |= EnginePhyLaneBitMap; + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnWrapper Exit [%d]\n", AgesaStatus); + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize engine data + * + * + * + * @param[in] ComplexDescriptor Pointer to user defined complex descriptor + * @param[in,out] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieMapInitializeEngineData ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + if (EngineList->Scratch != 0xFF) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, EngineList->Scratch); + LibAmdMemCopy (&EngineList->EngineData, &EngineDescriptor->EngineData, sizeof (EngineDescriptor->EngineData), GnbLibGetHeader (Pcie)); + if (PcieLibIsDdiEngine (EngineList)) { + LibAmdMemCopy (&EngineList->Type.Ddi, &((PCIe_DDI_DESCRIPTOR*) EngineDescriptor)->Ddi, sizeof (PCIe_DDI_DATA), GnbLibGetHeader (Pcie)); + EngineList->Type.Ddi.DisplayPriorityIndex = (UINT8) EngineList->Scratch; + } else if (PcieLibIsPcieEngine (EngineList)) { + LibAmdMemCopy (&EngineList->Type.Port, &((PCIe_PORT_DESCRIPTOR*) EngineDescriptor)->Port, sizeof (PCIe_PORT_DATA), GnbLibGetHeader (Pcie)); + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate PCI addresses for all PCIe engines on silicon + * + * + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + BOOLEAN Result; + + if ((PortDescriptor->Port.DeviceNumber == Engine->Type.Port.NativeDevNumber && + PortDescriptor->Port.FunctionNumber == Engine->Type.Port.NativeFunNumber) || + (PortDescriptor->Port.DeviceNumber == 0 && PortDescriptor->Port.FunctionNumber == 0)) { + Result = TRUE; + } else { + Result = PcieFmCheckPortPciDeviceMapping (PortDescriptor, Engine); + } + + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate PCI addresses for all PCIe engines on silicon + * + * + * + * @param[in] Silicon Pointer to silicon configurration + * @param[in] Pcie Pointer PCIe configuration + * @retval AGESA_ERROR Fail to allocate PCI device address + * @retval AGESA_SUCCESS Successfully allocate PCI address for all PCIe ports + */ + +AGESA_STATUS +STATIC +PcieMapPortsPciAddresses ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + PCIe_WRAPPER_CONFIG *WrapperList; + PCIe_ENGINE_CONFIG *EngineList; + AgesaStatus = AGESA_SUCCESS; + WrapperList = PcieConfigGetChildWrapper (Silicon); + while (WrapperList != NULL) { + EngineList = PcieConfigGetChildEngine (WrapperList); + while (EngineList != NULL) { + if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { + Status = PcieFmMapPortPciAddress (EngineList); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + EngineList->Type.Port.Address.AddressValue = MAKE_SBDFO ( + 0, + Silicon->Address.Address.Bus, + EngineList->Type.Port.PortData.DeviceNumber, + EngineList->Type.Port.PortData.FunctionNumber, + 0 + ); + } else { + EngineList->Type.Port.PortData.PortPresent = OFF; + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Fail to allocate PCI address for PCIe port\n" + ); + //Report error + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_PCIE_PORT_CONFIGURATION, + EngineList->Type.Port.PortData.DeviceNumber, + 0, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + WrapperList = PcieLibGetNextDescriptor (WrapperList); + } + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * If link width from user descriptor less or equal to link width of engine + * + * + * @param[in] EngineDescriptor Pointer to used define engine descriptor + * @param[in] Engine Pointer to engine config + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieCheckLanesMatch ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + Result = FALSE; + + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + // + // If link width from user descriptor less or equal to link width of engine (PCIe_ENGINE_CONFIG) + // + if (DescriptorNumberOfLanes <= PcieConfigGetNumberOfCoreLane (Engine)) { + Result = TRUE; + } + } else if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + // + //For Ddi, check lane from (PCIe_DDI_DESCRIPTOR) match exactly phy lane (PCIe_ENGINE_CONFIG) + // + if ((Engine->EngineData.StartLane == DescriptorLoLane) && (Engine->EngineData.EndLane == DescriptorHiLane)) { + Result = TRUE; + } + } + + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Correct link width for PCIe port x1, x2, x4, x8, x16, correct link width for DDI x4, x8 + * + * + * @param[in] EngineDescriptor A pointer of PCIe_ENGINE_DESCRIPTOR + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieIsDescriptorLinkWidthValid ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + Result = FALSE; + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + if (DescriptorNumberOfLanes == 1 || DescriptorNumberOfLanes == 2 || DescriptorNumberOfLanes == 4 || + DescriptorNumberOfLanes == 8 || DescriptorNumberOfLanes == 16) { + Result = TRUE; + } + } else if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + if (DescriptorNumberOfLanes == 4 || DescriptorNumberOfLanes == 8 || DescriptorNumberOfLanes == 7) { + Result = TRUE; + } + } + + GNB_DEBUG_CODE ( + if (!Result) { + IDS_HDT_CONSOLE (PCIE_MISC, " Invalid Link width [Engine Lanes %d..%d]\n", + DescriptorLoLane, + DescriptorHiLane + ); + } + ); + + return Result; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.h new file mode 100644 index 0000000000..9cd49db41e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.h @@ -0,0 +1,57 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to map user define topology to processor configuration + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEMAPTOPOLOGY_H_ +#define _PCIEMAPTOPOLOGY_H_ + +AGESA_STATUS +PcieMapTopologyOnComplex ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_COMPLEX_CONFIG *Complex, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/GnbPcieInitLibV1.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/GnbPcieInitLibV1.h new file mode 100644 index 0000000000..01cd3530a2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/GnbPcieInitLibV1.h @@ -0,0 +1,60 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe Init Library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEINITLIBV1_H_ +#define _PCIEINITLIBV1_H_ + +#include "PciePifServices.h" +#include "PciePortRegAcc.h" +#include "PciePowerMgmt.h" +#include "PcieTimer.h" +#include "PcieTopologyServices.h" +#include "PcieUtilityLib.h" +#include "PcieWrapperRegAcc.h" +#include "PcieAspmExitLatency.h" +#include "PcieSiliconServices.h" +#include "PciePortServices.h" +#include "PcieAspm.h" +#include "PciePhyServices.h" +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.c new file mode 100644 index 0000000000..64e7cb36fc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.c @@ -0,0 +1,173 @@ +/** + * @file + * + * PCIe link ASPM Black List + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "PcieAspmBlackList.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEASPMBLACKLIST_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +UINT16 AspmBrDeviceTable[] = { + 0x1002, 0x9441, (UINT16) ~(AspmL1 | AspmL0s), + 0x10B5, 0xFFFF, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0402, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0193, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0422, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0292, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x00F9, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0141, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0092, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D0, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D1, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D2, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D3, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D5, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D7, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01D8, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01DC, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01DE, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x01DF, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x016A, (UINT16) ~(AspmL1 | AspmL0s), + 0x10DE, 0x0392, (UINT16) ~(AspmL1 | AspmL0s), + 0x168C, 0xFFFF, (UINT16) ~(AspmL0s), + 0x1B4B, 0x91A3, (UINT16) ~(AspmL0s), + 0x1B4B, 0x9123, (UINT16) ~(AspmL0s), + 0x1969, 0x1083, (UINT16) ~(AspmL0s), + 0x1033, 0x0194, (UINT16) ~(AspmL0s), + 0x1180, 0xE832, (UINT16) ~(AspmL0s), + 0x1180, 0xE823, (UINT16) ~(AspmL0s) +}; + +UINT16 Aspm168cL0sEnabled[] = { + 0x002B, + 0x002C, + 0x002E, + 0x002A, + 0x002D, + 0x0024, + 0x001B, + 0x0030, + 0x0032 +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Pcie ASPM Black List + * + * + * + * @param[in] LinkAspm PCie ASPM black list + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +PcieAspmBlackListFeature ( + IN PCIe_LINK_ASPM *LinkAspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 UpstreamDeviceId; + UINT32 DownstreamDeviceId; + UINTN i; + UINT32 DeviceId; + UINT32 VendorId; + + GnbLibPciRead (LinkAspm->UpstreamPort.AddressValue, AccessWidth32, &UpstreamDeviceId, StdHeader); + GnbLibPciRead (LinkAspm->DownstreamPort.AddressValue, AccessWidth32, &DownstreamDeviceId, StdHeader); + LinkAspm->BlackList = FALSE; + for (i = 0; i < (sizeof (AspmBrDeviceTable) / sizeof (UINT16)); i = i + 3) { + VendorId = AspmBrDeviceTable[i]; + DeviceId = AspmBrDeviceTable[i + 1]; + if (VendorId == (UINT16)UpstreamDeviceId || VendorId == (UINT16)DownstreamDeviceId ) { + if (DeviceId == 0xFFFF || DeviceId == (UpstreamDeviceId >> 16) || DeviceId == (DownstreamDeviceId >> 16)) { + LinkAspm->UpstreamAspm &= AspmBrDeviceTable[i + 2]; + LinkAspm->DownstreamAspm &= AspmBrDeviceTable[i + 2]; + LinkAspm->BlackList = TRUE; + } + } + } + if ((UINT16)UpstreamDeviceId == 0x168c) { + // Atheros (Ignore dev capability enable L1 if requested) + LinkAspm->UpstreamAspm = LinkAspm->RequestedAspm & AspmL1; + LinkAspm->DownstreamAspm = LinkAspm->UpstreamAspm; + GnbLibPciRMW (LinkAspm->UpstreamPort.AddressValue | 0x70C, AccessS3SaveWidth32, 0x0, 0x0F003F01, StdHeader); + + DeviceId = UpstreamDeviceId >> 16; + for (i = 0; i < (sizeof (Aspm168cL0sEnabled) / sizeof (UINT16)); i++) { + if (DeviceId == Aspm168cL0sEnabled[i]) { + LinkAspm->UpstreamAspm = LinkAspm->RequestedAspm & AspmL0sL1; + LinkAspm->DownstreamAspm = LinkAspm->UpstreamAspm & AspmL1; + } + } + + } + if (UpstreamDeviceId == 0x10831969) { + GnbLibPciRMW (LinkAspm->UpstreamPort.AddressValue | 0x12F8, AccessS3SaveWidth32, 0xFFF7F7FF, 0, StdHeader); + } + + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.h new file mode 100644 index 0000000000..3ae175da73 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmBlackList.h @@ -0,0 +1,55 @@ +/** + * @file + * + * PCIe ASPM Black List + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIEASPMBLACKLIST_H_ +#define _PCIEASPMBLACKLIST_H_ + +///PCIe ASPM Black List + +AGESA_STATUS +PcieAspmBlackListFeature ( + IN PCIe_LINK_ASPM *LinkAspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.h new file mode 100644 index 0000000000..a6aff55594 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieAspmExitLatency.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to calculate PCIe topology segment maximum exit latency + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIEASPMEXITLATENCY_H_ +#define _PCIEASPMEXITLATENCY_H_ + +VOID +PcieAspmGetMaxExitLatency ( + IN PCI_ADDR DownstreamPort, + OUT PCIe_ASPM_LATENCY_INFO *AspmLatencyInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.h new file mode 100644 index 0000000000..9b8156b563 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePhyServices.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PHY initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIEPHYSERVICES_H_ +#define _PCIEPHYSERVICES_H_ + +VOID +PciePhyApplyGanging ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePhyAvertClockPickers ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePhyChannelCharacteristic ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PciePhyForceDccRecalibration ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.c new file mode 100644 index 0000000000..2c9d1ce304 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.c @@ -0,0 +1,622 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PIF initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersCommon.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEPIFSERVICES_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +#define PIF_GANG_0to1 0x1 +#define PIF_GANG_2to3 (0x1 << 1) +#define PIF_GANG_4to5 (0x1 << 2) +#define PIF_GANG_6to7 (0x1 << 3) +#define PIF_GANG_0to3 (0x1 << 4) +#define PIF_GANG_4to7 (0x1 << 8) +#define PIF_GANG_0to7 (0x1 << 9) +#define PIF_GANG_ALL (0x1 << 25) + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Apply PIF ganging for all lanes for given wrapper + * + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + + +VOID +PciePifApplyGanging ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT32 LaneBitmap; + UINT8 Pif; + D0F0xE4_PIF_0011_STRUCT D0F0xE4_PIF_0011[2]; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifApplyGanging Enter\n"); + LibAmdMemFill (&D0F0xE4_PIF_0011, 0, sizeof (D0F0xE4_PIF_0011), GnbLibGetHeader (Pcie)); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + LaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE | LANE_TYPE_DDI_PHY_NATIVE, 0, EngineList); + switch (LaneBitmap) { + case 0x0003: + D0F0xE4_PIF_0011[0].Field.X2Lane10 = 0x1; + break; + case 0x000c: + D0F0xE4_PIF_0011[0].Field.X2Lane32 = 0x1; + break; + case 0x0030: + D0F0xE4_PIF_0011[0].Field.X2Lane54 = 0x1; + break; + case 0x00c0: + D0F0xE4_PIF_0011[0].Field.X2Lane76 = 0x1; + break; + case 0x000f: + D0F0xE4_PIF_0011[0].Field.X4Lane30 = 0x1; + break; + case 0x00f0: + D0F0xE4_PIF_0011[0].Field.X4Lane74 = 0x1; + break; + case 0x00ff: + D0F0xE4_PIF_0011[0].Field.X8Lane70 = 0x1; + break; + case 0x0300: + D0F0xE4_PIF_0011[1].Field.X2Lane10 = 1; + break; + case 0x0c00: + D0F0xE4_PIF_0011[1].Field.X2Lane32 = 0x1; + break; + case 0x3000: + D0F0xE4_PIF_0011[1].Field.X2Lane54 = 0x1; + break; + case 0xc000: + D0F0xE4_PIF_0011[1].Field.X2Lane76 = 0x1; + break; + case 0x0f00: + D0F0xE4_PIF_0011[1].Field.X4Lane30 = 0x1; + break; + case 0xf000: + D0F0xE4_PIF_0011[1].Field.X4Lane74 = 0x1; + break; + case 0xff00: + D0F0xE4_PIF_0011[1].Field.X8Lane70 = 0x1; + break; + case 0xffff: + D0F0xE4_PIF_0011[0].Field.MultiPif = 0x1; + D0F0xE4_PIF_0011[1].Field.MultiPif = 0x1; + break; + default: + break; + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0011_ADDRESS), + D0F0xE4_PIF_0011[Pif].Value, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifApplyGanging Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * PLL powerdown + * + * + * @param[in] LaneBitmap Power down PLL for these lanes + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifPllPowerDown ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Nibble; + UINT16 NibbleBitmap; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllPowerDown Enter\n"); + for (Nibble = 0; Nibble < 4; Nibble++) { + NibbleBitmap = (0xF << (Nibble * 4)); + if ((LaneBitmap & NibbleBitmap) == NibbleBitmap) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + Pcie + ); + + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateOff; + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllPowerDown Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PLL init for DDI + * + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifPllInitForDdi ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Nibble; + UINT32 LaneBitmap; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllInitForDdi Enter\n"); + LaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_DDI_PHY_NATIVE, 0, Wrapper); + for (Nibble = 0; Nibble < 4; Nibble++) { + if (LaneBitmap & (0xF << (Nibble * 4))) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + Pcie + ); + + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x2; + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + D0F0xE4_PIF_0012.Value, + FALSE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllInitForDdi Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Poll for on PIF to indicate action completion + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePollPifForCompeletion ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + UINT32 Value; + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + do { + Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, 0x15), + Pcie + ); + } while ((Value & 0xff) != 0xff); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable fifo reset + * + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + + +VOID +PciePifDisableFifoReset ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_RxDetectFifoResetMode_OFFSET, + D0F0xE4_PIF_0010_RxDetectFifoResetMode_WIDTH, + 0, + FALSE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Program LS2 exit time + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePifSetLs2ExitTime ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetLs2ExitTime Enter\n"); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_Ls2ExitTime_OFFSET, + D0F0xE4_PIF_0010_Ls2ExitTime_WIDTH, + 0x0, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetLs2ExitTime Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set PLL mode for L1 + * + * + * @param[in] LaneBitmap Power down PLL for these lanes + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifSetPllModeForL1 ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Nibble; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + for (Nibble = 0; Nibble < 4; Nibble++) { + if (LaneBitmap & (0xF << (Nibble * 4))) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + Pcie + ); + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x1; + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, (Nibble >> 1), D0F0xE4_PIF_0012_ADDRESS + (Nibble & 0x1)), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Program receiver detection power mode + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePifSetRxDetectPowerMode ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetRxDetectPowerMode Enter\n"); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_RxDetectTxPwrMode_OFFSET, + D0F0xE4_PIF_0010_RxDetectTxPwrMode_WIDTH, + 0x1, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetRxDetectPowerMode Enter\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Pll ramp up time + * + * + * + * @param[in] Rampup Ramp up time + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePifSetPllRampTime ( + IN PCIE_PLL_RAMPUP_TIME Rampup, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + D0F0xE4_PIF_0013_STRUCT D0F0xE4_PIF_0013; + D0F0xE4_PIF_0010_STRUCT D0F0xE4_PIF_0010; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetPllRampTime Enter\n"); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + Pcie + ); + D0F0xE4_PIF_0013.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + Pcie + ); + D0F0xE4_PIF_0010.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + Pcie + ); + if (Rampup == NormalRampup) { + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x1; + D0F0xE4_PIF_0013.Field.PllRampUpTime = 0x1; + D0F0xE4_PIF_0010.Field.Ls2ExitTime = 0x0; + } else { + D0F0xE4_PIF_0012.Field.PllRampUpTime = 0x3; + D0F0xE4_PIF_0013.Field.PllRampUpTime = 0x3; + D0F0xE4_PIF_0010.Field.Ls2ExitTime = 0x6; + } + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + D0F0xE4_PIF_0012.Value, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + D0F0xE4_PIF_0013.Value, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010.Value, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetPllRampTime Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Power down PIFs + * + * + * + * @param[in] Control Power up or Power down control + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePifPllPowerControl ( + IN PCIE_PIF_POWER_CONTROL Control, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + UINT8 PllPowerStateInOff; + PllPowerStateInOff = (Control == PowerDownPifs) ? PifPowerStateOff : PifPowerStateL0; + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + D0F0xE4_PIF_0012_PllPowerStateInOff_OFFSET, + D0F0xE4_PIF_0012_PllPowerStateInOff_WIDTH, + PllPowerStateInOff, + FALSE, + Pcie + ); + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + D0F0xE4_PIF_0013_PllPowerStateInOff_OFFSET, + D0F0xE4_PIF_0013_PllPowerStateInOff_WIDTH, + PllPowerStateInOff, + FALSE, + Pcie + ); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Power down PIFs + * + * + * + * @param[in] Control Power up/Down control + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePifFullPowerStateControl ( + IN PCIE_PIF_POWER_CONTROL Control, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + D0F0xE4_PIF_0013_STRUCT D0F0xE4_PIF_0013; + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + Pcie + ); + D0F0xE4_PIF_0013.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + Pcie + ); + if (Control == PowerDownPifs) { + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateOff; + D0F0xE4_PIF_0013.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0013.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0013.Field.TxPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0013.Field.RxPowerStateInRxs2 = PifPowerStateOff; + } else { + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateL0; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateL0; + D0F0xE4_PIF_0013.Field.PllPowerStateInOff = PifPowerStateLS2; + D0F0xE4_PIF_0013.Field.PllPowerStateInTxs2 = PifPowerStateLS2; + D0F0xE4_PIF_0013.Field.TxPowerStateInTxs2 = PifPowerStateL0; + D0F0xE4_PIF_0013.Field.RxPowerStateInRxs2 = PifPowerStateL0; + } + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0012_ADDRESS), + D0F0xE4_PIF_0012.Value, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0013_ADDRESS), + D0F0xE4_PIF_0013.Value, + FALSE, + Pcie + ); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.h new file mode 100644 index 0000000000..50dca90570 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePifServices.h @@ -0,0 +1,120 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PIF initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIEPIFSERVICES_H_ +#define _PCIEPIFSERVICES_H_ + +VOID +PciePifApplyGanging ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifPllPowerDown ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifPllInitForDdi ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePollPifForCompeletion ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifDisableFifoReset ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetLs2ExitTime ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetPllModeForL1 ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetRxDetectPowerMode ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetPllRampTime ( + IN PCIE_PLL_RAMPUP_TIME Rampup, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifPllPowerControl ( + IN PCIE_PIF_POWER_CONTROL Control, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifFullPowerStateControl ( + IN PCIE_PIF_POWER_CONTROL Control, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.c new file mode 100644 index 0000000000..3fc8561c02 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.c @@ -0,0 +1,273 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to access PCIe port indirect register + * space. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEPORTREGACC_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +UINT32 +PciePortRegisterRead ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterWrite ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PciePortRegisterReadField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterWriteField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterRMW ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCIe port indirect register. + * + * Support for unify register access through index/data pair on PCIe port + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] Pcie Pointer to internal configuration data area + * @retval Register Value + */ + +UINT32 +PciePortRegisterRead ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + GnbLibPciWrite (Engine->Type.Port.Address.AddressValue | 0xE0, AccessWidth32, &Address, GnbLibGetHeader (Pcie)); + GnbLibPciRead (Engine->Type.Port.Address.AddressValue | 0xE4, AccessWidth32, &Value, GnbLibGetHeader (Pcie)); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe Port Indirect register. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] Value New register value + * @param[in] S3Save Save for S3 flag + * @param[in] Pcie Pointer to internal configuration data area + */ +VOID +PciePortRegisterWrite ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + ASSERT (S3Save == TRUE || S3Save == FALSE); + + IDS_HDT_CONSOLE (PCIE_PORTREG_TRACE, " *WR PCIEIND_P (%d:%d:%d):0x%04x = 0x%08x\n", + Engine->Type.Port.Address.Address.Bus, + Engine->Type.Port.Address.Address.Device, + Engine->Type.Port.Address.Address.Function, + Address, + Value + ); + GnbLibPciWrite (Engine->Type.Port.Address.AddressValue | 0xE0, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Address, GnbLibGetHeader (Pcie)); + GnbLibPciWrite (Engine->Type.Port.Address.AddressValue | 0xE4, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Value, GnbLibGetHeader (Pcie)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe Port Indirect register field. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] S3Save Save for S3 flag + * @param[in] Value New register value + * @param[in] Pcie Pointer to internal configuration data area + */ + +VOID +PciePortRegisterWriteField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Data; + UINT32 Mask; + Data = PciePortRegisterRead (Engine, Address, Pcie); + Mask = (1 << FieldWidth) - 1; + Value &= Mask; + Data &= (~(Mask << FieldOffset)); + PciePortRegisterWrite (Engine, Address, Data | (Value << FieldOffset), S3Save, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe Port Indirect register field. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] Pcie Pointer to internal configuration data area + * @retval Register Field Value. + */ + +UINT32 +PciePortRegisterReadField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + Value = PciePortRegisterRead (Engine, Address, Pcie); + Value = (Value >> FieldOffset) & ((1 << FieldWidth) - 1); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCIe port register. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Engine Pointer to Engine descriptor for this port + * @param[in] Address Register address + * @param[in] AndMask Value & (~AndMask) + * @param[in] OrMask Value | OrMask + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePortRegisterRMW ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + Value = PciePortRegisterRead (Engine, Address, Pcie); + Value = (Value & (~AndMask)) | OrMask; + PciePortRegisterWrite (Engine, Address, Value, S3Save, Pcie); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.h new file mode 100644 index 0000000000..a6195485e8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortRegAcc.h @@ -0,0 +1,94 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to access PCIe port indirect register space. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEPORTREGACC_H_ +#define _PCIEPORTREGACC_H_ + +UINT32 +PciePortRegisterRead ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterWrite ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterWriteField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PciePortRegisterReadField ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortRegisterRMW ( + IN PCIe_ENGINE_CONFIG *Engine, + IN UINT16 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.c new file mode 100644 index 0000000000..c6688ebe96 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.c @@ -0,0 +1,396 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe port initialization service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersCommon.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEPORTSERVICES_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +UINT8 L1State = 0x1b; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Set completion timeout + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieCompletionTimeout ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | 0x80, + AccessWidth32, + 0xffffffff, + 0x6 << 0, + GnbLibGetHeader (Pcie) + ); + if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + PciePortRegisterWriteField ( + Engine, + 0x20, + 15, + 1, + 0x0, + TRUE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init hotplug port + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieLinkInitHotplug ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + if ((Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced) || (Engine->Type.Port.PortData.LinkHotplug == HotplugInboard)) { + Value = PciePortRegisterRead (Engine, 0xb5, Pcie); + Value |= 3 << 12; + Value |= 3 << 14; + Value |= 1 << 10; + PciePortRegisterWrite ( + Engine, + 0xb5, + Value, + TRUE, + Pcie + ); + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (Engine), + CORE_SPACE (Engine->Type.Port.CoreId, D0F0xE4_CORE_0010_ADDRESS), + D0F0xE4_CORE_0010_LcHotPlugDelSel_OFFSET, + D0F0xE4_CORE_0010_LcHotPlugDelSel_WIDTH, + 0x5, + TRUE, + Pcie + ); + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (Engine), + WRAP_SPACE (PcieConfigGetParentWrapper (Engine)->WrapId, D0F0xE4_WRAP_8011_ADDRESS), + D0F0xE4_WRAP_8011_RcvrDetClkEnable_OFFSET, + D0F0xE4_WRAP_8011_RcvrDetClkEnable_WIDTH, + 0x1, + TRUE, + Pcie + ); + } + if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | 0x6c, + AccessS3SaveWidth32, + 0xffffffff, + 1 << 6, + GnbLibGetHeader (Pcie) + ); + PciePortRegisterWriteField ( + Engine, + 0x20, + 15, + 1, + 0x0, + TRUE, + Pcie + ); + PciePortRegisterWriteField ( + Engine, + 0x70, + 19, + 1, + 0x1, + FALSE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set misc slot capability + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieLinkSetSlotCap ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | 0x58, + AccessWidth32, + 0xffffffff, + 1 << 24, + GnbLibGetHeader (Pcie) + ); + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | 0x3c, + AccessWidth32, + 0xffffffff, + 1 << 8, + GnbLibGetHeader (Pcie) + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Safe mode to force link advertize Gen1 only capability in TS + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieLinkSafeMode ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieFmSetLinkSpeedCap (PcieGen1, Engine, Pcie); + PciePortRegisterRMW ( + Engine, + 0xa2, + 0x2000, + (1 << 13), + FALSE, + Pcie + ); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set current link speed + * + * + * @param[in] Engine Pointer to engine configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieSetLinkWidthCap ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PciePortRegisterRMW ( + Engine, + 0xa2, + 0x2000, + 0, + FALSE, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set current link speed + * + * + * @param[in] LinkSpeedCapability Link Speed Capability + * @param[in] Engine Pointer to engine configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Force compliance + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieForceCompliance ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if (Engine->Type.Port.PortData.LinkSpeedCapability >= PcieGen2) { + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | 0x88, + AccessWidth32, + 0xffffffff, + 0x1 << 4, + GnbLibGetHeader (Pcie) + ); + } else if (Engine->Type.Port.PortData.LinkSpeedCapability == PcieGen1) { + PciePortRegisterWriteField ( + Engine, + 0xc0, + 13, + 1, + 0x1, + FALSE, + Pcie + ); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable ASPM on SB link + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieEnableAspm ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if (Engine->Type.Port.PortData.LinkAspm != AspmDisabled) { + if (PcieConfigIsSbPcieEngine (Engine)) { + SbPcieLinkAspmControl (Engine, Pcie); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Poll for link to get into L1 + * + * + * + * @param[in] Engine Pointer to Engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePollLinkForL1Entry ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkHwStateHistory[8]; + do { + PcieUtilGetLinkHwStateHistory (Engine, &LinkHwStateHistory[0], sizeof (LinkHwStateHistory), Pcie); + } while (!PcieUtilSearchArray (LinkHwStateHistory, sizeof (LinkHwStateHistory), &L1State, sizeof (L1State))); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Poll for link to get into L0 + * + * + * + * @param[in] Engine Pointer to Engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePollLinkForL0Exit ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkHwStateHistory[4]; + do { + PcieUtilGetLinkHwStateHistory (Engine, &LinkHwStateHistory[0], sizeof (LinkHwStateHistory), Pcie); + } while (LinkHwStateHistory[0] != 0x10); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.h new file mode 100644 index 0000000000..67c66bb6fc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePortServices.h @@ -0,0 +1,118 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe port initialization service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEPORTSERVICES_H_ +#define _PCIEPORTSERVICES_H_ + + +VOID +PcieSetLinkSpeedCap ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSetLinkWidthCap ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLinkSafeMode ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieCompletionTimeout ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLinkSetSlotCap ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLinkInitHotplug ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieForceCompliance ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieEnableSlotPowerLimit ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieEnableAspm ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePollLinkForL1Entry ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePollLinkForL0Exit ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.h new file mode 100644 index 0000000000..0eeee7979a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PciePowerMgmt.h @@ -0,0 +1,74 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Power saving features/services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEPOWERSAVINGFEATURES_H_ +#define _PCIEPOWERSAVINGFEATURES_H_ + + +VOID +PciePwrPowerDownUnusedLanes ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PcieLanesToPowerDownPllInL1 ( + IN UINT8 PllPowerUpLatency, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePwrAutoPowerDownElectricalIdleDetector ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePwrClockGating ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.h new file mode 100644 index 0000000000..66e59f41ea --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieSiliconServices.h @@ -0,0 +1,72 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe Complex Services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIESILICONSERVICES_H_ +#define _PCIESILICONSERVICES_H_ + +UINT8 +PcieSiliconGetGen1VoltageIndex ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieSiliconRequestVoltage ( + IN UINT8 VidIndex, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieSiliconUnHidePorts ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSiliconHidePorts ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.c new file mode 100644 index 0000000000..2a7a0db50c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.c @@ -0,0 +1,95 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe timer access procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 86079 $ @e \$Date: 2013-01-16 00:59:04 -0600 (Wed, 16 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbTimerLib.h" +#include "GnbRegistersCommon.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIETIMER_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Get PCIe timer timestamp + * + * + * + * @param[in] Pcie Pointer to internal configuration data area + * @retval Time stamp value + */ + +UINT32 +PcieTimerGetTimeStamp ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + return GnbFmTimeStamp (GnbLibGetHeader (Pcie)); +} \ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.h new file mode 100644 index 0000000000..c68d214602 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTimer.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe timer access procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIETIMER_H_ +#define _PCIETIMER_H_ + +UINT32 +PcieTimerGetTimeStamp ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#define TIMESTAMPS_DELTA(Time2, Time1) ((Time2 > Time1) ? (Time2 - Time1) : (0xffffffffull - Time1 + Time2)) + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.c new file mode 100644 index 0000000000..5151fb445d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.c @@ -0,0 +1,722 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe topology initialization service procedures. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersCommon.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIETOPOLOGYSERVICES_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Cleanup reconfig + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyCleanUpReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if (PcieLibIsPcieWrapper (Wrapper)) { + PcieRegisterRMW ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062_ConfigXferMode_MASK, + 1 << D0F0xE4_WRAP_8062_ConfigXferMode_OFFSET, + FALSE, + Pcie + ); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Prepare for reconfiguration + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyPrepareForReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; + UINT8 CoreId; + if (PcieLibIsPcieWrapper (Wrapper)) { + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + PcieRegisterWriteField ( + Wrapper, + CORE_SPACE (CoreId, D0F0xE4_CORE_0011_ADDRESS), + D0F0xE4_CORE_0011_DynClkLatency_OFFSET, + D0F0xE4_CORE_0011_DynClkLatency_WIDTH, + 0xf, + FALSE, + Pcie + ); + } + + D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8062.Field.ConfigXferMode = 0x0; + D0F0xE4_WRAP_8062.Field.BlockOnIdle = 0x0; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + } +} + + +UINT8 LaneMuxSelectorTable[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate mux array index + * + * + * + * @param[in, out] LaneMuxSelectorArrayPtr Pointer to mux selector array + * @param[in] LaneMuxValue The value that match to array + * @retval Index Index successfully mapped + */ +STATIC UINT8 +PcieTopologyLocateMuxIndex ( + IN OUT UINT8 *LaneMuxSelectorArrayPtr, + IN UINT8 LaneMuxValue + ) +{ + UINT8 Index; + for (Index = 0; Index < sizeof (LaneMuxSelectorTable); Index++ ) { + if (LaneMuxSelectorArrayPtr [Index] == LaneMuxValue) { + return Index; + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Apply lane mux + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieTopologyApplyLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT8 CurrentPhyLane; + UINT8 CurrentCoreLane; + UINT8 CoreLaneIndex; + UINT8 PhyLaneIndex; + UINT8 NumberOfPhyLane; + UINT8 TxLaneMuxSelectorArray [sizeof (LaneMuxSelectorTable)]; + UINT8 RxLaneMuxSelectorArray [sizeof (LaneMuxSelectorTable)]; + UINT8 Index; + UINT32 TxMaxSelectorValue; + UINT32 RxMaxSelectorValue; + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMux Enter\n"); + if (PcieLibIsPcieWrapper (Wrapper)) { + EngineList = PcieConfigGetChildEngine (Wrapper); + LibAmdMemCopy ( + &TxLaneMuxSelectorArray[0], + &LaneMuxSelectorTable[0], + sizeof (LaneMuxSelectorTable), + GnbLibGetHeader (Pcie) + ); + LibAmdMemCopy ( + &RxLaneMuxSelectorArray[0], + &LaneMuxSelectorTable[0], + sizeof (LaneMuxSelectorTable), + GnbLibGetHeader (Pcie) + ); + while (EngineList != NULL) { + if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { + CurrentPhyLane = (UINT8) PcieLibGetLoPhyLane (EngineList) - Wrapper->StartPhyLane; + NumberOfPhyLane = (UINT8) PcieConfigGetNumberOfPhyLane (EngineList); + CurrentCoreLane = (UINT8) EngineList->Type.Port.StartCoreLane; + if (PcieUtilIsLinkReversed (FALSE, EngineList, Pcie)) { + CurrentCoreLane = CurrentCoreLane + PcieConfigGetNumberOfCoreLane (EngineList) - NumberOfPhyLane; + } + for (Index = 0; Index < NumberOfPhyLane; Index = Index + 2 ) { + CoreLaneIndex = (CurrentCoreLane + Index) / 2; + PhyLaneIndex = (CurrentPhyLane + Index) / 2; + + if (RxLaneMuxSelectorArray [CoreLaneIndex] != PhyLaneIndex) { + RxLaneMuxSelectorArray [PcieTopologyLocateMuxIndex (RxLaneMuxSelectorArray, PhyLaneIndex)] = RxLaneMuxSelectorArray [CoreLaneIndex]; + RxLaneMuxSelectorArray [CoreLaneIndex] = PhyLaneIndex; + } + if (TxLaneMuxSelectorArray [PhyLaneIndex] != CoreLaneIndex) { + TxLaneMuxSelectorArray [PcieTopologyLocateMuxIndex (TxLaneMuxSelectorArray, CoreLaneIndex)] = TxLaneMuxSelectorArray [PhyLaneIndex]; + TxLaneMuxSelectorArray [PhyLaneIndex] = CoreLaneIndex; + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + RxMaxSelectorValue = 0; + TxMaxSelectorValue = 0; + for (Index = 0; Index < sizeof (LaneMuxSelectorTable); Index++) { + RxMaxSelectorValue |= (RxLaneMuxSelectorArray[Index] << (Index * 4)); + TxMaxSelectorValue |= (TxLaneMuxSelectorArray[Index] << (Index * 4)); + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8021_ADDRESS), + TxMaxSelectorValue, + FALSE, + Pcie + ); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8022_ADDRESS), + RxMaxSelectorValue, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMux Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Select master PLL + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[out] ConfigChanged Pointer to boolean indicator that configuration was changed + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieTopologySelectMasterPll ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + OUT BOOLEAN *ConfigChanged, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT16 MasterLane; + UINT16 MasterHotplugLane; + D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; + D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013_BASE; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); + MasterLane = 0xFFFF; + MasterHotplugLane = 0xFFFF; + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieConfigIsEngineAllocated (EngineList) && EngineList->Type.Port.PortData.PortPresent != PortDisabled && PcieConfigIsPcieEngine (EngineList)) { + if (EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) { + MasterHotplugLane = PcieConfigGetPcieEngineMasterLane (EngineList); + } else { + MasterLane = PcieConfigGetPcieEngineMasterLane (EngineList); + if (PcieConfigIsSbPcieEngine (EngineList)) { + break; + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + + if (MasterLane == 0xffff) { + if (MasterHotplugLane != 0xffff) { + MasterLane = MasterHotplugLane; + } else { + MasterLane = 0x0; + } + } + + D0F0xE4_WRAP_8013.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8013_BASE.Value = D0F0xE4_WRAP_8013.Value; + if ( MasterLane <= 3 ) { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x1; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; + Wrapper->MasterPll = 0xA; + } else if (MasterLane <= 7) { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x1; + D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; + Wrapper->MasterPll = 0xB; + } else if (MasterLane <= 11) { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x1; + D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; + Wrapper->MasterPll = 0xC; + } else { + D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; + D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x1; + Wrapper->MasterPll = 0xD; + } + if (ConfigChanged != NULL) { + *ConfigChanged = (D0F0xE4_WRAP_8013.Value == D0F0xE4_WRAP_8013_BASE.Value) ? FALSE : TRUE; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), + D0F0xE4_WRAP_8013.Value, + FALSE, + Pcie + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute/clean up reconfiguration + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyExecuteReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; + D0F0xE4_WRAP_8060_STRUCT D0F0xE4_WRAP_8060; + + if (PcieLibIsPcieWrapper (Wrapper)) { + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfig Enter\n"); + + PcieTopologyServices136_fun (FALSE, Wrapper, Pcie); + + D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8060.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8060_ADDRESS), + Pcie + ); + + D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x1; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + D0F0xE4_WRAP_8060.Field.Reconfigure = 0x1; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8060_ADDRESS), + D0F0xE4_WRAP_8060.Value, + FALSE, + Pcie + ); + do { + D0F0xE4_WRAP_8060.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8060_ADDRESS), + Pcie + ); + + } while (D0F0xE4_WRAP_8060.Field.Reconfigure == 1); + D0F0xE4_WRAP_8062.Field.ConfigXferMode = 0x1; + D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x0; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + PcieTopologyServices136_fun (TRUE, Wrapper, Pcie); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfig Exit\n"); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable lane reversal + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologySetLinkReversal ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Enter\n"); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + if (PcieLibIsPcieEngine (EngineList)) { + if (EngineList->EngineData.StartLane > EngineList->EngineData.EndLane) { + PciePortRegisterWriteField ( + EngineList, + 0xc1, + 4, + 1, + 0x1, + FALSE, + Pcie + ); + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Reduce link width + * + * + * @param[in] LinkWidth Link width + * @param[in] Engine Pointer to Engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyReduceLinkWidth ( + IN UINT8 LinkWidth, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_WRAPPER_CONFIG *Wrapper; + UINT32 LinkReversed; + UINT8 DeltaLinkWidthBitmap; + UINT32 LanesToDisable; + Wrapper = PcieConfigGetParentWrapper (Engine); + LinkReversed = PcieUtilIsLinkReversed (TRUE, Engine, Pcie); + + DeltaLinkWidthBitmap = (1 << (PcieConfigGetNumberOfCoreLane (Engine) - LinkWidth)) - 1; + LanesToDisable = (DeltaLinkWidthBitmap << ((LinkReversed == 1) ? Engine->Type.Port.StartCoreLane : (Engine->Type.Port.StartCoreLane + LinkWidth))); + + PcieTopologyLaneControl ( + DisableLanes, + LanesToDisable, + Wrapper, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Lanes enable/disable control + * + * @param[in] Control Lane control action + * @param[in] LaneBitMap Core lanes bitmap + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyLaneControl ( + IN LANE_CONTROL Control, + IN UINT32 LaneBitMap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8023_STRUCT D0F0xE4_WRAP_8023; + D0F0xE4_WRAP_8023.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8023_ADDRESS), + Pcie + ); + + if (Control == EnableLanes) { + D0F0xE4_WRAP_8023.Value |= LaneBitMap; + } else if (Control == DisableLanes) { + D0F0xE4_WRAP_8023.Value &= (~LaneBitMap); + } + D0F0xE4_WRAP_8023.Value &= ((1 << Wrapper->NumberOfLanes) - 1); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8023_ADDRESS), + D0F0xE4_WRAP_8023.Value, + TRUE, + Pcie + ); +} + +VOID +PcieTopologyServices136_fun ( + IN BOOLEAN fv0, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + GNBREGCOMMON_STR1_STRUCT GNBREGCOMMON_STR1; + GNBREGCOMMON_STR1.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x8063), + Pcie + ); + if (fv0) { + GNBREGCOMMON_STR1.Field.bit4 = 0x1; + GNBREGCOMMON_STR1.Field.bit5 = 0x1; + GNBREGCOMMON_STR1.Field.bit12 = 0x1; + GNBREGCOMMON_STR1.Field.bit13 = 0x1; + GNBREGCOMMON_STR1.Field.bit14 = 0x1; + } else { + GNBREGCOMMON_STR1.Field.bit4 = 0x0; + GNBREGCOMMON_STR1.Field.bit5 = 0x0; + GNBREGCOMMON_STR1.Field.bit12 = 0x0; + GNBREGCOMMON_STR1.Field.bit13 = 0x0; + GNBREGCOMMON_STR1.Field.bit14 = 0x0; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, 0x8063), + GNBREGCOMMON_STR1.Value, + FALSE, + Pcie + ); + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set core configuration according to PCIe port topology + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[out] ConfigChanged Pointer to boolean indicator that configuration was changed + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ + +AGESA_STATUS +PcieTopologySetCoreConfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + OUT BOOLEAN *ConfigChanged, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 CoreId; + AGESA_STATUS Status; + D0F0xE4_WRAP_0080_STRUCT D0F0xE4_WRAP_0080; + + Status = AGESA_SUCCESS; + if (PcieLibIsPcieWrapper (Wrapper)) { + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + UINT64 ConfigurationSignature; + UINT8 NewConfigurationValue; + ConfigurationSignature = PcieConfigGetConfigurationSignature (Wrapper, CoreId); + Status = PcieFmGetCoreConfigurationValue (Wrapper, CoreId, ConfigurationSignature, &NewConfigurationValue); + if (Status == AGESA_SUCCESS) { + IDS_HDT_CONSOLE (PCIE_MISC, " Core Configuration: Wrapper [%s], CoreID [%d] - %s\n", + PcieFmDebugGetWrapperNameString (Wrapper), + CoreId, + PcieFmDebugGetCoreConfigurationString (Wrapper, NewConfigurationValue) + ); + D0F0xE4_WRAP_0080.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_0080_ADDRESS), + Pcie + ); + if (ConfigChanged != NULL) { + if (D0F0xE4_WRAP_0080.Field.StrapBifLinkConfig != NewConfigurationValue) { + *ConfigChanged = TRUE; + } + } + D0F0xE4_WRAP_0080.Field.StrapBifLinkConfig = NewConfigurationValue; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_0080_ADDRESS), + D0F0xE4_WRAP_0080.Value, + FALSE, + Pcie + ); + } else { + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Core Configuration : Wrapper [%s], Signature [0x%x, 0x%x]\n", + PcieFmDebugGetWrapperNameString (Wrapper), + ((UINT32*)&ConfigurationSignature)[1], + ((UINT32*)&ConfigurationSignature)[0] + ); + PcieConfigDisableAllEngines (PciePortEngine | PcieDdiEngine, Wrapper); + } + } + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set TX control for PCIe lanes + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieWrapSetTxS1CtrlForLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8025_STRUCT D0F0xE4_WRAP_8025; + UINT32 LaneBitmap; + UINTN Index; + D0F0xE4_WRAP_8025.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS), + Pcie + ); + Index = 0; + LaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_CORE_ALL, LANE_TYPE_PCIE_SB_CORE_CONFIG, Wrapper); + while (LaneBitmap != 0) { + if ((LaneBitmap & 0xf) != 0) { + D0F0xE4_WRAP_8025.Value &= (~(0xff << (Index * 8))); + D0F0xE4_WRAP_8025.Value |= (((0x03 << 3) | 0x1) << (Index * 8)); + } + LaneBitmap >>= 4; + ++Index; + } + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS), + D0F0xE4_WRAP_8025.Value, + FALSE, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set TX control for lane muxes + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieWrapSetTxOffCtrlForLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8025_ADDRESS), + 0x1f1f1f1f, + FALSE, + Pcie + ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.h new file mode 100644 index 0000000000..00ffd58d9f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieTopologyServices.h @@ -0,0 +1,135 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe topology initialization service procedures. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIETOPOLOGYSERVICES_H_ +#define _PCIETOPOLOGYSERVICES_H_ + +VOID +PcieTopologyCleanUpReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyPrepareForReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieTopologySetCoreConfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + OUT BOOLEAN *ConfigChanged, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyApplyLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologySelectMasterPll ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + OUT BOOLEAN *ConfigChanged, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyExecuteReconfig ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologySetLinkReversal ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +VOID +PcieTopologyReduceLinkWidth ( + IN UINT8 LinkWidth, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyLaneControl ( + IN LANE_CONTROL Control, + IN UINT32 LaneBitMap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyServices136_fun ( + IN BOOLEAN fv0, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSetDdiOwnPhy ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieWrapSetTxS1CtrlForLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieWrapSetTxOffCtrlForLaneMux ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.c new file mode 100644 index 0000000000..6af26def32 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.c @@ -0,0 +1,661 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe utility. Various supporting functions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersCommon.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEUTILITYLIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +/// Lane type +typedef enum { + LaneTypeCore, ///< Core Lane + LaneTypePhy, ///< Package Phy Lane + LaneTypeNativePhy ///< Native Phy Lane +} LANE_TYPE; + +/// Lane Property +typedef enum { + LanePropertyConfig, ///< Configuration + LanePropertyActive, ///< Active + LanePropertyAllocated ///< Allocated +} LANE_PROPERTY; + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +typedef struct { + UINT32 Flags; + PCIE_LINK_SPEED_CAP LinkSpeedCapability; +} PCIE_GLOBAL_GEN_CAP_WORKSPACE; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Get link state history from HW state machine + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[out] History Buffer to save history + * @param[in] Length Buffer length + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieUtilGetLinkHwStateHistory ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT UINT8 *History, + IN UINT8 Length, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 ReadLength; + UINT32 LocalHistory [6]; + UINT16 Index; + ASSERT (Length <= 16); + ASSERT (Length > 0); + if (Length > 6*4) { + Length = 6*4; + } + ReadLength = (Length + 3) / 4; + for (Index = 0; Index < ReadLength; Index++) { + LocalHistory[Index] = PciePortRegisterRead ( + Engine, + 0xa5 + Index, + Pcie + ); + } + LibAmdMemCopy (History, LocalHistory, Length, GnbLibGetHeader (Pcie)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Search array for specific pattern + * + * + * @param[in] Buf1 Pointer to source buffer which will be subject of search + * @param[in] Buf1Length Length of the source buffer + * @param[in] Buf2 Pointer to pattern buffer + * @param[in] Buf2Length Length of the pattern buffer + * @retval TRUE Pattern found + * @retval TRUE Pattern not found + */ + +BOOLEAN +PcieUtilSearchArray ( + IN UINT8 *Buf1, + IN UINTN Buf1Length, + IN UINT8 *Buf2, + IN UINTN Buf2Length + ) +{ + UINT8 *CurrentBuf1Ptr; + CurrentBuf1Ptr = Buf1; + while (CurrentBuf1Ptr < (Buf1 + Buf1Length - Buf2Length)) { + UINT8 *SourceBufPtr; + UINT8 *PatternBufPtr; + UINTN PatternBufLength; + SourceBufPtr = CurrentBuf1Ptr; + PatternBufPtr = Buf2; + PatternBufLength = Buf2Length; + while ((*SourceBufPtr++ == *PatternBufPtr++) && (PatternBufLength-- != 0)); + if (PatternBufLength == 0) { + return TRUE; + } + CurrentBuf1Ptr++; + } + return FALSE; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if link reversed + * + * + * @param[in] HwLinkState Check for HW auto link reversal + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to PCIe config descriptor + * @retval TRUE if link reversed + */ +BOOLEAN +PcieUtilIsLinkReversed ( + IN BOOLEAN HwLinkState, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 LinkReversal; + + LinkReversal = (Engine->EngineData.StartLane > Engine->EngineData.EndLane) ? 1 : 0; + if (HwLinkState) { + UINT32 Value; + Value = PciePortRegisterRead ( + Engine, + 0x50, + Pcie + ); + LinkReversal ^= (Value & 1); + } + return ((LinkReversal & BIT0) != 0) ? TRUE : FALSE; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get link width detected during training + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Link width + */ +UINT8 +PcieUtilGetLinkWidth ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkWidth; + UINT32 Value; + Value = PciePortRegisterRead ( + Engine, + 0xA2, + Pcie + ); + switch ((Value & 7) >> 4) { + case 0x6: + LinkWidth = 16; + break; + case 0x5: + LinkWidth = 12; + break; + case 0x4: + LinkWidth = 8; + break; + case 0x3: + LinkWidth = 4; + break; + case 0x2: + LinkWidth = 2; + break; + case 0x1: + LinkWidth = 1; + break; + default: + LinkWidth = 0; + } + return LinkWidth; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of PCIE engine lane of requested type + * + * + * @param[in] LaneType Lane type + * @param[in] LaneProperty Lane Property + * @param[in] Engine Pointer to engine config descriptor + * @retval Lane bitmap + */ + +STATIC UINT32 +PcieUtilGetPcieEngineLaneBitMap ( + IN LANE_TYPE LaneType, + IN LANE_PROPERTY LaneProperty, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT32 LaneBitmap; + UINT8 Width; + UINT16 Offset; + UINT16 LoPhylane; + UINT16 HiPhylane; + PCIe_PLATFORM_CONFIG *Pcie; + + Width = 0; + Offset = 0; + LaneBitmap = 0; + Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Engine->Header); + + if (PcieConfigIsPcieEngine (Engine)) { + if (LaneType == LaneTypeCore && LaneProperty == LanePropertyConfig) { + Width = PcieConfigGetNumberOfCoreLane (Engine); + Offset = Engine->Type.Port.StartCoreLane; + LaneBitmap = ((1 << Width) - 1) << Offset; + } else if (PcieConfigIsEngineAllocated (Engine)) { + if (LaneType == LaneTypeNativePhy) { + LaneBitmap = PcieUtilGetPcieEngineLaneBitMap (LaneTypePhy, LaneProperty, Engine); + LaneBitmap = PcieFmGetNativePhyLaneBitmap (LaneBitmap, Engine); + } else { + if (LaneType == LaneTypeCore) { + if (LaneProperty == LanePropertyActive) { + Width = PcieUtilGetLinkWidth (Engine, Pcie); + Offset = PcieUtilIsLinkReversed (TRUE, Engine, Pcie) ? (Engine->Type.Port.EndCoreLane - Width + 1) : Engine->Type.Port.StartCoreLane; + } else if (LaneProperty == LanePropertyAllocated) { + Width = PcieConfigGetNumberOfPhyLane (Engine); + Offset = PcieUtilIsLinkReversed (FALSE, Engine, Pcie) ? (Engine->Type.Port.EndCoreLane - Width + 1) : Engine->Type.Port.StartCoreLane; + } + } + if (LaneType == LaneTypePhy) { + LoPhylane = PcieLibGetLoPhyLane (Engine); + HiPhylane = PcieLibGetHiPhyLane (Engine); + if (LaneProperty == LanePropertyActive) { + Width = PcieUtilGetLinkWidth (Engine, Pcie); + Offset = (PcieUtilIsLinkReversed (TRUE, Engine, Pcie) ? (HiPhylane - Width + 1) : LoPhylane) - PcieConfigGetParentWrapper (Engine)->StartPhyLane; + } else if (LaneProperty == LanePropertyAllocated) { + Width = PcieConfigGetNumberOfPhyLane (Engine); + Offset = LoPhylane - PcieConfigGetParentWrapper (Engine)->StartPhyLane; + } + } + LaneBitmap = ((1 << Width) - 1) << Offset; + } + } + } + return LaneBitmap; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of PCIE engine lane of requested type + * + * + * @param[in] LaneType Lane type + * @param[in] LaneProperty Lane Property + * @param[in] Engine Pointer to engine config descriptor + * @retval Lane bitmap + */ + +STATIC UINT32 +PcieUtilGetDdiEngineLaneBitMap ( + IN LANE_TYPE LaneType, + IN LANE_PROPERTY LaneProperty, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT32 LaneBitmap; + UINT8 Width; + UINT16 Offset; + Width = 0; + Offset = 0; + LaneBitmap = 0; + if (PcieConfigIsDdiEngine (Engine)) { + if (PcieConfigIsEngineAllocated (Engine)) { + if (LaneType == LaneTypePhy && ((LaneProperty == LanePropertyActive && (Engine->InitStatus & INIT_STATUS_DDI_ACTIVE)) || (LaneProperty == LanePropertyAllocated))) { + Width = PcieConfigGetNumberOfPhyLane (Engine); + Offset = PcieLibGetLoPhyLane (Engine) - PcieConfigGetParentWrapper (Engine)->StartPhyLane; + LaneBitmap = ((1 << Width) - 1) << Offset; + } + if (LaneType == LaneTypeNativePhy) { + LaneBitmap = PcieUtilGetDdiEngineLaneBitMap (LaneTypePhy, LaneProperty, Engine); + LaneBitmap = PcieFmGetNativePhyLaneBitmap (LaneBitmap, Engine); + } + } + } + return LaneBitmap; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of engine lane of requested type + * + * + * @param[in] IncludeLaneType Include Lane type + * @param[in] ExcludeLaneType Exclude Lane type + * @param[in] Engine Pointer to engine config descriptor + * @retval Lane bitmap + */ + +UINT32 +PcieUtilGetEngineLaneBitMap ( + IN UINT32 IncludeLaneType, + IN UINT32 ExcludeLaneType, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + UINT32 LaneBitmap; + LaneBitmap = 0; + if (IncludeLaneType & LANE_TYPE_PCIE_LANES) { + if (IncludeLaneType & LANE_TYPE_PCIE_CORE_CONFIG) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyConfig, Engine); + } + if (IncludeLaneType & LANE_TYPE_PCIE_CORE_ALLOC) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & (LANE_TYPE_PCIE_CORE_ACTIVE | LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE)) { + if (Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_PORT_IN_COMPLIANCE)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); + } else if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + if (IncludeLaneType & LANE_TYPE_PCIE_CORE_ALLOC_ACTIVE) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); + } else { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyActive, Engine); + } + } + } + if ((IncludeLaneType & LANE_TYPE_PCIE_SB_CORE_CONFIG) && PcieConfigIsSbPcieEngine (Engine)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyConfig, Engine); + } + if ((IncludeLaneType & LANE_TYPE_PCIE_CORE_HOTPLUG) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeCore, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & LANE_TYPE_PCIE_PHY) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypePhy, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & (LANE_TYPE_PCIE_PHY_NATIVE_ACTIVE | LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE)) { + if (Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced || PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_PORT_IN_COMPLIANCE)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } else if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + if (IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_ALLOC_ACTIVE) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } else { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyActive, Engine); + } + } + } + if ((IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_HOTPLUG) && (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled)) { + LaneBitmap |= PcieUtilGetPcieEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } + } + if (IncludeLaneType & LANE_TYPE_DDI_LANES) { + if (IncludeLaneType & LANE_TYPE_DDI_PHY) { + LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypePhy, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & LANE_TYPE_DDI_PHY_NATIVE) { + LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypeNativePhy, LanePropertyAllocated, Engine); + } + if (IncludeLaneType & LANE_TYPE_DDI_PHY_NATIVE_ACTIVE) { + LaneBitmap |= PcieUtilGetDdiEngineLaneBitMap (LaneTypeNativePhy, LanePropertyActive, Engine); + } + } + if (ExcludeLaneType != 0) { + LaneBitmap &= (~PcieUtilGetEngineLaneBitMap (ExcludeLaneType, 0, Engine)); + } + return LaneBitmap; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of phy lane confugred for master pll + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @retval Lane bitmap + */ + +STATIC UINT32 +PcieUtilGetMasterPllLaneBitMap ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + if (Wrapper->MasterPll != 0) { + return 0xf << (Wrapper->MasterPll - 0xA) * 4; + } + return 0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of Wrapper lane of requested type + * + * + * @param[in] IncludeLaneType Include Lane type + * @param[in] ExcludeLaneType Exclude Lane type + * @param[in] Wrapper Pointer to wrapper config descriptor + * @retval Lane bitmap + */ + +UINT32 +PcieUtilGetWrapperLaneBitMap ( + IN UINT32 IncludeLaneType, + IN UINT32 ExcludeLaneType, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT32 LaneBitmap; + EngineList = PcieConfigGetChildEngine (Wrapper); + LaneBitmap = 0; + if ((IncludeLaneType | ExcludeLaneType) != 0) { + if ((IncludeLaneType & LANE_TYPE_ALL) == LANE_TYPE_ALL) { + LaneBitmap = (1 << (Wrapper->NumberOfLanes)) - 1; + if (ExcludeLaneType != 0) { + LaneBitmap &= (~PcieUtilGetWrapperLaneBitMap (ExcludeLaneType, 0, Wrapper)); + } + } else { + while (EngineList != NULL) { + LaneBitmap |= PcieUtilGetEngineLaneBitMap (IncludeLaneType, ExcludeLaneType, EngineList); + EngineList = PcieLibGetNextDescriptor (EngineList); + } + if ((IncludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_MASTER_PLL) != 0) { + LaneBitmap |= PcieUtilGetMasterPllLaneBitMap (Wrapper); + } + if ((ExcludeLaneType & LANE_TYPE_PCIE_PHY_NATIVE_MASTER_PLL) != 0) { + LaneBitmap &= (~PcieUtilGetMasterPllLaneBitMap (Wrapper)); + } + } + } + return LaneBitmap; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Program port register table + * + * + * + * @param[in] Table Pointer to table + * @param[in] Length number of entries + * @param[in] Engine Pointer to engine config descriptor + * @param[in] S3Save Save for S3 flag + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PciePortProgramRegisterTable ( + IN PCIE_PORT_REGISTER_ENTRY *Table, + IN UINTN Length, + IN PCIe_ENGINE_CONFIG *Engine, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINTN Index; + UINT32 Value; + for (Index = 0; Index < Length; Index++) { + Value = PciePortRegisterRead ( + Engine, + Table[Index].Reg, + Pcie + ); + Value &= (~Table[Index].Mask); + Value |= Table[Index].Data; + PciePortRegisterWrite ( + Engine, + Table[Index].Reg, + Value, + S3Save, + Pcie + ); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Lock registers + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieLockRegisters ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 CoreId; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieLockRegisters Enter\n"); + if (PcieLibIsPcieWrapper (Wrapper)) { + for (CoreId = Wrapper->StartPcieCoreId; CoreId <= Wrapper->EndPcieCoreId; CoreId++) { + PcieRegisterWriteField ( + Wrapper, + CORE_SPACE (CoreId, D0F0xE4_CORE_0010_ADDRESS), + D0F0xE4_CORE_0010_HwInitWrLock_OFFSET, + D0F0xE4_CORE_0010_HwInitWrLock_WIDTH, + 0x1, + TRUE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieLockRegisters Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Training state handling + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Indicate if engine in non final state + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieUtilGlobalGenCapabilityCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_GLOBAL_GEN_CAP_WORKSPACE *GlobalGenCapability; + PCIE_LINK_SPEED_CAP LinkSpeedCapability; + PCIE_HOTPLUG_TYPE HotPlugType; + UINT32 Flags; + + Flags = PCIE_GLOBAL_GEN_CAP_ALL_PORTS; + GlobalGenCapability = (PCIE_GLOBAL_GEN_CAP_WORKSPACE*) Buffer; + LinkSpeedCapability = PcieGen1; + if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS)) { + Flags |= PCIE_GLOBAL_GEN_CAP_TRAINED_PORTS; + } + HotPlugType = Engine->Type.Port.PortData.LinkHotplug; + if ((HotPlugType == HotplugBasic) || (HotPlugType == HotplugServer) || (HotPlugType == HotplugEnhanced)) { + Flags |= PCIE_GLOBAL_GEN_CAP_HOTPLUG_PORTS; + } + if ((GlobalGenCapability->Flags & Flags) != 0) { + ASSERT ((GlobalGenCapability->Flags & (PCIE_PORT_GEN_CAP_MAX | PCIE_PORT_GEN_CAP_BOOT)) != 0); + LinkSpeedCapability = PcieFmGetLinkSpeedCap (GlobalGenCapability->Flags, Engine); + if (GlobalGenCapability->LinkSpeedCapability < LinkSpeedCapability) { + GlobalGenCapability->LinkSpeedCapability = LinkSpeedCapability; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Determine global GEN capability + * + * + * @param[in] Flags global GEN capability flags + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +PCIE_LINK_SPEED_CAP +PcieUtilGlobalGenCapability ( + IN UINT32 Flags, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_LINK_SPEED_CAP GlobalCapability; + PCIE_GLOBAL_GEN_CAP_WORKSPACE GlobalGenCap; + + GlobalGenCap.LinkSpeedCapability = PcieGen1; + GlobalGenCap.Flags = Flags; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieUtilGlobalGenCapabilityCallback, + &GlobalGenCap, + Pcie + ); + + GlobalCapability = GlobalGenCap.LinkSpeedCapability; + + return GlobalCapability; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.h new file mode 100644 index 0000000000..09f090329b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieUtilityLib.h @@ -0,0 +1,131 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe utility. Various supporting functions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIEUTILLIB_H_ +#define _PCIEUTILLIB_H_ + +/// Core lanes +typedef enum { + AllCoreLanes, ///< All core lanes + AllocatedCoreLanes, ///< Allocated core lanes + ActiveCoreLanes, ///< Active core lanes + HotplugCoreLanes, ///< Hot plug core lanes + SbCoreLanes, ///< South bridge core lanes +} CORE_LANES; + +/// DDI lanes +typedef enum { + DdiAllLanes, ///< All DDI Lanes + DdiActiveLanes ///< Active DDI Lanes +} DDI_LANES; + +BOOLEAN +PcieUtilSearchArray ( + IN UINT8 *Buf1, + IN UINTN Buf1Length, + IN UINT8 *Buf2, + IN UINTN Buf2Length + ); + +VOID +PcieUtilGetLinkHwStateHistory ( + IN PCIe_ENGINE_CONFIG *Engine, + OUT UINT8 *History, + IN UINT8 Length, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +BOOLEAN +PcieUtilIsLinkReversed ( + IN BOOLEAN HwLinkState, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +UINT8 +PcieUtilGetLinkWidth ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +UINT32 +PcieUtilGetEngineLaneBitMap ( + IN UINT32 IncludeLaneType, + IN UINT32 ExcludeLaneType, + IN PCIe_ENGINE_CONFIG *Engine + ); + +UINT32 +PcieUtilGetWrapperLaneBitMap ( + IN UINT32 IncludeLaneType, + IN UINT32 ExcludeLaneType, + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PciePortProgramRegisterTable ( + IN PCIE_PORT_REGISTER_ENTRY *Table, + IN UINTN Length, + IN PCIe_ENGINE_CONFIG *Engine, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLockRegisters ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +PCIE_LINK_SPEED_CAP +PcieUtilGlobalGenCapability ( + IN UINT32 Flags, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.c new file mode 100644 index 0000000000..eed1d2fb77 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.c @@ -0,0 +1,300 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to access PCIe wrapper/core/PIF/PHY indirect register spaces + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#include "AGESA.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV1_PCIEWRAPPERREGACC_FILECODE +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCIe register value. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to Wrapper descriptor + * @param[in] Address Register address + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Register Value + */ +UINT32 +PcieRegisterRead ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if ((Wrapper->Features.AccessEncoding == 1) && ((Address & 0xff0000) == 0x010000)) { + Address = (Address & 0xffff) | 0x1400000 | ((Address >> 8) & 0xF0000); + } + return PcieSiliconRegisterRead (PcieConfigGetParentSilicon (Wrapper), Address, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCIe register value. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Silicon Pointer to silicon descriptor + * @param[in] Address Register address + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Register Value + */ + +UINT32 +PcieSiliconRegisterRead ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + GnbLibPciWrite (Silicon->Address.AddressValue | 0xE0, AccessWidth32, &Address, GnbLibGetHeader (Pcie)); + GnbLibPciRead (Silicon->Address.AddressValue | 0xE4, AccessWidth32, &Value, GnbLibGetHeader (Pcie)); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe register value. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper descriptor + * @param[in] Address Register address + * @param[in] Value New register value + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieRegisterWrite ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if ((Wrapper->Features.AccessEncoding == 1) && ((Address & 0xff0000) == 0x010000)) { + Address = (Address & 0xffff) | 0x1400000 | ((Address >> 8) & 0xF0000); + } + PcieSiliconRegisterWrite ( + PcieConfigGetParentSilicon (Wrapper), + Address, + Value, + S3Save, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe register value. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Silicon Pointer to silicon descriptor + * @param[in] Address Register address + * @param[in] Value New register value + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieSiliconRegisterWrite ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + IDS_HDT_CONSOLE (PCIE_HOSTREG_TRACE, " *WR %s (%d:%d:%d):0x%08x = 0x%08x\n", + PcieFmDebugGetHostRegAddressSpaceString (Silicon, (UINT16) (Address >> 16)), + Silicon->Address.Address.Bus, + Silicon->Address.Address.Device, + Silicon->Address.Address.Function, + Address, + Value + ); + GnbLibPciWrite (Silicon->Address.AddressValue | 0xE0, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Address, GnbLibGetHeader (Pcie)); + GnbLibPciWrite (Silicon->Address.AddressValue | 0xE4, S3Save ? AccessS3SaveWidth32 : AccessWidth32, &Value, GnbLibGetHeader (Pcie)); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCIe register field. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper descriptor + * @param[in] Address Register address + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] Pcie Pointer to global PCIe configuration + * @retval Register field value + */ + +UINT32 +PcieRegisterReadField ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + Value = PcieRegisterRead (Wrapper, Address, Pcie); + Value = (Value >> FieldOffset) & (~(0xFFFFFFFF << FieldWidth)); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCIe register field. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper descriptor + * @param[in] Address Register address + * @param[in] FieldOffset Field offset + * @param[in] FieldWidth Field width + * @param[in] Value Value to write + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ + + +VOID +PcieRegisterWriteField ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TempValue; + UINT32 Mask; + TempValue = PcieRegisterRead (Wrapper, Address, Pcie); + Mask = (~(0xFFFFFFFF << FieldWidth)); + Value &= Mask; + TempValue &= (~(Mask << FieldOffset)); + PcieRegisterWrite (Wrapper, Address, TempValue | (Value << FieldOffset), S3Save, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCIe register. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Wrapper Pointer to wrapper descriptor + * @param[in] Address Register address + * @param[in] AndMask Value & (~AndMask) + * @param[in] OrMask Value | OrMask + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieRegisterRMW ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if ((Wrapper->Features.AccessEncoding == 1) && ((Address & 0xff0000) == 0x010000)) { + Address = (Address & 0xffff) | 0x1400000 | ((Address >> 8) & 0xF0000); + } + PcieSiliconRegisterRMW ( + PcieConfigGetParentSilicon (Wrapper), + Address, + AndMask, + OrMask, + S3Save, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCIe register. + * + * Support for unify register access through index/data pair on GNB + * + * @param[in] Silicon Pointer to silicon descriptor + * @param[in] Address Register address + * @param[in] AndMask Value & (~AndMask) + * @param[in] OrMask Value | OrMask + * @param[in] S3Save Save register for S3 (True/False) + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PcieSiliconRegisterRMW ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + Value = PcieSiliconRegisterRead (Silicon, Address, Pcie); + Value = (Value & (~AndMask)) | OrMask; + PcieSiliconRegisterWrite (Silicon, Address, Value, S3Save, Pcie); +} \ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.h new file mode 100644 index 0000000000..9a7e9013ef --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV1/PcieWrapperRegAcc.h @@ -0,0 +1,127 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Supporting services to access PCIe wrapper/core/PIF/PHY indirect register spaces + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _PCIEWRAPPERREGACC_H_ +#define _PCIEWRAPPERREGACC_H_ + +//#define WRAP_SPACE(w, x) (0x01300000ul | (w << 16) | (x)) +//#define CORE_SPACE(c, x) (0x00010000ul | (c << 24) | (x)) +//#define PHY_SPACE(w, p, x) (0x00200000ul | ((p + 1) << 24) | (w << 16) | (x)) +//#define PIF_SPACE(w, p, x) (0x00100000ul | ((p + 1) << 24) | (w << 16) | (x)) +#define IMP_SPACE(x) (0x01080000ul | (x)) + +UINT32 +PcieRegisterRead ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieRegisterWrite ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PcieRegisterReadField ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieRegisterWriteField ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT8 FieldOffset, + IN UINT8 FieldWidth, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieRegisterRMW ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +UINT32 +PcieSiliconRegisterRead ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSiliconRegisterWrite ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN UINT32 Value, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSiliconRegisterRMW ( + IN PCIe_SILICON_CONFIG *Silicon, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask, + IN BOOLEAN S3Save, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/GnbPcieInitLibV4.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/GnbPcieInitLibV4.h new file mode 100644 index 0000000000..e6221fff07 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/GnbPcieInitLibV4.h @@ -0,0 +1,52 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe Init Library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBPCIEINITLIBV4_H_ +#define _GNBPCIEINITLIBV4_H_ + +#include "PcieWrapperServicesV4.h" +#include "PciePowerMgmtV4.h" +#include "PciePortServicesV4.h" + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePortServicesV4.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePortServicesV4.c new file mode 100644 index 0000000000..fc43dee21d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePortServicesV4.c @@ -0,0 +1,202 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe port initialization service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV4_PCIEPORTSERVICESV4_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +PcieInitPortForIommuV4 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSetLinkSpeedCapV4 ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Set current link speed + * + * + * @param[in] LinkSpeedCapability Link Speed Capability + * @param[in] Engine Pointer to engine configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieSetLinkSpeedCapV4 ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D2FxxE4_xA4_STRUCT D2FxxE4_xA4; + D2FxxE4_xC0_STRUCT D2FxxE4_xC0; + D2Fxx88_STRUCT D2Fxx88; + GnbLibPciRead ( + Engine->Type.Port.Address.AddressValue | D2Fxx88_ADDRESS, + AccessWidth32, + &D2Fxx88.Value, + GnbLibGetHeader (Pcie) + ); + D2FxxE4_xA4.Value = PciePortRegisterRead ( + Engine, + D2FxxE4_xA4_ADDRESS, + Pcie + ); + D2FxxE4_xC0.Value = PciePortRegisterRead ( + Engine, + D2FxxE4_xC0_ADDRESS, + Pcie + ); + + switch (LinkSpeedCapability) { + case PcieGen2: + D2FxxE4_xA4.Field.LcGen2EnStrap = 0x1; + D2FxxE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x1; + D2Fxx88.Field.TargetLinkSpeed = 0x2; + D2Fxx88.Field.HwAutonomousSpeedDisable = 0x0; + break; + case PcieGen1: + D2FxxE4_xA4.Field.LcGen2EnStrap = 0x0; + D2FxxE4_xA4.Field.LcMultUpstreamAutoSpdChngEn = 0x0; + D2Fxx88.Field.TargetLinkSpeed = 0x1; + D2Fxx88.Field.HwAutonomousSpeedDisable = 0x1; + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (Engine), + WRAP_SPACE (PcieConfigGetParentWrapper (Engine)->WrapId, D0F0xE4_WRAP_0803_ADDRESS + 0x100 * Engine->Type.Port.PortId), + D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_OFFSET, + D0F0xE4_WRAP_0803_StrapBifDeemphasisSel_WIDTH, + 0, + FALSE, + Pcie + ); + break; + default: + ASSERT (FALSE); + break; + } + + if (Pcie->PsppPolicy == PsppDisabled) { + D2FxxE4_xC0.Field.StrapAutoRcSpeedNegotiationDis = 0x0; + } else { + D2FxxE4_xC0.Field.StrapAutoRcSpeedNegotiationDis = 0x1; + } + + PciePortRegisterWrite ( + Engine, + D2FxxE4_xA4_ADDRESS, + D2FxxE4_xA4.Value, + FALSE, + Pcie + ); + PciePortRegisterWrite ( + Engine, + D2FxxE4_xC0_ADDRESS, + D2FxxE4_xC0.Value, + FALSE, + Pcie + ); + GnbLibPciWrite ( + Engine->Type.Port.Address.AddressValue | D2Fxx88_ADDRESS, + AccessWidth32, + &D2Fxx88.Value, + GnbLibGetHeader (Pcie) + ); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Enable passing TLP prefix to IOMMU if IOMMU enabled + * + * + * @param[in] Engine Pointer to engine configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieInitPortForIommuV4 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PciePortRegisterRMW ( + Engine, + D2FxxE4_xC1_ADDRESS, + D2FxxE4_xC1_StrapE2EPrefixEn_MASK | D2FxxE4_xC1_StrapExtendedFmtSupported_MASK, + (1 << D2FxxE4_xC1_StrapE2EPrefixEn_OFFSET) | (1 << D2FxxE4_xC1_StrapExtendedFmtSupported_OFFSET), + TRUE, + Pcie + ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePortServicesV4.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePortServicesV4.h new file mode 100644 index 0000000000..b6f485fae7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePortServicesV4.h @@ -0,0 +1,64 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe port initialization service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEPORTSERVICESV4_H_ +#define _PCIEPORTSERVICESV4_H_ + + +VOID +PcieSetLinkSpeedCapV4 ( + IN PCIE_LINK_SPEED_CAP LinkSpeedCapability, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieInitPortForIommuV4 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePowerMgmtV4.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePowerMgmtV4.h new file mode 100644 index 0000000000..b55c2d4672 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PciePowerMgmtV4.h @@ -0,0 +1,71 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Power saving features/services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEPOWERSAVINGFEATURESV4_H_ +#define _PCIEPOWERSAVINGFEATURESV4_H_ + +VOID +PciePwrClockGatingV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePwrPowerDownDdiPllsV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieAcsCapabilityWrapperEnableV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieAcsCapabilityPortEnableV4 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PcieWrapperServicesV4.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PcieWrapperServicesV4.c new file mode 100644 index 0000000000..2d1a9ddb62 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PcieWrapperServicesV4.c @@ -0,0 +1,204 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe wrapper services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbNbInitLibV4.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV4_PCIEWRAPPERSERVICESV4_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +PcieSetSsidV4 ( + IN UINT32 Ssid, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologySetLinkReversalV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSetDdiOwnPhyV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyExecuteReconfigV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Relinquish control to DDI for specific lanes + * + * + * @param[in] Wrapper Pointer to wrapper configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieSetDdiOwnPhyV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + + UINT32 LaneBitmap; + UINT8 Slice; + if (PcieLibIsDdiWrapper (Wrapper)) { + IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetDdiOwnPhyV4 Enter\n"); + LaneBitmap = PcieUtilGetWrapperLaneBitMap (LANE_TYPE_DDI_PHY_NATIVE, 0, Wrapper); + for (Slice = 0; Slice < 4; Slice++) { + if ((LaneBitmap & (1 << (Slice * 4))) != 0) { + PcieRegisterRMW ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8040_ADDRESS + Slice), + D0F0xE4_WRAP_8040_OwnSlice_MASK, + 1 << D0F0xE4_WRAP_8040_OwnSlice_OFFSET, + FALSE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetDdiOwnPhyV4 Exit\n"); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set SSID + * + * + * @param[in] Ssid SSID + * @param[in] Wrapper Pointer to wrapper configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieSetSsidV4 ( + IN UINT32 Ssid, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if (PcieLibIsPcieWrapper (Wrapper)) { + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_0046_ADDRESS), + Ssid, + FALSE, + Pcie + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable lane reversal + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologySetLinkReversalV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Enter\n"); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + if (PcieLibIsPcieEngine (EngineList)) { + if (EngineList->EngineData.StartLane > EngineList->EngineData.EndLane) { + PciePortRegisterWriteField ( + EngineList, + D2FxxE4_xC1_ADDRESS, + D2FxxE4_xC1_StrapReverseLanes_OFFSET, + D2FxxE4_xC1_StrapReverseLanes_WIDTH, + 0x1, + FALSE, + Pcie + ); + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Exit\n"); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PcieWrapperServicesV4.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PcieWrapperServicesV4.h new file mode 100644 index 0000000000..52002ff065 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV4/PcieWrapperServicesV4.h @@ -0,0 +1,77 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe wrapper services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEWRAPPERSERVICESV4_H_ +#define _PCIEWRAPPERSERVICESV4_H_ + + +VOID +PcieSetDdiOwnPhyV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +VOID +PcieTopologyExecuteReconfigV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieSetSsidV4 ( + IN UINT32 Ssid, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologySetLinkReversalV4 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/GnbPcieInitLibV5.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/GnbPcieInitLibV5.h new file mode 100644 index 0000000000..f2bdf75d24 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/GnbPcieInitLibV5.h @@ -0,0 +1,141 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe Init Library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 87271 $ @e \$Date: 2013-01-31 10:11:23 -0600 (Thu, 31 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBPCIEINITLIBV5_H_ +#define _GNBPCIEINITLIBV5_H_ + +VOID +PciePifApplyGangingV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifPllPowerDownV5 ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyApplyLaneMuxV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +BOOLEAN +PcieTopologyIsGen3SupportedV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PciePwrPowerDownUnusedLanesV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePwrClockGatingV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePortsVisibilityControlV5 ( + IN PCIE_PORT_VISIBILITY Control, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieLinkInitHotplugV5 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieEnableSlotPowerLimitV5 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePhyApplyGangingV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePhyChannelCharacteristicV5 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyLaneControlV5 ( + IN LANE_CONTROL Control, + IN UINT32 LaneBitMap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyReduceLinkWidthV5 ( + IN UINT8 LinkWidth, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTopologyExecuteReconfigV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetLs2ExitTimeV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePhyServicesV5.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePhyServicesV5.c new file mode 100644 index 0000000000..bc5023431e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePhyServicesV5.c @@ -0,0 +1,111 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PIF initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV5_PCIEPHYSERVICESV5_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +PciePhyApplyGangingV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePhyChannelCharacteristicV5 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set PHY channel characteristic + * + * + * + * @param[in] Engine Pointer to engine configuration + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePhyChannelCharacteristicV5 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + /// @todo +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePifServicesV5.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePifServicesV5.c new file mode 100644 index 0000000000..1f7dc6545d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePifServicesV5.c @@ -0,0 +1,269 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe PIF initialization routine + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 88079 $ @e \$Date: 2013-02-15 15:28:53 -0600 (Fri, 15 Feb 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV5_PCIEPIFSERVICESV5_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +PciePifApplyGangingV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifPllPowerDownV5 ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PciePifSetLs2ExitTimeV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Apply PIF ganging for all lanes for given wrapper + * + * + * + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + + +VOID +PciePifApplyGangingV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT32 LaneBitmap; + D0F0xE4_PIF_0011_STRUCT D0F0xE4_PIF_0011; + D0F0xE4_PIF_0011.Value = 0; + + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifApplyGangingV5 Enter\n"); + EngineList = PcieConfigGetChildEngine (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + LaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, EngineList); + switch (LaneBitmap) { + case 0x0003: + D0F0xE4_PIF_0011.Field.X2Lane10 = 0x1; + break; + case 0x000c: + D0F0xE4_PIF_0011.Field.X2Lane32 = 0x1; + break; + case 0x0030: + D0F0xE4_PIF_0011.Field.X2Lane54 = 0x1; + break; + case 0x00c0: + D0F0xE4_PIF_0011.Field.X2Lane76 = 0x1; + break; + case 0x000f: + D0F0xE4_PIF_0011.Field.X4Lane30 = 0x1; + break; + case 0x00f0: + D0F0xE4_PIF_0011.Field.X4Lane74 = 0x1; + break; + case 0x00ff: + D0F0xE4_PIF_0011.Field.X8Lane70 = 0x1; + break; + case 0x0300: + D0F0xE4_PIF_0011.Field.X2Lane98 = 0x1; + break; + case 0x0c00: + D0F0xE4_PIF_0011.Field.X2Lane1110 = 0x1; + break; + case 0x3000: + D0F0xE4_PIF_0011.Field.X2Lane1312 = 0x1; + break; + case 0xc000: + D0F0xE4_PIF_0011.Field.X2Lane1514 = 0x1; + break; + case 0x0f00: + D0F0xE4_PIF_0011.Field.X4Lane118 = 0x1; + break; + case 0xf000: + D0F0xE4_PIF_0011.Field.X4Lane1512 = 0x1; + break; + case 0xff00: + D0F0xE4_PIF_0011.Field.X8Lane158 = 0x1; + break; + case 0xffff: + D0F0xE4_PIF_0011.Field.X16Lane150 = 0x1; + break; + default: + break; + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0011_ADDRESS), + D0F0xE4_PIF_0011.Value, + FALSE, + Pcie + ); + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifApplyGangingV5 Exit\n"); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * PLL powerdown + * + * + * @param[in] LaneBitmap Power down PLL for these lanes + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to PICe configuration data area + */ + +VOID +PciePifPllPowerDownV5 ( + IN UINT32 LaneBitmap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Nibble; + UINT16 NibbleBitmap; + UINT16 PifRegAffress; + D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllPowerDownV5 Enter\n"); + for (Nibble = 0; Nibble < 4; Nibble++) { + NibbleBitmap = (0xF << (Nibble * 4)); + if ((LaneBitmap & NibbleBitmap) == NibbleBitmap) { + PifRegAffress = ((Nibble < 2) ? D0F0xE4_PIF_0012_ADDRESS : D0F0xE4_PIF_0017_ADDRESS) + (Nibble & 0x1); + D0F0xE4_PIF_0012.Value = PcieRegisterRead ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, PifRegAffress), + Pcie + ); + + D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.TxPowerStateInTxs2 = PifPowerStateOff; + D0F0xE4_PIF_0012.Field.RxPowerStateInRxs2 = PifPowerStateOff; + PcieRegisterWrite ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, 0, PifRegAffress), + D0F0xE4_PIF_0012.Value, + TRUE, + Pcie + ); + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifPllPowerDownV5 Exit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Program LS2 exit time + * + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +PciePifSetLs2ExitTimeV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 Pif; + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetLs2ExitTimeV5 Enter\n"); + for (Pif = 0; Pif < Wrapper->NumberOfPIFs; Pif++) { + PcieRegisterWriteField ( + Wrapper, + PIF_SPACE (Wrapper->WrapId, Pif, D0F0xE4_PIF_0010_ADDRESS), + D0F0xE4_PIF_0010_Ls2ExitTime_OFFSET, + D0F0xE4_PIF_0010_Ls2ExitTime_WIDTH, + 0x5, + FALSE, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PciePifSetLs2ExitTimeV5 Exit\n"); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePortServicesV5.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePortServicesV5.c new file mode 100644 index 0000000000..803d134dd1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PciePortServicesV5.c @@ -0,0 +1,147 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe port initialization service procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV5.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV5_PCIEPORTSERVICESV5_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init hotplug port + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +PcieLinkInitHotplugV5 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 Value; + PcieLinkInitHotplug (Engine, Pcie); + if (Engine->Type.Port.PortData.LinkHotplug == HotplugEnhanced) { + Value = 1; + } else { + Value = 0; + } + PciePortRegisterWriteField ( + Engine, + 0x10, + 3, + 1, + Value, + TRUE, + Pcie + ); +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set slot power limit + * + * + * + * @param[in] Engine Pointer to engine configuration + * @param[in] Pcie Pointer to PCIe configuration + */ + + +VOID +PcieEnableSlotPowerLimitV5 ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *Silicon; + if (PcieLibIsEngineAllocated (Engine) && Engine->Type.Port.PortData.PortPresent != PortDisabled && !PcieConfigIsSbPcieEngine (Engine)) { + IDS_HDT_CONSOLE (PCIE_MISC, " Enable Slot Power Limit for Port % d\n", Engine->Type.Port.Address.Address.Device); + Silicon = PcieConfigGetParentSilicon (Engine); + GnbLibPciIndirectRMW ( + Silicon->Address.AddressValue | D0F0xC8_ADDRESS, + D0F0xCC_x01_ADDRESS | ((Engine->Type.Port.PortData.DeviceNumber << 3 | Engine->Type.Port.PortData.FunctionNumber) << D0F0xC8_NB_DEV_IND_SEL_OFFSET), + AccessS3SaveWidth32, + 0xffffffff, + 1 << D0F0xCC_x01_SetPowEn_OFFSET, + GnbLibGetHeader (Pcie) + ); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieSiliconServicesV5.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieSiliconServicesV5.c new file mode 100644 index 0000000000..0b2be80970 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieSiliconServicesV5.c @@ -0,0 +1,198 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific PCIe complex initialization services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV5.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV5_PCIESILICONSERVICESV5_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +STATIC +PcieSiliconControlPortsV5 ( + IN PCIE_PORT_VISIBILITY Control, + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +STATIC +PcieSiliconEnablePortsV5 ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Control port visibility in PCI config space + * + * + * @param[in] Control Control Hide/Unhide ports + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PciePortsVisibilityControlV5 ( + IN PCIE_PORT_VISIBILITY Control, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *SiliconList; + SiliconList = (PCIe_SILICON_CONFIG *) PcieConfigGetChild (DESCRIPTOR_SILICON, &Pcie->Header); + while (SiliconList != NULL) { + switch (Control) { + case UnhidePorts: + PcieSiliconControlPortsV5 (UnhidePorts, SiliconList, Pcie); + break; + case HidePorts: + PcieSiliconControlPortsV5 (HidePorts, SiliconList, Pcie); + PcieSiliconEnablePortsV5 (SiliconList, Pcie); + break; + default: + ASSERT (FALSE); + } + SiliconList = (PCIe_SILICON_CONFIG *) PcieConfigGetNextTopologyDescriptor (SiliconList, DESCRIPTOR_TERMINATE_TOPOLOGY); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Hide/Unhide all ports + * + * + * @param[in] Control Control Hide/Unhide ports + * @param[in] Silicon Pointer to silicon configuration descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ + +VOID +STATIC +PcieSiliconControlPortsV5 ( + IN PCIE_PORT_VISIBILITY Control, + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + UINT32 Value; + Value = (Control == HidePorts) ? ((1 << D0F0xCC_x01_BridgeDis_OFFSET) | (1 << D0F0xCC_x01_CfgDis_OFFSET)) : 0; + EngineList = PcieConfigGetChildEngine (Silicon); + while (EngineList != NULL) { + if (PcieConfigIsPcieEngine (EngineList)) { + GnbLibPciIndirectRMW ( + Silicon->Address.AddressValue | D0F0xC8_ADDRESS, + D0F0xCC_x01_ADDRESS | ((EngineList->Type.Port.NativeDevNumber << 3 | EngineList->Type.Port.NativeFunNumber) << D0F0xC8_NB_DEV_IND_SEL_OFFSET), + AccessS3SaveWidth32, + (UINT32)~(D0F0xCC_x01_BridgeDis_MASK | D0F0xCC_x01_CfgDis_MASK | D0F0xCC_x01_CsrEnable_MASK | D0F0xCC_x01_SetPowEn_MASK), + Value, + GnbLibGetHeader (Pcie) + ); + } + EngineList = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (EngineList, DESCRIPTOR_TERMINATE_GNB); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Hide unused ports + * + * + * + * @param[in] Silicon Pointer to silicon configuration data area + * @param[in] Pcie Pointer to data area up to 256 byte + */ + +VOID +STATIC +PcieSiliconEnablePortsV5 ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + EngineList = PcieConfigGetChildEngine (Silicon); + while (EngineList != NULL) { + if (PcieConfigIsPcieEngine (EngineList)) { + if (!PcieConfigIsSbPcieEngine (EngineList) && + (PcieConfigCheckPortStatus (EngineList, INIT_STATUS_PCIE_TRAINING_SUCCESS) || + ((EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) && + (EngineList->Type.Port.PortData.LinkHotplug != HotplugInboard)))) { + GnbLibPciIndirectRMW ( + Silicon->Address.AddressValue | D0F0xC8_ADDRESS, + D0F0xCC_x01_ADDRESS | ((EngineList->Type.Port.PortData.DeviceNumber << 3 | EngineList->Type.Port.PortData.FunctionNumber) << D0F0xC8_NB_DEV_IND_SEL_OFFSET), + AccessS3SaveWidth32, + (UINT32)~(D0F0xCC_x01_BridgeDis_MASK | D0F0xCC_x01_CfgDis_MASK | D0F0xCC_x01_CsrEnable_MASK | D0F0xCC_x01_SetPowEn_MASK), + ((1 << D0F0xCC_x01_CsrEnable_OFFSET) | (1 << D0F0xCC_x01_SetPowEn_OFFSET)), + GnbLibGetHeader (Pcie) + ); + } + } + EngineList = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (EngineList, DESCRIPTOR_TERMINATE_GNB); + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieTopologyServicesV5.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieTopologyServicesV5.c new file mode 100644 index 0000000000..9c602e1442 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieTopologyServicesV5.c @@ -0,0 +1,152 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe topology initialization service procedures. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV5.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV5_PCIETOPOLOGYSERVICESV5_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Lanes enable/disable control + * + * @param[in] Control Lane control action + * @param[in] LaneBitMap Core lanes bitmap + * @param[in] Wrapper Pointer to Wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyLaneControlV5 ( + IN LANE_CONTROL Control, + IN UINT32 LaneBitMap, + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8029_STRUCT D0F0xE4_WRAP_8029; + D0F0xE4_WRAP_8029.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8029_ADDRESS), + Pcie + ); + + if (Control == EnableLanes) { + D0F0xE4_WRAP_8029.Value |= LaneBitMap; + } else if (Control == DisableLanes) { + D0F0xE4_WRAP_8029.Value &= (~LaneBitMap); + } + D0F0xE4_WRAP_8029.Value &= ((1 << Wrapper->NumberOfLanes) - 1); + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8029_ADDRESS), + D0F0xE4_WRAP_8029.Value, + TRUE, + Pcie + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Reduce link width + * + * + * @param[in] LinkWidth Link width + * @param[in] Engine Pointer to Engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyReduceLinkWidthV5 ( + IN UINT8 LinkWidth, + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_WRAPPER_CONFIG *Wrapper; + UINT32 LinkReversed; + UINT8 DeltaLinkWidthBitmap; + UINT32 LanesToDisable; + Wrapper = PcieConfigGetParentWrapper (Engine); + LinkReversed = PcieUtilIsLinkReversed (TRUE, Engine, Pcie); + + DeltaLinkWidthBitmap = (1 << (PcieConfigGetNumberOfCoreLane (Engine) - LinkWidth)) - 1; + LanesToDisable = (DeltaLinkWidthBitmap << ((LinkReversed == 1) ? Engine->Type.Port.StartCoreLane : (Engine->Type.Port.StartCoreLane + LinkWidth))); + + PcieTopologyLaneControlV5 ( + DisableLanes, + LanesToDisable, + Wrapper, + Pcie + ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieWrapperServicesV5.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieWrapperServicesV5.c new file mode 100644 index 0000000000..89547bfd95 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieInitLibV5/PcieWrapperServicesV5.c @@ -0,0 +1,184 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe topology initialization service procedures. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV5.h" +#include "GnbRegistersCommonV2.h" +#include "GnbSmuInitLibV7.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV5_PCIEWRAPPERSERVICESV5_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +UINT8 LaneMuxSelectorArrayV5[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if lane topology supports Gen3 + * + * Check if more that one link mapped to single PIF slice + * + * @param[in] Wrapper Pointer to wrapper config descriptor + */ + +BOOLEAN +PcieTopologyIsGen3SupportedV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + UINT8 LaneNibbleArray [4]; + UINT32 LaneBitmap; + UINT8 Nibble; + UINT8 NibbleBitmap; + PCIe_ENGINE_CONFIG *Engine; + + + LibAmdMemFill (&LaneNibbleArray[0], 0x00, sizeof (LaneNibbleArray), PcieConfigGetStdHeader (Wrapper)); + Engine = PcieConfigGetChildEngine (Wrapper); + while (Engine != NULL) { + LaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, Engine); + for (Nibble = 0; Nibble < 4; Nibble++) { + NibbleBitmap = (0xF << (Nibble * 4)); + if ((LaneBitmap & NibbleBitmap) != 0) { + if (++LaneNibbleArray [Nibble] > 1) { + return FALSE; + } + } + } + Engine = PcieLibGetNextDescriptor (Engine); + } + return TRUE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Execute/clean up reconfiguration + * + * + * @param[in] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieTopologyExecuteReconfigV5 ( + IN PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + D0F0xE4_WRAP_8062_STRUCT D0F0xE4_WRAP_8062; + PCIe_SILICON_CONFIG *Silicon; + DEV_OBJECT DevObject; + + if (PcieLibIsPcieWrapper (Wrapper)) { + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigV5 Enter\n"); + + D0F0xE4_WRAP_8062.Value = PcieRegisterRead ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + Pcie + ); + D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x1; + D0F0xE4_WRAP_8062.Field.ResetPeriod = 0x2; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + + Silicon = PcieConfigGetParentSilicon (Wrapper); + DevObject.StdHeader = GnbLibGetHeader (Pcie); + DevObject.GnbHandle = GnbGetHandle (GnbLibGetHeader (Pcie)); + DevObject.DevPciAddress.AddressValue = Silicon->Address.AddressValue; + GnbSmuServiceRequestV7 ( + &DevObject, + 25, + 0, + 0 + ); + + D0F0xE4_WRAP_8062.Field.ConfigXferMode = 0x1; + D0F0xE4_WRAP_8062.Field.ReconfigureEn = 0x0; + PcieRegisterWrite ( + Wrapper, + WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8062_ADDRESS), + D0F0xE4_WRAP_8062.Value, + FALSE, + Pcie + ); + + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyExecuteReconfigV5 Exit\n"); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.c new file mode 100644 index 0000000000..edf877264b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.c @@ -0,0 +1,376 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Configure Max Payload + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "PcieMaxPayload.h" +#include "OptionGnb.h" +#include "GnbFamServices.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIEMAXPAYLOAD_PCIEMAXPAYLOAD_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern GNB_BUILD_OPTIONS GnbBuildOptions; + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +typedef struct { + GNB_PCI_SCAN_DATA ScanData; + UINT8 MaxPayload; +} PCIE_MAX_PAYLOAD_DATA; + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +SCAN_STATUS +PcieGetMaxPayloadCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +SCAN_STATUS +PcieSetMaxPayloadCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ); + +AGESA_STATUS +PciePayloadBlackListFeature ( + IN PCI_ADDR Device, + IN UINT8 *MaxPayload, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieMaxPayloadInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Determine maximum payload size for PCIe segment + * + * Scan through all link in segment to determine maximum payload by EPs. + * + * @param[in] DownstreamPort PCI address of PCIe port + * @param[in] EngineMaxPayload MaxPayload supported by the engine + * @param[in] StdHeader Standard configuration header + * + */ + +VOID +PcieSetMaxPayload ( + IN PCI_ADDR DownstreamPort, + IN UINT8 EngineMaxPayload, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIE_MAX_PAYLOAD_DATA PcieMaxPayloadData; + + IDS_HDT_CONSOLE (GNB_TRACE, " PcieSetMaxPayload for Device = %d:%d:%d\n", + DownstreamPort.Address.Bus, + DownstreamPort.Address.Device, + DownstreamPort.Address.Function + ); + PcieMaxPayloadData.MaxPayload = EngineMaxPayload; + PcieMaxPayloadData.ScanData.StdHeader = StdHeader; + PcieMaxPayloadData.ScanData.GnbScanCallback = PcieGetMaxPayloadCallback; + GnbLibPciScan (DownstreamPort, DownstreamPort, &PcieMaxPayloadData.ScanData); + PcieMaxPayloadData.ScanData.GnbScanCallback = PcieSetMaxPayloadCallback; + GnbLibPciScan (DownstreamPort, DownstreamPort, &PcieMaxPayloadData.ScanData); + IDS_HDT_CONSOLE (GNB_TRACE, " PcieSetMaxPayloadExit\n"); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Evaluate device Max Payload - save SMALLEST Max Payload for PCIe Segment + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status of 0 + */ + +SCAN_STATUS +PcieGetMaxPayloadCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + SCAN_STATUS ScanStatus; + PCIE_MAX_PAYLOAD_DATA *PcieMaxPayloadData; + PCIE_DEVICE_TYPE DeviceType; + UINT32 Value; + UINT8 PcieCapPtr; + UINT8 DeviceMaxPayload; + + PcieMaxPayloadData = (PCIE_MAX_PAYLOAD_DATA*) ScanData; + ScanStatus = SCAN_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, " PcieGetMaxPayloadCallback for Device = %d:%d:%d\n", + Device.Address.Bus, + Device.Address.Device, + Device.Address.Function + ); + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, ScanData->StdHeader); + if (PcieCapPtr != 0) { + GnbLibPciRead ( + Device.AddressValue | (PcieCapPtr + PCIE_DEVICE_CAP_REGISTER), + AccessWidth32, + &Value, + ScanData->StdHeader + ); + DeviceMaxPayload = (UINT8) (Value & 0x7); + PciePayloadBlackListFeature (Device, &DeviceMaxPayload, ScanData->StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, " Found DeviceMaxPayload as %d (Value = %x\n", DeviceMaxPayload, Value); + if (DeviceMaxPayload < PcieMaxPayloadData->MaxPayload) { + PcieMaxPayloadData->MaxPayload = DeviceMaxPayload; + } + } + DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader); + switch (DeviceType) { + case PcieDeviceRootComplex: + case PcieDeviceDownstreamPort: + case PcieDeviceUpstreamPort: + GnbLibPciScanSecondaryBus (Device, &PcieMaxPayloadData->ScanData); + break; + case PcieDeviceEndPoint: + case PcieDeviceLegacyEndPoint: + break; + default: + break; + } + return SCAN_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure the Max Payload setting to all devices in the PCIe Segment + * + * + * + * @param[in] Device PCI Address + * @param[in,out] ScanData Scan configuration data + * @retval Scan Status of 0 + */ + +SCAN_STATUS +PcieSetMaxPayloadCallback ( + IN PCI_ADDR Device, + IN OUT GNB_PCI_SCAN_DATA *ScanData + ) +{ + SCAN_STATUS ScanStatus; + PCIE_MAX_PAYLOAD_DATA *PcieMaxPayloadData; + PCIE_DEVICE_TYPE DeviceType; + UINT8 PcieCapPtr; + + PcieMaxPayloadData = (PCIE_MAX_PAYLOAD_DATA*) ScanData; + ScanStatus = SCAN_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, " PcieSetMaxPayloadCallback for Device = %d:%d:%d to %d\n", + Device.Address.Bus, + Device.Address.Device, + Device.Address.Function, + PcieMaxPayloadData->MaxPayload + ); + PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, ScanData->StdHeader); + if (PcieCapPtr != 0) { + GnbLibPciRMW ( + Device.AddressValue | (PcieCapPtr + PCIE_DEVICE_CTRL_REGISTER), + AccessWidth32, + ~(UINT32) (0x7 << 5), + ((UINT32)PcieMaxPayloadData->MaxPayload << 5), + ScanData->StdHeader + ); + } + DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader); + switch (DeviceType) { + case PcieDeviceRootComplex: + case PcieDeviceDownstreamPort: + case PcieDeviceUpstreamPort: + GnbLibPciScanSecondaryBus (Device, &PcieMaxPayloadData->ScanData); + break; + case PcieDeviceEndPoint: + case PcieDeviceLegacyEndPoint: + break; + default: + break; + } + return SCAN_SUCCESS; +} + +UINT16 PayloadBlacklistDeviceTable[] = { + 0x1969, 0x1083, (UINT16) MAX_PAYLOAD_128 +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Pcie Max_Payload_Size Black List + * + * + * + * @param[in] Device PCI_ADDR of PCIe Device to evaluate + * @param[in] MaxPayload Pointer to Max_Payload_Size value + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +PciePayloadBlackListFeature ( + IN PCI_ADDR Device, + IN UINT8 *MaxPayload, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TargetDeviceId; + UINTN i; + UINT32 DeviceId; + UINT32 VendorId; + + GnbLibPciRead (Device.AddressValue, AccessWidth32, &TargetDeviceId, StdHeader); + for (i = 0; i < (sizeof (PayloadBlacklistDeviceTable) / sizeof (UINT16)); i = i + 3) { + VendorId = PayloadBlacklistDeviceTable[i]; + DeviceId = PayloadBlacklistDeviceTable[i + 1]; + if (VendorId == (UINT16)TargetDeviceId) { + if (DeviceId == 0xFFFF || DeviceId == (TargetDeviceId >> 16)) { + *MaxPayload = (UINT8) PayloadBlacklistDeviceTable[i + 2]; + } + } + } + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Callback to init various features on all active ports + * + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Not used + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieMaxPayloadInitCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIE_MAXPAYLOAD_SERVICE *PcieMaxPayloadProtocol; + UINT8 EngineMaxPayload; + AGESA_STATUS Status; + PCIe_COMPLEX_CONFIG *Complex; + + + + if ((GnbBuildOptions.CfgMaxPayloadEnable != 0) && + (!PcieConfigIsSbPcieEngine (Engine)) && + (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS))) { + EngineMaxPayload = MAX_PAYLOAD; + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header); + Status = GnbLibLocateService (GnbPcieMaxPayloadService, Complex->SocketId, (VOID **)&PcieMaxPayloadProtocol, GnbLibGetHeader (Pcie)); + if (Status == AGESA_SUCCESS) { + EngineMaxPayload = PcieMaxPayloadProtocol->SetMaxPayload (Engine); + } + PcieSetMaxPayload (Engine->Type.Port.Address, EngineMaxPayload, GnbLibGetHeader (Pcie)); + } +} + +/**----------------------------------------------------------------------------------------*/ +/** + * Interface to configure MaxPayloadSize on PCIE interface + * + * + * + * @param[in] StdHeader Standard configuration header + * + * @retval AGESA_STATUS + */ + /*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieMaxPayloadInterface ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + PCIe_PLATFORM_CONFIG *Pcie; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMaxPayloadInterface Enter\n"); + AgesaStatus = PcieLocateConfigurationData (StdHeader, &Pcie); + if (AgesaStatus == AGESA_SUCCESS) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieMaxPayloadInitCallback, + NULL, + Pcie + ); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMaxPayloadInterface Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.h new file mode 100644 index 0000000000..d36724400e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieMaxPayload/PcieMaxPayload.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Configure Max Payload + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEMAXPAYLOAD_H_ +#define _PCIEMAXPAYLOAD_H_ + +VOID +PcieSetMaxPayload ( + IN PCI_ADDR DownstreamPort, + IN UINT8 EngineMaxPayload, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/GnbPcieTrainingV2.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/GnbPcieTrainingV2.h new file mode 100644 index 0000000000..490d5eb348 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/GnbPcieTrainingV2.h @@ -0,0 +1,51 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe training library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBPCIETRAININGV2_H_ +#define _GNBPCIETRAININGV2_H_ + +#include "PcieTrainingV2.h" +#include "PcieWorkaroundsV2.h" + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.c new file mode 100644 index 0000000000..36044ac885 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.c @@ -0,0 +1,801 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link training + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85361 $ @e \$Date: 2013-01-07 11:15:28 -0600 (Mon, 07 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "GeneralServices.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieInitLibV1.h" +#include "GnbPcieInitLibV5.h" +#include "GnbPcieTrainingV2.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIETRAININGV2_PCIETRAININGV2_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Set link State + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] State State to set + * @param[in] UpdateTimeStamp Update time stamp + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +PcieTrainingSetPortState ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIE_LINK_TRAINING_STATE State, + IN BOOLEAN UpdateTimeStamp, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + CurrentEngine->Type.Port.State = (UINT8) State; + if (UpdateTimeStamp) { + TimeStamp = PcieTimerGetTimeStamp (Pcie); + CurrentEngine->Type.Port.TimeStamp = TimeStamp; + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set state for all engines connected to same reset ID + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Pointer to Reset Id + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +STATIC VOID +PcieSetResetStateOnEngines ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 ResetId; + ResetId = *(UINT8 *)Buffer; + if (Engine->Type.Port.PortData.ResetId == ResetId && !PcieConfigIsSbPcieEngine (Engine)) { + PcieTrainingSetPortState (Engine, LinkStateResetDuration, TRUE, Pcie); + GnbLibPciRMW ( + Engine->Type.Port.Address.AddressValue | DxFxx68_ADDRESS, + AccessWidth32, + (UINT32) ~DxFxx68_LinkDis_MASK, + 1 << DxFxx68_LinkDis_OFFSET, + GnbLibGetHeader (Pcie) + ); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Assert GPIO port reset. + * + * Transition to LinkStateResetDuration state + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingAssertReset ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SLOT_RESET_INFO ResetInfo; + ResetInfo.ResetControl = AssertSlotReset; + ResetInfo.ResetId = CurrentEngine->Type.Port.PortData.ResetId; + LibAmdMemCopy (&ResetInfo.StdHeader, GnbLibGetHeader (Pcie), sizeof (AMD_CONFIG_PARAMS), GnbLibGetHeader (Pcie)); + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieSetResetStateOnEngines, + (VOID *)&CurrentEngine->Type.Port.PortData.ResetId, + Pcie + ); + AgesaPcieSlotResetControl (0, &ResetInfo); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check for reset duration + * + * Transition to LinkStateResetDuration state + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +STATIC VOID +PcieTrainingCheckResetDuration ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= Pcie->LinkGpioResetAssertionTime) { + PcieTrainingSetPortState (CurrentEngine, LinkStateResetExit, FALSE, Pcie); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Deassert GPIO port reset. + * + * Transition to LinkStateResetDuration state + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Platform configuration + * + */ +STATIC VOID +PcieTrainingDeassertReset ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SLOT_RESET_INFO ResetInfo; + ResetInfo.ResetControl = DeassertSlotReset; + ResetInfo.ResetId = CurrentEngine->Type.Port.PortData.ResetId; + LibAmdMemCopy (&ResetInfo.StdHeader, GnbLibGetHeader (Pcie), sizeof (AMD_CONFIG_PARAMS), GnbLibGetHeader (Pcie)); + AgesaPcieSlotResetControl (0, &ResetInfo); + GnbLibPciRMW ( + CurrentEngine->Type.Port.Address.AddressValue | DxFxx68_ADDRESS, + AccessWidth32, + (UINT32) ~DxFxx68_LinkDis_MASK, + 0 << DxFxx68_LinkDis_OFFSET, + GnbLibGetHeader (Pcie) + ); + PcieTrainingSetPortState (CurrentEngine, LinkTrainingResetTimeout, TRUE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check for after reset deassertion timeout + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingCheckResetTimeout ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= Pcie->LinkResetToTrainingTime) { + PcieTrainingSetPortState (CurrentEngine, LinkStateReleaseTraining, FALSE, Pcie); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Release training + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingRelease ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkTrainingState; + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (CurrentEngine), + WRAP_SPACE (PcieConfigGetParentWrapper (CurrentEngine)->WrapId, D0F0xE4_WRAP_0800_ADDRESS + 0x100 * CurrentEngine->Type.Port.PortId), + D0F0xE4_WRAP_0800_HoldTraining_OFFSET, + D0F0xE4_WRAP_0800_HoldTraining_WIDTH, + 0, + FALSE, + Pcie + ); + if (CurrentEngine->Type.Port.PortData.MiscControls.LinkComplianceMode == 0x1) { + LinkTrainingState = LinkStateCompliance; + } else { + LinkTrainingState = LinkStateDetectPresence; + } + PcieTrainingSetPortState (CurrentEngine, LinkTrainingState, TRUE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Detect presence of any EP on the link + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieTrainingDetectPresence ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkHwStateHistory[4]; + UINT32 TimeStamp; + PcieUtilGetLinkHwStateHistory (CurrentEngine, &LinkHwStateHistory[0], 4, Pcie); + if (LinkHwStateHistory[0] > 4) { + PcieTrainingSetPortState (CurrentEngine, LinkStateDetecting, TRUE, Pcie); + return; + } + TimeStamp = PcieTimerGetTimeStamp (Pcie); + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= Pcie->LinkReceiverDetectionPooling) { + PcieTrainingSetPortState (CurrentEngine, LinkStateDeviceNotPresent, FALSE, Pcie); + } +} + +UINT8 FailPattern1 [] = {0x2a, 0x6}; +UINT8 FailPattern2 [] = {0x2a, 0x9}; +UINT8 FailPattern3 [] = {0x2a, 0xb}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Detect Link State + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieTrainingDetectLinkState ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkHwStateHistory[16]; + UINT32 TimeStamp; + UINT8 LinkTrainingState; + PcieUtilGetLinkHwStateHistory (CurrentEngine, &LinkHwStateHistory[0], 4, Pcie); + if (LinkHwStateHistory[0] == 0x10) { + PcieTrainingSetPortState (CurrentEngine, LinkStateL0, FALSE, Pcie); + return; + }; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= Pcie->LinkL0Pooling) { + LinkTrainingState = LinkStateTrainingFail; + PcieUtilGetLinkHwStateHistory (CurrentEngine, &LinkHwStateHistory[0], 16, Pcie); + if (LinkHwStateHistory[0] == 0x7) { + LinkTrainingState = LinkStateCompliance; + } else if (PcieUtilSearchArray (LinkHwStateHistory, sizeof (LinkHwStateHistory), FailPattern1, sizeof (FailPattern1))) { + LinkTrainingState = LinkStateBrokenLane; + } else if (PcieUtilSearchArray (LinkHwStateHistory, sizeof (LinkHwStateHistory), FailPattern2, sizeof (FailPattern2))) { + LinkTrainingState = LinkStateGen2Fail; + } else if (PcieUtilSearchArray (LinkHwStateHistory, sizeof (LinkHwStateHistory), FailPattern3, sizeof (FailPattern3))) { + LinkTrainingState = LinkStateGen2Fail; + } + PcieTrainingSetPortState (CurrentEngine, LinkTrainingState, FALSE, Pcie); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Broken Lane + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +STATIC VOID +PcieTrainingBrokenLineV2 ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 CurrentLinkWidth; + UINT8 LinkTrainingState; + CurrentLinkWidth = PcieUtilGetLinkWidth (CurrentEngine, Pcie); + if (CurrentLinkWidth < PcieConfigGetNumberOfPhyLane (CurrentEngine) && CurrentLinkWidth > 0) { + CurrentEngine->InitStatus |= INIT_STATUS_PCIE_PORT_BROKEN_LANE_RECOVERY; + PcieTopologyReduceLinkWidthV5 (CurrentLinkWidth, CurrentEngine, Pcie); + LinkTrainingState = LinkStateResetAssert; + PutEventLog ( + AGESA_WARNING, + GNB_EVENT_BROKEN_LANE_RECOVERY, + CurrentEngine->Type.Port.Address.AddressValue, + 0, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + } else { + LinkTrainingState = LinkStateGen2Fail; + } + PcieTrainingSetPortState (CurrentEngine, LinkTrainingState, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if link fail because device does not support Gen2 + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +STATIC VOID +PcieTrainingGen2Fail ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 LinkTrainingState; + if (CurrentEngine->Type.Port.PortData.MiscControls.LinkSafeMode != PcieGen1) { + PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_PORT_GEN2_RECOVERY, 0); + CurrentEngine->Type.Port.PortData.MiscControls.LinkSafeMode = PcieGen1; + PcieLinkSafeMode (CurrentEngine, Pcie); + LinkTrainingState = LinkStateResetAssert; + PutEventLog ( + AGESA_WARNING, + GNB_EVENT_BROKEN_LANE_RECOVERY, + CurrentEngine->Type.Port.Address.AddressValue, + 0, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + } else { + LinkTrainingState = LinkStateTrainingFail; + } + PcieTrainingSetPortState (CurrentEngine, LinkTrainingState, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Link in L0 + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieCheckLinkL0 ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieTrainingSetPortState (CurrentEngine, LinkStateVcoNegotiation, TRUE, Pcie); +} +/*----------------------------------------------------------------------------------------*/ +/** + * Check if link fail because device does not support Gen X + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingCheckVcoNegotiation ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + DxFxx128_STRUCT DxFxx128; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + GnbLibPciRead (CurrentEngine->Type.Port.Address.AddressValue | DxFxx128_ADDRESS, AccessWidth32, &DxFxx128, GnbLibGetHeader (Pcie)); + if (DxFxx128.Field.VcNegotiationPending == 0) { + UINT16 NumberOfPhyLane; + NumberOfPhyLane = PcieConfigGetNumberOfPhyLane (CurrentEngine); + if (Pcie->GfxCardWorkaround == GfxWorkaroundEnable && NumberOfPhyLane >= 8) { + // Limit exposure of workaround to x8 and x16 port. + PcieTrainingSetPortState (CurrentEngine, LinkStateGfxWorkaround, TRUE, Pcie); + } else { + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingSuccess, FALSE, Pcie); + } + return; + } + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= 1000 * 1000) { + PcieTrainingSetPortState (CurrentEngine, LinkStateRetrain, FALSE, Pcie); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if for GFX workaround condition + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingGfxWorkaround ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT32 TimeStamp; + GFX_WORKAROUND_STATUS GfxWorkaroundStatus; + TimeStamp = PcieTimerGetTimeStamp (Pcie); + + GfxWorkaroundStatus = PcieGfxCardWorkaroundV2 (CurrentEngine->Type.Port.Address, GnbLibGetHeader (Pcie)); + switch (GfxWorkaroundStatus) { + case GFX_WORKAROUND_DEVICE_NOT_READY: + if (TIMESTAMPS_DELTA (TimeStamp, CurrentEngine->Type.Port.TimeStamp) >= (3 * 1000000)) { + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingFail, TRUE, Pcie); + } + break; + case GFX_WORKAROUND_SUCCESS: + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingSuccess, FALSE, Pcie); + break; + case GFX_WORKAROUND_RESET_DEVICE: + if (CurrentEngine->Type.Port.GfxWrkRetryCount < 5) { + CurrentEngine->Type.Port.GfxWrkRetryCount++; + PcieTrainingSetPortState (CurrentEngine, LinkStateResetAssert, TRUE, Pcie); + } else { + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingFail, TRUE, Pcie); + } + break; + default: + ASSERT (FALSE); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Retrain link + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingRetrainLink ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + GnbLibPciRMW ( + CurrentEngine->Type.Port.Address.AddressValue | DxFxx68_ADDRESS, + AccessWidth32, + (UINT32) ~DxFxx68_RetrainLink_MASK, + 1 << DxFxx68_RetrainLink_OFFSET, + GnbLibGetHeader (Pcie) + ); + PcieTrainingSetPortState (CurrentEngine, LinkStateDetecting, TRUE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Training fail on this port + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingFail ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_PORT_TRAINING_FAIL, 0); + PcieTrainingSetPortState (CurrentEngine, LinkStateDeviceNotPresent, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Links training success + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieTrainingSuccess ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_TRAINING_SUCCESS, 0); + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingCompleted, FALSE, Pcie); + GnbLibPciRMW ( + CurrentEngine->Type.Port.Address.AddressValue | DxFxx68_ADDRESS, + AccessWidth32, + (UINT32) ~DxFxx68_LinkBWManagementStatus_MASK, + 1 << DxFxx68_LinkBWManagementStatus_OFFSET, + GnbLibGetHeader (Pcie) + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Links in compliance + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingCompliance ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PcieConfigUpdatePortStatus (CurrentEngine, INIT_STATUS_PCIE_PORT_IN_COMPLIANCE, 0); + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingCompleted, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PCie EP not present + * + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingNotPresent ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + if ((CurrentEngine->Type.Port.PortData.LinkHotplug == HotplugEnhanced) || (CurrentEngine->Type.Port.PortData.LinkHotplug == HotplugServer)) { + } else { + PcieRegisterWriteField ( + PcieConfigGetParentWrapper (CurrentEngine), + WRAP_SPACE (PcieConfigGetParentWrapper (CurrentEngine)->WrapId, D0F0xE4_WRAP_0800_ADDRESS + 0x100 * CurrentEngine->Type.Port.PortId), + D0F0xE4_WRAP_0800_HoldTraining_OFFSET, + D0F0xE4_WRAP_0800_HoldTraining_WIDTH, + 1, + FALSE, + Pcie + ); + } + PcieTrainingSetPortState (CurrentEngine, LinkStateTrainingCompleted, FALSE, Pcie); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Final state. Port training completed. + * + * Initialization status recorded in PCIe_ENGINE_CONFIG.InitStatus + * + * @param[in] CurrentEngine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ +VOID +STATIC +PcieTrainingCompleted ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Training state handling + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in, out] Buffer Indicate if engine in non final state + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +VOID +STATIC +PcieTrainingPortCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + BOOLEAN *TrainingComplete; + TrainingComplete = (BOOLEAN *) Buffer; + if (Engine->Type.Port.State < Pcie->TrainingExitState) { + *TrainingComplete = FALSE; + } else { + return; + } + switch (Engine->Type.Port.State) { + case LinkStateResetAssert: + PcieTrainingAssertReset (Engine, Pcie); + break; + case LinkStateResetDuration: + PcieTrainingCheckResetDuration (Engine, Pcie); + break; + case LinkStateResetExit: + PcieTrainingDeassertReset (Engine, Pcie); + break; + case LinkTrainingResetTimeout: + PcieTrainingCheckResetTimeout (Engine, Pcie); + break; + case LinkStateReleaseTraining: + PcieTrainingRelease (Engine, Pcie); + break; + case LinkStateDetectPresence: + PcieTrainingDetectPresence (Engine, Pcie); + break; + case LinkStateDetecting: + PcieTrainingDetectLinkState (Engine, Pcie); + break; + case LinkStateBrokenLane: + PcieTrainingBrokenLineV2 (Engine, Pcie); + break; + case LinkStateGen2Fail: + PcieTrainingGen2Fail (Engine, Pcie); + break; + case LinkStateL0: + PcieCheckLinkL0 (Engine, Pcie); + break; + case LinkStateVcoNegotiation: + PcieTrainingCheckVcoNegotiation (Engine, Pcie); + break; + case LinkStateRetrain: + PcieTrainingRetrainLink (Engine, Pcie); + break; + case LinkStateTrainingFail: + PcieTrainingFail (Engine, Pcie); + break; + case LinkStateGfxWorkaround: + PcieTrainingGfxWorkaround (Engine, Pcie); + break; + case LinkStateTrainingSuccess: + PcieTrainingSuccess (Engine, Pcie); + break; + case LinkStateCompliance: + PcieTrainingCompliance (Engine, Pcie); + break; + case LinkStateDeviceNotPresent: + PcieTrainingNotPresent (Engine, Pcie); + break; + case LinkStateTrainingCompleted: + PcieTrainingCompleted (Engine, Pcie); + break; + default: + break; + } + +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Main link training procedure + * + * Port end up in three possible state LinkStateTrainingNotPresent/LinkStateCompliance/ + * LinkStateTrainingSuccess + * + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_STATUS + * + */ + +AGESA_STATUS +PcieTraining ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + BOOLEAN TrainingComplete; + + IDS_PERF_TIMESTAMP (TP_BEGINGNBPCIETRAINING, GnbLibGetHeader (Pcie)); + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTraining Enter\n"); + do { + TrainingComplete = TRUE; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, + PcieTrainingPortCallback, + &TrainingComplete, + Pcie + ); + } while (!TrainingComplete); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieTraining Exit [%x]\n", Status); + IDS_PERF_TIMESTAMP (TP_ENDGNBPCIETRAINING, GnbLibGetHeader (Pcie)); + return Status; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.h new file mode 100644 index 0000000000..c31f73aa47 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieTrainingV2.h @@ -0,0 +1,63 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * PCIe link training + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIETRAINING_H_ +#define _PCIETRAINING_H_ + + +AGESA_STATUS +PcieTraining ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieTrainingSetPortState ( + IN PCIe_ENGINE_CONFIG *CurrentEngine, + IN PCIE_LINK_TRAINING_STATE State, + IN BOOLEAN UpdateTimeStamp, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +#endif + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.c new file mode 100644 index 0000000000..159ea3e699 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.c @@ -0,0 +1,375 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various workarounds + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbPcieTrainingV2.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIETRAININGV2_PCIEWORKAROUNDSV2_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PcieConfigureBridgeResources ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieFreeBridgeResources ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +GFX_WORKAROUND_STATUS +PcieDeskewWorkaround ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +GFX_WORKAROUND_STATUS +PcieNvWorkaround ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieProgramCpuMmio ( + OUT UINT32 *SaveValues, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +PcieRestoreCpuMmio ( + IN UINT32 *RestoreValues, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +PcieIsDeskewCardDetected ( + IN UINT16 DeviceId + ); + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * + * + * + * + * @param[in] Port PCI address of the port + * @param[in] StdHeader Standard configuration header + * @retval GFX_WORKAROUND_STATUS Return the GFX Card Workaround status + */ +GFX_WORKAROUND_STATUS +PcieGfxCardWorkaroundV2 ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GFX_WORKAROUND_STATUS Status; + UINT16 DeviceId; + UINT16 VendorId; + UINT8 DevClassCode; + UINT32 SaveValueData[2]; + PCI_ADDR Ep; + + Status = GFX_WORKAROUND_SUCCESS; + + Ep.AddressValue = MAKE_SBDFO (0, Port.Address.Bus + Port.Address.Device, 0, 0, 0); + if (PcieConfigureBridgeResources (Port, StdHeader) == AGESA_SUCCESS) { + GnbLibPciRead (Ep.AddressValue | 0x00, AccessWidth16, &DeviceId, StdHeader); + Status = GFX_WORKAROUND_DEVICE_NOT_READY; + if (DeviceId != 0xffff) { + GnbLibPciRead (Ep.AddressValue | 0x02, AccessWidth16, &VendorId, StdHeader); + if (VendorId != 0xffff) { + GnbLibPciRead (Ep.AddressValue | 0x0B, AccessWidth8, &DevClassCode, StdHeader); + Status = GFX_WORKAROUND_SUCCESS; + if (DevClassCode == 3) { + PcieProgramCpuMmio (SaveValueData, StdHeader); + if (VendorId == 0x1002 && PcieIsDeskewCardDetected (DeviceId)) { + Status = PcieDeskewWorkaround (Ep, StdHeader); + } else if (VendorId == 0x10DE) { + Status = PcieNvWorkaround (Ep, StdHeader); + } + PcieRestoreCpuMmio (SaveValueData, StdHeader); + } + } + } + PcieFreeBridgeResources (Port, StdHeader); + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * RV370/RV380 Deskew workaround + * + * + * + * @param[in] Device Pcie Address + * @param[in] StdHeader Standard configuration header + */ +GFX_WORKAROUND_STATUS +PcieDeskewWorkaround ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN MmioBase; + UINT16 MmioData1; + UINT32 MmioData2; + + MmioBase = UserOptions.CfgTempPcieMmioBaseAddress; + if (MmioBase == 0) { + return GFX_WORKAROUND_SUCCESS; + } + GnbLibPciWrite (Device.AddressValue | 0x18, AccessWidth32, &MmioBase, StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x04, AccessWidth8 , (UINT32)~BIT1, BIT1, StdHeader); + GnbLibMemRMW (MmioBase + 0x120, AccessWidth16, 0, 0xb700, StdHeader); + GnbLibMemRead (MmioBase + 0x120, AccessWidth16, &MmioData1, StdHeader); + if (MmioData1 == 0xb700) { + GnbLibMemRMW (MmioBase + 0x124, AccessWidth32, 0, 0x13, StdHeader); + GnbLibMemRead (MmioBase + 0x124, AccessWidth32, &MmioData2, StdHeader); + if (MmioData2 == 0x13) { + GnbLibMemRead (MmioBase + 0x12C, AccessWidth32, &MmioData2, StdHeader); + if (MmioData2 & BIT8) { + return GFX_WORKAROUND_RESET_DEVICE; + } + } + } + GnbLibPciRMW (Device.AddressValue | 0x04, AccessWidth8, (UINT32)~BIT1, 0x0, StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x18, AccessWidth32, 0x0, 0x0, StdHeader); + + return GFX_WORKAROUND_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NV43 card workaround (lost SSID) + * + * + * + * @param[in] Device Pcie Address of NV43 card. + * @param[in] StdHeader Standard configuration header + */ +GFX_WORKAROUND_STATUS +PcieNvWorkaround ( + IN PCI_ADDR Device, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 DeviceSSID; + UINTN MmioBase; + UINT32 MmioData3; + + MmioBase = UserOptions.CfgTempPcieMmioBaseAddress; + if (MmioBase == 0) { + return GFX_WORKAROUND_SUCCESS; + } + GnbLibPciRMW (Device.AddressValue | 0x30, AccessWidth32, 0x0, ((UINT32)MmioBase) | 1, StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x4, AccessWidth8, 0x0, 0x2, StdHeader); + GnbLibPciRead (Device.AddressValue | 0x2c, AccessWidth32, &DeviceSSID, StdHeader); + GnbLibMemRead (MmioBase + 0x54, AccessWidth32, &MmioData3, StdHeader); + if (DeviceSSID != MmioData3) { + GnbLibPciRMW (Device.AddressValue | 0x40, AccessWidth32, 0x0, MmioData3, StdHeader); + } + GnbLibPciRMW (Device.AddressValue | 0x30, AccessWidth32, 0x0, 0x0, StdHeader); + GnbLibPciRMW (Device.AddressValue | 0x4, AccessWidth8, 0x0, 0x0, StdHeader); + return GFX_WORKAROUND_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate temporary resources for Pcie P2P bridge + * + * + * + * @param[in] Port Pci Address of Port to initialize. + * @param[in] StdHeader Standard configuration header + */ +AGESA_STATUS +PcieConfigureBridgeResources ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Value; + UINT32 MmioBase; + + MmioBase = UserOptions.CfgTempPcieMmioBaseAddress; + if (MmioBase == 0) { + return AGESA_WARNING; + } + Value = Port.Address.Bus + ((Port.Address.Bus + Port.Address.Device) << 8) + ((Port.Address.Bus + Port.Address.Device) << 16); + GnbLibPciWrite (Port.AddressValue | DxFxx18_ADDRESS, AccessWidth32, &Value, StdHeader); + Value = MmioBase + (MmioBase >> 16); + GnbLibPciWrite (Port.AddressValue | DxFxx20_ADDRESS, AccessWidth32, &Value, StdHeader); + Value = 0x000fff0; + GnbLibPciWrite (Port.AddressValue | DxFxx24_ADDRESS, AccessWidth32, &Value, StdHeader); + Value = 0x2; + GnbLibPciWrite (Port.AddressValue | D0F0x04_ADDRESS, AccessWidth8, &Value, StdHeader); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Free temporary resources for Pcie P2P bridge + * + * + * + * @param[in] Port Pci Address of Port to clear resource allocation. + * @param[in] StdHeader Standard configuration header + */ +VOID +PcieFreeBridgeResources ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Value; + + Value = 0; + GnbLibPciWrite (Port.AddressValue | D0F0x04_ADDRESS, AccessWidth8, &Value, StdHeader); + GnbLibPciWrite (Port.AddressValue | DxFxx18_ADDRESS, AccessWidth32, &Value, StdHeader); + GnbLibPciWrite (Port.AddressValue | DxFxx20_ADDRESS, AccessWidth32, &Value, StdHeader); + GnbLibPciWrite (Port.AddressValue | DxFxx24_ADDRESS, AccessWidth32, &Value, StdHeader); + +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Save CPU MMIO register + * + * + * + * @param[out] UINT32 SaveValues + * @param[in] StdHeader Standard configuration header + * + */ +VOID +PcieProgramCpuMmio ( + OUT UINT32 *SaveValues, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + //Save CPU MMIO Register + GnbLibPciRead (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xB8), AccessWidth32, SaveValues, StdHeader); + GnbLibPciRead (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xBC), AccessWidth32, SaveValues + 1, StdHeader); + + //Write Temp Pcie MMIO to CPU + GnbLibPciRMW (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xBC), AccessWidth32, 0, (UserOptions.CfgTempPcieMmioBaseAddress >> 16) << 8, StdHeader); + GnbLibPciRMW (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xB8), AccessWidth32, 0, ((UserOptions.CfgTempPcieMmioBaseAddress >> 16) << 8) | 0x3, StdHeader); + +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Restore CPU MMIO register + * + * + * + * @param[in] PCIe_PLATFORM_CONFIG Pcie + * @param[in] StdHeader Standard configuration header + */ +VOID +PcieRestoreCpuMmio ( + IN UINT32 *RestoreValues, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + //Restore CPU MMIO Register + GnbLibPciRMW (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xB8), AccessWidth32, 0, *RestoreValues, StdHeader); + GnbLibPciRMW (MAKE_SBDFO (0, 0, 0x18, 0x1, 0xBC), AccessWidth32, 0, *(RestoreValues + 1), StdHeader); + +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if card required test for deskew workaround + * + * + * + * @param[in] DeviceId Device ID + */ + +BOOLEAN +PcieIsDeskewCardDetected ( + IN UINT16 DeviceId + ) +{ + if ((DeviceId >= 0x3150 && DeviceId <= 0x3152) || (DeviceId == 0x3154) || + (DeviceId == 0x3E50) || (DeviceId == 0x3E54) || + ((DeviceId & 0xfff8) == 0x5460) || ((DeviceId & 0xfff8) == 0x5B60)) { + return TRUE; + } + return FALSE; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.h new file mode 100644 index 0000000000..3fefdd2a19 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbPcieTrainingV2/PcieWorkaroundsV2.h @@ -0,0 +1,55 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various workarounds + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _PCIEWORKAROUNDSV2_H_ +#define _PCIEWORKAROUNDSV2_H_ + +GFX_WORKAROUND_STATUS +PcieGfxCardWorkaroundV2 ( + IN PCI_ADDR Port, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSSocketLib/GnbSSocketLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSSocketLib/GnbSSocketLib.c new file mode 100644 index 0000000000..43705063f7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSSocketLib/GnbSSocketLib.c @@ -0,0 +1,169 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB Single Socket Library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "cpuFamilyTranslation.h" +#include "cpuServices.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbLib.h" +#include "GnbLibPciAcc.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSSOCKETLIB_GNBSSOCKETLIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +PCI_ADDR +GnbFmGetPciAddress ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbFmGetBusDecodeRange ( + IN GNB_HANDLE *GnbHandle, + OUT UINT8 *StartBusNumber, + OUT UINT8 *EndBusNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbFmGetLinkId ( + IN GNB_HANDLE *GnbHandle, + OUT UINT8 *LinkId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Host bridge PCI Address + * + * + * + * @param[in] GnbHandle GNB handle + * @param[in] StdHeader Standard configuration header + * @retval PCI address of GNB for a given socket/silicon. + */ + +PCI_ADDR +GnbFmGetPciAddress ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR Gnb; + Gnb.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + return Gnb; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bus range decoded by GNB + * + * Final bus allocation can not be assumed until AmdInitMid + * + * @param[in] GnbHandle GNB handle + * @param[out] StartBusNumber Beginning of the Bus Range + * @param[out] EndBusNumber End of the Bus Range + * @param[in] StdHeader Standard configuration header + * @retval Status + */ + +AGESA_STATUS +GnbFmGetBusDecodeRange ( + IN GNB_HANDLE *GnbHandle, + OUT UINT8 *StartBusNumber, + OUT UINT8 *EndBusNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *StartBusNumber = 0x0; + *EndBusNumber = 0xff; + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get link to which GNB connected to + * + * + * @param[in] GnbHandle GNB handle + * @param[out] LinkId Link to which GNB connected to + * @param[in] StdHeader Standard configuration header + * @retval Status + */ + +AGESA_STATUS +GnbFmGetLinkId ( + IN GNB_HANDLE *GnbHandle, + OUT UINT8 *LinkId, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + *LinkId = 0x00; + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.c new file mode 100644 index 0000000000..209da2394d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.c @@ -0,0 +1,143 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * SB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbCommonLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSBLIB_GNBSBLIB_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +UINT32 +SbGetSbIoApicBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +SbGetSbMmioBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT16 +SbGetAlinkIoAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + *Get SB IOAPIC Base Address + * + * + * @param[in] StdHeader Standard configuration header + * @retval ApicBaseAddress + */ +UINT32 +SbGetSbIoApicBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ApicBaseAddress; + GnbLibIndirectIoBlockRead (0xCD6, 0xCD7, AccessWidth8, 0x34, 4, &ApicBaseAddress, StdHeader); + return ApicBaseAddress & 0xffffffe0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Get SB MMIO Base Address + * + * + * @param[in] StdHeader Standard configuration header + * @retval MMIO base address + */ +UINT32 +SbGetSbMmioBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MmioBaseAddress; + GnbLibIndirectIoBlockRead (0xCD6, 0xCD7, AccessWidth8, 0x24, 4, &MmioBaseAddress, StdHeader); + return MmioBaseAddress & 0xfffffffc; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Alink config address + * + * @param[in] StdHeader Standard configuration header + * @retval AlinkPortAddress + */ +/*----------------------------------------------------------------------------------------*/ + +UINT16 +SbGetAlinkIoAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + UINT16 AlinkPortAddress; + GnbLibIndirectIoBlockRead (0xCD6, 0xCD7, AccessWidth8, 0xE0, 2, &AlinkPortAddress, StdHeader); + return AlinkPortAddress; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.h new file mode 100644 index 0000000000..516b77ac3c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbLib.h @@ -0,0 +1,78 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * SB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBSBLIB_H_ +#define _GNBSBLIB_H_ + +#include "GnbPcie.h" + +UINT32 +SbGetSbIoApicBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +SbGetSbMmioBaseAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT16 +SbGetAlinkIoAddress ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +SbPcieInitAspm ( + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +SbPcieLinkAspmControl ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbPcie.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbPcie.c new file mode 100644 index 0000000000..cc8cbf873c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSbLib/GnbSbPcie.c @@ -0,0 +1,142 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB-SB link procedure + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbSbLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSBLIB_GNBSBPCIE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable/Disable ASPM on GNB-SB link + * + * + * + * @param[in] Engine Pointer to engine config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * + */ + +AGESA_STATUS +SbPcieLinkAspmControl ( + IN PCIe_ENGINE_CONFIG *Engine, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + PCIE_ASPM_TYPE Aspm; + + Aspm = Engine->Type.Port.PortData.LinkAspm; + + Status = SbPcieInitAspm (Aspm, GnbLibGetHeader (Pcie)); + if (Status != AGESA_SUCCESS) { + return AGESA_UNSUPPORTED; + } + + excel950_fun4 (Engine->Type.Port.Address, Aspm, GnbLibGetHeader (Pcie)); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init SB ASPM. + * Enable ASPM states on SB + * + * + * @param[in] Aspm ASPM bitmap. + * @param[in] StdHeader Standard configuration header + */ +/*----------------------------------------------------------------------------------------*/ + +AGESA_STATUS +SbPcieInitAspm ( + IN PCIE_ASPM_TYPE Aspm, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 AlinkPort; + + AlinkPort = SbGetAlinkIoAddress (StdHeader); + ASSERT (AlinkPort != 0); + if (AlinkPort == 0) { + return AGESA_UNSUPPORTED; + } + GnbLibIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x40000038, StdHeader); + GnbLibIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0x0, 0xA0, StdHeader); + GnbLibIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x4000003c, StdHeader); + GnbLibIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffff00ff, 0x6900, StdHeader); + GnbLibIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x80000068, StdHeader); + GnbLibIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xfffffffc, Aspm, StdHeader); + return AGESA_SUCCESS; +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbScsLibV1/GnbScsLibV1.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbScsLibV1/GnbScsLibV1.c new file mode 100644 index 0000000000..91130298f8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbScsLibV1/GnbScsLibV1.c @@ -0,0 +1,198 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "OptionGnb.h" +#include "GnbSmuInitLibV7.h" +#include "heapManager.h" +#include "GnbFamServices.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSCSLIBV1_GNBSCSLIBV1_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +#ifndef TYPE_D0F0xBC + #define TYPE_D0F0xBC 0x4 +#endif + +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +GnbSmuInitLibV7139_fun0 ( + IN GNB_HANDLE *GnbHandle, + IN UINT8 *ScsDataPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + DEV_OBJECT DevObject; + AGESA_STATUS Status; + + IDS_PERF_TIMESTAMP (TP_BEGINGNBLOADSCSDATA, StdHeader); + + Status = AGESA_SUCCESS; + if (GnbBuildOptions.CfgScsSupport == TRUE) { + IDS_HDT_CONSOLE (GNB_TRACE, "GnbSmuInitLibV7139_fun0 Enter\n"); + //Check input parameters + ASSERT ((ScsDataPtr != NULL) && (StdHeader != NULL)); + if ((ScsDataPtr == NULL) || (StdHeader == NULL)) { + return AGESA_ERROR; + } + + //Verify the SCS block signature + ASSERT (*(UINT32 *)ScsDataPtr == GnbSmuInitLibV7136_macro0); + if (*(UINT32 *)ScsDataPtr != GnbSmuInitLibV7136_macro0) { + IDS_HDT_CONSOLE (GNB_TRACE, "Verify SCS Binary fail\n", ScsDataPtr); + return AGESA_ERROR; + } + + //Load SCS block + IDS_HDT_CONSOLE (GNB_TRACE, "Load SCS @%08x\n", ScsDataPtr); + DevObject.DevPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + DevObject.GnbHandle = GnbHandle; + DevObject.StdHeader = StdHeader; + GnbSmuServiceRequestV7 (&DevObject, 0x50, (UINT32) (UINTN) ScsDataPtr, 0); + + //Get SCS result and save to Heap + IDS_HDT_CONSOLE (GNB_TRACE, "Get SCS Result\n", ScsDataPtr); + Status = GnbSmuInitLibV7139_fun1 (GnbHandle, StdHeader); + + IDS_HDT_CONSOLE (GNB_TRACE, "Get SCS Result %s\n", (Status == AGESA_SUCCESS) ? "Success" : "Fail"); + } + + IDS_PERF_TIMESTAMP (TP_ENDGNBLOADSCSDATA, StdHeader); + return Status; +} + +AGESA_STATUS +GnbSmuInitLibV7139_fun1 ( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 i; + UINT32 ScsResultAddr; + UINT32 *ScsResultBuf; + UINT32 NumApmWeights; + AGESA_STATUS Status; + DEV_OBJECT DevObject; + GNB_REGISTER_SERVICE *GnbRegisterAccessProtocol; + ALLOCATE_HEAP_PARAMS AllocateHeapParams; + + Status = AGESA_SUCCESS; + DevObject.GnbHandle = GnbHandle; + DevObject.StdHeader = StdHeader; + DevObject.DevPciAddress = GnbGetHostPciAddress (GnbHandle); + + Status = GnbLibLocateService (GnbRegisterAccessService, GnbGetSocketId (GnbHandle), (VOID **)&GnbRegisterAccessProtocol, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status != AGESA_SUCCESS) { + return Status; + } + + //Get the command result (A pointer to SMURAM) + ScsResultAddr = 0; + GnbUraGet (&DevObject, TRxSmuIntArgument, &ScsResultAddr); + IDS_HDT_CONSOLE (GNB_TRACE, "SMURAMAddr %08x ", ScsResultAddr); + ASSERT (ScsResultAddr != 0); + + + Status = GnbRegisterAccessProtocol->Read (GnbHandle, 0x4, ScsResultAddr + offsetof (SMU_RAM_CPU_INFO, CountApmWeights), &NumApmWeights, 0, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, "NumApmWeights %d\n", NumApmWeights); + ASSERT (Status == AGESA_SUCCESS); + if (Status != AGESA_SUCCESS) { + return Status; + } + + //Allocate heap for store the result + AllocateHeapParams.BufferHandle = AMD_SCS_SMU_RAM_INFO; + AllocateHeapParams.Persist = HEAP_LOCAL_CACHE; + AllocateHeapParams.BufferPtr = NULL; + AllocateHeapParams.RequestedBufferSize = sizeof (SMU_RAM_CPU_INFO) + SIZE_OF_APMWEIGHTS * NumApmWeights; + Status = HeapAllocateBuffer (&AllocateHeapParams, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status != AGESA_SUCCESS) { + return Status; + } + + ScsResultBuf = (UINT32 *)AllocateHeapParams.BufferPtr; + //Get the result point by RxSmuIntArgument from SMURAM + for (i = 0; i < (sizeof (SMU_RAM_CPU_INFO) / sizeof (UINT32) + NumApmWeights); i++) { + Status = GnbRegisterAccessProtocol->Read (GnbHandle, 0x4, ScsResultAddr, &ScsResultBuf[i], 0, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status != AGESA_SUCCESS) { + break; + } + ScsResultAddr += sizeof (UINT32); + } + + if (Status != AGESA_SUCCESS) { + IDS_HDT_CONSOLE (GNB_TRACE, "Fail on get SCS Result @%08x\n", ScsResultAddr); + HeapDeallocateBuffer (AMD_SCS_SMU_RAM_INFO, StdHeader); + } else { + } + + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.c new file mode 100644 index 0000000000..2f4038979e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.c @@ -0,0 +1,330 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85506 $ @e \$Date: 2013-01-08 15:38:33 -0600 (Tue, 08 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "S3SaveState.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbPcieInitLibV1.h" +#include "GnbSmuInitLibV7.h" +#include "heapManager.h" +#include "GnbFamServices.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSMULIBV7_GNBSMUINITLIBV7_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +#define SMC_RAM_START_ADDR 0x20000ul +#ifndef INVALID_SMU_MSG + #define INVALID_SMU_MSG 0xFF +#endif + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +GnbSmuServiceRequestV7S3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID *Context + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * SMU service request + * + * + * @param[in] DevObject Pointer to Device object + * @param[in] RequestId Request ID + * @param[in] RequestArgument Request Argument + * @param[in] AccessFlags See GNB_ACCESS_FLAGS_* definitions + */ + +VOID +GnbSmuServiceRequestV7 ( + IN DEV_OBJECT *DevObject, + IN UINT8 RequestId, + IN UINT32 RequestArgument, + IN UINT32 AccessFlags + ) +{ + UINT32 BFIntDone; + UINT32 BFIntToggle; + UINT32 BFIntAck; + UINT32 RxSmuIntArgument; + URA_TUPLE UraTuple[2]; + UINT32 IsMsgValid; + + IsMsgValid = FALSE; + if (RequestId != INVALID_SMU_MSG) { + IsMsgValid = TRUE; + } + + if (IsMsgValid == TRUE) { + IDS_HDT_CONSOLE (GNB_TRACE, "GnbSmuServiceRequestV7 Enter\n"); + IDS_HDT_CONSOLE (NB_MISC, " Service Request %d\n", RequestId); + IDS_HDT_CONSOLE (NB_MISC, " Service Request Argument 0x%x\n", RequestArgument); + + if ((AccessFlags & GNB_REG_ACC_FLAG_S3SAVE) != 0) { + SMU_MSG_CONTEXTV7 SmuMsgContext; + SmuMsgContext.GnbPciAddress.AddressValue = DevObject->DevPciAddress.AddressValue; + SmuMsgContext.RequestId = RequestId; + SmuMsgContext.RequestArgument = RequestArgument; + S3_SAVE_DISPATCH (DevObject->StdHeader, GnbSmuServiceRequestV7S3Script_ID, sizeof (SmuMsgContext), &SmuMsgContext); + } + + do { + GnbUraGet (DevObject, TBfxSmuIntDone, &BFIntDone); + } while (BFIntDone == 0x0); + + RxSmuIntArgument = RequestArgument; + GnbUraSet (DevObject, TRxSmuIntArgument, &RxSmuIntArgument); + + GnbUraGet (DevObject, TBfxSmuIntToggle, &BFIntToggle); + UraTuple[0].Token = TBfxSmuIntToggle; + UraTuple[0].Value = ~BFIntToggle; + UraTuple[1].Token = TBfxSmuServiceIndex; + UraTuple[1].Value = RequestId; + GnbUraCombinedSet (DevObject, TRxSmuIntReq, &UraTuple[0], 2); + + do { + GnbUraGet (DevObject, TBfxSmuIntAck, &BFIntAck); + } while (BFIntAck == 0x0); + + do { + GnbUraGet (DevObject, TBfxSmuIntDone, &BFIntDone); + } while (BFIntDone == 0x0); + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbSmuServiceRequestV7 Exit\n"); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * SMU service request for S3 script + * + * + * @param[in] StdHeader Standard configuration header + * @param[in] ContextLength Context length + * @param[in] Context Pointer to Context + */ + +VOID +GnbSmuServiceRequestV7S3Script ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN UINT16 ContextLength, + IN VOID *Context + ) +{ + SMU_MSG_CONTEXTV7 *SmuMsgContext; + DEV_OBJECT DevObject; + SmuMsgContext = (SMU_MSG_CONTEXTV7 *) Context; + + DevObject.StdHeader = StdHeader; + DevObject.DevPciAddress = SmuMsgContext->GnbPciAddress; + DevObject.GnbHandle = GnbGetHandle (StdHeader); + + GnbSmuServiceRequestV7 (&DevObject, SmuMsgContext->RequestId, SmuMsgContext->RequestArgument, 0); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * SMU firmware download + * + * + * @param[in] GnbHandle Pointer to GNB_HANDLE + * @param[in] Firmware Pointer t0 firmware + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +GnbSmuFirmwareLoadV7 ( + IN GNB_HANDLE *GnbHandle, + IN FIRMWARE_HEADER_V7 *Firmware, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + UINT32 BfxSmuProtectedMode; + UINT32 BfxSmuBootSeqDone; + UINT32 BfxSmuAuthDone; + UINT32 BfxSmuAuthPass; + UINT32 RxSmuAuthVector; + UINT32 BfxSmuRstReg; + UINT32 BfxSmuCkDisable; + UINT32 BfxSmuInterruptsEnabled; + UINT32 RxSmuRamStartAddr; + GNB_REGISTER_SERVICE *GnbRegisterAccessProtocol; + PCI_ADDR GnbPciAddress; + DEV_OBJECT DevObject; + URA_TUPLE UraTuple; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbSmuFirmwareLoadV7 Enter\n"); + IDS_HDT_CONSOLE (NB_MISC, " Firmware version 0x%x\n", Firmware->Version); + IDS_OPTION_HOOK (IDS_REPORT_SMU_FW_VERSION, &(Firmware->Version), StdHeader); + + GnbPciAddress = GnbGetHostPciAddress (GnbHandle); + Status = GnbLibLocateService (GnbRegisterAccessService, GnbGetSocketId (GnbHandle), (VOID **)&GnbRegisterAccessProtocol, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + + DevObject.GnbHandle = GnbHandle; + DevObject.StdHeader = StdHeader; + DevObject.DevPciAddress.AddressValue = GnbPciAddress.AddressValue; + + IDS_HDT_CONSOLE (GNB_TRACE, "Step 2 & 10: make sure Rom firmware sequence is done\n"); + // Step 2, 10, make sure Rom firmware sequence is done + do { + GnbUraGet (&DevObject, TBfxSmuBootSeqDone, &BfxSmuBootSeqDone); + } while (BfxSmuBootSeqDone == 0); + + IDS_HDT_CONSOLE (GNB_TRACE, "Step 1: check if firmware running in protected mode\n"); + // Step 1, check if firmware running in protected mode + GnbUraGet (&DevObject, TBfxSmuProtectedMode, &BfxSmuProtectedMode); + if (BfxSmuProtectedMode == 0) { + // Step3, Clear firmware interrupt flags + IDS_HDT_CONSOLE (GNB_TRACE, "Step 3: Clear firmware interrupt flags\n"); + //IDS_HDT_CONSOLE (GNB_TRACE, "Read register data 0x%x\n", FIRMWARE_FLAGS.Value); + BfxSmuInterruptsEnabled = 0; + GnbUraSet (&DevObject, TBfxSmuInterruptsEnabled, &BfxSmuInterruptsEnabled); + } + + //Step 4, 11, Assert SMU reset + IDS_HDT_CONSOLE (GNB_TRACE, "Step 4, 11: Assert SMU reset\n"); + BfxSmuRstReg = 1; + GnbUraSet (&DevObject, TBfxSmuRstReg, &BfxSmuRstReg); + + // Step5, 12, Load firmware + IDS_HDT_CONSOLE (GNB_TRACE, "Step5, 12, Load firmware\n"); + // 4 means byte length of next address during firmware download + UraTuple.StepLength = 4; + UraTuple.Value = (UINT32) ((UINTN) (Firmware)); + GnbUraCombinedSet (&DevObject, TRxSmuRamStartAddr | GNB_URA_STREAM_SET, &UraTuple, (Firmware->ImageSize >> 2)); + + if (BfxSmuProtectedMode == 0) { + IDS_HDT_CONSOLE (GNB_TRACE, "Step6, write jmp to RAM firmware\n"); + //Step 6, Write jmp to RAM firmware + RxSmuRamStartAddr = 0xE0000000 + ((SMC_RAM_START_ADDR + Firmware->HeaderSize) >> 2); + GnbUraSet (&DevObject, TRxSmuRomStartAddr, &RxSmuRamStartAddr); + } else { + //Step 13, Clear authentification done + IDS_HDT_CONSOLE (GNB_TRACE, "Step 13, Clear authentification done\n"); + BfxSmuAuthDone = 0; + GnbUraSet (&DevObject, TBfxSmuAuthDone, &BfxSmuAuthDone); + } + + // Step 7, 14 Enable SMU clock + IDS_HDT_CONSOLE (GNB_TRACE, "Step 7, 14 Enable SMU clock\n"); + BfxSmuCkDisable = 0; + GnbUraSet (&DevObject, TBfxSmuCkDisable, &BfxSmuCkDisable); + + //Step 8, 15, Deassert SMU reset + IDS_HDT_CONSOLE (GNB_TRACE, "Step 8, 15, Deassert SMU reset\n"); + BfxSmuRstReg = 0; + GnbUraSet (&DevObject, TBfxSmuRstReg, &BfxSmuRstReg); + + if (BfxSmuProtectedMode == 1) { + IDS_HDT_CONSOLE (NB_MISC, " Protected mode: poll init authentication vector\n"); + // Step 16, Wait for rom firmware init authentication vector + IDS_HDT_CONSOLE (GNB_TRACE, "Step 16, Wait for rom firmware init authentication vector\n"); + do { + GnbUraGet (&DevObject, TRxSmuAuthVector, &RxSmuAuthVector); + } while (RxSmuAuthVector != 0x400); + // Call Authentication service + GnbSmuServiceRequestV7 (&DevObject, 0, 0, 0); + IDS_HDT_CONSOLE (NB_MISC, " Protected mode: poll init authentication done\n"); + // Wait for authentication done + do { + GnbUraGet (&DevObject, TBfxSmuAuthDone, &BfxSmuAuthDone); + } while (BfxSmuAuthDone == 0x0); + + //Step 17, Check Authentication results + IDS_HDT_CONSOLE (GNB_TRACE, "Step 17, Check Authentication results\n"); + GnbUraGet (&DevObject, TBfxSmuAuthPass, &BfxSmuAuthPass); + if (BfxSmuAuthPass == 0) { + IDS_HDT_CONSOLE (NB_MISC, " ERROR!!!Authentication fail!!!\n"); + ASSERT (FALSE); + return AGESA_FATAL; + } + // Step 18, Clear firmware interrupt enable flag + IDS_HDT_CONSOLE (GNB_TRACE, "Step 18, Clear firmware interrupt enable flag\n"); + BfxSmuInterruptsEnabled = 0; + GnbUraSet (&DevObject, TBfxSmuInterruptsEnabled, &BfxSmuInterruptsEnabled); + + //Step 19, Assert SMU reset + IDS_HDT_CONSOLE (GNB_TRACE, "Step 19, Assert SMU reset\n"); + BfxSmuRstReg = 1; + GnbUraSet (&DevObject, TBfxSmuRstReg, &BfxSmuRstReg); + + //Step 20, Deassert SMU reset + IDS_HDT_CONSOLE (GNB_TRACE, "Step 20, Deassert SMU reset\n"); + BfxSmuRstReg = 0; + GnbUraSet (&DevObject, TBfxSmuRstReg, &BfxSmuRstReg); + } + + //Step 9, 21 Wait firmware to initialize + IDS_HDT_CONSOLE (GNB_TRACE, "Step 9, 21 Wait firmware to initialize\n"); + do { + GnbUraGet (&DevObject, TBfxSmuInterruptsEnabled, &BfxSmuInterruptsEnabled); + } while (BfxSmuInterruptsEnabled == 0); + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbSmuFirmwareLoadV7 Exit\n"); + return AGESA_SUCCESS; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.h new file mode 100644 index 0000000000..6f7f9d7faf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSmuLibV7/GnbSmuInitLibV7.h @@ -0,0 +1,123 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85506 $ @e \$Date: 2013-01-08 15:38:33 -0600 (Tue, 08 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBNBINITLIBV7_H_ +#define _GNBNBINITLIBV7_H_ + +#pragma pack (push, 1) +#include "GnbUraServices.h" + +/// Firmware header +typedef struct { + UINT32 Digest[5]; ///< Digest + UINT32 Version; ///< Version + UINT32 HeaderSize; ///< Header length + UINT32 Flags; ///< Flags + UINT32 EntryPoint; ///< Entry Point + UINT32 CodeSize; ///< Code Size + UINT32 ImageSize; ///< Image Size + UINT32 Rtos; ///< Rtos + UINT32 SoftRegisters; ///< Soft Registers + UINT32 DpmTable; ///< Dpm Table + UINT32 FanTable; ///< Fan Table + UINT32 CacConfigTable; ///< Cac Configuration Table + UINT32 CacStatusTable; ///< Cac Status Table + UINT32 mcRegisterTable; ///< mc Register Table + UINT32 mcArbDramTimingTable; ///< mc Arb Dram Timing Table + UINT32 Globals; ///< Globals + UINT32 Signature; ///< Signature + UINT32 Reserved[44]; ///< Reserved space +} FIRMWARE_HEADER_V7; + +/// SMU service request contect +typedef struct { + PCI_ADDR GnbPciAddress; ///< PCIe address of GNB + UINT8 RequestId; ///< Request/Msg ID + UINT32 RequestArgument; ///< Request/Msg Argument +} SMU_MSG_CONTEXTV7; + + +#define SIZE_OF_APMWEIGHTS (sizeof (UINT32)) +typedef struct { + UINT64 EnergyCountConstant; + UINT64 BoostTimeConstant; + UINT32 CountApmWeights; ///< length of APMWeights array +// UINT32 ApmWeights[1]; ///< ApmWeights +} SMU_RAM_CPU_INFO; + + +#pragma pack (pop) + +VOID +GnbSmuServiceRequestV7 ( + IN DEV_OBJECT *DevObject, + IN UINT8 RequestId, + IN UINT32 RequestArgument, + IN UINT32 AccessFlags + ); + +AGESA_STATUS +GnbSmuFirmwareLoadV7 ( + IN GNB_HANDLE *GnbHandle, + IN FIRMWARE_HEADER_V7 *Firmware, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#define GnbSmuInitLibV7136_macro0 STRING_TO_UINT32 ('!', 'S', 'C', 'S') + +AGESA_STATUS +GnbSmuInitLibV7139_fun0( + IN GNB_HANDLE *GnbHandle, + IN UINT8 *ScsDataPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GnbSmuInitLibV7139_fun1( + IN GNB_HANDLE *GnbHandle, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSview/GnbSview.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSview/GnbSview.c new file mode 100644 index 0000000000..4ebb28f59c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbSview/GnbSview.c @@ -0,0 +1,128 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Interface to initialize Graphics Controller at mid POST + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbGfxConfig.h" +#include "GnbGfxInitLibV1.h" +#include "GnbCommonLib.h" +#include "GnbGfxFamServices.h" +#include "GnbRegistersCommon.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBSVIEW_GNBSVIEW_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +GfxInitSview ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init SVIEW configuration + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GfxInitSview ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + GFX_PLATFORM_CONFIG *Gfx; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxInitSview Enter\n"); + AgesaStatus = AGESA_SUCCESS; + Status = GfxLocateConfigData (StdHeader, &Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + if (GfxLibIsControllerPresent (StdHeader)) { + if (!GfxFmIsVbiosPosted (Gfx)) { + GFX_VBIOS_IMAGE_INFO VbiosImageInfo; + LibAmdMemCopy (&VbiosImageInfo.StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader); + VbiosImageInfo.ImagePtr = NULL; + VbiosImageInfo.GfxPciAddress = Gfx->GfxPciAddress; + VbiosImageInfo.Flags = GFX_VBIOS_IMAGE_FLAG_SPECIAL_POST; + GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessS3SaveWidth8, 0xff, BIT1 | BIT2 | BIT0, StdHeader); + Status = AgesaGetVbiosImage (0, &VbiosImageInfo); + if (Status == AGESA_SUCCESS && VbiosImageInfo.ImagePtr != NULL) { + GfxLibCopyMemToFb (VbiosImageInfo.ImagePtr, 0, (*((UINT8*) VbiosImageInfo.ImagePtr + 2)) << 9, Gfx); + } else { + GfxFmDisableController (StdHeader); + AgesaStatus = AGESA_ERROR; + } + GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessS3SaveWidth8, 0xf8, BIT1 | BIT2, StdHeader); + } + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "GfxInitSview Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbTable/GnbTable.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbTable/GnbTable.c new file mode 100644 index 0000000000..82b234885f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbTable/GnbTable.c @@ -0,0 +1,357 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "cpuFamilyTranslation.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbLib.h" +#include "GnbTimerLib.h" +#include "GnbFamServices.h" +#include "GnbTable.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBTABLE_GNBTABLE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +STATIC +GnbProcessTableRegisterRmw ( + IN GNB_HANDLE *GnbHandle, + IN GNB_REGISTER_SERVICE *GnbRegisterAccessProtocol, + IN GNB_RMW_BLOCK *Data, + IN UINT32 Flags, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Process table + * + * @param[in] GnbHandle Gnb handle + * @param[in] Table Table pointer + * @param[in] Property Property + * @param[in] Flags Flags + * @param[in] StdHeader Standard configuration header + */ + +AGESA_STATUS +GnbProcessTable ( + IN GNB_HANDLE *GnbHandle, + IN GNB_TABLE *Table, + IN UINT32 Property, + IN UINT32 Flags, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *EntryPointer; + UINT64 Data; + UINT64 Temp; + UINT64 Mask; + UINT32 WriteAccFlags; + GNB_REGISTER_SERVICE *GnbRegisterAccessProtocol; + CPU_LOGICAL_ID LogicalId; + AGESA_STATUS Status; + + IDS_HDT_CONSOLE (GNB_TRACE, "GnbProcessTableExt Enter\n"); + IDS_HDT_CONSOLE (GNB_TRACE, " Property - 0x%08x\n", Property); + + GetLogicalIdOfSocket (GnbGetSocketId (GnbHandle), &LogicalId, StdHeader); + EntryPointer = (UINT8 *) Table; + WriteAccFlags = 0; + if ((Flags & GNB_TABLE_FLAGS_FORCE_S3_SAVE) != 0) { + WriteAccFlags |= GNB_REG_ACC_FLAG_S3SAVE; + } + + Status = GnbLibLocateService (GnbRegisterAccessService, GnbGetSocketId (GnbHandle), (VOID **)&GnbRegisterAccessProtocol, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + + while (*EntryPointer != GnbEntryTerminate) { + Data = 0; + Temp = 0; + switch (*EntryPointer) { + case GnbEntryWr: + GnbRegisterAccessProtocol->Write ( + GnbHandle, + ((GNB_TABLE_ENTRY_WR*) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_WR*) EntryPointer)->Address, + &((GNB_TABLE_ENTRY_WR*) EntryPointer)->Value, + WriteAccFlags, + StdHeader + ); + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_WR); + break; + case GnbEntryPropertyWr: + if ((Property & ((GNB_TABLE_ENTRY_PROPERTY_WR *) EntryPointer)->Property) != 0) { + GnbRegisterAccessProtocol->Write ( + GnbHandle, + ((GNB_TABLE_ENTRY_PROPERTY_WR *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_PROPERTY_WR *) EntryPointer)->Address, + &((GNB_TABLE_ENTRY_PROPERTY_WR *) EntryPointer)->Value, + WriteAccFlags, + StdHeader + ); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_PROPERTY_WR); + break; + case GnbEntryFullWr: + if ((Property & ((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->Property) != 0) { + if ((LogicalId.Revision & ((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->Revision) != 0) { + GnbRegisterAccessProtocol->Write ( + GnbHandle, + ((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->Address, + &((GNB_TABLE_ENTRY_FULL_WR*) EntryPointer)->Value, + WriteAccFlags, + StdHeader + ); + } + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_FULL_WR); + break; + case GnbEntryRmw: + GnbProcessTableRegisterRmw ( + GnbHandle, + GnbRegisterAccessProtocol, + &((GNB_TABLE_ENTRY_RMW *) EntryPointer)->Data, + WriteAccFlags, + StdHeader + ); + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_RMW); + break; + case GnbEntryPropertyRmw: + if ((Property & ((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->Property) != 0) { + GnbProcessTableRegisterRmw ( + GnbHandle, + GnbRegisterAccessProtocol, + &((GNB_TABLE_ENTRY_PROPERTY_RMW *) EntryPointer)->Data, + WriteAccFlags, + StdHeader + ); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_PROPERTY_RMW); + break; + case GnbEntryRevRmw: + if ((LogicalId.Revision & ((GNB_TABLE_ENTRY_REV_RMW *) EntryPointer)->Revision) != 0) { + GnbProcessTableRegisterRmw ( + GnbHandle, + GnbRegisterAccessProtocol, + &((GNB_TABLE_ENTRY_REV_RMW *) EntryPointer)->Data, + WriteAccFlags, + StdHeader + ); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_REV_RMW); + break; + case GnbEntryFullRmw: + if ((Property & ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->Property) != 0) { + if ((LogicalId.Revision & ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->Revision) != 0) { + GnbProcessTableRegisterRmw ( + GnbHandle, + GnbRegisterAccessProtocol, + &((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->Data, + WriteAccFlags, + StdHeader + ); + } + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_FULL_RMW); + break; + case GnbEntryPoll: + do { + GnbRegisterAccessProtocol->Read ( + GnbHandle, + ((GNB_TABLE_ENTRY_POLL *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_POLL *) EntryPointer)->Address, + &Data, + 0, + StdHeader + ); + } while ((Data & ((GNB_TABLE_ENTRY_POLL*) EntryPointer)->AndMask) != ((GNB_TABLE_ENTRY_POLL*) EntryPointer)->CompareValue); + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_POLL); + break; + case GnbEntryPropertyPoll: + if ((Property & ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->Property) != 0) { + do { + GnbRegisterAccessProtocol->Read ( + GnbHandle, + ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->Address, + &Data, + 0, + StdHeader + ); + } while ((Data & ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->AndMask) != ((GNB_TABLE_ENTRY_PROPERTY_POLL *) EntryPointer)->CompareValue); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_PROPERTY_POLL); + break; + case GnbEntryFullPoll: + if ((Property & ((GNB_TABLE_ENTRY_FULL_POLL *) EntryPointer)->Property) != 0) { + if ((LogicalId.Revision & ((GNB_TABLE_ENTRY_FULL_RMW *) EntryPointer)->Revision) != 0) { + do { + GnbRegisterAccessProtocol->Read ( + GnbHandle, + ((GNB_TABLE_ENTRY_FULL_POLL *) EntryPointer)->RegisterSpaceType, + ((GNB_TABLE_ENTRY_FULL_POLL *) EntryPointer)->Address, + &Data, + 0, + StdHeader + ); + } while ((Data & ((GNB_TABLE_ENTRY_FULL_POLL *) EntryPointer)->AndMask) != ((GNB_TABLE_ENTRY_FULL_POLL *) EntryPointer)->CompareValue); + } + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_FULL_POLL); + break; + case GnbEntryCopy: + GnbRegisterAccessProtocol->Read ( + GnbHandle, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->SrcRegisterSpaceType, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->SrcAddress, + &Data, + 0, + StdHeader + ); + Mask = (1ull << ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->SrcFieldWidth) - 1; + Data = (Data >> ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->SrcFieldOffset) & Mask; + GnbRegisterAccessProtocol->Read ( + GnbHandle, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestRegisterSpaceType, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestAddress, + &Temp, + 0, + StdHeader + ); + Mask = (1ull << ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestFieldWidth) - 1; + Temp = Temp & ( ~ (Mask << ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestFieldOffset)); + Temp = Temp | ((Data & Mask) << ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestFieldOffset); + GnbRegisterAccessProtocol->Write ( + GnbHandle, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestRegisterSpaceType, + ((GNB_TABLE_ENTRY_COPY*) EntryPointer)->DestAddress, + &Temp, + WriteAccFlags, + StdHeader + ); + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_COPY); + break; + case GnbEntryStall: + if ((WriteAccFlags & GNB_TABLE_FLAGS_FORCE_S3_SAVE) != 0) { + GnbLibStallS3Save (((GNB_TABLE_ENTRY_STALL*) EntryPointer)->Microsecond, StdHeader); + } else { + GnbLibStall (((GNB_TABLE_ENTRY_STALL*) EntryPointer)->Microsecond, StdHeader); + } + EntryPointer = EntryPointer + sizeof (GNB_TABLE_ENTRY_STALL); + break; + default: + ASSERT (FALSE); + IDS_HDT_CONSOLE (NB_MISC, " ERROR!!! Register table parse\n"); + return AGESA_ERROR; + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "GnbProcessTableExt Exit\n"); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Supporting function for register read modify write + * + * @param[in] GnbHandle Gnb handle + * @param[in] GnbRegisterAccessProtocol Register access protocol + * @param[in] Data Data pointer + * @param[in] Flags Flags + * @param[in] StdHeader Standard configuration header + */ + +VOID +STATIC +GnbProcessTableRegisterRmw ( + IN GNB_HANDLE *GnbHandle, + IN GNB_REGISTER_SERVICE *GnbRegisterAccessProtocol, + IN GNB_RMW_BLOCK *Data, + IN UINT32 Flags, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 Value; + Value = 0; + GnbRegisterAccessProtocol->Read ( + GnbHandle, + Data->RegisterSpaceType, + Data->Address, + &Value, + 0, + StdHeader + ); + Value = (Value & (~ (UINT64) Data->AndMask)) | Data->OrMask; + GnbRegisterAccessProtocol->Write ( + GnbHandle, + Data->RegisterSpaceType, + Data->Address, + &Value, + Flags, + StdHeader + ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbTable/GnbTable.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbTable/GnbTable.h new file mode 100644 index 0000000000..52693f4261 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbTable/GnbTable.h @@ -0,0 +1,238 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _GNBTABLE_H_ +#define _GNBTABLE_H_ + +#include "GnbPcie.h" + +#pragma pack (push, 1) + +#define GNB_TABLE_FLAGS_FORCE_S3_SAVE 0x00000001ul + +typedef UINT8 GNB_TABLE; + +#define __DATA(x) x + +#define _DATA32(Data) (__DATA(Data)) & 0xFF, ((__DATA(Data)) >> 8) & 0xFF, ((__DATA(Data)) >> 16) & 0xFF, ((__DATA(Data)) >> 24) & 0xFF +#define _DATA64(Data) _DATA32(Data & 0xfffffffful) , _DATA32(Data >> 32) + +/// Entry type +typedef enum { + GnbEntryWr, ///< Write register + GnbEntryPropertyWr, ///< Write register check property + GnbEntryFullWr, ///< Write Rgister check revision and property + GnbEntryRmw, ///< Read Modify Write register + GnbEntryPropertyRmw, ///< Read Modify Write register check property + GnbEntryRevRmw, ///< Read Modify Write register check revision + GnbEntryFullRmw, ///< Read Modify Write register check revision and property + GnbEntryPoll, ///< Poll register + GnbEntryPropertyPoll, ///< Poll register check property + GnbEntryFullPoll, ///< Poll register check property + GnbEntryCopy, ///< Copy field from one register to another + GnbEntryStall, ///< Copy field from one register to another + GnbEntryTerminate = 0xFF ///< Terminate table +} GNB_TABLE_ENTRY_TYPE; + +#define GNB_ENTRY_WR(RegisterSpaceType, Address, Value) \ + GnbEntryWr, RegisterSpaceType, _DATA32 (Address), _DATA32 (Value) + +/// Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 Value; ///< Value +} GNB_TABLE_ENTRY_WR; + +#define GNB_ENTRY_PROPERTY_WR(Property, RegisterSpaceType, Address, Value) \ + GnbEntryPropertyWr, _DATA32 (Property), RegisterSpaceType, _DATA32 (Address), _DATA32 (Value) + +/// Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 Value; ///< Value +} GNB_TABLE_ENTRY_PROPERTY_WR; + + +#define GNB_ENTRY_RMW(RegisterSpaceType, Address, AndMask, OrMask) \ + GnbEntryRmw, RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (OrMask) + +///Read Modify Write data Block +typedef struct { + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< And Mask + UINT32 OrMask; ///< Or Mask +} GNB_RMW_BLOCK; + +/// Read Modify Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + GNB_RMW_BLOCK Data; ///< Data +} GNB_TABLE_ENTRY_RMW; + +#define GNB_ENTRY_FULL_WR(Property, Revision, RegisterSpaceType, Address, Value) \ + GnbEntryFullWr, _DATA32 (Property), _DATA64 (Revision), RegisterSpaceType, _DATA32 (Address), _DATA32 (Value) + +/// Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT64 Revision; ///< Revision + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 Value; ///< Value +} GNB_TABLE_ENTRY_FULL_WR; + + +#define GNB_ENTRY_PROPERTY_RMW(Property, RegisterSpaceType, Address, AndMask, OrMask) \ + GnbEntryPropertyRmw, _DATA32 (Property), RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (OrMask) + +/// Read Modify Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + GNB_RMW_BLOCK Data; ///< Data +} GNB_TABLE_ENTRY_PROPERTY_RMW; + +#define GNB_ENTRY_REV_RMW(Rev, RegisterSpaceType, Address, AndMask, OrMask) \ + GnbEntryRevRmw, _DATA64 (Rev), RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (OrMask) + +/// Read Modify Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT64 Revision; ///< revision + GNB_RMW_BLOCK Data; ///< Data +} GNB_TABLE_ENTRY_REV_RMW; + +#define GNB_ENTRY_FULL_RMW(Property, Revision, RegisterSpaceType, Address, AndMask, OrMask) \ + GnbEntryFullRmw, _DATA32 (Property), _DATA64 (Revision), RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (OrMask) + +/// Read Modify Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT64 Revision; ///< Revision + GNB_RMW_BLOCK Data; ///< Data +} GNB_TABLE_ENTRY_FULL_RMW; + +#define GNB_ENTRY_POLL(RegisterSpaceType, Address, AndMask, CompareValue) \ + GnbEntryPoll, RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (CompareValue) +/// Poll register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< End mask + UINT32 CompareValue; ///< Compare value +} GNB_TABLE_ENTRY_POLL; + +#define GNB_ENTRY_PROPERTY_POLL(Property, RegisterSpaceType, Address, AndMask, CompareValue) \ + GnbEntryPropertyPoll, _DATA32 (Property), RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (CompareValue) +/// Poll register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< End mask + UINT32 CompareValue; ///< Compare value +} GNB_TABLE_ENTRY_PROPERTY_POLL; + +#define GNB_ENTRY_FULL_POLL(Property, Revision, RegisterSpaceType, Address, AndMask, CompareValue) \ + GnbEntryFullPoll, _DATA32 (Property), _DATA64 (Revision), RegisterSpaceType, _DATA32 (Address), _DATA32 (AndMask), _DATA32 (CompareValue) +/// Poll register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Property; ///< Property + UINT64 Revision; ///< Revision + UINT8 RegisterSpaceType; ///< Register space + UINT32 Address; ///< Register address + UINT32 AndMask; ///< End mask + UINT32 CompareValue; ///< Compare value +} GNB_TABLE_ENTRY_FULL_POLL; + +#define GNB_ENTRY_COPY(DestRegSpaceType, DestAddress, DestFieldOffset, DestFieldWidth, SrcRegisterSpaceType, SrcAddress, SrcFieldOffset, SrcFieldWidth) \ + GnbEntryCopy, DestRegSpaceType, _DATA32 (DestAddress), DestFieldOffset, DestFieldWidth, SrcRegisterSpaceType, _DATA32 (SrcAddress), SrcFieldOffset, SrcFieldWidth + +/// Copy register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT8 DestRegisterSpaceType; ///< Register space + UINT32 DestAddress; ///< Register address + UINT8 DestFieldOffset; ///< Field Offset + UINT8 DestFieldWidth; ///< Field Width + UINT8 SrcRegisterSpaceType; ///< Register space + UINT32 SrcAddress; ///< Register address + UINT8 SrcFieldOffset; ///< Field Offset + UINT8 SrcFieldWidth; ///< Field Width +} GNB_TABLE_ENTRY_COPY; + +#define GNB_ENTRY_STALL(Microsecond) \ + GnbEntryStall, _DATA32 (Microsecond) + +/// Write register entry +typedef struct { + UINT8 EntryType; ///< Entry type + UINT32 Microsecond; ///< Value +} GNB_TABLE_ENTRY_STALL; + +#define GNB_ENTRY_TERMINATE GnbEntryTerminate + +AGESA_STATUS +GnbProcessTable ( + IN GNB_HANDLE *GnbHandle, + IN GNB_TABLE *Table, + IN UINT32 Property, + IN UINT32 Flags, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#pragma pack (pop) + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c new file mode 100644 index 0000000000..7156f7e52d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c @@ -0,0 +1,388 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to access PCI config space registers + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbLib.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "GnbUraServices.h" +#include "Filecode.h" + +#define FILECODE PROC_GNB_MODULES_GNBURALIBV1_GNBURALIBV1_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +UINT8 RegisterDomainMap[] = { + 0x0, ///< Stub + 0x0, ///< Stub + 0x64, ///< 0x2 + 0x98, ///< 0x3 + 0xB8, ///< TYPE_D0F0xB8 + 0xFD ///< End +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Convert URA Token to register address and field location + * + * @param[in] UraToken Register of bit field identifier + * @param[in] UraTable Pointer to register token table + * @param[in, out] TokenInfo Pointer to URA_TOKEN_INFO structure + * + * @retval UraToken Token is defined + * @retval _UNUSED Token is undefined + * + */ +URA_TOKEN +STATIC +UraTranslateToken ( + IN URA_TOKEN UraToken, + IN URA_ENTRY *UraTable, + IN OUT URA_TOKEN_INFO *TokenInfo + ) +{ + URA_TOKEN_STRUCT Token; + URA_FIELD_16B_ENTRY *Field16; + URA_REGISTER_32B_ENTRY *Reg32; + URA_REGISTER_64B_ENTRY *Reg64; + + Token.Encode = UraToken; + Reg32 = NULL; + Reg64 = NULL; + Field16 = NULL; + + switch (Token.Parser.Type) { + // + // Parse 16 bit field encoding + // + case URA_TYPE_FIELD_16: + Field16 = (URA_FIELD_16B_ENTRY *) &(UraTable[Token.Parser.Index]); + TokenInfo->BfWidth = (UINT8) Field16->BfWidth; + TokenInfo->BfOffset = (UINT8) Field16->BfOffset; + while (Field16->Offset == 0) { + Token.Parser.Index -= 15; + Field16 = (URA_FIELD_16B_ENTRY *) &UraTable[Token.Parser.Index]; + } + + ASSERT (Field16->Offset != 0); + + if (Token.Parser.ParentType == URA_TOKEN_PARENT_TYPE_32) { + Token.Parser.Index -= (Field16->Offset - 1) * 2 + 2; + Reg32 = (URA_REGISTER_32B_ENTRY *) &UraTable[Token.Parser.Index]; + } else if (Token.Parser.ParentType == URA_TOKEN_PARENT_TYPE_64) { + Token.Parser.Index -= Field16->Offset + 3; + Reg64 = (URA_REGISTER_64B_ENTRY *) &(UraTable[Token.Parser.Index]); + } else { + ASSERT (FALSE); + return _UNUSED; + } + + TokenInfo->WholeRegAccess = FALSE; + break; + + // + // Parse 32 bit register encoding + // + case URA_TYPE_REGISTER_32: + Reg32 = (URA_REGISTER_32B_ENTRY *) &UraTable[Token.Parser.Index]; + if (Reg32->Address == _UNUSED) { + return _UNUSED; + } + TokenInfo->WholeRegAccess = TRUE; + break; + + // + // Parse 64 bit register encoding + // + case URA_TYPE_REGISTER_64: + Reg64 = (URA_REGISTER_64B_ENTRY *) &(UraTable[Token.Parser.Index]); + if (Reg64->DomainAddress == _UNUSED) { + return _UNUSED; + } + TokenInfo->WholeRegAccess = TRUE; + break; + + default: + ASSERT (FALSE); + } + + // Get register address + if ((Token.Parser.ParentType == URA_TOKEN_PARENT_TYPE_32) && (Reg32 != NULL)) { + TokenInfo->RegAddress = Reg32->Address; + TokenInfo->RegDomainType = 0; + } else if ((Token.Parser.ParentType == URA_TOKEN_PARENT_TYPE_64) && (Reg64 != NULL)) { + TokenInfo->RegAddress = (UINT32)Reg64->DomainAddress; + TokenInfo->RegDomainType = (UINT8)Reg64->DomainType; + } else { + ASSERT (FALSE); + return _UNUSED; + } + + TokenInfo->MethodType = Token.Parser.Selector; + + // Patch DomainType field + if (TokenInfo->MethodType == TYPE_GNB_INDIRECT_ACCESS) { + TokenInfo->RegDomainType = RegisterDomainMap[TokenInfo->RegDomainType]; + } + + TokenInfo->Flags = Token.Parser.S3Save; + TokenInfo->StreamSet = Token.Parser.StreamSet; + + return Token.Encode; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb Unified Register Access method + * + * + * @param[in] Device Standard configuration header + * @param[in] UraToken Context length + * @param[in, out] Value Pointer to Context + */ +VOID +GnbUraGet ( + IN DEV_OBJECT *Device, + IN URA_TOKEN UraToken, + IN OUT VOID *Value + ) +{ + AGESA_STATUS Status; + GNB_URA_SERVICE *GnbUraProtocol; + URA_TOKEN_INFO TokenInfo; + URA_ENTRY *UraTable; + UINT32 UraTableAddress; + + UraTable = NULL; + Status = GnbLibLocateService (GnbUraService, GnbGetSocketId (Device->GnbHandle), (VOID **)&GnbUraProtocol, Device->StdHeader); + ASSERT (Status == AGESA_SUCCESS); + + GnbUraProtocol->GnbUraLocateRegTbl (Device, &UraTableAddress); + UraTable = (URA_ENTRY *) ((UINTN)UraTableAddress); + UraToken = UraTranslateToken (UraToken, UraTable, &TokenInfo); + if (UraToken == _UNUSED) { + return; + } + + GnbUraProtocol->GnbUraGet (Device, &TokenInfo, Value); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb Unified Register Access method + * + * + * @param[in] Device Standard configuration header + * @param[in] UraToken Ura token + * @param[in] Value Pointer to Context + */ +VOID +GnbUraSet ( + IN DEV_OBJECT *Device, + IN URA_TOKEN UraToken, + IN VOID *Value + ) +{ + AGESA_STATUS Status; + GNB_URA_SERVICE *GnbUraProtocol; + URA_TOKEN_INFO TokenInfo; + URA_ENTRY *UraTable; + UINT32 UraTableAddress; + + Status = GnbLibLocateService (GnbUraService, GnbGetSocketId (Device->GnbHandle), (VOID **)&GnbUraProtocol, Device->StdHeader); + ASSERT (Status == AGESA_SUCCESS); + + GnbUraProtocol->GnbUraLocateRegTbl (Device, &UraTableAddress); + UraTable = (URA_ENTRY *) ((UINTN)UraTableAddress); + UraToken = UraTranslateToken (UraToken, UraTable, &TokenInfo); + if (UraToken == _UNUSED) { + return; + } + + GnbUraProtocol->GnbUraSet (Device, &TokenInfo, Value); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb Unified Register Access method + * + * + * @param[in] Device Standard configuration header + * @param[in, out] UraTokenRegister Register token + * @param[in] UraTuple Pointer to Context + * @param[in, out] CombinedCount Token count + */ +VOID +GnbUraCombinedGet ( + IN DEV_OBJECT *Device, + IN URA_TOKEN UraTokenRegister, + IN OUT URA_TUPLE *UraTuple, + IN UINT32 CombinedCount + ) +{ + AGESA_STATUS Status; + GNB_URA_SERVICE *GnbUraProtocol; + URA_TOKEN_INFO TokenInfo; + URA_ENTRY *UraTable; + UINT32 UraTableAddress; + UINT32 RegValue; + UINT32 TempValue; + UINT32 FieldMask; + URA_TOKEN UraToken; + UINT32 Index; + + Status = GnbLibLocateService (GnbUraService, GnbGetSocketId (Device->GnbHandle), (VOID **)&GnbUraProtocol, Device->StdHeader); + ASSERT (Status == AGESA_SUCCESS); + + GnbUraProtocol->GnbUraLocateRegTbl (Device, &UraTableAddress); + UraTable = (URA_ENTRY *) ((UINTN)UraTableAddress); + UraTokenRegister = UraTranslateToken (UraTokenRegister, UraTable, &TokenInfo); + if (UraTokenRegister == _UNUSED) { + return; + } + + GnbUraProtocol->GnbUraGet (Device, &TokenInfo, &RegValue); + + Index = 0; + do { + UraToken = UraTuple[Index].Token; + UraToken = UraTranslateToken (UraToken, UraTable, &TokenInfo); + if (UraToken == _UNUSED) { + return; + } + + TempValue = RegValue; + TempValue = TempValue >> TokenInfo.BfOffset; + FieldMask = (((UINT32)1 << TokenInfo.BfWidth) - 1); + UraTuple[Index].Value = TempValue & FieldMask; + Index++; + } while (Index < CombinedCount); + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Gnb Unified Register Access method + * + * + * @param[in] Device Standard configuration header + * @param[in, out] UraTokenRegister Register token + * @param[in] UraTuple Pointer to Context + * @param[in, out] CombinedCount Token count + */ +VOID +GnbUraCombinedSet ( + IN DEV_OBJECT *Device, + IN URA_TOKEN UraTokenRegister, + IN OUT URA_TUPLE *UraTuple, + IN UINT32 CombinedCount + ) +{ + AGESA_STATUS Status; + GNB_URA_SERVICE *GnbUraProtocol; + URA_TOKEN_INFO TokenInfo; + URA_ENTRY *UraTable; + UINT32 UraTableAddress; + UINT32 RegValue; + UINT32 TempValue; + UINT32 FieldMask; + URA_TOKEN UraToken; + UINT32 Index; + + Status = GnbLibLocateService (GnbUraService, GnbGetSocketId (Device->GnbHandle), (VOID **)&GnbUraProtocol, Device->StdHeader); + ASSERT (Status == AGESA_SUCCESS); + + GnbUraProtocol->GnbUraLocateRegTbl (Device, &UraTableAddress); + UraTable = (URA_ENTRY *) ((UINTN)UraTableAddress); + UraTokenRegister = UraTranslateToken (UraTokenRegister, UraTable, &TokenInfo); + if (UraTokenRegister == _UNUSED) { + return; + } + + if (TokenInfo.StreamSet == 1) { + GnbUraProtocol->GnbUraStreamSet (Device, &TokenInfo, UraTuple, CombinedCount); + } else { + GnbUraProtocol->GnbUraGet (Device, &TokenInfo, &RegValue); + + Index = 0; + do { + UraToken = UraTuple[Index].Token; + UraToken = UraTranslateToken (UraToken, UraTable, &TokenInfo); + if (UraToken == _UNUSED) { + return; + } + FieldMask = (((UINT32)1 << TokenInfo.BfWidth) - 1); + TempValue = UraTuple[Index].Value & FieldMask; + RegValue &= ~(FieldMask << TokenInfo.BfOffset); + RegValue |= TempValue << TokenInfo.BfOffset; + Index++; + } while (Index < CombinedCount); + + UraTokenRegister = UraTranslateToken (UraTokenRegister, UraTable, &TokenInfo); + GnbUraProtocol->GnbUraSet (Device, &TokenInfo, &RegValue); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbFam16.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbFam16.c new file mode 100644 index 0000000000..0f782ed5b5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbFam16.c @@ -0,0 +1,150 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * The initializer for Family 16h Model 00-0Fh northbridge support. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionsHt.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htNb.h" +#include "CommonReturns.h" +#include "htNbUtilitiesFam16.h" +#include "cpuFamRegisters.h" +#include "Filecode.h" + +#define FILECODE PROC_HT_FAM16_HTNBFAM16_FILECODE + +extern OPTION_HT_CONFIGURATION OptionHtConfiguration; + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*************************************************************************** + *** FAMILY/NORTHBRIDGE SPECIFIC FUNCTIONS *** + ***************************************************************************/ + + +/** + * Initial construction data for no HT Northbridge. + */ +CONST NORTHBRIDGE ROMDATA HtFam16Nb = +{ + 1, + 1, + (PF_WRITE_ROUTING_TABLE)CommonVoid, + (PF_WRITE_NODEID)CommonVoid, + (PF_READ_DEFAULT_LINK)CommonReturnZero8, + (PF_ENABLE_ROUTING_TABLES)CommonVoid, + (PF_DISABLE_ROUTING_TABLES)CommonVoid, + (PF_VERIFY_LINK_IS_COHERENT)CommonReturnFalse, + (PF_READ_TOKEN)CommonReturnZero8, + (PF_WRITE_TOKEN)CommonVoid, + (PF_WRITE_FULL_ROUTING_TABLE)CommonVoid, + (PF_IS_ILLEGAL_TYPE_MIX)CommonReturnFalse, + (PF_IS_EXCEEDED_CAPABLE)CommonReturnFalse, + (PF_STOP_LINK)CommonVoid, + (PF_HANDLE_SPECIAL_LINK_CASE)CommonReturnFalse, + (PF_HANDLE_SPECIAL_NODE_CASE)CommonReturnFalse, + (PF_READ_SB_LINK)CommonReturnZero8, + (PF_VERIFY_LINK_IS_NON_COHERENT)CommonReturnFalse, + (PF_SET_CONFIG_ADDR_MAP)CommonVoid, + (PF_GET_CONFIG_ADDR_MAP)CommonVoid, + (PF_NORTH_BRIDGE_FREQ_MASK)CommonReturnZero32, + (PF_GATHER_LINK_FEATURES)CommonVoid, + (PF_SET_LINK_REGANG)CommonVoid, + (PF_SET_LINK_FREQUENCY)CommonVoid, + (PF_SET_LINK_UNITID_CLUMPING)CommonVoid, + (PF_WRITE_TRAFFIC_DISTRIBUTION)CommonVoid, + (PF_WRITE_LINK_PAIR_DISTRIBUTION)CommonVoid, + (PF_WRITE_VICTIM_DISTRIBUTION)CommonVoid, + (PF_BUFFER_OPTIMIZATIONS)CommonVoid, + Fam16GetNumCoresOnNode, + Fam16SetTotalCores, + Fam16GetNodeCount, + (PF_LIMIT_NODES)CommonVoid, + (PF_READ_TRUE_LINK_FAIL_STATUS)CommonReturnFalse, + (PF_GET_NEXT_LINK)CommonReturnZero32, + (PF_GET_PACKAGE_LINK)CommonReturnZero8, + (PF_MAKE_LINK_BASE)CommonReturnZero32, + (PF_GET_MODULE_INFO)CommonVoid, + (PF_POST_MAILBOX)CommonVoid, + (PF_RETRIEVE_MAILBOX)CommonReturnZero32, + (PF_GET_SOCKET)CommonReturnZero8, + Fam16GetEnabledComputeUnits, + Fam16GetDualcoreComputeUnits, + Fam16GetTriplecoreComputeUnits, + Fam16GetQuadcoreComputeUnits, + 0, + 0, + 0, + TRUE, + TRUE, + AMD_FAMILY_16, + NULL, + 0, + NULL, + (PF_MAKE_KEY)CommonReturnZero64, + NULL +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.c new file mode 100644 index 0000000000..5d761d47c9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.c @@ -0,0 +1,300 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Northbridge utility routines. + * + * These routines are needed for support of more than one feature area. + * Collect them in this file so build options don't remove them. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htNb.h" +#include "htNbCommonHardware.h" +#include "htNbUtilitiesFam16.h" +#include "Filecode.h" +#define FILECODE PROC_HT_FAM16_HTNBUTILITIESFAM16_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Write the total number of cores to the Node + * + * @HtNbMethod{::F_SET_TOTAL_NODES_AND_CORES} + * + * @param[in] Node the Node that will be examined + * @param[in] TotalNodes the total number of Nodes + * @param[in] TotalCores the total number of cores + * @param[in] Nb this northbridge + */ +VOID +Fam16SetTotalCores ( + IN UINT8 Node, + IN UINT8 TotalNodes, + IN UINT8 TotalCores, + IN NORTHBRIDGE *Nb + ) +{ + PCI_ADDR NodeIDReg; + UINT32 Temp; + + NodeIDReg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_HTNB_FUNC_00, + REG_NODE_ID_0X60); + + Temp = ((TotalCores - 1) & HTREG_NODE_CPUCNT_4_0); + LibAmdPciWriteBits (NodeIDReg, 20, 16, &Temp, Nb->ConfigHandle); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return the number of cores (1 based count) on Node. + * + * @HtNbMethod{::F_GET_NUM_CORES_ON_NODE} + * + * @param[in] Node the Node that will be examined + * @param[in] Nb this northbridge + * + * @return the number of cores + */ +UINT8 +Fam16GetNumCoresOnNode ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ) +{ + UINT32 Result; + UINT32 Leveling; + UINT32 Cores; + UINT8 i; + PCI_ADDR Reg; + + ASSERT ((Node < MAX_NODES)); + // Read CmpCap + Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_NB_FUNC_05, + REG_NB_CAPABILITY_2_5X84); + + LibAmdPciReadBits (Reg, 7, 0, &Result, Nb->ConfigHandle); + + // Support Downcoring + Cores = Result; + Cores++; + Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_NB_FUNC_03, + REG_NB_DOWNCORE_3X190); + LibAmdPciReadBits (Reg, 31, 0, &Leveling, Nb->ConfigHandle); + for (i = 0; i < Cores; i++) { + if ((Leveling & ((UINT32) 1 << i)) != 0) { + Result--; + } + } + return (UINT8) (Result + 1); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the Count (1 based) of Nodes in the system. + * + * @HtNbMethod{::F_GET_NODE_COUNT} + * + * This is intended to support AP Core HT init, since the Discovery State data is not + * available (State->NodesDiscovered), there needs to be this way to find the number + * of Nodes, which is just one. + * + * @param[in] Nb this northbridge + * + * @return The number of nodes + */ +UINT8 +Fam16GetNodeCount ( + IN NORTHBRIDGE *Nb + ) +{ + ASSERT (Nb != NULL); + return (1); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the enable compute unit status for this node. + * + * @HtNbMethod{::F_GET_ENABLED_COMPUTE_UNITS} + * + * @param[in] Node The node for which we want the enabled compute units. + * @param[in] Nb Our Northbridge. + * + * @return The Enabled Compute Unit value + */ +UINT8 +Fam16GetEnabledComputeUnits ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ) +{ + UINT32 Enabled; + PCI_ADDR Reg; + + ASSERT ((Node < MAX_NODES)); + + Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_NB_FUNC_05, + REG_NB_COMPUTE_UNIT_5X80); + LibAmdPciReadBits (Reg, 3, 0, &Enabled, Nb->ConfigHandle); + return ((UINT8) Enabled); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the dual core compute unit status for this node. + * + * @HtNbMethod{::PF_GET_DUALCORE_COMPUTE_UNITS} + * + * @param[in] Node The node for which we want the dual core status + * @param[in] Nb Our Northbridge. + * + * @return The dual core compute unit status. + */ +UINT8 +Fam16GetDualcoreComputeUnits ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ) +{ + UINT32 Dual; + PCI_ADDR Reg; + + ASSERT ((Node < MAX_NODES)); + + Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_NB_FUNC_05, + REG_NB_COMPUTE_UNIT_5X80); + LibAmdPciReadBits (Reg, 19, 16, &Dual, Nb->ConfigHandle); + return ((UINT8) Dual); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the triple core compute unit status for this node. + * + * @HtNbMethod{::PF_GET_TRIPLECORE_COMPUTE_UNITS} + * + * @param[in] Node The node for which we want the triple core status + * @param[in] Nb Our Northbridge. + * + * @return The triple core compute unit status. + */ +UINT8 +Fam16GetTriplecoreComputeUnits ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ) +{ + UINT32 Triple; + PCI_ADDR Reg; + + ASSERT ((Node < MAX_NODES)); + + Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_NB_FUNC_05, + REG_NB_COMPUTE_UNIT_5X80); + LibAmdPciReadBits (Reg, 11, 8, &Triple, Nb->ConfigHandle); + return ((UINT8) Triple); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the quad core compute unit status for this node. + * + * @HtNbMethod{::PF_GET_QUADCORE_COMPUTE_UNITS} + * + * @param[in] Node The node for which we want the quad core status + * @param[in] Nb Our Northbridge. + * + * @return The quad core compute unit status. + */ +UINT8 +Fam16GetQuadcoreComputeUnits ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ) +{ + UINT32 Quad; + PCI_ADDR Reg; + + ASSERT ((Node < MAX_NODES)); + + Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_NB_FUNC_05, + REG_NB_COMPUTE_UNIT_5X80); + LibAmdPciReadBits (Reg, 27, 24, &Quad, Nb->ConfigHandle); + return ((UINT8) Quad); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.h new file mode 100644 index 0000000000..af6408c66e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/Fam16/htNbUtilitiesFam16.h @@ -0,0 +1,110 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Northbridge utility routines. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _HT_NB_UTILITIES_FAM16_H_ +#define _HT_NB_UTILITIES_FAM16_H_ + +/** + * Return the number of cores (1 based count) on Node. + * + */ +UINT8 +Fam16GetNumCoresOnNode ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +UINT8 +Fam16GetNodeCount ( + IN NORTHBRIDGE *Nb + ); + +/** + * Get the enable compute unit status for this node. + */ +UINT8 +Fam16GetEnabledComputeUnits ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +/** + * Get the dual core compute unit status for this node. + */ +UINT8 +Fam16GetDualcoreComputeUnits ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +/** + * Get the triple core compute unit status for this node. + */ +UINT8 +Fam16GetTriplecoreComputeUnits ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +/** + * Get the quad core compute unit status for this node. + */ +UINT8 +Fam16GetQuadcoreComputeUnits ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +/** + * Write the total number of cores to the Node + * + */ +VOID +Fam16SetTotalCores ( + IN UINT8 Node, + IN UINT8 TotalNodes, + IN UINT8 TotalCores, + IN NORTHBRIDGE *Nb + ); + +#endif // _HT_NB_UTILITIES_FAM15MOD1X_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.c new file mode 100644 index 0000000000..0807a41f9e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.c @@ -0,0 +1,112 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * HyperTransport features constructor. + * + * Initialize the set of available features. + * This file implements build options using conditional compilation. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionsHt.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "CommonReturns.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_HT_HTFEAT_FILECODE +extern CONST OPTION_HT_CONFIGURATION OptionHtConfiguration; + +/** + * A no features Initializer. + */ +CONST HT_FEATURES ROMDATA HtFeaturesNone = +{ + (PF_COHERENT_DISCOVERY)CommonVoid, + (PF_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES)CommonVoid, + (PF_MAKE_HOP_COUNT_TABLE)CommonVoid, + (PF_ALLOCATE_BUS_NUMBERS)CommonVoid, + (PF_PROCESS_LINK)CommonVoid, + (PF_GATHER_LINK_DATA)CommonVoid, + (PF_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY)CommonVoid, + (PF_REGANG_LINKS)CommonVoid, + (PF_SUBLINK_RATIO_FIXUP)CommonVoid, + (PF_IS_COHERENT_RETRY_FIXUP)CommonReturnFalse, + (PF_SET_LINK_DATA)CommonVoid, + (PF_TRAFFIC_DISTRIBUTION)CommonVoid, + (PF_SET_HT_CONTROL_REGISTER_BITS)CommonVoid, + (PF_CONVERT_WIDTH_TO_BITS)CommonReturnZero8 +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Provide the current Feature set implementation. + * + * Initialize using the installed initializer. + * + * @param[in] HtFeatures A feature object to initialize + * @param[in] StdHeader Opaque handle to standard config header +*/ +VOID +NewHtFeatures ( + OUT HT_FEATURES *HtFeatures, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LibAmdMemCopy ( + (VOID *) HtFeatures, + (VOID *) OptionHtConfiguration.HtOptionInternalFeatures , + (UINT32) (sizeof (HT_FEATURES)), + StdHeader + ); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.h new file mode 100644 index 0000000000..1801c62aa9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htFeat.h @@ -0,0 +1,579 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * HT Features. + * + * This file provides definitions used in common by HT internal modules. The + * data is private and not for external client access. + * Definitions include the HT global internal state data structures, and + * access to the available HT features from the main HT entry point. + * + * This file includes the feature constructor and feature support which is not + * removed with various build options. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _HT_FEAT_H_ +#define _HT_FEAT_H_ + +/** + * @page htimplfeat HT Features Implementation Guide + * + * HT Features provides access to the HT Feature set, in a manner that isolates + * calling code from knowledge about the Feature set implementation or which + * features are supported in the current build. In the case of feature sets, this + * is mostly used for build options to reduce code size by removing unneeded features. + * + * @par Adding a Method to HT Features + * + * To add a new method to the HT Features, follow these steps. + *
    + *
  • Create a typedef for the Method with the correct parameters and return type. + * + *
      + *
    • Name the method typedef (F_METHOD_NAME)(), where METHOD_NAME is the same name as the method table item, + * but with "_"'s and UPPERCASE, rather than mixed case. + * @n typedef VOID (F_METHOD_NAME)(); @n + * + *
    • Make a reference type for references to a method implementation: + * @n /// Reference to a Method + * @n typedef F_METHOD_NAME *PF_METHOD_NAME @n + *
    + * + *
  • Provide a standard doxygen function preamble for the Method typedef. Begin the + * detailed description by providing a reference to the method instances page by including + * the lines below: + * @code + * * + * * @HtFeatInstances. + * * + * @endcode + * @note It is important to provide documentation for the method type, because the method may not + * have an implementation in any families supported by the current package. @n + * + *
  • Add to the _HT_FEATURES struct an item for the Method: + * @n PF_METHOD_NAME MethodName; ///< Method: description. @n + *
+ * + * @par Implementing an HT Features Instance of the method. + * + * To implement an instance of a method for a specific feature follow these steps. + * + * - In appropriate files, implement the method with the return type and parameters + * matching the method typedef. + * + * - Name the function MethodName(). + * + * - Create a doxygen function preamble for the method instance. Begin the detailed description with + * an Implements command to reference the method type and add this instance to the Method Instances page. + * @code + * * + * * @HtFeatMethod{::F_METHOD_NAME}. + * * + * @endcode + * + * - To access other Ht feature routines or data as part of the method implementation, the function + * must use HtFeatures->OtherMethod(). Do not directly access other HT feature + * routines, because in the table there may be overrides or this routine may be shared by multiple configurations. + * + * - Add the instance to the HT_FEATURES instances. + * + * - If a configuration does not need an instance of the method use one of the CommonReturns from + * CommonReturns.h with the same return type. + * + * @par Invoking HT Features Methods. + * + * The first step is carried out only once by the top level HT entry point. + * @n @code + * HT_FEATURES HtFeatures; + * // Get the current HT Feature Set + * NewHtFeatures (&HtFeatures); + * State->HtFeatures = &HtFeatures; + * @endcode + * + * The following example shows how to invoke a HT Features method. + * @n @code + * State->HtFeatures->MethodName (); + * @endcode + * + */ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define MAX_PLATFORM_LINKS 64 +#define MAX_LINK_PAIRS 4 + +/* These following are internal definitions */ +#define ROUTE_TO_SELF 0x0F +#define INVALID_LINK 0xCC /* Used in port list data structure to mark unused data entries. + Can also be used for no Link found in a port list search */ + +/* definitions for working with the port list structure */ +#define PORTLIST_TYPE_CPU 0 +#define PORTLIST_TYPE_IO 1 + +/* + * Hypertransport Capability definitions and macros + * + */ + +#define HT_INTERFACE_CAP_SUBTYPE_MASK ((UINT32)0xE00000FFul) +#define HT_CAP_SUBTYPE_MASK ((UINT32)0xF80000FFul) + +/* HT Host Capability */ +#define HT_HOST_CAPABILITY 1 +#define HT_HOST_CAP_SIZE 0x20 + +/* Host CapabilityRegisters */ +#define HTHOST_LINK_CAPABILITY_REG 0x00 +#define HTHOST_LINK_CONTROL_REG 0x04 +#define HTHOST_FREQ_REV_REG 0x08 +#define HTHOST_REV_REV3 0x60 +#define HTHOST_FEATURE_CAP_REG 0x0C +#define HTHOST_BUFFER_COUNT_REG 0x10 +#define HTHOST_ISOC_REG 0x14 +#define HTHOST_LINK_TYPE_REG 0x18 +#define HTHOST_FREQ_EXTENSION 0x1C +#define HTHOST_TYPE_COHERENT 3 +#define HTHOST_TYPE_NONCOHERENT 7 +#define HTHOST_TYPE_MASK 0x1F + +/* HT Slave Capability (HT1 compat) */ +#define HT_SLAVE_CAPABILITY 0 +#define HTSLAVE_LINK01_OFFSET 4 +#define HTSLAVE_LINK_CONTROL_0_REG 4 +#define HTSLAVE_FREQ_REV_0_REG 0xC +#define HTSLAVE_FEATURECAP_REG 0x10 +#define HT_CONTROL_CLEAR_CRC (~(3 << 8)) +#define HT_FREQUENCY_CLEAR_LINK_ERRORS (~(0x7 << 12)) +#define MAX_BUID 31 + +/* HT3 gen Capability */ +#define HT_GEN3_CAPABILITY (0xD << 1) +#define HTGEN3_LINK01_OFFSET 0x10 +#define HTGEN3_LINK_TRAINING_0_REG 0x10 + +/* HT3 Retry Capability */ +#define HT_RETRY_CAPABILITY (0xC << 1) +#define HTRETRY_CONTROL_REG 4 + +/* Unit ID Clumping Capability */ +#define HT_UNITID_CAPABILITY (0x9 << 1) +#define HTUNIT_SUPPORT_REG 4 +#define HTUNIT_ENABLE_REG 8 +#define HT_CLUMPING_PASSIVE 1 + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +// Forward declarations. +/// Used for forward reference. +typedef struct _NORTHBRIDGE NORTHBRIDGE; +/// Used for forward reference. +typedef struct _HT_FEATURES HT_FEATURES; +/// Used for forward reference. +typedef struct _HT_INTERFACE HT_INTERFACE; + +/** + * Coherent Init Data. + * + * Metrics representing the coherent fabric which was discovered: Degree of nodes, adjacency, + * node numbering permutations, and the topology which it matched. + */ +typedef struct { + /** The number of coherent Links connected on each Node (the 'Degree' of the Node) */ + UINT8 SysDegree[MAX_NODES]; + /** The systems adjacency (sysMatrix[i][j] is true if Node_i has a Link to Node_j) */ + BOOLEAN SysMatrix[MAX_NODES][MAX_NODES]; + + UINT8 DbDegree[MAX_NODES]; /**< Like sysDegree, but for the current database topology */ + BOOLEAN DbMatrix[MAX_NODES][MAX_NODES]; /**< Like sysMatrix, but for the current database topology */ + + UINT8 Perm[MAX_NODES]; /**< The Node mapping from the system to the database */ + UINT8 ReversePerm[MAX_NODES]; /**< The Node mapping from the database to the system */ + UINT8 *MatchedTopology; /**< The topology that matched the current system or NULL */ +} COHERENT_FABRIC; + +/** + * Represent the system as Links of matched port pairs. + * A pair consists of a source Node, a Link to the destination Node, the + * destination Node, and its Link back to source Node. The even indices are + * the source Nodes and Links, and the odd indices are for the destination + * Nodes and Links. + * @note The Port pair 2*N and 2*N+1 are connected together to form a Link + * (e.g. 0,1 and 8,9 are ports on either end of an HT Link) The lower number + * port (2*N) is the source port. The device that owns the source port is + * always the device closer to the BSP. (i.e. nearer the CPU in a + * non-coherent chain, or the CPU with the lower NodeID). + */ +typedef struct { + /* This section is where the Link is in the system and how to find it */ + UINT8 Type; /**< 0 = CPU, 1 = Device, all others reserved */ + UINT8 Link; /**< 0-1 for devices, 0-7 for CPUs */ + UINT8 NodeID; /**< The Node, or a pointer to the devices parent Node */ + UINT8 HostLink; /**< For Devices, the root CPU's Link to the chain */ + UINT8 HostDepth; /**< Link Depth in chain, only used by devices */ + PCI_ADDR Pointer; /**< A pointer to the device's slave HT capability, so we don't have to keep searching */ + + /* This section is for the final settings, which are written to hardware */ + BOOLEAN SelRegang; /**< Indicates to software regang Link, only used for CPU->CPU Links */ + UINT8 SelWidthIn; /**< Width in setting */ + UINT8 SelWidthOut; /**< Width out setting */ + UINT8 SelFrequency; /**< Frequency setting */ + + /* This section is for keeping track of capabilities and possible configurations */ + BOOLEAN RegangCap; /**< Is the port capable of reganging? CPUs only */ + UINT32 PrvFrequencyCap; /**< Possible frequency settings */ + UINT8 PrvWidthInCap; /**< Possible Width setting */ + UINT8 PrvWidthOutCap; /**< Possible Width setting */ + UINT32 CompositeFrequencyCap; /**< Possible Link frequency setting */ + UINT32 ClumpingSupport; /**< Unit ID Clumping value (bit 0 = passive support) */ +} PORT_DESCRIPTOR; + +/// Reference to a set of PORT_DESCRIPTORs. +typedef PORT_DESCRIPTOR (*PORT_LIST)[MAX_PLATFORM_LINKS*2]; + +/** + * Our global state data structure + */ +typedef struct { + AMD_HT_INTERFACE *HtBlock; /**< The input data structure. */ + + UINT8 NodesDiscovered; /**< One less than the number of Nodes found in the system */ + UINT8 TotalLinks; /**< How many HT Links have we discovered so far. */ + UINT8 SysMpCap; /**< The maximum number of Nodes that all processors are capable of */ + AGESA_STATUS MaxEventClass; /**< The event class of the highest severity event generated */ + + PORT_LIST PortList; /**< Represent the system as a set of Links, each two Ports. */ + COHERENT_FABRIC *Fabric; /**< Describe metrics about the coherent fabric. + * Limited scope to CoherentInit(). */ + /* Data interface to other Agesa Modules */ + SOCKET_DIE_TO_NODE_MAP SocketDieToNodeMap; /**< For each Socket, Die the Node ids */ + NODE_TO_SOCKET_DIE_MAP NodeToSocketDieMap; /**< For each Node id, Socket and Die */ + HOP_COUNT_TABLE *HopCountTable; /**< Table of hops between nodes */ + + /* Data for non-coherent initialization */ + UINT8 AutoBusCurrent; /**< The next bus number available */ + UINT8 UsedCfgMapEntries; /**< The next Config address Map set available, Limit 4 (F1X[EC:E0]) */ + BOOLEAN IsUsingRecoveryHt; /**< Manual BUID Swap List processing should assume that HT Recovery was used */ + BOOLEAN IsSetHtCrcFlood; /**< Enable setting of HT CRC Flood */ + BOOLEAN IsUsingUnitIdClumping; /**< Enable automatic Unit Id Clumping configuration. */ + + HT_INTERFACE *HtInterface; /**< Interface for feature code to external parameters */ + HT_FEATURES *HtFeatures; /**< The current feature implementations */ + NORTHBRIDGE *Nb; /**< The current northbridge */ + + PLATFORM_CONFIGURATION *PlatformConfiguration; /**< The platform specific configuration customizations */ + VOID *ConfigHandle; /**< Config Pointer, opaque handle for passing to lib */ +} STATE_DATA; + +// +// Feature Method types +// + +/** + * Discover all coherent devices in the system. + * + * @HtFeatInstances. + * + * @param[in,out] State our global state + * + */ +typedef VOID F_COHERENT_DISCOVERY ( + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_COHERENT_DISCOVERY *PF_COHERENT_DISCOVERY; + +/** + * Using the description of the fabric topology we discovered, try to find a match + * among the supported topologies. + * + * @HtFeatInstances. + * + * @param[in,out] State the discovered fabric, degree matrix, permutation + * + */ +typedef VOID F_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES ( + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES *PF_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES; + +/** + * Make a Hop Count Table for the installed topology. + * + * @HtFeatInstances. + * + * @param[in,out] State access topology, permutation, update hop table + * + */ +typedef VOID F_MAKE_HOP_COUNT_TABLE ( + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_MAKE_HOP_COUNT_TABLE *PF_MAKE_HOP_COUNT_TABLE; + +/** + * Allocate PCI Bus Numbers to an IO Link. + * + * @HtFeatInstances. + * + * @param[in] Node Node on which to allocate a bus range + * @param[in] Link The destination Link on that Node + * @param[in,out] State our global state + */ +typedef VOID F_ALLOCATE_BUS_NUMBERS ( + IN UINT8 Node, + IN UINT8 Link, + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_ALLOCATE_BUS_NUMBERS *PF_ALLOCATE_BUS_NUMBERS; + +/** + * Process a non-coherent Link. + * + * @HtFeatInstances. + * + * @param[in] Node Node on which to process nc init + * @param[in] Link The non-coherent Link on that Node + * @param[in] IsCompatChain Is this the chain with the southbridge? TRUE if yes. + * @param[in,out] State our global state + */ +typedef VOID F_PROCESS_LINK ( + IN UINT8 Node, + IN UINT8 Link, + IN BOOLEAN IsCompatChain, + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_PROCESS_LINK *PF_PROCESS_LINK; + +/** + * Get Link features into system data structure. + * + * @HtFeatInstances. + * + * @param[in] State our global state, port list + */ +typedef VOID F_GATHER_LINK_DATA ( + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GATHER_LINK_DATA *PF_GATHER_LINK_DATA; + +/** + * Optimize Links. + * + * @HtFeatInstances. + * + * @param[in,out] State Process and update portlist + */ +typedef VOID F_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY ( + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY *PF_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY; + +/** + * Change the hardware state for all Links according to the now optimized data in the + * port list data structure. + * + * @HtFeatInstances. + * + * @param[in] State our global state, port list + */ +typedef VOID F_SET_LINK_DATA ( + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_SET_LINK_DATA *PF_SET_LINK_DATA; + +/** + * Retry must be enabled on all coherent links if it is enabled on any coherent links. + * + * @HtFeatInstances. + * + * @param[in,out] State global state, port frequency settings. + * + * @retval TRUE Fixup occurred, all coherent links HT1 + * @retval FALSE No changes + */ +typedef BOOLEAN F_IS_COHERENT_RETRY_FIXUP ( + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_IS_COHERENT_RETRY_FIXUP *PF_IS_COHERENT_RETRY_FIXUP; + + +/** + * Test the subLinks of a Link to see if they qualify to be reganged. + * + * @HtFeatInstances. + * + * @param[in,out] State Our global state + */ +typedef VOID F_REGANG_LINKS ( + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_REGANG_LINKS *PF_REGANG_LINKS; + +/** + * Iterate through all Links, checking the frequency of each subLink pair. + * + * @HtFeatInstances. + * + * @param[in,out] State Link state and port list + * + */ +typedef VOID F_SUBLINK_RATIO_FIXUP ( + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_SUBLINK_RATIO_FIXUP *PF_SUBLINK_RATIO_FIXUP; + +/** + * Identify Links which can have traffic distribution. + * + * @HtFeatInstances. + * + * @param[in] State port list data + */ +typedef VOID F_TRAFFIC_DISTRIBUTION ( + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_TRAFFIC_DISTRIBUTION *PF_TRAFFIC_DISTRIBUTION; + +/** + * Access HT Link Control Register. + * + * @HtFeatInstances. + * + * @param[in] Reg the PCI config address the control register + * @param[in] HiBit the high bit number + * @param[in] LoBit the low bit number + * @param[in] Value the value to write to that bit range. Bit 0 => loBit. + * @param[in] State Our state, config handle for lib + */ +typedef VOID F_SET_HT_CONTROL_REGISTER_BITS ( + IN PCI_ADDR Reg, + IN UINT8 HiBit, + IN UINT8 LoBit, + IN UINT32 *Value, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_SET_HT_CONTROL_REGISTER_BITS *PF_SET_HT_CONTROL_REGISTER_BITS; + +/** + * Translate a desired width setting to the bits to set in the register field. + * + * @HtFeatInstances. + * + * @param[in] Value the width Value + * + * @return The bits for the register + */ +typedef UINT8 F_CONVERT_WIDTH_TO_BITS ( + IN UINT8 Value + ); +/// Reference to a method. +typedef F_CONVERT_WIDTH_TO_BITS *PF_CONVERT_WIDTH_TO_BITS; + +/** + * HT Feature Methods. + * + * Provides abstract methods which are bound to specific feature implementations. + */ +struct _HT_FEATURES { + PF_COHERENT_DISCOVERY CoherentDiscovery; /**< Method: Coherent Discovery. */ + PF_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES LookupComputeAndLoadRoutingTables; + /**< Method: Route the discovered system */ + PF_MAKE_HOP_COUNT_TABLE MakeHopCountTable; /**< Method: Compute slit hop counts */ + PF_ALLOCATE_BUS_NUMBERS AllocateBusNumbers; /**< Method: Allocate Bus Numbers to IO */ + PF_PROCESS_LINK ProcessLink; /**< Method: Process a non-coherent Link. */ + PF_GATHER_LINK_DATA GatherLinkData; /**< Method: Gather Link Capabilities and data. */ + PF_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY SelectOptimalWidthAndFrequency; + /**< Method: Optimize link features. */ + PF_REGANG_LINKS RegangLinks; /**< Method: Regang Sublinks. */ + PF_SUBLINK_RATIO_FIXUP SubLinkRatioFixup; /**< Method: Fix Sublink Frequency ratios */ + PF_IS_COHERENT_RETRY_FIXUP IsCoherentRetryFixup; + /**< Method: Fix Retry mixed on coherent links. */ + PF_SET_LINK_DATA SetLinkData; /**< Method: Set optimized values. */ + PF_TRAFFIC_DISTRIBUTION TrafficDistribution; /**< Method: Detect and Initialize Traffic Distribution */ + PF_SET_HT_CONTROL_REGISTER_BITS SetHtControlRegisterBits; /**< Method: Access HT Link Control Reg. */ + PF_CONVERT_WIDTH_TO_BITS ConvertWidthToBits; /**< Method: Convert a bit width to the value used for register setting. */ +} ; + +/*---------------------------------------------------------------------------- + * Prototypes + * + *---------------------------------------------------------------------------- + */ + +/** + * Provide the current Feature set implementation. + * + * Add an implementation reference for the constructor, just to make sure the page is created. + * @HtFeatMethod{_HT_FEATURES}. + * + */ +VOID +NewHtFeatures ( + OUT HT_FEATURES *HtFeatures, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +#endif /* _HT_FEAT_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterface.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterface.c new file mode 100644 index 0000000000..7959665e8a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterface.c @@ -0,0 +1,262 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * External Interface implementation. + * + * Contains routines for implementing the interface to the client BIOS. + * This file includes the interface access constructor. + * This file implements build options using conditional compilation. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "OptionsHt.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htInterface.h" +#include "CommonReturns.h" +#include "htInterfaceGeneral.h" +#include "htInterfaceCoherent.h" +#include "htInterfaceNonCoherent.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_HT_HTINTERFACE_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +extern CONST OPTION_HT_CONFIGURATION OptionHtConfiguration; + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/** + * The default initializer for the HT internal interface, full features. + */ +CONST HT_INTERFACE ROMDATA HtInterfaceDefault = +{ + GetCpu2CpuPcbLimits, + GetSkipRegang, + NewHopCountTable, + GetOverrideBusNumbers, + GetManualBuidSwapList, + GetDeviceCapOverride, + GetIoPcbLimits, + GetSocketFromMap, + GetIgnoreLink, + PostMapToAp, + NewNodeAndSocketTables, + CleanMapsAfterError, + SetNodeToSocketMap, + GetMinNbCoreFreq +}; + +/** + * The initializer for the HT internal interface, coherent only features. + */ +CONST HT_INTERFACE ROMDATA HtInterfaceCoherentOnly = +{ + GetCpu2CpuPcbLimits, + GetSkipRegang, + NewHopCountTable, + GetOverrideBusNumbers, + (PF_GET_MANUAL_BUID_SWAP_LIST)CommonReturnFalse, + (PF_GET_DEVICE_CAP_OVERRIDE)CommonVoid, + (PF_GET_IO_PCB_LIMITS)CommonVoid, + GetSocketFromMap, + GetIgnoreLink, + PostMapToAp, + NewNodeAndSocketTables, + CleanMapsAfterError, + SetNodeToSocketMap, + GetMinNbCoreFreq +}; + +/** + * The non-coherent only build option initializer for the HT internal interface. + */ +CONST HT_INTERFACE ROMDATA HtInterfaceNonCoherentOnly = +{ + (PF_GET_CPU_2_CPU_PCB_LIMITS)CommonVoid, + (PF_GET_SKIP_REGANG)CommonReturnFalse, + (PF_NEW_HOP_COUNT_TABLE)CommonVoid, + GetOverrideBusNumbers, + GetManualBuidSwapList, + GetDeviceCapOverride, + GetIoPcbLimits, + GetSocketFromMap, + GetIgnoreLink, + PostMapToAp, + NewNodeAndSocketTables, + (PF_CLEAN_MAPS_AFTER_ERROR)CommonVoid, + SetNodeToSocketMap, + GetMinNbCoreFreq +}; + +/** + * Topology Maps only feature build option initializer for the HT internal interface. + */ +CONST HT_INTERFACE ROMDATA HtInterfaceMapsOnly = +{ + (PF_GET_CPU_2_CPU_PCB_LIMITS)CommonVoid, + (PF_GET_SKIP_REGANG)CommonReturnFalse, + (PF_NEW_HOP_COUNT_TABLE)CommonVoid, + (PF_GET_OVERRIDE_BUS_NUMBERS)CommonReturnFalse, + (PF_GET_MANUAL_BUID_SWAP_LIST)CommonReturnFalse, + (PF_GET_DEVICE_CAP_OVERRIDE)CommonVoid, + (PF_GET_IO_PCB_LIMITS)CommonVoid, + (PF_GET_SOCKET_FROM_MAP)CommonReturnZero8, + (PF_GET_IGNORE_LINK)CommonReturnFalse, + PostMapToAp, + NewNodeAndSocketTables, + (PF_CLEAN_MAPS_AFTER_ERROR)CommonVoid, + SetNodeToSocketMap, + (PF_GET_MIN_NB_CORE_FREQ)CommonReturnZero8 +}; + +/** + * No features build option initializer for the HT internal interface. + */ +CONST HT_INTERFACE ROMDATA HtInterfaceNone = +{ + (PF_GET_CPU_2_CPU_PCB_LIMITS)CommonVoid, + (PF_GET_SKIP_REGANG)CommonReturnFalse, + (PF_NEW_HOP_COUNT_TABLE)CommonVoid, + (PF_GET_OVERRIDE_BUS_NUMBERS)CommonReturnFalse, + (PF_GET_MANUAL_BUID_SWAP_LIST)CommonReturnFalse, + (PF_GET_DEVICE_CAP_OVERRIDE)CommonVoid, + (PF_GET_IO_PCB_LIMITS)CommonVoid, + (PF_GET_SOCKET_FROM_MAP)CommonReturnZero8, + (PF_GET_IGNORE_LINK)CommonReturnFalse, + (PF_POST_MAP_TO_AP)CommonVoid, + (PF_NEW_NODE_AND_SOCKET_TABLES)CommonVoid, + (PF_CLEAN_MAPS_AFTER_ERROR)CommonVoid, + (PF_SET_NODE_TO_SOCKET_MAP)CommonVoid, + (PF_GET_MIN_NB_CORE_FREQ)CommonReturnZero8 +}; + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * A constructor for the internal Ht Interface. + * + * The install has a reference to the initializer appropriate to the user selected build + * options. Use the selected initializer to construct the internal interface. + * + * @param[in,out] HtInterface Contains pointer to HT Interface structure to initialize. + * @param[in] StdHeader Opaque handle to standard config header + * +*/ +VOID +NewHtInterface ( + OUT HT_INTERFACE *HtInterface, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + LibAmdMemCopy ( + (VOID *) HtInterface, + (VOID *) OptionHtConfiguration.HtOptionInternalInterface, + (sizeof (HT_INTERFACE)), + StdHeader + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * A "constructor" for the HyperTransport external interface. + * + * Sets inputs to valid, basic level, defaults. + * + * Copy the initial default values from the build options tables to the interface struct. + * + * @param[in] StdHeader Opaque handle to standard config header + * @param[in] AmdHtInterface HT Interface structure to initialize. + * + * @retval AGESA_SUCCESS Constructors are not allowed to fail +*/ +AGESA_STATUS +AmdHtInterfaceConstructor ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_HT_INTERFACE *AmdHtInterface + ) +{ + LibAmdMemCopy ( + (VOID *) AmdHtInterface, + (VOID *) OptionHtConfiguration.HtOptionPlatformDefaults, + (UINT32) (sizeof (AMD_HT_INTERFACE)), + StdHeader + ); + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterface.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterface.h new file mode 100644 index 0000000000..1486aa670e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterface.h @@ -0,0 +1,489 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Internal access to HT Interface. + * + * This file provides definitions used by HT internal modules. The + * external HT interface (in agesa.h) is accessed using these methods. + * This keeps the HT Feature implementations abstracted from the HT + * interface. + * + * This file includes the interface access constructor and interface + * support which is not removed with various build options. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _HT_INTERFACE_H_ +#define _HT_INTERFACE_H_ + +/** + * @page htimplintf HT Internal Interface Implementation Guide + * + * HT Internal Interface provides access to the HT Component external interface (see AGESA.h), + * in a manner that isolates calling code from knowledge about the external interface or which + * interfaces are supported in the current build. + * + * @par Adding a Method to HT Internal Interface + * + * To add a new method to the HT Internal Interface, follow these steps. + *
    + *
  • Create a typedef for the Method with the correct parameters and return type. + * + *
      + *
    • Name the method typedef (F_METHOD_NAME)(), where METHOD_NAME is the same name as the method table item, + * but with "_"'s and UPPERCASE, rather than mixed case. + * @n typedef VOID (F_METHOD_NAME)(); @n + * + *
    • Make a reference type for references to a method implementation: + * @n /// Reference to a Method + * @n typedef F_METHOD_NAME *PF_METHOD_NAME @n + *
    + * + *
  • Provide a standard doxygen function preamble for the Method typedef. Begin the + * detailed description by providing a reference to the method instances page by including + * the lines below: + * @code + * * + * * @HtInterfaceInstances + * * + * @endcode + * @note It is important to provide documentation for the method type, because the method may not + * have an implementation in any families supported by the current package. @n + * + *
  • Add to the HT_INTERFACE struct an item for the Method: + * @n PF_METHOD_NAME MethodName; ///< Method: description. @n + *
+ * + * @par Implementing an HT Internal Interface Instance of the method. + * + * To implement an instance of a method for a specific interface follow these steps. + * + * - In appropriate files, implement the method with the return type and parameters + * matching the method typedef. + * + * - Name the function MethodName(). + * + * - Create a doxygen function preamble for the method instance. Begin the detailed description with + * an Implements command to reference the method type and add this instance to the Method Instances page. + * @code + * * + * * @HtInterfaceMethod{::F_METHOD_NAME}. + * * + * @endcode + * + * - To access other Ht internal interface routines or data as part of the method implementation, the function + * must use HtInterface->OtherMethod(). Do not directly access other HT internal interface + * routines, because in the table there may be overrides or this routine may be shared by multiple families. + * + * - Add the instance to the HT_INTERFACE instances. + * + * - If a configuration does not need an instance of the method use one of the CommonReturns from + * CommonReturns.h with the same return type. + * + * @par Invoking HT Internal Interface Methods. + * + * The first step is carried out only once by the top level HT entry point. + * @n @code + * HT_INTERFACE HtInterface; + * // Get the current HT internal interface (to HtBlock data) + * NewHtInterface (&HtInterface); + * State->HtInterface = &HtInterface; + * @endcode + * + * The following example shows how to invoke a HT Internal Interface method. + * @n @code + * State->HtInterface->MethodName (); + * @endcode + * + */ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/** + * Get limits for CPU to CPU Links. + * + * @HtInterfaceInstances. + * + * @param[in] NodeA One Node on which this Link is located + * @param[in] LinkA The Link on this Node + * @param[in] NodeB The other Node on which this Link is located + * @param[in] LinkB The Link on that Node + * @param[in,out] ABLinkWidthLimit modify to change the Link Width In + * @param[in,out] BALinkWidthLimit modify to change the Link Width Out + * @param[in,out] PcbFreqCap modify to change the Link's frequency capability + * @param[in] State the input data + * + */ +typedef VOID F_GET_CPU_2_CPU_PCB_LIMITS ( + IN UINT8 NodeA, + IN UINT8 LinkA, + IN UINT8 NodeB, + IN UINT8 LinkB, + IN OUT UINT8 *ABLinkWidthLimit, + IN OUT UINT8 *BALinkWidthLimit, + IN OUT UINT32 *PcbFreqCap, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GET_CPU_2_CPU_PCB_LIMITS *PF_GET_CPU_2_CPU_PCB_LIMITS; + +/** + * Skip reganging of subLinks. + * + * @HtInterfaceInstances. + * + * @param[in] NodeA One Node on which this Link is located + * @param[in] LinkA The Link on this Node + * @param[in] NodeB The other Node on which this Link is located + * @param[in] LinkB The Link on that Node + * @param[in] State the input data + * + * @retval MATCHED leave Link unganged + * @retval POWERED_OFF leave link unganged and power off the paired sublink + * @retval UNMATCHED regang Link automatically + */ +typedef FINAL_LINK_STATE F_GET_SKIP_REGANG ( + IN UINT8 NodeA, + IN UINT8 LinkA, + IN UINT8 NodeB, + IN UINT8 LinkB, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GET_SKIP_REGANG *PF_GET_SKIP_REGANG; + +/** + * Manually control bus number assignment. + * + * @HtInterfaceInstances. + * + * @param[in] Node The Node on which this chain is located + * @param[in] Link The Link on the host for this chain + * @param[out] SecBus Secondary Bus number for this non-coherent chain + * @param[out] SubBus Subordinate Bus number + * @param[in] State the input data + * + * @retval TRUE this routine is supplying the bus numbers + * @retval FALSE use auto Bus numbering + */ +typedef BOOLEAN F_GET_OVERRIDE_BUS_NUMBERS ( + IN UINT8 Node, + IN UINT8 Link, + OUT UINT8 *SecBus, + OUT UINT8 *SubBus, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GET_OVERRIDE_BUS_NUMBERS *PF_GET_OVERRIDE_BUS_NUMBERS; + +/** + * Get Manual BUID assignment list. + * + * @HtInterfaceInstances. + * + * @param[in] Node The Node on which this chain is located + * @param[in] Link The Link on the host for this chain + * @param[out] List a pointer to a list, if returns TRUE + * @param[in] State the input data + * + * @retval TRUE use manual List + * @retval FALSE initialize the Link automatically. List not valid. + */ +typedef BOOLEAN F_GET_MANUAL_BUID_SWAP_LIST ( + IN UINT8 Node, + IN UINT8 Link, + OUT BUID_SWAP_LIST **List, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GET_MANUAL_BUID_SWAP_LIST *PF_GET_MANUAL_BUID_SWAP_LIST; + +/** + * Override capabilities of a device. + * + * @HtInterfaceInstances. + * + * @param[in] HostNode The Node on which this chain is located + * @param[in] HostLink The Link on the host for this chain + * @param[in] Depth The Depth in the I/O chain from the Host + * @param[in] PciAddress The Device's PCI config address (for callout) + * @param[in] DevVenId The Device's PCI Vendor + Device ID (offset 0x00) + * @param[in] Revision The Device's PCI Revision + * @param[in] Link The Device's Link number (0 or 1) + * @param[in,out] LinkWidthIn modify to change the Link Width In + * @param[in,out] LinkWidthOut modify to change the Link Width Out + * @param[in,out] FreqCap modify to change the Link's frequency capability + * @param[in,out] Clumping modify to change unit id clumping capability + * @param[in] State the input data + * + */ +typedef VOID F_GET_DEVICE_CAP_OVERRIDE ( + IN UINT8 HostNode, + IN UINT8 HostLink, + IN UINT8 Depth, + IN PCI_ADDR PciAddress, + IN UINT32 DevVenId, + IN UINT8 Revision, + IN UINT8 Link, + IN OUT UINT8 *LinkWidthIn, + IN OUT UINT8 *LinkWidthOut, + IN OUT UINT32 *FreqCap, + IN OUT UINT32 *Clumping, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GET_DEVICE_CAP_OVERRIDE *PF_GET_DEVICE_CAP_OVERRIDE; + +/** + * Get limits for non-coherent Links. + * + * @HtInterfaceInstances. + * + * @param[in] HostNode The Node on which this Link is located + * @param[in] HostLink The Link about to be initialized + * @param[in] Depth The Depth in the I/O chain from the Host + * @param[in,out] DownstreamLinkWidthLimit modify to change the Link Width In + * @param[in,out] UpstreamLinkWidthLimit modify to change the Link Width Out + * @param[in,out] PcbFreqCap modify to change the Link's frequency capability + * @param[in] State the input data + */ +typedef VOID F_GET_IO_PCB_LIMITS ( + IN UINT8 HostNode, + IN UINT8 HostLink, + IN UINT8 Depth, + IN OUT UINT8 *DownstreamLinkWidthLimit, + IN OUT UINT8 *UpstreamLinkWidthLimit, + IN OUT UINT32 *PcbFreqCap, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GET_IO_PCB_LIMITS *PF_GET_IO_PCB_LIMITS; + +/** + * Get the Socket number for a given Node number. + * + * @HtInterfaceInstances. + * + * @param[in] Node Node discovered event data. + * @param[in] State reference to Node to socket map + * + * @return the socket id + * + */ +typedef UINT8 F_GET_SOCKET_FROM_MAP ( + IN UINT8 Node, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GET_SOCKET_FROM_MAP *PF_GET_SOCKET_FROM_MAP; + +/** + * Ignore a Link. + * + * @HtInterfaceInstances. + * + * @param[in] Node The Node on which this Link is located + * @param[in] Link The Link about to be initialized + * @param[in] NbList The northbridge default ignore link list + * @param[in] State the input data + * + * @retval MATCHED ignore this Link and skip it + * @retval POWERED_OFF ignore this link and power it off. + * @retval UNMATCHED initialize the Link normally + */ +typedef FINAL_LINK_STATE F_GET_IGNORE_LINK ( + IN UINT8 Node, + IN UINT8 Link, + IN IGNORE_LINK *NbIgnoreLinkList, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_GET_IGNORE_LINK *PF_GET_IGNORE_LINK; + +/** + * Post Node id and other context info to AP cores via mailbox. + * + * @HtInterfaceInstances. + * + * @param[in] State Our state + */ +typedef VOID F_POST_MAP_TO_AP ( + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_POST_MAP_TO_AP *PF_POST_MAP_TO_AP; + +/** + * Clean up the map structures after severe event has caused a fall back to 1 node. + * + * @HtInterfaceInstances. + * + * @param[in] State Our state + */ +typedef VOID F_CLEAN_MAPS_AFTER_ERROR ( + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_CLEAN_MAPS_AFTER_ERROR *PF_CLEAN_MAPS_AFTER_ERROR; + +/** + * Get a new Socket Die to Node Map. + * + * @HtInterfaceInstances. + * + * @param[in,out] State global state + */ +typedef VOID F_NEW_NODE_AND_SOCKET_TABLES ( + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_NEW_NODE_AND_SOCKET_TABLES *PF_NEW_NODE_AND_SOCKET_TABLES; + +/** + * Fill in the socket's Node id when a processor is discovered in that socket. + * + * @HtInterfaceInstances. + * + * @param[in] Node Node from which a new node was discovered + * @param[in] CurrentNodeModule The current node's module id in it's processor. + * @param[in] PackageLink The package level link from Node to NewNode. + * @param[in] NewNode The new node's id + * @param[in] HardwareSocket If we use the hardware method (preferred), this is the socket of new node. + * @param[in] Module The new node's module id in it's processor. + * @param[in] State our State + */ +typedef VOID F_SET_NODE_TO_SOCKET_MAP ( + IN UINT8 Node, + IN UINT8 CurrentNodeModule, + IN UINT8 PackageLink, + IN UINT8 NewNode, + IN UINT8 HardwareSocket, + IN UINT8 Module, + IN STATE_DATA *State + ); +/// Reference to a method. +typedef F_SET_NODE_TO_SOCKET_MAP *PF_SET_NODE_TO_SOCKET_MAP; + +/** + * Get a new, empty Hop Count Table, to make one for the installed topology. + * + * @HtInterfaceInstances. + * + * @param[in,out] State Keep our buffer handle. + * + */ +typedef VOID F_NEW_HOP_COUNT_TABLE ( + IN OUT STATE_DATA *State + ); +/// Reference to a method. +typedef F_NEW_HOP_COUNT_TABLE *PF_NEW_HOP_COUNT_TABLE; + +/** + * Get the minimum Northbridge frequency for the system. + * + * @HtInterfaceInstances. + * + * Invoke the CPU component power mgt interface. + * + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] StdHeader Config for library and services. + * + * @return Frequency in MHz. + * + */ +typedef UINT32 F_GET_MIN_NB_CORE_FREQ ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a Method. +typedef F_GET_MIN_NB_CORE_FREQ *PF_GET_MIN_NB_CORE_FREQ; + +/** + * The HT Interface, feature code uses these methods to get interface parameters. + */ +struct _HT_INTERFACE { // See Forward Declaration in HtFeates.h + PF_GET_CPU_2_CPU_PCB_LIMITS GetCpu2CpuPcbLimits; /**< Method: Get link limits for coherent links. */ + PF_GET_SKIP_REGANG GetSkipRegang; /**< Method: Skip reganging for coherent links. */ + PF_NEW_HOP_COUNT_TABLE NewHopCountTable; /**< Method: Get a new hop count table. */ + PF_GET_OVERRIDE_BUS_NUMBERS GetOverrideBusNumbers; /**< Method: Control Bus number assignment. */ + PF_GET_MANUAL_BUID_SWAP_LIST GetManualBuidSwapList; /**< Method: Assign device IDs. */ + PF_GET_DEVICE_CAP_OVERRIDE GetDeviceCapOverride; /**< Method: Override Device capabilities. */ + PF_GET_IO_PCB_LIMITS GetIoPcbLimits; /**< Method: Get link limits for noncoherent links. */ + PF_GET_SOCKET_FROM_MAP GetSocketFromMap; /**< Method: Get the Socket for a node id. */ + PF_GET_IGNORE_LINK GetIgnoreLink; /**< Method: Ignore a link. */ + PF_POST_MAP_TO_AP PostMapToAp; /**< Method: Post Socket and other info to AP cores. */ + PF_NEW_NODE_AND_SOCKET_TABLES NewNodeAndSocketTables; /**< Method: Get new socket and node maps. */ + PF_CLEAN_MAPS_AFTER_ERROR CleanMapsAfterError; /**< Method: Clean up maps for forced 1P on error fall back. */ + PF_SET_NODE_TO_SOCKET_MAP SetNodeToSocketMap; /**< Method: Associate a node id with a socket. */ + PF_GET_MIN_NB_CORE_FREQ GetMinNbCoreFreq; /**< Method: Get the minimum northbridge frequency */ +} ; + +/*---------------------------------------------------------------------------- + * Prototypes to Interface from Feature Code + * + *---------------------------------------------------------------------------- + */ + +/** + * A constructor for the internal Ht Interface. + * +*/ +VOID +NewHtInterface ( + OUT HT_INTERFACE *HtInterface, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif /* _HT_INTERFACE_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.c new file mode 100644 index 0000000000..189fbb99ee --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.c @@ -0,0 +1,263 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * External Interface implementation for coherent features. + * + * Contains routines for accessing the interface to the client BIOS, + * for support only required for coherent features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htInterface.h" +#include "htInterfaceGeneral.h" +#include "htInterfaceCoherent.h" +#include "htNb.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_HT_HTINTERFACECOHERENT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------*/ +/** + * Get limits for CPU to CPU Links. + * + * @HtInterfaceMethod{::F_GET_CPU_2_CPU_PCB_LIMITS} + * + * For each coherent connection this routine is called once. Update the frequency + * and width if needed for this Link (usually based on board restriction). This is + * used with CPU device capabilities and northbridge limits to compute the default + * settings. The input width and frequency are valid, but do not necessarily reflect + * the minimum setting that will be chosen. + * + * @param[in] NodeA One Node on which this Link is located + * @param[in] LinkA The Link on this Node + * @param[in] NodeB The other Node on which this Link is located + * @param[in] LinkB The Link on that Node + * @param[in,out] ABLinkWidthLimit modify to change the Link Width In + * @param[in,out] BALinkWidthLimit modify to change the Link Width Out + * @param[in,out] PcbFreqCap modify to change the Link's frequency capability + * @param[in] State the input data + * + */ +VOID +GetCpu2CpuPcbLimits ( + IN UINT8 NodeA, + IN UINT8 LinkA, + IN UINT8 NodeB, + IN UINT8 LinkB, + IN OUT UINT8 *ABLinkWidthLimit, + IN OUT UINT8 *BALinkWidthLimit, + IN OUT UINT32 *PcbFreqCap, + IN STATE_DATA *State + ) +{ + CPU_TO_CPU_PCB_LIMITS *p; + UINT8 SocketA; + UINT8 SocketB; + UINT8 PackageLinkA; + UINT8 PackageLinkB; + + ASSERT ((NodeA < MAX_NODES) && (NodeB < MAX_NODES)); + ASSERT ((LinkA < State->Nb->MaxLinks) && (LinkB < State->Nb->MaxLinks)); + + SocketA = State->HtInterface->GetSocketFromMap (NodeA, State); + PackageLinkA = State->Nb->GetPackageLink (NodeA, LinkA, State->Nb); + SocketB = State->HtInterface->GetSocketFromMap (NodeB, State); + PackageLinkB = State->Nb->GetPackageLink (NodeB, LinkB, State->Nb); + + if (State->HtBlock->CpuToCpuPcbLimitsList != NULL) { + p = State->HtBlock->CpuToCpuPcbLimitsList; + + while (p->SocketA != HT_LIST_TERMINAL) { + if (((p->SocketA == SocketA) || (p->SocketA == HT_LIST_MATCH_ANY)) && + ((p->LinkA == PackageLinkA) || ((p->LinkA == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLinkA))) || + ((p->LinkA == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLinkA)))) && + ((p->SocketB == SocketB) || (p->SocketB == HT_LIST_MATCH_ANY)) && + ((p->LinkB == PackageLinkB) || ((p->LinkB == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLinkB))) || + ((p->LinkB == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLinkB))))) { + // Found a match, update width and frequency + *ABLinkWidthLimit = p->ABLinkWidthLimit; + *BALinkWidthLimit = p->BALinkWidthLimit; + *PcbFreqCap = p->PcbFreqCap; + break; + } else { + p++; + } + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Skip reganging of subLinks. + * + * @HtInterfaceMethod{::F_GET_SKIP_REGANG} + * + * This routine is called whenever two subLinks are both connected to the same CPUs. + * Normally, unganged sublinks between the same two CPUs are reganged. Return true + * from this routine to leave the Links unganged. + * + * @param[in] NodeA One Node on which this Link is located + * @param[in] LinkA The Link on this Node + * @param[in] NodeB The other Node on which this Link is located + * @param[in] LinkB The Link on that Node + * @param[in] State the input data + * + * @retval MATCHED leave Link unganged + * @retval POWERED_OFF leave link unganged and power off the paired sublink + * @retval UNMATCHED regang Link automatically + */ +FINAL_LINK_STATE +GetSkipRegang ( + IN UINT8 NodeA, + IN UINT8 LinkA, + IN UINT8 NodeB, + IN UINT8 LinkB, + IN STATE_DATA *State + ) +{ + SKIP_REGANG *p; + FINAL_LINK_STATE Result; + UINT8 SocketA; + UINT8 SocketB; + UINT8 PackageLinkA; + UINT8 PackageLinkB; + + ASSERT ((NodeA < MAX_NODES) && (NodeB < MAX_NODES)); + ASSERT ((LinkA < State->Nb->MaxLinks) && (LinkB < State->Nb->MaxLinks)); + + Result = UNMATCHED; + SocketA = State->HtInterface->GetSocketFromMap (NodeA, State); + PackageLinkA = State->Nb->GetPackageLink (NodeA, LinkA, State->Nb); + SocketB = State->HtInterface->GetSocketFromMap (NodeB, State); + PackageLinkB = State->Nb->GetPackageLink (NodeB, LinkB, State->Nb); + + if (State->HtBlock->SkipRegangList != NULL) { + p = State->HtBlock->SkipRegangList; + + while (p->SocketA != HT_LIST_TERMINAL) { + if (((p->SocketA == SocketA) || (p->SocketA == HT_LIST_MATCH_ANY)) && + ((p->LinkA == PackageLinkA) || ((p->LinkA == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLinkA))) || + ((p->LinkA == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLinkA)))) && + ((p->SocketB == SocketB) || (p->SocketB == HT_LIST_MATCH_ANY)) && + ((p->LinkB == PackageLinkB) || ((p->LinkB == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLinkB))) || + ((p->LinkB == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLinkB))))) { + // Found a match return final link state + Result = p->LinkState; + break; + } else { + p++; + } + } + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get a new, empty Hop Count Table, to make one for the installed topology. + * + * @HtInterfaceMethod{::F_NEW_HOP_COUNT_TABLE} + * + * For SLIT, publish a matrix with the hop count, by allocating a buffer on heap with a + * known signature. + * + * @param[in,out] State Keep our buffer handle. + * + */ +VOID +NewHopCountTable ( + IN OUT STATE_DATA *State + ) +{ + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + AllocHeapParams.RequestedBufferSize = sizeof (HOP_COUNT_TABLE); + AllocHeapParams.BufferHandle = HOP_COUNT_TABLE_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer ( &AllocHeapParams, State->ConfigHandle) == AGESA_SUCCESS) { + State->HopCountTable = (HOP_COUNT_TABLE *)AllocHeapParams.BufferPtr; + } else { + State->HopCountTable = NULL; + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.h new file mode 100644 index 0000000000..2878e2ffd0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceCoherent.h @@ -0,0 +1,114 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Internal access to HT Interface for coherent features. + * + * This file provides definitions used by HT internal modules. The + * external HT interface (in agesa.h) is accessed using these methods. + * This keeps the HT Feature implementations abstracted from the HT + * interface. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _HT_INTERFACE_COHERENT_H_ +#define _HT_INTERFACE_COHERENT_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * Prototypes to Interface from Feature Code + * + *---------------------------------------------------------------------------- + */ + +/** + * Get limits for CPU to CPU Links. + * + */ +VOID +GetCpu2CpuPcbLimits ( + IN UINT8 NodeA, + IN UINT8 LinkA, + IN UINT8 NodeB, + IN UINT8 LinkB, + IN OUT UINT8 *ABLinkWidthLimit, + IN OUT UINT8 *BALinkWidthLimit, + IN OUT UINT32 *PcbFreqCap, + IN STATE_DATA *State + ); + +/** + * Skip reganging of subLinks. + * + */ +FINAL_LINK_STATE +GetSkipRegang ( + IN UINT8 NodeA, + IN UINT8 LinkA, + IN UINT8 NodeB, + IN UINT8 LinkB, + IN STATE_DATA *State + ); + +/** + * Get a new, empty Hop Count Table, to make one for the installed topology. + * + */ +VOID +NewHopCountTable ( + IN OUT STATE_DATA *State + ); + +#endif /* _HT_INTERFACE_COHERENT_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.c new file mode 100644 index 0000000000..ab0ef1cc81 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.c @@ -0,0 +1,538 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * External Interface implementation, general purpose features. + * + * Contains routines for implementing the interface to the client BIOS. This file + * includes the interface support which is not removed with various build options. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionMultiSocket.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htInterface.h" +#include "htInterfaceGeneral.h" +#include "htNb.h" +#include "cpuServices.h" +#include "cpuFeatures.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_HT_HTINTERFACEGENERAL_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Is PackageLink an Internal Link? + * + * This is a test for the logical link match codes in the user interface, not a test for + * the actual northbridge links. + * + * @param[in] PackageLink The link + * + * @retval TRUE This is an internal link + * @retval FALSE This is not an internal link + */ +BOOLEAN +IsPackageLinkInternal ( + IN UINT8 PackageLink + ) +{ + return (BOOLEAN) ((PackageLink <= HT_LIST_MATCH_INTERNAL_LINK_2) && (PackageLink >= HT_LIST_MATCH_INTERNAL_LINK_0)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Ignore a Link. + * + * @HtInterfaceMethod{::F_GET_IGNORE_LINK} + * + * This routine is called every time a coherent Link is found and then every time a + * non-coherent Link from a CPU is found. Any coherent or non-coherent Link from a + * CPU can be ignored and not used for discovery or initialization. Useful for + * connection based systems. + * + * @note not called for IO device to IO Device Links. + * + * @param[in] Node The Node on which this Link is located + * @param[in] Link The Link about to be initialized + * @param[in] NbIgnoreLinkList The northbridge default ignore link list + * @param[in] State the input data + * + * @retval MATCHED ignore this Link and skip it + * @retval POWERED_OFF ignore this link and power it off. + * @retval UNMATCHED initialize the Link normally + */ +FINAL_LINK_STATE +GetIgnoreLink ( + IN UINT8 Node, + IN UINT8 Link, + IN IGNORE_LINK *NbIgnoreLinkList, + IN STATE_DATA *State + ) +{ + IGNORE_LINK *p; + FINAL_LINK_STATE Result; + BOOLEAN IsFound; + UINT8 Socket; + UINT8 PackageLink; + + ASSERT ((Node < MAX_NODES) && (Link < MAX_NODES)); + + Result = UNMATCHED; + IsFound = FALSE; + Socket = State->HtInterface->GetSocketFromMap (Node, State); + PackageLink = State->Nb->GetPackageLink (Node, Link, State->Nb); + + if (State->HtBlock->IgnoreLinkList != NULL) { + p = State->HtBlock->IgnoreLinkList; + while (p->Socket != HT_LIST_TERMINAL) { + if (((p->Socket == Socket) || (p->Socket == HT_LIST_MATCH_ANY)) && + ((p->Link == PackageLink) || + ((p->Link == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLink))) || + ((p->Link == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLink))))) { + // Found a match return the desired link state. + ASSERT (Result < MaxFinalLinkState); + Result = p->LinkState; + IsFound = TRUE; + break; + } else { + p++; + } + } + } + // If there wasn't a match in the user interface, see if the northbridge provides one. + if (!IsFound && (NbIgnoreLinkList != NULL)) { + p = NbIgnoreLinkList; + while (p->Socket != HT_LIST_TERMINAL) { + if (((p->Socket == Socket) || (p->Socket == HT_LIST_MATCH_ANY)) && + ((p->Link == PackageLink) || + ((p->Link == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLink))) || + ((p->Link == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLink))))) { + // Found a match return the desired link state. + ASSERT (Result < MaxFinalLinkState); + Result = p->LinkState; + break; + } else { + p++; + } + } + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the Socket number for a given Node number. + * + * @HtInterfaceMethod{::F_GET_SOCKET_FROM_MAP} + * + * Return the id. + * + * @param[in] Node The Node to translate + * @param[in] State reference to Node to socket map + * + * @return the socket id + * + */ +UINT8 +GetSocketFromMap ( + IN UINT8 Node, + IN STATE_DATA *State + ) +{ + UINT8 Socket; + + ASSERT (State->NodeToSocketDieMap != NULL); + + Socket = (*State->NodeToSocketDieMap)[Node].Socket; + return Socket; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get a new Socket Die to Node Map. + * + * @HtInterfaceMethod{::F_NEW_NODE_AND_SOCKET_TABLES} + * + * Put the Socket Die Table in heap with a known handle. Content will be generated as + * each node is discovered. + * + * @param[in,out] State global state + */ +VOID +NewNodeAndSocketTables ( + IN OUT STATE_DATA *State + ) +{ + UINT8 i; + UINT8 j; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + // Allocate heap for the table + State->SocketDieToNodeMap = NULL; + AllocHeapParams.RequestedBufferSize = (((MAX_SOCKETS) * (MAX_DIES)) * sizeof (SOCKET_DIE_TO_NODE_ITEM)); + AllocHeapParams.BufferHandle = SOCKET_DIE_MAP_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, State->ConfigHandle) == AGESA_SUCCESS) { + State->SocketDieToNodeMap = (SOCKET_DIE_TO_NODE_MAP)AllocHeapParams.BufferPtr; + // Initialize shared data structures + for (i = 0; i < MAX_SOCKETS; i++) { + for (j = 0; j < MAX_DIES; j++) { + (*State->SocketDieToNodeMap)[i][j].Node = HT_LIST_TERMINAL; + (*State->SocketDieToNodeMap)[i][j].LowCore = HT_LIST_TERMINAL; + (*State->SocketDieToNodeMap)[i][j].HighCore = HT_LIST_TERMINAL; + } + } + } + // Allocate heap for the table + State->NodeToSocketDieMap = NULL; + AllocHeapParams.RequestedBufferSize = (MAX_NODES * sizeof (NODE_TO_SOCKET_DIE_ITEM)); + AllocHeapParams.BufferHandle = NODE_ID_MAP_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, State->ConfigHandle) == AGESA_SUCCESS) { + State->NodeToSocketDieMap = (NODE_TO_SOCKET_DIE_MAP)AllocHeapParams.BufferPtr; + // Initialize shared data structures + for (i = 0; i < MAX_NODES; i++) { + (*State->NodeToSocketDieMap)[i].Socket = HT_LIST_TERMINAL; + (*State->NodeToSocketDieMap)[i].Die = HT_LIST_TERMINAL; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the minimum Northbridge frequency for the system. + * + * @HtInterfaceMethod{::F_GET_MIN_NB_CORE_FREQ} + * + * Invoke the CPU component power mgt interface. + * + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] StdHeader Config for library and services. + * + * @return Frequency in MHz. + * + */ +UINT32 +GetMinNbCoreFreq ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MinSysNbFreq; + UINT32 MinP0NbFreq; + + OptionMultiSocketConfiguration.GetMinNbCof (PlatformConfig, &MinSysNbFreq, &MinP0NbFreq, StdHeader); + + ASSERT (MinSysNbFreq != 0); + + return MinSysNbFreq; +} + +/** + * @page physicalsockethowto Physical Socket Map, How To Create + * + * To create a physical system socket map for a platform: + * + * - Start at the Node which will be the BSP. + * + * - Begin a breadth first enumeration of all the coherent Links between sockets + * by creating a socket structure for each socket connection from the BSP. + * For example, if the BSP is in socket zero and Link one connects to socket two, + * create socket {0, 1, 2}. + * + * - When all Links from the BSP are described, go to the first socket connected + * to the BSP and continue the breadth first enumeration. + * + * - It should not be necessary to describe the back Links; in the example above, there + * should be no need to create {2, 1, 0} (assuming socket two connects back to + * socket zero on its Link one). + * + * - When completed: + * + * - Every socket except the BSP's (usually zero) must be listed as a targetSocket, + * at least once. Some sockets may be listed more than once. + * + * - There usually should be at least as many entries as Links. An exception is a + * fully connected system, only the Links from the BSP are needed. + * + * - Every socket but the last one in the breadth first order should usually have one + * or more entries listing it as a currentSocket. (The last one has only back Links.) + * + * There are no strict assumptions about the ordering of the socket structures. + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Update maps between Sockets and Nodes for a specific newly discovered node. + * + * @HtInterfaceMethod{::F_SET_NODE_TO_SOCKET_MAP} + * + * There are two methods for providing socket naming of nodes. + * + * Hardware Method (preferred): A value strapped in hardware by the board is read and + * passed to this routine. + * + * Software Method: The current node's socket is looked up, since it was + * previously a new node and went through this process. The link is converted to + * a package level link. A user data structure describing the package level + * layout of the system is searched for the current node's socket and package link, + * and now we know the new node's socket. + * + * In either case, the Socket, Module to Node map and the Node to Socket, Module + * map are updated with the new node, socket, and module. + * + * Data needed to do this is passed in to the routine as arguments rather than read by this routine, + * so that it is not necessary to know a valid temporary route to either node at the time this code runs. + * + * @param[in] Node Node from which a new node was discovered + * @param[in] CurrentNodeModule The current node's module id in it's processor. + * @param[in] PackageLink The package link for the current node's link. + * @param[in] NewNode The new node's id + * @param[in] HardwareSocket If we use the hardware method (preferred), this is the socket of new node. + * @param[in] Module The new node's module id in it's processor. + * @param[in] State our State + */ +VOID +SetNodeToSocketMap ( + IN UINT8 Node, + IN UINT8 CurrentNodeModule, + IN UINT8 PackageLink, + IN UINT8 NewNode, + IN UINT8 HardwareSocket, + IN UINT8 Module, + IN STATE_DATA *State + ) +{ + UINT8 SourceSocket; + UINT8 TargetSocket; + SYSTEM_PHYSICAL_SOCKET_MAP *Map; + + // While this code could be written to recover from a NULL socket map, AGESA cannot function without one. + ASSERT (State->SocketDieToNodeMap != NULL); + + if (State->HtBlock->SystemPhysicalSocketMap != NULL) { + if (NewNode != 0) { + // Find the logical Node from which a new Node was discovered in the Node field of + // some socket. It must already be there, Nodes are assigned ascending. + // + for (SourceSocket = 0; SourceSocket < MAX_SOCKETS; SourceSocket++) { + if ((*State->SocketDieToNodeMap)[SourceSocket][CurrentNodeModule].Node == Node) { + break; + } + } + // This ASSERT should be understood as "the Node did not have a match", not as a limit check on SourceSocket. + ASSERT (SourceSocket != MAX_SOCKETS); + + // Find the sourceSocket in the CurrentSocket field, for the Link on which a new Node + // was discovered. When we find an entry with that socket and Link number, update the + // Node for that socket. + // + if (IsPackageLinkInternal (PackageLink)) { + // Internal Nodes are in the same socket, don't search the physical system map. + TargetSocket = SourceSocket; + } else { + // Find the target socket in the physical system map. + Map = State->HtBlock->SystemPhysicalSocketMap; + while ((Map->CurrentSocket != 0xFF) && + ((Map->CurrentSocket != SourceSocket) || (Map->CurrentLink != PackageLink))) { + Map++; + } + ASSERT (Map->CurrentSocket != 0xFF); + TargetSocket = Map->TargetSocket; + } + } else { + // The BSP (BSN, if you will) has no predecessor node from which it is discovered. + TargetSocket = 0; + } + } else { + // Use the hardware method + // The hardware strapped socket id is passed to us in this case. + TargetSocket = HardwareSocket; + } + // If the target socket, module is already mapped to something, that's not good. Socket labeling conflict. + // Check that the board is strapped correctly. If not you need a SystemPhysicalSocketMap. If you have one, + // check it for correctness. + ASSERT ((*State->SocketDieToNodeMap)[TargetSocket][Module].Node == 0xFF); + // Update the map for the rest of agesa + (*State->SocketDieToNodeMap)[TargetSocket][Module].Node = NewNode; + // and the node to socket map + ASSERT (State->NodeToSocketDieMap != NULL); + (*State->NodeToSocketDieMap)[NewNode].Socket = TargetSocket; + (*State->NodeToSocketDieMap)[NewNode].Die = Module; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Clean up the map structures after severe event has caused a fall back to 1 node. + * + * @HtInterfaceMethod{::F_CLEAN_MAPS_AFTER_ERROR} + * + * @param[in] State Our state, access to socket, node maps + * + */ +VOID +CleanMapsAfterError ( + IN STATE_DATA *State + ) +{ + UINTN Socket; + UINTN Module; + UINTN Node; + + ASSERT (State->NodeToSocketDieMap != NULL); + ASSERT (State->SocketDieToNodeMap != NULL); + + // Clear all the socket, module items except for the socket and module containing node zero. + for (Socket = 0; Socket < MAX_SOCKETS; Socket++) { + for (Module = 0; Module < MAX_DIES; Module++) { + if (((*State->NodeToSocketDieMap)[0].Socket != Socket) || ((*State->NodeToSocketDieMap)[0].Die != Module)) { + (*State->SocketDieToNodeMap)[Socket][Module].Node = HT_LIST_TERMINAL; + (*State->SocketDieToNodeMap)[Socket][Module].LowCore = HT_LIST_TERMINAL; + (*State->SocketDieToNodeMap)[Socket][Module].HighCore = HT_LIST_TERMINAL; + } + } + } + // Clear all the node items except for node zero. + for (Node = 1; Node < MAX_NODES; Node++) { + (*State->NodeToSocketDieMap)[Node].Socket = HT_LIST_TERMINAL; + (*State->NodeToSocketDieMap)[Node].Die = HT_LIST_TERMINAL; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Post Node id and other context info to AP cores via mailbox. + * + * @HtInterfaceMethod{::F_POST_MAP_TO_AP} + * + * Since Ap's can not view map until after mp communication is established, + * provide them with initial context info via a mailbox register. A mailbox + * register is one that can be written in PCI space and read in MSR space. + * + * @param[in] State Our state, access to socket, node maps + */ +VOID +PostMapToAp ( + IN STATE_DATA *State + ) +{ + UINT8 ModuleType; + UINT8 Module; + AP_MAILBOXES ApMailboxes[MAX_NODES]; + UINT8 Node; + UINT32 Degree; + AGESA_STATUS CalledStatus; + + // Dispatch any features (such as Preserve Mailbox) that need to run as soon as discovery is completed. + IDS_HDT_CONSOLE (CPU_TRACE, " Dispatch CPU features after HT discovery\n"); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_AFTER_COHERENT_DISCOVERY, State->PlatformConfiguration, State->ConfigHandle); + + ASSERT (State->Fabric != NULL); + Degree = 0; + // Compute the degree of the system by finding the maximum degree of any node. + for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) { + if (State->Fabric->SysDegree[Node] > Degree) { + Degree = State->Fabric->SysDegree[Node]; + } + } + // Post the information on all nodes. + for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) { + ModuleType = 0; + Module = 0; + State->Nb->GetModuleInfo (Node, &ModuleType, &Module, State->Nb); + ApMailboxes[Node].ApMailInfo.Info = 0; + ApMailboxes[Node].ApMailInfo.Fields.Node = Node; + ApMailboxes[Node].ApMailInfo.Fields.Socket = State->HtInterface->GetSocketFromMap (Node, State); + ApMailboxes[Node].ApMailInfo.Fields.ModuleType = ModuleType; + ApMailboxes[Node].ApMailInfo.Fields.Module = Module; + ApMailboxes[Node].ApMailExtInfo.Info = 0; + ApMailboxes[Node].ApMailExtInfo.Fields.SystemDegree = Degree; + // other fields of the extended info are used during ap init, and will be initialized at that time. + State->Nb->PostMailbox (Node, ApMailboxes[Node], State->Nb); + } + // Now that the mailboxes have been initialized, cache the info on the BSC. The APs + // will cache during heap initialization. + CacheBspMailbox (State->ConfigHandle, ApMailboxes, (State->NodesDiscovered + 1)); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.h new file mode 100644 index 0000000000..cfa27ca2f2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceGeneral.h @@ -0,0 +1,161 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Internal access to HT Interface, general purpose features. + * + * This file provides definitions used by HT internal modules. The + * external HT interface (in agesa.h) is accessed using these methods. + * This keeps the HT Feature implementations abstracted from the HT + * external interface. + * + * This file includes the interface support which is not removed with + * various build options. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _HT_INTERFACE_GENERAL_H_ +#define _HT_INTERFACE_GENERAL_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * Prototypes to Interface from Feature Code + * + *---------------------------------------------------------------------------- + */ + +/** + * Is PackageLink an Internal Link? + */ +BOOLEAN +IsPackageLinkInternal ( + IN UINT8 PackageLink + ); + +/** + * Get the Socket number for a given Node number. + * + */ +UINT8 +GetSocketFromMap ( + IN UINT8 Node, + IN STATE_DATA *State + ); + +/** + * Ignore a Link. + * + */ +FINAL_LINK_STATE +GetIgnoreLink ( + IN UINT8 Node, + IN UINT8 Link, + IN IGNORE_LINK *NbIgnoreLinkList, + IN STATE_DATA *State + ); + +/** + * Get a new Socket Die to Node Map. + * + */ +VOID +NewNodeAndSocketTables ( + IN OUT STATE_DATA *State + ); + +/** + * Get the minimum Northbridge frequency for the system. + * + */ +UINT32 +GetMinNbCoreFreq ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Fill in the socket's Node id when a processor is discovered in that socket. + * + */ +VOID +SetNodeToSocketMap ( + IN UINT8 Node, + IN UINT8 CurrentNodeModule, + IN UINT8 PackageLink, + IN UINT8 NewNode, + IN UINT8 HardwareSocket, + IN UINT8 Module, + IN STATE_DATA *State + ); + +/** + * Clean up the map structures after severe event has caused a fall back to 1 node. + * + */ +VOID +CleanMapsAfterError ( + IN STATE_DATA *State + ); + +/** + * Post Node id and other context info to AP cores via mailbox. + * + */ +VOID +PostMapToAp ( + IN STATE_DATA *State + ); + +#endif /* _HT_INTERFACE_GENERAL_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceNonCoherent.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceNonCoherent.c new file mode 100644 index 0000000000..1c124d398c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceNonCoherent.c @@ -0,0 +1,393 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * External Interface implementation for non-coherent features. + * + * Contains routines for accessing the interface to the client BIOS, + * for non-coherent features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htInterface.h" +#include "htInterfaceNonCoherent.h" +#include "htNb.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_HT_HTINTERFACENONCOHERENT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define UNUSED_ZERO_32 ((UINT32)0) + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Manual BUID assignment list. + * + * @HtInterfaceMethod{::F_GET_MANUAL_BUID_SWAP_LIST} + * + * This routine is called every time a non-coherent chain is processed. BUID + * assignment may be controlled explicitly on a non-coherent chain. Swaps controls + * the BUID assignment and FinalIds provides the device to device Linking. Device + * orientation can be detected automatically, or explicitly. See documentation for + * more details. + * + * If a manual swap list is not supplied, automatic non-coherent init assigns BUIDs + * starting at 1 and incrementing sequentially based on each device's unit count. + * + * @param[in] Node The Node on which this chain is located + * @param[in] Link The Link on the host for this chain + * @param[out] List supply a pointer to a list. + * List is NOT valid unless routine returns TRUE. + * @param[in] State the input data + * + * @retval TRUE use a manual list + * @retval FALSE initialize the Link automatically + */ +BOOLEAN +GetManualBuidSwapList ( + IN UINT8 Node, + IN UINT8 Link, + OUT BUID_SWAP_LIST **List, + IN STATE_DATA *State + ) +{ + MANUAL_BUID_SWAP_LIST *p; + BOOLEAN result; + UINT8 Socket; + UINT8 PackageLink; + + ASSERT ((Node < MAX_NODES) && (List != NULL)); + + result = FALSE; + Socket = State->HtInterface->GetSocketFromMap (Node, State); + PackageLink = State->Nb->GetPackageLink (Node, Link, State->Nb); + + if (State->HtBlock->ManualBuidSwapList != NULL) { + p = State->HtBlock->ManualBuidSwapList; + + while (p->Socket != HT_LIST_TERMINAL) { + if (((p->Socket == Socket) || (p->Socket == HT_LIST_MATCH_ANY)) && + ((p->Link == PackageLink) || (p->Link == HT_LIST_MATCH_ANY))) { + // Found a match implies TRUE, ignore the Link + result = TRUE; + *List = &(p->SwapList); + break; + } else { + p++; + } + } + } + // List is not valid if Result is FALSE. + return result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Override capabilities of a device. + * + * @HtInterfaceMethod{::F_GET_DEVICE_CAP_OVERRIDE} + * + * This routine is called once for every Link on every IO device. Update the width + * and frequency capability if needed for this device. This is used along with + * device capabilities, the limit call backs, and northbridge limits to compute the + * default settings. The components of the device's PCI config address are provided, + * so its settings can be consulted if need be. The input width and frequency are the + * reported device capabilities. + * + * @param[in] HostNode The Node on which this chain is located + * @param[in] HostLink The Link on the host for this chain + * @param[in] Depth The Depth in the I/O chain from the Host + * @param[in] PciAddress The Device's PCI config address (for callout) + * @param[in] DevVenId The Device's PCI Vendor + Device ID (offset 0x00) + * @param[in] Revision The Device's PCI Revision + * @param[in] Link The Device's Link number (0 or 1) + * @param[in,out] LinkWidthIn modify to change the Link Width In + * @param[in,out] LinkWidthOut modify to change the Link Width Out + * @param[in,out] FreqCap modify to change the Link's frequency capability + * @param[in,out] Clumping modify to change unit id clumping capability + * @param[in] State the input data and config header + * + */ +VOID +GetDeviceCapOverride ( + IN UINT8 HostNode, + IN UINT8 HostLink, + IN UINT8 Depth, + IN PCI_ADDR PciAddress, + IN UINT32 DevVenId, + IN UINT8 Revision, + IN UINT8 Link, + IN OUT UINT8 *LinkWidthIn, + IN OUT UINT8 *LinkWidthOut, + IN OUT UINT32 *FreqCap, + IN OUT UINT32 *Clumping, + IN STATE_DATA *State + ) +{ + DEVICE_CAP_OVERRIDE *p; + UINT8 HostSocket; + UINT8 PackageLink; + DEVICE_CAP_CALLOUT_PARAMS CalloutParams; + AGESA_STATUS CalloutStatus; + + ASSERT ((HostNode < MAX_NODES) && (Depth < 32) && ((Link == 0) || (Link == 1))); + + HostSocket = State->HtInterface->GetSocketFromMap (HostNode, State); + PackageLink = State->Nb->GetPackageLink (HostNode, HostLink, State->Nb); + + if (State->HtBlock->DeviceCapOverrideList != NULL) { + p = State->HtBlock->DeviceCapOverrideList; + + while (p->HostSocket != HT_LIST_TERMINAL) { + if (((p->HostSocket == HostSocket) || (p->HostSocket == HT_LIST_MATCH_ANY)) && + ((p->HostLink == PackageLink) || (p->HostLink == HT_LIST_MATCH_ANY)) && + ((p->Depth == Depth) || (p->Depth == HT_LIST_MATCH_ANY)) && + ((p->Link == Link) || (p->Link == HT_LIST_MATCH_ANY)) && + // Found a potential match. Check the additional optional matches. + ((p->Options.IsCheckDevVenId == 0) || (p->DevVenId == DevVenId)) && + ((p->Options.IsCheckRevision == 0) || (p->Revision == Revision))) { + // + // Found a match. Check what override actions are desired. + // Unlike the PCB limit routines, which handle the info returned, + // deviceCapOverride is actually overriding the settings, so we need + // to check that the field actually has an update. + // The Callout is a catch all for situations the data is not up to handling. + // It is expected, but not enforced, that either the data overrides are used, + // or the callout is used, rather than both. + // + if (p->Options.IsOverrideWidthIn != 0) { + *LinkWidthIn = p->LinkWidthIn; + } + if (p->Options.IsOverrideWidthOut != 0) { + *LinkWidthOut = p->LinkWidthOut; + } + if (p->Options.IsOverrideFreq != 0) { + *FreqCap = p->FreqCap; + } + if (p->Options.IsOverrideClumping != 0) { + *Clumping = p->Clumping; + } + if (p->Options.IsDoCallout != 0) { + // + // Pass the actual info being matched, not the matched struct data. + // This callout is expected to be built in as part of the options file, and does not use the + // callout interface, even though we use the consistent interface declaration for the routine. + // So, the first two int parameters have no meaning in this case. + // It is not meaningful for the callout to have any status but Success. + // + CalloutParams.HostSocket = HostSocket; + CalloutParams.HostLink = PackageLink; + CalloutParams.Depth = Depth; + CalloutParams.DevVenId = DevVenId; + CalloutParams.Revision = Revision; + CalloutParams.Link = Link; + CalloutParams.PciAddress = PciAddress; + CalloutParams.LinkWidthIn = LinkWidthIn; + CalloutParams.LinkWidthOut = LinkWidthOut; + CalloutParams.FreqCap = FreqCap; + CalloutParams.Clumping = Clumping; + CalloutParams.StdHeader = *((AMD_CONFIG_PARAMS *) (State->ConfigHandle)); + CalloutStatus = p->Callout (UNUSED_ZERO_32, UNUSED_ZERO_32, (VOID *) &CalloutParams); + ASSERT (CalloutStatus == AGESA_SUCCESS); + } + break; + } else { + p++; + } + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get limits for non-coherent Links. + * + * @HtInterfaceMethod{::F_GET_IO_PCB_LIMITS} + * + * For each non-coherent connection this routine is called once. Update the + * frequency and width if needed for this Link (usually based on board restriction). + * This is used with device capabilities, device overrides, and northbridge limits to + * compute the default settings. The input width and frequency are valid, but do not + * necessarily reflect the minimum setting that will be chosen. + * + * @param[in] HostNode The Node on which this Link is located + * @param[in] HostLink The Link about to be initialized + * @param[in] Depth The Depth in the I/O chain from the Host + * @param[in,out] DownstreamLinkWidthLimit modify to change the Link Width In + * @param[in,out] UpstreamLinkWidthLimit modify to change the Link Width Out + * @param[in,out] PcbFreqCap modify to change the Link's frequency capability + * @param[in] State the input data + */ +VOID +GetIoPcbLimits ( + IN UINT8 HostNode, + IN UINT8 HostLink, + IN UINT8 Depth, + IN OUT UINT8 *DownstreamLinkWidthLimit, + IN OUT UINT8 *UpstreamLinkWidthLimit, + IN OUT UINT32 *PcbFreqCap, + IN STATE_DATA *State + ) +{ + IO_PCB_LIMITS *p; + UINT8 Socket; + UINT8 PackageLink; + + ASSERT ((HostNode < MAX_NODES) && (HostLink < MAX_NODES)); + + Socket = State->HtInterface->GetSocketFromMap (HostNode, State); + PackageLink = State->Nb->GetPackageLink (HostNode, HostLink, State->Nb); + + if (State->HtBlock->IoPcbLimitsList != NULL) { + p = State->HtBlock->IoPcbLimitsList; + + while (p->HostSocket != HT_LIST_TERMINAL) { + if (((p->HostSocket == Socket) || (p->HostSocket == HT_LIST_MATCH_ANY)) && + ((p->HostLink == PackageLink) || (p->HostLink == HT_LIST_MATCH_ANY)) && + ((p->Depth == Depth) || (p->Depth == HT_LIST_MATCH_ANY))) { + // Found a match, return the override info + *DownstreamLinkWidthLimit = p->DownstreamLinkWidthLimit; + *UpstreamLinkWidthLimit = p->UpstreamLinkWidthLimit; + *PcbFreqCap = p->PcbFreqCap; + break; + } else { + p++; + } + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Manually control bus number assignment. + * + * @HtInterfaceMethod{::F_GET_OVERRIDE_BUS_NUMBERS} + * + * This routine is called every time a non-coherent chain is processed. If a system + * can not use the auto Bus numbering feature for non-coherent chain bus assignments, + * this routine can provide explicit control. For each chain, provide the bus number + * range to use. + * + * The outputs SecBus and SubBus are not valid unless this routine returns TRUE + * + * @param[in] Node The Node on which this chain is located + * @param[in] Link The Link on the host for this chain + * @param[out] SecBus Secondary Bus number for this non-coherent chain + * @param[out] SubBus Subordinate Bus number + * @param[in] State the input data + * + * @retval TRUE this routine is supplying the bus numbers. + * @retval FALSE use auto Bus numbering, bus outputs not valid. + */ +BOOLEAN +GetOverrideBusNumbers ( + IN UINT8 Node, + IN UINT8 Link, + OUT UINT8 *SecBus, + OUT UINT8 *SubBus, + IN STATE_DATA *State + ) +{ + OVERRIDE_BUS_NUMBERS *p; + BOOLEAN result; + UINT8 Socket; + UINT8 PackageLink; + + ASSERT ((Node < MAX_NODES) && (Link < MAX_NODES)); + + result = FALSE; + Socket = State->HtInterface->GetSocketFromMap (Node, State); + PackageLink = State->Nb->GetPackageLink (Node, Link, State->Nb); + + if (State->HtBlock->OverrideBusNumbersList != NULL) { + p = State->HtBlock->OverrideBusNumbersList; + + while (p->Socket != HT_LIST_TERMINAL) { + if (((p->Socket == Socket) || (p->Socket == HT_LIST_MATCH_ANY)) && + ((p->Link == PackageLink) || (p->Link == HT_LIST_MATCH_ANY))) { + // Found a match, return the bus overrides + *SecBus = p->SecBus; + *SubBus = p->SubBus; + ASSERT (*SubBus > *SecBus); + result = TRUE; + break; + } else { + p++; + } + } + } + // SecBus, SubBus are not valid if Result is FALSE. + return result; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceNonCoherent.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceNonCoherent.h new file mode 100644 index 0000000000..1f10f2f36c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htInterfaceNonCoherent.h @@ -0,0 +1,137 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Internal access to HT Interface, for non-coherent features. + * + * This file provides definitions used by HT internal modules. The + * external HT interface (in agesa.h) is accessed using these methods. + * This keeps the HT Feature implementations abstracted from the HT + * interface. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _HT_INTERFACE_NONCOHERENT_H_ +#define _HT_INTERFACE_NONCOHERENT_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * Prototypes to Interface from Feature Code + * + *---------------------------------------------------------------------------- + */ + +/** + * Manually control bus number assignment. + * + */ +BOOLEAN +GetOverrideBusNumbers ( + IN UINT8 Node, + IN UINT8 Link, + OUT UINT8 *SecBus, + OUT UINT8 *SubBus, + IN STATE_DATA *State + ); + +/** + * Get Manual BUID assignment list. + * + */ +BOOLEAN +GetManualBuidSwapList ( + IN UINT8 Node, + IN UINT8 Link, + OUT BUID_SWAP_LIST **List, + IN STATE_DATA *State + ); + +/** + * Override capabilities of a device. + * + */ + +VOID +GetDeviceCapOverride ( + IN UINT8 HostNode, + IN UINT8 HostLink, + IN UINT8 Depth, + IN PCI_ADDR PciAddress, + IN UINT32 DevVenId, + IN UINT8 Revision, + IN UINT8 Link, + IN OUT UINT8 *LinkWidthIn, + IN OUT UINT8 *LinkWidthOut, + IN OUT UINT32 *FreqCap, + IN OUT UINT32 *Clumping, + IN STATE_DATA *State + ); + +/** + * Get limits for non-coherent Links. + * + */ +VOID +GetIoPcbLimits ( + IN UINT8 HostNode, + IN UINT8 HostLink, + IN UINT8 Depth, + IN OUT UINT8 *DownstreamLinkWidthLimit, + IN OUT UINT8 *UpstreamLinkWidthLimit, + IN OUT UINT32 *PcbFreqCap, + IN STATE_DATA *State + ); + +#endif /* _HT_INTERFACE_NONCOHERENT_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htMain.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htMain.c new file mode 100644 index 0000000000..bbad241cbf --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htMain.c @@ -0,0 +1,589 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * HyperTransport features and sequence implementation. + * + * Implements the external AmdHtInitialize entry point. + * Contains routines for directing the sequence of available features. + * Mostly, but not exclusively, AGESA_TESTPOINT invocations should be + * contained in this file, and not in the feature code. + * + * From a build option perspective, it may be that a few lines could be removed + * from compilation in this file for certain options. It is considered that + * the code savings from this are too small to be of concern and this file + * should not have any explicit build option implementation. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htInterface.h" +#include "htNb.h" +#include "heapManager.h" +#include "cpuServices.h" +#include "OptionsHt.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_HT_HTMAIN_FILECODE +#define APIC_Base_BSP 8 +#define APIC_Base 0x1b + +extern OPTION_HT_CONFIGURATION OptionHtConfiguration; + +BOOLEAN +STATIC +IsBootCore ( + IN STATE_DATA *State + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Update maps with the core range for each module. + * + * Cores are numbered relative to a Processor, but sometimes there is a need to know the + * starting and ending core ids on a particular node. This same info is also useful for + * supporting the Core count on a node other than the one currently executing. + * + * For each Processor, get the core count of each node using the family specific PCI core count + * interface. The order of cores in a processor, and whether it is special for the BSP is family + * specific. But whether the processor orders core ids by module or node, iterate in the right + * order and use the counts to determine each start and end range. + * + * Update compute unit status for each node. + * + * @param[in] State number of Nodes discovered. +*/ +VOID +STATIC +UpdateCoreRanges ( + IN STATE_DATA *State + ) +{ + UINT8 Node; + UINT8 ProcessorCores; + UINT8 ModuleCoreCount[MAX_DIES]; + UINT8 Socket; + UINT8 Module; + + ASSERT (State->SocketDieToNodeMap != NULL); + ASSERT (State->NodeToSocketDieMap != NULL); + + for (Socket = 0; Socket < MAX_SOCKETS; Socket++) { + // Is a Processor present in Socket? + if ((*State->SocketDieToNodeMap)[Socket][0].Node != HT_LIST_TERMINAL) { + // Get all the Module core counts for this processor + // Note that the core counts are 1 based counts. + // Since Compute Unit info is not module ordering dependent, write it now. + for (Module = 0; Module < MAX_DIES; Module++) { + if ((*State->SocketDieToNodeMap)[Socket][Module].Node != HT_LIST_TERMINAL) { + ModuleCoreCount[Module] = State->Nb->GetNumCoresOnNode ((*State->SocketDieToNodeMap)[Socket][Module].Node, State->Nb); + (*State->SocketDieToNodeMap)[Socket][Module].EnabledComputeUnits = + State->Nb->GetEnabledComputeUnits ((*State->SocketDieToNodeMap)[Socket][Module].Node, State->Nb); + (*State->SocketDieToNodeMap)[Socket][Module].DualCoreComputeUnits = + State->Nb->GetDualCoreComputeUnits ((*State->SocketDieToNodeMap)[Socket][Module].Node, State->Nb); + (*State->SocketDieToNodeMap)[Socket][Module].TripleCoreComputeUnits = + State->Nb->GetTripleCoreComputeUnits ((*State->SocketDieToNodeMap)[Socket][Module].Node, State->Nb); + (*State->SocketDieToNodeMap)[Socket][Module].QuadCoreComputeUnits = + State->Nb->GetQuadCoreComputeUnits ((*State->SocketDieToNodeMap)[Socket][Module].Node, State->Nb); + } else { + ModuleCoreCount[Module] = 0; + } + } + // Determine the core ordering rule for this processor. + if ((((*State->NodeToSocketDieMap)[0].Socket == Socket) && State->Nb->IsOrderBSPCoresByNode) || + (!State->Nb->IsOrderCoresByModule)) { + // Order core ranges on this processor by Node Id. + ProcessorCores = 0; + for (Node = 0; Node < State->Nb->GetNodeCount (State->Nb); Node++) { + // Is this node a module in this processor? + if ((*State->NodeToSocketDieMap)[Node].Socket == Socket) { + Module = (*State->NodeToSocketDieMap)[Node].Die; + if (ModuleCoreCount[Module] != 0) { + (*State->SocketDieToNodeMap)[Socket][Module].LowCore = ProcessorCores; + (*State->SocketDieToNodeMap)[Socket][Module].HighCore = ProcessorCores + (ModuleCoreCount[Module] - 1); + IDS_HDT_CONSOLE ( + HT_TRACE, + (IsBootCore (State) ? + "Topology: Socket %d, Die %d, is Node %d, with Cores %d thru %d. Compute Unit status (0x%x,0x%x,0x%x,0x%x).\n" : + ""), + Socket, + Module, + Node, + (*State->SocketDieToNodeMap)[Socket][Module].LowCore, + (*State->SocketDieToNodeMap)[Socket][Module].HighCore, + (*State->SocketDieToNodeMap)[Socket][Module].EnabledComputeUnits, + (*State->SocketDieToNodeMap)[Socket][Module].DualCoreComputeUnits, + (*State->SocketDieToNodeMap)[Socket][Module].TripleCoreComputeUnits, + (*State->SocketDieToNodeMap)[Socket][Module].QuadCoreComputeUnits + ); + ProcessorCores = ProcessorCores + ModuleCoreCount[Module]; + } + } + } + } else { + // Order core ranges in this processor by Module Id. + ProcessorCores = 0; + for (Module = 0; Module < MAX_DIES; Module++) { + if (ModuleCoreCount[Module] != 0) { + (*State->SocketDieToNodeMap)[Socket][Module].LowCore = ProcessorCores; + (*State->SocketDieToNodeMap)[Socket][Module].HighCore = ProcessorCores + (ModuleCoreCount[Module] - 1); + IDS_HDT_CONSOLE ( + HT_TRACE, + (IsBootCore (State) ? + "Topology: Socket %d, Die %d, is Node %d, with Cores %d thru %d. Compute Unit status (0x%x,0x%x,0x%x,0x%x).\n" : + ""), + Socket, + Module, + (*State->SocketDieToNodeMap)[Socket][Module].Node, + (*State->SocketDieToNodeMap)[Socket][Module].LowCore, + (*State->SocketDieToNodeMap)[Socket][Module].HighCore, + (*State->SocketDieToNodeMap)[Socket][Module].EnabledComputeUnits, + (*State->SocketDieToNodeMap)[Socket][Module].DualCoreComputeUnits, + (*State->SocketDieToNodeMap)[Socket][Module].TripleCoreComputeUnits, + (*State->SocketDieToNodeMap)[Socket][Module].QuadCoreComputeUnits + ); + ProcessorCores = ProcessorCores + ModuleCoreCount[Module]; + } + } + } + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Complete the coherent init with any system level initialization. + * + * Find the total number of cores and update the number of Nodes and cores in all cpus. + * Limit cpu config access to installed cpus. + * + * @param[in] State number of Nodes discovered. +*/ +VOID +STATIC +FinalizeCoherentInit ( + IN STATE_DATA *State + ) +{ + UINT8 Node; + UINT8 TotalCores; + + TotalCores = 0; + + for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) { + TotalCores = TotalCores + State->Nb->GetNumCoresOnNode (Node, State->Nb); + } + + for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) { + State->Nb->SetTotalNodesAndCores (Node, State->NodesDiscovered + 1, TotalCores, State->Nb); + } + + // Set all nodes to limit config space based on node count, after all nodes have a valid count. + // (just being cautious, probably we could combine the loops.) + for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) { + State->Nb->LimitNodes (Node, State->Nb); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize the coherent fabric. + * + * Perform discovery and initialization of the coherent fabric, for builds including + * support for multiple coherent nodes. + * + * @param[in] State global state + */ +VOID +STATIC +CoherentInit ( + IN OUT STATE_DATA *State + ) +{ + UINT8 i; + UINT8 j; + UINT8 ModuleType; + UINT8 Module; + UINT8 HardwareSocket; + COHERENT_FABRIC Fabric; + + // Because Node 0, the BSP, is not discovered, initialize info about it specially here. + // Allocate Socket Die Map. + // While the BSP is always capable of being the only processor in the system, call the + // IsExceededCapable method to make sure the BSP's capability is included in the aggregate system + // capability. We don't care to check the return value. + // + State->Fabric = &Fabric; + State->NodesDiscovered = 0; + State->TotalLinks = 0; + State->SysMpCap = MAX_NODES; + State->Nb->IsExceededCapable (0, State, State->Nb); + HardwareSocket = State->Nb->GetSocket (0, 0, State->Nb); + ModuleType = 0; + Module = 0; + State->Nb->GetModuleInfo (0, &ModuleType, &Module, State->Nb); + // No predecessor info for BSP, so pass 0xFF for those parameters. + State->HtInterface->SetNodeToSocketMap (0xFF, 0xFF, 0xFF, 0, HardwareSocket, Module, State); + + // Initialize system state data structures + for (i = 0; i < MAX_NODES; i++) { + State->Fabric->SysDegree[i] = 0; + for (j = 0; j < MAX_NODES; j++) { + State->Fabric->SysMatrix[i][j] = 0; + } + } + + // + // Call the coherent init features + // + + // Discovery + State->HtFeatures->CoherentDiscovery (State); + State->HtInterface->PostMapToAp (State); + // Topology matching and Routing + AGESA_TESTPOINT (TpProcHtTopology, State->ConfigHandle); + State->HtFeatures->LookupComputeAndLoadRoutingTables (State); + State->HtFeatures->MakeHopCountTable (State); + + // UpdateCoreRanges requires the other maps to be initialized, and the node count set. + FinalizeCoherentInit (State); + UpdateCoreRanges (State); + State->Fabric = NULL; +} + +/*************************************************************************** + *** Non-coherent init code *** + *** Algorithms *** + ***************************************************************************/ +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize the non-coherent fabric. + * + * Begin with the Compat Link on the BSP, then find and initialize all other + * non-coherent chains. + * + * @param[in] State our global state + */ +VOID +STATIC +NcInit ( + IN STATE_DATA *State + ) +{ + UINT8 Node; + UINT8 Link; + UINT8 CompatLink; + FINAL_LINK_STATE FinalLinkState; + + // Initialize the southbridge chain. + State->AutoBusCurrent = State->HtBlock->AutoBusStart; + State->UsedCfgMapEntries = 0; + CompatLink = State->Nb->ReadSouthbridgeLink (State->Nb); + State->HtFeatures->AllocateBusNumbers (0, CompatLink, State); + State->HtFeatures->ProcessLink (0, CompatLink, TRUE, State); + + // Find and initialize all other non-coherent chains. + for (Node = 0; Node <= State->NodesDiscovered; Node++) { + for (Link = 0; Link < State->Nb->MaxLinks; Link++) { + // Skip the Link, if any of these tests indicate + FinalLinkState = State->HtInterface->GetIgnoreLink (Node, Link, State->Nb->DefaultIgnoreLinkList, State); + if (FinalLinkState == UNMATCHED) { + if ( !((Node == 0) && (Link == CompatLink))) { + if ( !(State->Nb->ReadTrueLinkFailStatus (Node, Link, State, State->Nb))) { + if (State->Nb->VerifyLinkIsNonCoherent (Node, Link, State->Nb)) { + State->HtFeatures->AllocateBusNumbers (Node, Link, State); + State->HtFeatures->ProcessLink (Node, Link, FALSE, State); + } + } + } + } + } + } +} + +/*************************************************************************** + *** Link Optimization *** + ***************************************************************************/ + +/*----------------------------------------------------------------------------------------*/ +/** + * Optimize Link Features. + * + * Based on Link capabilities, apply optimization rules to come up with the best + * settings, including several external limit decision from the interface. This includes + * handling of subLinks. Finally, after the port list data is updated, set the hardware + * state for all Links. + * + * @param[in] State our global state + */ +VOID +STATIC +LinkOptimization ( + IN STATE_DATA *State + ) +{ + AGESA_TESTPOINT (TpProcHtOptGather, State->ConfigHandle); + State->HtFeatures->GatherLinkData (State); + + AGESA_TESTPOINT (TpProcHtOptRegang, State->ConfigHandle); + State->HtFeatures->RegangLinks (State); + + AGESA_TESTPOINT (TpProcHtOptLinks, State->ConfigHandle); + State->HtFeatures->SelectOptimalWidthAndFrequency (State); + + // A likely cause of mixed Retry settings on coherent links is sublink ratio balancing + // so check this after doing the sublinks. + AGESA_TESTPOINT (TpProcHtOptSubLinks, State->ConfigHandle); + State->HtFeatures->SubLinkRatioFixup (State); + if (State->HtFeatures->IsCoherentRetryFixup (State)) { + // Fix sublinks again within HT1 only frequencies, as ratios may be invalid again. + State->HtFeatures->SubLinkRatioFixup (State); + } + + AGESA_TESTPOINT (TpProcHtOptFinish, State->ConfigHandle); + State->HtFeatures->SetLinkData (State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Handle system and performance tunings. + * + * Including traffic distribution, fifo and + * buffer tuning that can't be placed in the register table, + * and special config tunings. + * + * @param[in] State Total Nodes, port list data + */ +VOID +STATIC +Tuning ( + IN STATE_DATA *State + ) +{ + UINT8 Node; + + // For each Node, invoke northbridge specific buffer tunings that can not be done in reg table. + // + AGESA_TESTPOINT (TpProcHtTuning, State->ConfigHandle); + for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) { + State->Nb->BufferOptimizations (Node, State, State->Nb); + } + + // See if traffic distribution can be done and do it if so. + // + AGESA_TESTPOINT (TpProcHtTrafficDist, State->ConfigHandle); + State->HtFeatures->TrafficDistribution (State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize the Node and Socket maps for an AP Core. + * + * In each core's local heap, create a Node to Socket map and a Socket/Module to Node map. + * The mapping is filled in by reading the AP Mailboxes from PCI config on each node. + * + * @param[in] State global state, input data + * + */ +VOID +STATIC +InitApMaps ( + IN STATE_DATA *State + ) +{ + UINT8 Node; + AP_MAIL_INFO NodeApMailBox; + + // There is no option to not have socket - node maps, if they aren't allocated that is a fatal bug. + ASSERT (State->SocketDieToNodeMap != NULL); + ASSERT (State->NodeToSocketDieMap != NULL); + + for (Node = 0; Node < State->Nb->GetNodeCount (State->Nb); Node++) { + //NodeApMailBox = State->Nb->RetrieveMailbox (Node, State->Nb); + *(UINT32 *)(&NodeApMailBox) = 0; + (*State->SocketDieToNodeMap)[NodeApMailBox.Fields.Socket][NodeApMailBox.Fields.Module].Node = Node; + (*State->NodeToSocketDieMap)[Node].Socket = (UINT8)NodeApMailBox.Fields.Socket; + (*State->NodeToSocketDieMap)[Node].Die = (UINT8)NodeApMailBox.Fields.Module; + } + // This requires the other maps to be initialized. + UpdateCoreRanges (State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Is the currently running core the BSC? + * + * Determine whether the init steps for BSC or AP core should be run. + * + * @param[in] State global state, input data + * + * @retval TRUE This is the boot core. + * @retval FALSE This is not the boot core. + */ +BOOLEAN +STATIC +IsBootCore ( + IN STATE_DATA *State + ) +{ + UINT64 Value; + + LibAmdMsrRead (APIC_Base, &Value, State->ConfigHandle); + + return ((BOOLEAN) (((UINT32) (Value & 0xFFFFFFFF) & ((UINT32)1 << APIC_Base_BSP)) != 0)); +} + +/*************************************************************************** + *** HT Initialize *** + ***************************************************************************/ + +/*----------------------------------------------------------------------------------------*/ +/** + * The top level external interface for Hypertransport Initialization. + * + * Create our initial internal state, initialize the coherent fabric, + * initialize the non-coherent chains, and perform any required fabric tuning or + * optimization. + * + * @param[in] StdHeader Opaque handle to standard config header + * @param[in] PlatformConfiguration The platform configuration options. + * @param[in] AmdHtInterface HT Interface structure. + * + * @retval AGESA_SUCCESS Only information events logged. + * @retval AGESA_ALERT Sync Flood or CRC error logged. + * @retval AGESA_WARNING Example: expected capability not found + * @retval AGESA_ERROR logged events indicating some devices may not be available + * @retval AGESA_FATAL Mixed Family or MP capability mismatch + * + */ +AGESA_STATUS +AmdHtInitialize ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfiguration, + IN AMD_HT_INTERFACE *AmdHtInterface + ) +{ + STATE_DATA State; + NORTHBRIDGE Nb; + HT_FEATURES HtFeatures; + HT_INTERFACE HtInterface; + AGESA_STATUS DeallocateStatus; + AP_MAIL_INFO ApMailboxInfo; + UINT8 ApNode; + + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + State.HtBlock = AmdHtInterface; + State.ConfigHandle = StdHeader; + State.PlatformConfiguration = PlatformConfiguration; + + // Get the current HT internal interface (to HtBlock data) + NewHtInterface (&HtInterface, State.ConfigHandle); + State.HtInterface = &HtInterface; + + // Get the current HT Feature Set + NewHtFeatures (&HtFeatures, State.ConfigHandle); + State.HtFeatures = &HtFeatures; + + // Initialize from static options + State.IsUsingRecoveryHt = OptionHtConfiguration.IsUsingRecoveryHt; + State.IsSetHtCrcFlood = OptionHtConfiguration.IsSetHtCrcFlood; + State.IsUsingUnitIdClumping = OptionHtConfiguration.IsUsingUnitIdClumping; + + // Initialize for status and event output + State.MaxEventClass = AGESA_SUCCESS; + + // Allocate permanent heap structs that are interfaces to other AGESA services. + State.HtInterface->NewNodeAndSocketTables (&State); + + if (IsBootCore (&State)) { + AGESA_TESTPOINT (TpProcHtEntry, State.ConfigHandle); + // Allocate Bsp only interface heap structs. + State.HtInterface->NewHopCountTable (&State); + // Allocate heap for our temporary working space. + AllocHeapParams.RequestedBufferSize = (sizeof (PORT_DESCRIPTOR) * (MAX_PLATFORM_LINKS * 2)); + AllocHeapParams.BufferHandle = HT_STATE_DATA_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, State.ConfigHandle) == AGESA_SUCCESS) { + State.PortList = (PORT_LIST)AllocHeapParams.BufferPtr; + // Create the BSP's northbridge. + NewNorthBridge (0, &State, &Nb); + State.Nb = &Nb; + + CoherentInit (&State); + NcInit (&State); + LinkOptimization (&State); + Tuning (&State); + + DeallocateStatus = HeapDeallocateBuffer (HT_STATE_DATA_HANDLE, State.ConfigHandle); + ASSERT (DeallocateStatus == AGESA_SUCCESS); + AGESA_TESTPOINT (TpProcHtDone, State.ConfigHandle); + } else { + ASSERT (FALSE); + State.MaxEventClass = AGESA_ERROR; + // Cannot Log entry due to heap allocate failed. + } + } else { + // Do the AP HT Init, which produces Node and Socket Maps for the AP's use. + AGESA_TESTPOINT (TpProcHtApMapEntry, State.ConfigHandle); + GetApMailbox (&ApMailboxInfo.Info, State.ConfigHandle); + ASSERT (ApMailboxInfo.Fields.Node < MAX_NODES); + ApNode = (UINT8)ApMailboxInfo.Fields.Node; + NewNorthBridge (ApNode, &State, &Nb); + State.Nb = &Nb; + InitApMaps (&State); + AGESA_TESTPOINT (TpProcHtApMapDone, State.ConfigHandle); + } + return State.MaxEventClass; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.c new file mode 100644 index 0000000000..293274a400 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.c @@ -0,0 +1,251 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Construct a northbridge interface for a Node. + * + * Handle build options and run-time detection. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionsHt.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htNb.h" +#include "htNbCommonHardware.h" +#include "CommonReturns.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuFamRegisters.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#include "Filecode.h" + +#define FILECODE PROC_HT_HTNB_FILECODE + +extern OPTION_HT_CONFIGURATION OptionHtConfiguration; + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*************************************************************************** + *** FAMILY/NORTHBRIDGE SPECIFIC FUNCTIONS *** + ***************************************************************************/ + + +/** + * Initial construction data for no HT Northbridge. + */ +CONST NORTHBRIDGE ROMDATA HtFam10NbNone = +{ + 1, + 1, + (PF_WRITE_ROUTING_TABLE)CommonVoid, + (PF_WRITE_NODEID)CommonVoid, + (PF_READ_DEFAULT_LINK)CommonReturnZero8, + (PF_ENABLE_ROUTING_TABLES)CommonVoid, + (PF_DISABLE_ROUTING_TABLES)CommonVoid, + (PF_VERIFY_LINK_IS_COHERENT)CommonReturnFalse, + (PF_READ_TOKEN)CommonReturnZero8, + (PF_WRITE_TOKEN)CommonVoid, + (PF_WRITE_FULL_ROUTING_TABLE)CommonVoid, + (PF_IS_ILLEGAL_TYPE_MIX)CommonReturnFalse, + (PF_IS_EXCEEDED_CAPABLE)CommonReturnFalse, + (PF_STOP_LINK)CommonVoid, + (PF_HANDLE_SPECIAL_LINK_CASE)CommonReturnFalse, + (PF_HANDLE_SPECIAL_NODE_CASE)CommonReturnFalse, + (PF_READ_SB_LINK)CommonReturnZero8, + (PF_VERIFY_LINK_IS_NON_COHERENT)CommonReturnFalse, + (PF_SET_CONFIG_ADDR_MAP)CommonVoid, + (PF_GET_CONFIG_ADDR_MAP)CommonVoid, + (PF_NORTH_BRIDGE_FREQ_MASK)CommonReturnZero32, + (PF_GATHER_LINK_FEATURES)CommonVoid, + (PF_SET_LINK_REGANG)CommonVoid, + (PF_SET_LINK_FREQUENCY)CommonVoid, + (PF_SET_LINK_UNITID_CLUMPING)CommonVoid, + (PF_WRITE_TRAFFIC_DISTRIBUTION)CommonVoid, + (PF_WRITE_LINK_PAIR_DISTRIBUTION)CommonVoid, + (PF_WRITE_VICTIM_DISTRIBUTION)CommonVoid, + (PF_BUFFER_OPTIMIZATIONS)CommonVoid, + (PF_GET_NUM_CORES_ON_NODE)CommonReturnZero8, + (PF_SET_TOTAL_NODES_AND_CORES)CommonVoid, + (PF_GET_NODE_COUNT)CommonReturnZero8, + (PF_LIMIT_NODES)CommonVoid, + (PF_READ_TRUE_LINK_FAIL_STATUS)CommonReturnFalse, + (PF_GET_NEXT_LINK)CommonReturnZero32, + (PF_GET_PACKAGE_LINK)CommonReturnZero8, + (PF_MAKE_LINK_BASE)CommonReturnZero32, + (PF_GET_MODULE_INFO)CommonVoid, + (PF_POST_MAILBOX)CommonVoid, + (PF_RETRIEVE_MAILBOX)CommonReturnZero32, + (PF_GET_SOCKET)CommonReturnZero8, + (PF_GET_ENABLED_COMPUTE_UNITS)CommonReturnZero8, + (PF_GET_DUALCORE_COMPUTE_UNITS)CommonReturnZero8, + (PF_GET_TRIPLECORE_COMPUTE_UNITS)CommonReturnZero8, + (PF_GET_QUADCORE_COMPUTE_UNITS)CommonReturnZero8, + 0, + 0, + 0, + TRUE, + TRUE, + 0, + NULL, + 0, + NULL, + (PF_MAKE_KEY)CommonReturnZero64, + NULL +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Make a compatibility key. + * + * @HtNbMethod{::F_MAKE_KEY} + * + * Private routine to northbridge code. + * Create a key which can be used to determine whether a Node is compatible with + * the discovered configuration so far. Currently, that means the family, + * extended family of the new Node are the same as the BSP's. Family specific + * implementations can add whatever else is necessary. + * + * @param[in] Node the Node + * @param[in] Nb this northbridge + * + * @return the key + */ +UINT64 +MakeKey ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ) +{ + CPU_LOGICAL_ID LogicalId; + UINT32 RawCpuId; + PCI_ADDR Reg; + + Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_NB_FUNC_03, + REG_NB_CPUID_3XFC); + + LibAmdPciReadBits (Reg, 31, 0, &RawCpuId, Nb->ConfigHandle); + GetLogicalIdFromCpuid (RawCpuId, &LogicalId, Nb->ConfigHandle); + return LogicalId.Family; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Construct a new northbridge. + * + * This routine encapsulates knowledge of how to tell significant differences between + * families of supported northbridges and what routines can be used in common and + * which are unique. A fully populated northbridge interface is provided by Nb. + * + * @param[in] Node create a northbridge interface for this Node. + * @param[in] State global state + * @param[out] Nb the caller's northbridge structure to initialize. + */ +VOID +NewNorthBridge ( + IN UINT8 Node, + IN STATE_DATA *State, + OUT NORTHBRIDGE *Nb + ) +{ + CPU_LOGICAL_ID LogicalId; + UINT64 Match; + UINT32 RawCpuId; + PCI_ADDR Reg; + NORTHBRIDGE **InitializerInstance; + + // Start with enough of the key to identify the northbridge interface + Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), + MakePciBusFromNode (Node), + MakePciDeviceFromNode (Node), + CPU_NB_FUNC_03, + REG_NB_CPUID_3XFC); + LibAmdPciReadBits (Reg, 31, 0, &RawCpuId, State->ConfigHandle); + IDS_HDT_CONSOLE (HT_TRACE, "AMD Processor at Node %d has raw CPUID=%x.\n", Node, RawCpuId); + GetLogicalIdFromCpuid (RawCpuId, &LogicalId, State->ConfigHandle); + Match = LogicalId.Family; + + // Test each Northbridge interface in turn looking for a match. + // Use it to Init the Nb struct if a match is found. + // + ASSERT (OptionHtConfiguration.HtOptionFamilyNorthbridgeList != NULL); + InitializerInstance = (NORTHBRIDGE **) (OptionHtConfiguration.HtOptionFamilyNorthbridgeList); + while (*InitializerInstance != NULL) { + if ((Match & (*InitializerInstance)->CompatibleKey) != 0) { + LibAmdMemCopy ((VOID *)Nb, (VOID *)*InitializerInstance, (UINT32) sizeof (NORTHBRIDGE), State->ConfigHandle); + break; + } + InitializerInstance++; + } + // There must be an available northbridge implementation. + ASSERT (*InitializerInstance != NULL); + + // Set the config handle for passing to the library. + Nb->ConfigHandle = State->ConfigHandle; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.h new file mode 100644 index 0000000000..d094da4ec5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNb.h @@ -0,0 +1,1200 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * HT NorthBridge header + * + * Defines the interface to the HT NorthBridge module for use by other internal + * HT modules. This is not a wrapper or external interface, "public" in the + * comments below is used in the class definition style and refers to HT client + * modules only ("private" being for use only by the HT NB module itself). + * + * It is expected that there will be multiple northbridge implementation files all + * conforming to this common interface. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _HT_NB_H_ +#define _HT_NB_H_ + +/** + * @page htimplnb HT Northbridge Implementation Guide + * + * The HT Northbridge provides access to the Northbridge hardware, in a manner that + * isolates calling code from knowledge about the hardware implementation or which + * features are supported in the current build. This is the mechanism in the HT code for + * supporting new Family or Model northbridges, as well as the means for supporting + * multiple northbridges in a single build or mixed revision northbridge sets. + * + * @par Adding a Method to the Northbridge + * + * To add a new method to the Northbridge, follow these steps. + *
    + *
  • Create a typedef for the Method with the correct parameters and return type. + * + *
      + *
    • Name the method typedef (F_METHOD_NAME)(), where METHOD_NAME is the same + * name as the method table item, but with "_"'s and UPPERCASE, rather than mixed case. + * @n typedef VOID (F_METHOD_NAME)(); @n + * + *
    • Make a reference type for references to a method implementation: + * @n /// Reference to a Method + * @n typedef F_METHOD_NAME *PF_METHOD_NAME @n + *
    + * + *
  • One of the parameters to @b all northbridge Methods is @b required to be a + * reference to its current northbridge object. By convention, this is the + * last parameter. + * + *
  • Provide a standard doxygen function preamble for the Method typedef. Begin the + * detailed description by providing a reference to the method instances page by including + * the lines below: + * @code + * * + * * @HtNbInstances + * * + * @endcode + * @note It is important to provide documentation for the method type, because the method may not + * have an implementation in any families supported by the current package. @n + * + *
  • Add to the NORTHBRIDGE struct an item for the Method: + * @n PF_METHOD_NAME MethodName; ///< Method: description. @n + *
+ * + * @par Implementing an Instance of a Northbridge method. + * + * To implement an instance of a method for a specific feature follow these steps. + * + * - In appropriate files, implement the method with the return type and parameters + * matching the Method typedef. + * - If the Method implementation is common to all families, use the northbridge file + * for the function area, for example, add a new coherent initialization support method to the + * coherent northbridge file. + * - If the Method implementation is unique to each supported northbridge, use the + * family specific file for that function area (create it, if it doesn't already exist). + * The family specific files have the same name as the common one suffixed with "FamNN", + * or "FamNNRevX" if for a model or revision. + * + * - Name the function MethodName(). If Family specific, FamNNMethodName(). + * + * - Create a doxygen function preamble for the method instance. Begin the detailed description with + * an Implements command to reference the method type and add this instance to the Method Instances page. + * @code + * * + * * @HtNbMethod{::F_METHOD_NAME}. + * * + * @endcode + * + * - To access other northbridge routines or data as part of the method implementation, + * the function must use Nb->OtherMethod(). Do not directly access other northbridge + * routines, because in the table there may be overrides or this routine may be shared by + * multiple configurations. + * + * - Add the instance, or the correct family specific instance, to the NORTHBRIDGE instances + * used by the northbridge constructor. + * + * - If a northbridge does not need an instance of the method use one of the CommonReturns from + * CommonReturns.h with the same return type. + * + * @par Making common Northbridge Methods. + * + * In some cases, Northbridge methods can easily have a common implementation because the hardware + * is very compatible or is even standard. In other cases, where processor family northbridges + * differ in their implementation, it may be possible to provide a single, common method + * implementation. This can be accomplished by adding Northbridge data members. + * + * For example, a bit position or bit field mask can be used to accommodate different bit placement or size. + * Another example, a small table can be used to translate index values from a common set + * to specific sets. + * + * The Northbridge Method Instance must use its NORTHBRIDGE reference parameter to access + * private data members. + * + * @par Invoking HT Northbridge Methods. + * + * Each unique northbridge is constructed based on matching the current northbridge. + * @n @code + * NORTHBRIDGE Nb; + * // Create the BSP's northbridge. + * NewNorthBridge (0, State, &Nb); + * State->Nb = &Nb; + * @endcode + * + * The following example shows how to invoke a Northbridge method. + * @n @code + * State->Nb->MethodName (State->Nb); + * @endcode + * + */ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/** Use a macro to convert a Node number to a PCI device. If some future port of + * this code needs to, this can easily be replaced by the function declaration: + * UINT8 makePCIDeviceFromNode(UINT8 Node); + */ +#define MakePciDeviceFromNode(Node) \ + ((UINT8) (24 + (Node))) + +/** Use a macro to convert a Node number to a PCI bus. If some future port of + * this code needs to, this can easily be replaced by the function declaration: + * UINT8 MakePciBusFromNode(UINT8 Node); + */ +#define MakePciBusFromNode(Node) \ + ((UINT8) (0)) + +/** Use a macro to convert a Node number to a PCI Segment. If some future port of + * this code needs to, this can easily be replaced by the function declaration: + * UINT8 MakePciSegmentFromNode(UINT8 Node); + */ +#define MakePciSegmentFromNode(Node) \ + ((UINT8) (0)) + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ +/** + * Status for iterating through internal (if supported) and external links. + */ +typedef enum { + LinkIteratorEnd, ///< This is the end of all links, no valid link. + LinkIteratorExternal, ///< The next link (the one we got on this call) is an external link. + LinkIteratorInternal, ///< The next link (the one we got on this call) is an internal link. + LinkIteratorMax ///< For bounds checking and limit only. +} LINK_ITERATOR_STATUS; + +#define LINK_ITERATOR_BEGIN 0xFF + +/** + * Write a temporary Route. + * + * @HtNbInstances + * + * @param[in] Node The node on which to set a temporary route + * @param[in] Target A route to this node, which route table entry is to be set + * @param[in] Link The link which routes to the target node + * @param[in] Nb This northbridge + */ +typedef VOID F_WRITE_ROUTING_TABLE ( + IN UINT8 Node, + IN UINT8 Target, + IN UINT8 Link, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_WRITE_ROUTING_TABLE *PF_WRITE_ROUTING_TABLE; + +/** + * Modifies the NodeID register on the target Node + * + * @HtNbInstances + * + * @param[in] Node the Node that will have its NodeID altered. + * @param[in] NodeID the new value for NodeID + * @param[in] Nb this northbridge + */ +typedef VOID F_WRITE_NODEID ( + IN UINT8 Node, + IN UINT8 NodeID, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_WRITE_NODEID *PF_WRITE_NODEID; + +/** + * Read the Default Link + * + * @HtNbInstances + * + * @param[in] Node the Node that will have its NodeID altered. + * @param[in] Nb this northbridge + * + * @return The HyperTransport Link where the request to + * read the default Link came from. Since this code is running on the BSP, + * this should be the Link pointing back towards the BSP. + */ +typedef UINT8 F_READ_DEFAULT_LINK ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_READ_DEFAULT_LINK *PF_READ_DEFAULT_LINK; + +/** + * Turns routing tables on for a given Node + * + * @HtNbInstances + * + * @param[in] Node the Node that will have it's routing tables enabled + * @param[in] Nb this northbridge + */ +typedef VOID F_ENABLE_ROUTING_TABLES ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_ENABLE_ROUTING_TABLES *PF_ENABLE_ROUTING_TABLES; + +/** + * Turns routing tables off for a given Node + * + * @HtNbInstances + * + * @param[in] Node the Node that will have it's routing tables disabled + * @param[in] Nb this northbridge + */ +typedef VOID F_DISABLE_ROUTING_TABLES ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_DISABLE_ROUTING_TABLES *PF_DISABLE_ROUTING_TABLES; + +/** + * Verify that the Link is coherent, connected, and ready + * + * @HtNbInstances + * + * @param[in] Node the Node that will be examined + * @param[in] Link the Link on that Node to examine + * @param[in] Nb this northbridge + * + * @retval TRUE The Link is coherent + * @retval FALSE The Link has some other status +*/ +typedef BOOLEAN F_VERIFY_LINK_IS_COHERENT ( + IN UINT8 Node, + IN UINT8 Link, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_VERIFY_LINK_IS_COHERENT *PF_VERIFY_LINK_IS_COHERENT; + +/** + * Read the token stored in the scratchpad register field. + * + * @HtNbInstances + * + * @param[in] Node the Node that will be examined + * @param[in] Nb this northbridge + * + * @return the Token read from the Node + */ +typedef UINT8 F_READ_TOKEN ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_READ_TOKEN *PF_READ_TOKEN; + +/** + * Write the token stored in the scratchpad register + * + * @HtNbInstances + * + * @param[in] Node the Node that marked with token + * @param[in] Value the token Value + * @param[in] Nb this northbridge + */ +typedef VOID F_WRITE_TOKEN ( + IN UINT8 Node, + IN UINT8 Value, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_WRITE_TOKEN *PF_WRITE_TOKEN; + +/** + * Full Routing Table Register initialization + * + * @HtNbInstances + * + * @param[in] Node the Node that will be examined + * @param[in] Target the Target Node for these routes + * @param[in] ReqLink the Link for requests to Target + * @param[in] RspLink the Link for responses to Target + * @param[in] BroadcastLinks the broadcast Links + * @param[in] Nb this northbridge + */ +typedef VOID F_WRITE_FULL_ROUTING_TABLE ( + IN UINT8 Node, + IN UINT8 Target, + IN UINT8 ReqLink, + IN UINT8 RspLink, + IN UINT32 BroadcastLinks, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_WRITE_FULL_ROUTING_TABLE *PF_WRITE_FULL_ROUTING_TABLE; + +/** + * Determine whether a Node is compatible with the discovered configuration so far. + * + * @HtNbInstances + * + * @param[in] Node the Node + * @param[in] Nb this northbridge + * + * @retval TRUE the node is not compatible + * @retval FALSE the node is compatible + */ +typedef BOOLEAN F_IS_ILLEGAL_TYPE_MIX ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_IS_ILLEGAL_TYPE_MIX *PF_IS_ILLEGAL_TYPE_MIX; + +/** + * Return whether the current configuration exceeds the capability + * of the nodes detected. + * + * @HtNbInstances + * + * @param[in] Node the Node + * @param[in] State sysMpCap (updated) and NodesDiscovered + * @param[in] Nb this northbridge + * + * @retval TRUE system is not capable of current config. + * @retval FALSE system is capable of current config. + */ +typedef BOOLEAN F_IS_EXCEEDED_CAPABLE ( + IN UINT8 Node, + IN STATE_DATA *State, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_IS_EXCEEDED_CAPABLE *PF_IS_EXCEEDED_CAPABLE; + +/** + * Stop a link, so that it is isolated from a connected device. + * + * @HtNbInstances + * + * Use is for fatal incompatible configurations. + * While XMIT and RCV off are HT standard, the use of these bits + * is generally family specific. + * + * @param[in] Node the node to stop a link on. + * @param[in] Link the link to stop. + * @param[in] State access to special routine for writing link control register + * @param[in] Nb this northbridge. + */ +typedef VOID F_STOP_LINK ( + IN UINT8 Node, + IN UINT8 Link, + IN STATE_DATA *State, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_STOP_LINK *PF_STOP_LINK; + +/** + * Fix (hopefully) exceptional conditions. + * + * @HtNbInstances + * + * This routine is expected to be unimplemented for most families. + * Some configurations may require that links be processed specially to prevent + * serious problems, like hangs. Check for that condition in this routine, + * handle the link both for hardware and for adding to port list, if appropriate. + * If this routine adds the link to port list or the link should not be added, return TRUE. + * + * @param[in] Node The Node which has this link + * @param[in] Link The link to check for special conditions. + * @param[in] State our global state. + * @param[in] Nb this northbridge. + * + * @retval TRUE This link received special handling. + * @retval FALSE This link was not handled specially, handle it normally. + * + */ +typedef BOOLEAN F_HANDLE_SPECIAL_LINK_CASE ( + IN UINT8 Node, + IN UINT8 Link, + IN STATE_DATA *State, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_HANDLE_SPECIAL_LINK_CASE *PF_HANDLE_SPECIAL_LINK_CASE; + +/** + * Fix (hopefully) exceptional conditions. + * + * @HtNbInstances + * + * This routine is expected to be unimplemented for most families. + * Some configurations may require that nodes be processed specially to prevent + * serious problems, like hangs. Check for that condition in this routine, + * handle the node both for hardware and for adding to port list, if appropriate. + * If this routine adds the node to port list or the node should not be added, return TRUE. + * + * @param[in] Node The Node which need to be checked. + * @param[in] Link The link to check for special conditions. + * @param[in] State our global state. + * @param[in] Nb this northbridge. + * + * @retval TRUE This node received special handling. + * @retval FALSE This node was not handled specially, handle it normally. + * + */ +typedef BOOLEAN F_HANDLE_SPECIAL_NODE_CASE ( + IN UINT8 Node, + IN UINT8 Link, + IN STATE_DATA *State, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_HANDLE_SPECIAL_NODE_CASE *PF_HANDLE_SPECIAL_NODE_CASE; + +/** + * Get Info about Module Type of this northbridge + * + * @HtNbInstances + * + * @param[in] Node the Node + * @param[out] ModuleType 0 for Single, 1 for Multi + * @param[out] Module The module number of this node (0 if Single) + * @param[in] Nb this northbridge + * + */ +typedef VOID F_GET_MODULE_INFO ( + IN UINT8 Node, + OUT UINT8 *ModuleType, + OUT UINT8 *Module, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_GET_MODULE_INFO *PF_GET_MODULE_INFO; + +/** + * Post info to AP cores via a mailbox. + * + * @HtNbInstances + * + * @param[in] Node the Node + * @param[in] ApMailInfo The info to post + * @param[in] Nb this northbridge + * + */ +typedef VOID F_POST_MAILBOX ( + IN UINT8 Node, + IN AP_MAILBOXES ApMailInfo, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_POST_MAILBOX *PF_POST_MAILBOX; + +/** + * Retrieve info from a node's AP mailbox. + * + * @HtNbInstances + * + * @param[in] Node the Node + * @param[in] ApMailInfo The info to post + * @param[in] Nb this northbridge + * + */ +typedef AP_MAIL_INFO F_RETRIEVE_MAILBOX ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_RETRIEVE_MAILBOX *PF_RETRIEVE_MAILBOX; + +/** + * Implement the hardware method of doing Socket Naming, by accessing this northbridge's Socket Id register. + * + * @HtNbInstances + * + * @param[in] Node The node for which we want the socket id. + * @param[in] TempNode The temporary node id route where the node can be accessed. + * @param[in] Nb Our Northbridge. + * + * @return The Socket Id + */ +typedef UINT8 F_GET_SOCKET ( + IN UINT8 Node, + IN UINT8 TempNode, + IN NORTHBRIDGE *Nb + ); + +/// Reference to a method. +typedef F_GET_SOCKET *PF_GET_SOCKET; + +/** + * Get the enabled Compute Units. + * + * Processors which don't support compute units return zero. + * + * @HtNbInstances + * + * @param[in] Node The node for which we want the enabled compute units. + * @param[in] Nb Our Northbridge. + * + * @return The enabled compute units value. + */ +typedef UINT8 F_GET_ENABLED_COMPUTE_UNITS ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +/// Reference to a method. +typedef F_GET_ENABLED_COMPUTE_UNITS *PF_GET_ENABLED_COMPUTE_UNITS; + +/** + * Get the dual core Compute Units. + * + * Processors which don't support compute units return zero. + * + * @HtNbInstances + * + * @param[in] Node The node for which we want the dual core compute units. + * @param[in] Nb Our Northbridge. + * + * @return The dual core compute units value. + */ +typedef UINT8 F_GET_DUALCORE_COMPUTE_UNITS ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +/// Reference to a method. +typedef F_GET_DUALCORE_COMPUTE_UNITS *PF_GET_DUALCORE_COMPUTE_UNITS; + +/** + * Get the triple core Compute Units. + * + * Processors which don't support compute units or triple core compute units return zero. + * + * @HtNbInstances + * + * @param[in] Node The node for which we want the triple core compute units. + * @param[in] Nb Our Northbridge. + * + * @return The triple core compute units value. + */ +typedef UINT8 F_GET_TRIPLECORE_COMPUTE_UNITS ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +/// Reference to a method. +typedef F_GET_TRIPLECORE_COMPUTE_UNITS *PF_GET_TRIPLECORE_COMPUTE_UNITS; + +/** + * Get the quad core Compute Units. + * + * Processors which don't support compute units or quad core compute units return zero. + * + * @HtNbInstances + * + * @param[in] Node The node for which we want the quad core compute units. + * @param[in] Nb Our Northbridge. + * + * @return The quad core compute units value. + */ +typedef UINT8 F_GET_QUADCORE_COMPUTE_UNITS ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +/// Reference to a method. +typedef F_GET_QUADCORE_COMPUTE_UNITS *PF_GET_QUADCORE_COMPUTE_UNITS; + +/** + * Return the Link to the Southbridge + * + * @HtNbInstances + * + * @param[in] Nb this northbridge + * + * @return the Link to the southbridge + */ +typedef UINT8 F_READ_SB_LINK ( + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_READ_SB_LINK *PF_READ_SB_LINK; + +/** + * Verify that the Link is non-coherent, connected, and ready + * + * @HtNbInstances + * + * @param[in] Node the Node that will be examined + * @param[in] Link the Link on that Node to examine + * @param[in] Nb this northbridge + * + * @retval TRUE The Link is non-coherent. + * @retval FALSE The Link has some other status + */ +typedef BOOLEAN F_VERIFY_LINK_IS_NON_COHERENT ( + IN UINT8 Node, + IN UINT8 Link, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_VERIFY_LINK_IS_NON_COHERENT *PF_VERIFY_LINK_IS_NON_COHERENT; + +/** + * Enable config access to a non-coherent chain for the given bus range. + * + * @HtNbInstances + * + * @param[in] ConfigMapIndex the map entry to set + * @param[in] SecBus The secondary bus number to use + * @param[in] SubBus The subordinate bus number to use + * @param[in] TargetNode The Node that shall be the recipient of the traffic + * @param[in] TargetLink The Link that shall be the recipient of the traffic + * @param[in] State our global state + * @param[in] Nb this northbridge + */ +typedef VOID F_SET_CONFIG_ADDR_MAP ( + IN UINT8 ConfigMapIndex, + IN UINT8 SecBus, + IN UINT8 SubBus, + IN UINT8 TargetNode, + IN UINT8 TargetLink, + IN STATE_DATA *State, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_SET_CONFIG_ADDR_MAP *PF_SET_CONFIG_ADDR_MAP; + +/** + * For a given non-coherent chain provide the bus range and mapping. + * + * @HtNbInstances + * + * @param[in] ConfigMapIndex the map entry to get + * @param[out] SecBus The secondary bus number. + * @param[out] SubBus The subordinate bus number. + * @param[out] TargetNode The Node that is the recipient of the traffic + * @param[out] TargetLink The Link that is the recipient of the traffic + * @param[in] Nb this northbridge + */ +typedef VOID F_GET_CONFIG_ADDR_MAP ( + IN UINT8 ConfigMapIndex, + OUT UINT8 *SecBus, + OUT UINT8 *SubBus, + OUT UINT8 *TargetNode, + OUT UINT8 *TargetLink, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_GET_CONFIG_ADDR_MAP *PF_GET_CONFIG_ADDR_MAP; + +/** + * Northbridge specific Frequency limit. + * + * @HtNbInstances + * + * Return a mask that eliminates HT frequencies that cannot be used due to a slow + * northbridge frequency. + * + * @param[in] Node Result could (later) be for a specific Node + * @param[in] Interface Access to non-HT support functions. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] Nb this northbridge + * + * @return Frequency mask + */ +typedef UINT32 F_NORTH_BRIDGE_FREQ_MASK ( + IN UINT8 Node, + IN HT_INTERFACE *Interface, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_NORTH_BRIDGE_FREQ_MASK *PF_NORTH_BRIDGE_FREQ_MASK; + +/** + * Get Link features into system data structure. + * + * @HtNbInstances + * + * @param[in,out] ThisPort The PortList structure entry for this link's port + * @param[in] Interface Access to non-HT support functions. + * @param[in] PlatformConfig Platform profile/build option config structure. + * @param[in] Nb this northbridge + */ +typedef VOID F_GATHER_LINK_FEATURES ( + IN OUT PORT_DESCRIPTOR *ThisPort, + IN HT_INTERFACE *Interface, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_GATHER_LINK_FEATURES *PF_GATHER_LINK_FEATURES; + +/** + * Change the hardware state for all Links according to the now optimized data in the + * port list data structure. + * + * @HtNbInstances + * + * @param[in] Node the node on which to regang a link + * @param[in] Link the sublink 0 of the sublink pair to regang + * @param[in] Nb this northbridge + */ +typedef VOID F_SET_LINK_REGANG ( + IN UINT8 Node, + IN UINT8 Link, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_SET_LINK_REGANG *PF_SET_LINK_REGANG; + +/** + * Change the hardware state for all Links according to the now optimized data in the + * port list data structure. + * + * @HtNbInstances + * + * @param[in] Node the node on which to set frequency for a link + * @param[in] Link the link to set frequency + * @param[in] Frequency the frequency to set + * @param[in] Nb this northbridge + */ +typedef VOID F_SET_LINK_FREQUENCY ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Frequency, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_SET_LINK_FREQUENCY *PF_SET_LINK_FREQUENCY; + +/** + * Set the link's Unit Id Clumping enable. + * + * @HtNbInstances + * + * This applies to the host root of a non-coherent chain. + * + * @param[in] Node the node on which to set frequency for a link + * @param[in] Link the link to set frequency + * @param[in] ClumpingEnables the unit id clumping enables to set + * @param[in] Nb this northbridge + */ +typedef VOID F_SET_LINK_UNITID_CLUMPING ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT32 ClumpingEnables, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_SET_LINK_UNITID_CLUMPING *PF_SET_LINK_UNITID_CLUMPING; + +/** + * Set the traffic distribution register for the Links provided. + * + * @HtNbInstances + * + * @param[in] Links01 coherent Links from Node 0 to 1 + * @param[in] Links10 coherent Links from Node 1 to 0 + * @param[in] Nb this northbridge + */ +typedef VOID F_WRITE_TRAFFIC_DISTRIBUTION ( + IN UINT32 Links01, + IN UINT32 Links10, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_WRITE_TRAFFIC_DISTRIBUTION *PF_WRITE_TRAFFIC_DISTRIBUTION; + +/** + * Set the traffic distribution register for the Links provided. + * + * @HtNbInstances + * + * @param[in] NodeA Source Node from Node A To Node B and DstNode from Node A To Node B + * @param[in] NodeB Source Node from Node B To Node A and DstNode from Node A To Node B + * @param[in] VictimedLinkFromNodeAToNodeB Victimed Link from Node A To Node B + * @param[in] VictimedLinkFromNodeBToNodeA Victimed Link from Node B To Node A + * @param[in] Nb this northbridge + */ +typedef VOID F_WRITE_VICTIM_DISTRIBUTION ( + IN UINT8 NodeA, + IN UINT8 NodeB, + IN UINT32 VictimedLinkFromNodeAToNodeB, + IN UINT32 VictimedLinkFromNodeBToNodeA, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_WRITE_VICTIM_DISTRIBUTION *PF_WRITE_VICTIM_DISTRIBUTION; + +/** + * Write a link pair to the link pair distribution and fixups. + * + * @HtNbInstances + * + * @param[in] Node Set the pair on this node + * @param[in] ConnectedNode The Node to which this link pair directly connects. + * @param[in] Pair Using this pair set in the register + * @param[in] Asymmetric True if different widths + * @param[in] MasterLink Set this as the master link and in the route + * @param[in] AlternateLink Set this as the alternate link + * @param[in] Nb this northbridge + * + */ +typedef VOID F_WRITE_LINK_PAIR_DISTRIBUTION ( + IN UINT8 Node, + IN UINT8 ConnectedNode, + IN UINT8 Pair, + IN BOOLEAN Asymmetric, + IN UINT8 MasterLink, + IN UINT8 AlternateLink, + IN NORTHBRIDGE *Nb + ); +/// Pointer to method WriteLinkPairDistribution +typedef F_WRITE_LINK_PAIR_DISTRIBUTION *PF_WRITE_LINK_PAIR_DISTRIBUTION; + +/** + * Family specific tunings. + * + * @HtNbInstances + * + * Buffer tunings are inherently northbridge specific. Check for specific configs + * which require adjustments and apply any standard workarounds to this Node. + * + * @param[in] Node the Node to tune + * @param[in] State global state + * @param[in] Nb this northbridge + */ +typedef VOID F_BUFFER_OPTIMIZATIONS ( + IN UINT8 Node, + IN STATE_DATA *State, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_BUFFER_OPTIMIZATIONS *PF_BUFFER_OPTIMIZATIONS; + +/** + * Return the number of cores (1 based count) on Node. + * + * @HtNbInstances + * + * @param[in] Node the Node that will be examined + * @param[in] Nb this northbridge + * + * @return the number of cores + */ +typedef UINT8 F_GET_NUM_CORES_ON_NODE ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_GET_NUM_CORES_ON_NODE *PF_GET_NUM_CORES_ON_NODE; + +/** + * Write the total number of cores and Nodes to the Node + * + * @HtNbInstances + * + * @param[in] Node the Node that will be examined + * @param[in] TotalNodes the total number of Nodes + * @param[in] TotalCores the total number of cores + * @param[in] Nb this northbridge + */ +typedef VOID F_SET_TOTAL_NODES_AND_CORES ( + IN UINT8 Node, + IN UINT8 TotalNodes, + IN UINT8 TotalCores, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_SET_TOTAL_NODES_AND_CORES *PF_SET_TOTAL_NODES_AND_CORES; + +/** + * Get the Count of Nodes in the system. + * + * @HtNbInstances + * + * @param[in] Nb This Northbridge. + * + * @return The Count (1 based) of Nodes in the system. + */ +typedef UINT8 F_GET_NODE_COUNT ( + IN NORTHBRIDGE *Nb + ); + +/// Reference to a method. +typedef F_GET_NODE_COUNT *PF_GET_NODE_COUNT; + +/** + * Limit coherent config accesses to cpus as indicated by Nodecnt. + * + * @HtNbInstances + * + * @param[in] Node the Node that will be examined + * @param[in] Nb this northbridge + */ +typedef VOID F_LIMIT_NODES ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_LIMIT_NODES *PF_LIMIT_NODES; + +/** + * Return the LinkFailed status AFTER an attempt is made to clear the bit. + * + * @HtNbInstances + * + * @param[in] Node the Node that will be examined + * @param[in] Link the Link on that Node to examine + * @param[in] State access to call back routine + * @param[in] Nb this northbridge + * + * @retval TRUE the Link is not connected or has hard error + * @retval FALSE the Link is connected + */ +typedef BOOLEAN F_READ_TRUE_LINK_FAIL_STATUS ( + IN UINT8 Node, + IN UINT8 Link, + IN STATE_DATA *State, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_READ_TRUE_LINK_FAIL_STATUS *PF_READ_TRUE_LINK_FAIL_STATUS; + +/** + * Get the next link for iterating over the links on a node in the correct order. + * + * @HtNbInstances + * + * @param[in] Node The node on which to iterate links. + * @param[in,out] Link IN: the current iteration context, OUT: the next link. + * @param[in] Nb This Northbridge, access to config pointer. + * + * @retval LinkIteratorEnd There is no next link (Link is back to BEGIN). + * @retval LinkIteratorExternal The next Link is an external link. + * @retval LinkIteratorInternal The next Link is an internal link. + */ +typedef LINK_ITERATOR_STATUS F_GET_NEXT_LINK ( + IN UINT8 Node, + IN OUT UINT8 *Link, + IN NORTHBRIDGE *Nb + ); +/// Pointer to method GetNextLink +typedef F_GET_NEXT_LINK *PF_GET_NEXT_LINK; + +/** + * Get the Package Link number, given the node and real link number. + * + * @HtNbInstances + * + * @param[in] Node the node which has this link + * @param[in] Link the link on that node + * @param[in] Nb this northbridge + * + * @return the Package Link + * + */ +typedef UINT8 F_GET_PACKAGE_LINK ( + IN UINT8 Node, + IN UINT8 Link, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method +typedef F_GET_PACKAGE_LINK *PF_GET_PACKAGE_LINK; + +/** + * Return the HT Host capability base PCI config address for a Link. + * + * @HtNbInstances + * + * @param[in] Node the Node this Link is on + * @param[in] Link the Link + * @param[in] Nb this northbridge + * + * @return the pci config address + */ +typedef PCI_ADDR F_MAKE_LINK_BASE ( + IN UINT8 Node, + IN UINT8 Link, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_MAKE_LINK_BASE *PF_MAKE_LINK_BASE; + +/** + * Make a compatibility key. + * + * @HtNbInstances + * + * @param[in] Node the Node + * @param[in] Nb this northbridge + * + * @return the key + */ +typedef UINT64 F_MAKE_KEY ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); +/// Reference to a method. +typedef F_MAKE_KEY *PF_MAKE_KEY; + +/** + * The northbridge interface. + * + * Abstract the hardware implementation of the processor northbridge. Feature code does + * not need to be tailored to specific families. Also, more than a single family (or + * model in some cases) can be supported at once. Multiple family support can be for + * mixed revisions or for incompatible revisions where only one is used at a time. + * + * The northbridge object contains both HT component public and northbridge private + * members. These sets are grouped together. Within each group, members are grouped + * according to the function area they support. + * + */ +struct _NORTHBRIDGE { // See forward declaration in HtFeats.h + /* Public data, clients of northbridge can access */ + UINT8 MaxLinks; /**< The maximum number of Links implemented by the northbridge */ + UINT8 MaxConfigMaps; /**< The maximum number of PCI config maps implemented by the northbridge */ + + /* Public Interfaces for northbridge clients, coherent init*/ + PF_WRITE_ROUTING_TABLE WriteRoutingTable; /**< Method: Write a Temporary route for discovery */ + PF_WRITE_NODEID WriteNodeID; /**< Method: Assign a Node ID*/ + PF_READ_DEFAULT_LINK ReadDefaultLink; /**< Method: Which link are we connected to on a remote node? */ + PF_ENABLE_ROUTING_TABLES EnableRoutingTables; /**< Method: Make the routing table active */ + PF_DISABLE_ROUTING_TABLES DisableRoutingTables; /**< Method: Put a node back in discoverable state (deflnk) */ + PF_VERIFY_LINK_IS_COHERENT VerifyLinkIsCoherent; /**< Method: is a link connected and coherent? */ + PF_READ_TOKEN ReadToken; /**< Method: Read the enumeration token from a node */ + PF_WRITE_TOKEN WriteToken; /**< Method: Assign an enumeration token to a node */ + PF_WRITE_FULL_ROUTING_TABLE WriteFullRoutingTable; /**< Method: Set a complete routing table entry on a node */ + PF_IS_ILLEGAL_TYPE_MIX IsIllegalTypeMix; /**< Method: Is this node compatible with the system */ + PF_IS_EXCEEDED_CAPABLE IsExceededCapable; /**< Method: Is this node capable of working in this system */ + PF_STOP_LINK StopLink; /**< Method: stop a link which must be unused */ + PF_HANDLE_SPECIAL_LINK_CASE HandleSpecialLinkCase; /**< Method: Fix broken configuration designs */ + PF_HANDLE_SPECIAL_NODE_CASE HandleSpecialNodeCase; /**< Method: Fix broken configuration designs */ + + /* Public Interfaces for northbridge clients, noncoherent init */ + PF_READ_SB_LINK ReadSouthbridgeLink; /**< Method: Which link goes to the southbridge? */ + PF_VERIFY_LINK_IS_NON_COHERENT VerifyLinkIsNonCoherent; /**< Method: is a link connected and non-coherent? */ + PF_SET_CONFIG_ADDR_MAP SetConfigAddrMap; /**< Method: Add a non-coherent chain to the PCI Config Bus Address Map */ + PF_GET_CONFIG_ADDR_MAP GetConfigAddrMap; /**< Method: Provide a chain's mapping and bus allocation */ + + /* Public Interfaces for northbridge clients, Optimization */ + PF_NORTH_BRIDGE_FREQ_MASK NorthBridgeFreqMask; /**< Method: Check for frequency limits other than HT */ + PF_GATHER_LINK_FEATURES GatherLinkFeatures; /**< Method: Get frequency and link features */ + PF_SET_LINK_REGANG SetLinkRegang; /**< Method: Set a Link to regang */ + PF_SET_LINK_FREQUENCY SetLinkFrequency; /**< Method: Set the link Frequency */ + PF_SET_LINK_UNITID_CLUMPING SetLinkUnitIdClumping; /**< Method: Set the link's Unit Id Clumping register */ + + /* Public Interfaces for northbridge clients, System and performance Tuning. */ + PF_WRITE_TRAFFIC_DISTRIBUTION WriteTrafficDistribution; /**< Method: traffic distribution setting */ + PF_WRITE_LINK_PAIR_DISTRIBUTION WriteLinkPairDistribution; /**< Method: Link Pair setting and fix up */ + PF_WRITE_VICTIM_DISTRIBUTION WriteVictimDistribution; /**< Method: victim distribution setting */ + PF_BUFFER_OPTIMIZATIONS BufferOptimizations; /**< Method: system tunings which can not be + * done using register table */ + + /* Public Interfaces for northbridge clients, utility routines */ + PF_GET_NUM_CORES_ON_NODE GetNumCoresOnNode; /**< Method: Count cores */ + PF_SET_TOTAL_NODES_AND_CORES SetTotalNodesAndCores; /**< Method: Set Node and Core counts */ + PF_GET_NODE_COUNT GetNodeCount; /**< Method: Get the Count (1 based) of Nodes in the system. */ + PF_LIMIT_NODES LimitNodes; /**< Method: Set the Limit Config Space feature */ + PF_READ_TRUE_LINK_FAIL_STATUS ReadTrueLinkFailStatus; /**< Method: Get Fault status and connectivity of a link */ + PF_GET_NEXT_LINK GetNextLink; /**< Method: Iterate over a node's Internal, then External links. */ + PF_GET_PACKAGE_LINK GetPackageLink; /**< Method: the package link corresponding to a node's link */ + PF_MAKE_LINK_BASE MakeLinkBase; /**< Method: Provide the PCI Config Base register offset of a CPU link */ + PF_GET_MODULE_INFO GetModuleInfo; /**< Method: Get Module Type and internal Module number */ + PF_POST_MAILBOX PostMailbox; /**< Method: Post info to the mailbox register */ + PF_RETRIEVE_MAILBOX RetrieveMailbox; /**< Method: Retrieve info from the mailbox register */ + PF_GET_SOCKET GetSocket; /**< Method: Get a node's Socket, using the hardware naming method. */ + PF_GET_ENABLED_COMPUTE_UNITS GetEnabledComputeUnits; /**< Method: Get the Enabled Compute Units */ + PF_GET_DUALCORE_COMPUTE_UNITS GetDualCoreComputeUnits; /**< Method: Get which Compute Units have two cores. */ + PF_GET_TRIPLECORE_COMPUTE_UNITS GetTripleCoreComputeUnits; /**< Method: Get which Compute Units have triple cores. */ + PF_GET_QUADCORE_COMPUTE_UNITS GetQuadCoreComputeUnits; /**< Method: Get which Compute Units have quad cores. */ + + /* Private Data for northbridge implementation use only */ + UINT32 SelfRouteRequestMask; /**< Bit pattern for route request to self in routing table register */ + UINT32 SelfRouteResponseMask; /**< Bit pattern for route response to self in routing table register */ + UINT8 BroadcastSelfBit; /**< Bit offset of broadcast self bit in routing table register */ + BOOLEAN IsOrderBSPCoresByNode; /**< This processor orders Cores by Node id on the BSP, if TRUE. */ + BOOLEAN IsOrderCoresByModule; /**< Processors other than the BSP order Cores by Module, if TRUE. */ + UINT64 CompatibleKey; /**< Used for checking compatibility of northbridges in the system */ + PACKAGE_HTLINK_MAP PackageLinkMap; /**< Tell GetPackageLink() how to assign link names */ + UINT32 CoreFrequency; /**< Cache the northbridge core frequency, so repeated interface calls are avoided. + * A value of zero, means no value yet. */ + IGNORE_LINK *DefaultIgnoreLinkList; /**< After processing the user interface ignore link, process this list. */ + + /* Private Interfaces for northbridge implementation. */ + PF_MAKE_KEY MakeKey; /**< Method: make the compatibility key for this node */ + + /** Config Pointer, opaque handle for passing to lib */ + VOID *ConfigHandle; +}; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +/** + * Make a compatibility key. + * + */ +UINT64 +MakeKey ( + IN UINT8 Node, + IN NORTHBRIDGE *Nb + ); + +VOID +NewNorthBridge ( + IN UINT8 Node, + IN STATE_DATA *State, + OUT NORTHBRIDGE *Nb + ); + +#endif /* _HT_NB_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNbCommonHardware.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNbCommonHardware.h new file mode 100644 index 0000000000..eda0f5efe9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNbCommonHardware.h @@ -0,0 +1,122 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Northbridge hardware definitions for Family 10h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _HT_NB_HARDWARE_FAM10_H_ +#define _HT_NB_HARDWARE_FAM10_H_ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/* CPU Northbridge Functions */ +#define CPU_HTNB_FUNC_00 0 +#define CPU_HTNB_FUNC_04 4 +#define CPU_ADDR_FUNC_01 1 +#define CPU_NB_FUNC_03 3 +#define CPU_NB_FUNC_05 5 + +/* Function 0 registers */ +#define REG_ROUTE0_0X40 0x40 +#define REG_ROUTE1_0X44 0x44 +#define REG_NODE_ID_0X60 0x60 +#define REG_UNIT_ID_0X64 0x64 +#define REG_LINK_TRANS_CONTROL_0X68 0x68 +#define REG_LINK_INIT_CONTROL_0X6C 0x6C +#define REG_HT_CAP_BASE_0X80 0x80 +#define REG_HT_LINK_CLUMPING0_0X110 0x110 +#define REG_HT_LINK_RETRY0_0X130 0x130 +#define REG_HT_EXTENDED_NODE_ID_F0X160 0x160 +#define HTREG_NODE_CPUCNT_4_0 0x1F +#define HTREG_EXTNODE_CPUCNT_7_5 0xE0 +#define REG_HT_TRAFFIC_DIST_0X164 0x164 +#define REG_LINK_GLOBAL_EXT_CONTROL_0x16C 0x16C +#define REG_HT_LINK_EXT_CONTROL0_0X170 0x170 +#define REG_HT_LINK_INITIALIZATION_0X1A0 0x1A0 +#define PAIR_SELECT_OFFSET 8 +#define REG_HT_LINK_PAIR_DIST_0X1E0 0x1E0 + +/* Function 1 registers */ +#define REG_ADDR_CONFIG_MAP0_1XE0 0xE0 +#define CPU_ADDR_NUM_CONFIG_MAPS 4 + +/* Function 3 registers */ +#define REG_NB_SRI_XBAR_BUF_3X70 0x70 +#define REG_NB_MCT_XBAR_BUF_3X78 0x78 +#define REG_NB_FIFOPTR_3XDC 0xDC +#define REG_NB_CAPABILITY_3XE8 0xE8 +#define REG_NB_CPUID_3XFC 0xFC +#define REG_NB_LINK_XCS_TOKEN0_3X148 0x148 +#define REG_NB_MCA_LINK_THRESHOLD_3X168 0x168 +#define REG_NB_MCA_L3_THRESHOLD_3X170 0x170 +#define REG_NB_DOWNCORE_3X190 0x190 +#define REG_NB_SBI_CONTROL_3X1E4 0x1E4 + +/* Function 4 registers */ + +/* Function 5 registers */ +#define REG_NB_COMPUTE_UNIT_5X80 0x80 +#define REG_NB_CAPABILITY_2_5X84 0x84 + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +#endif /* _HT_NB_HARDWARE_FAM10_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.c b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.c new file mode 100644 index 0000000000..22c3eb89ec --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.c @@ -0,0 +1,669 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Code for detailed notification of events and status. + * + * Routines for logging and reporting details and summary status. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "Topology.h" +#include "htFeat.h" +#include "htNotify.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_HT_HTNOTIFY_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Log an event. + * + * Errors, events, faults, warnings, and useful information are provided by + * calling this routine as often as necessary, once for each notification. + * @sa AGESA.h for class, and event definitions. + * @sa htNotify.h for event data definitions. + * + * @param[in] EvtClass What level event is this + * @param[in] Event A unique ID of this event + * @param[in] EventData useful data associated with the event. + * @param[in] State the log area and remaining free space + */ +VOID +STATIC +setEventNotify ( + IN AGESA_STATUS EvtClass, + IN UINT32 Event, + IN CONST UINT8 *EventData, + IN STATE_DATA *State + ) +{ + UINT32 DataParam[NUMBER_OF_EVENT_DATA_PARAMS]; + + // Remember the highest event class notified, that becomes our return code. + if (State->MaxEventClass < EvtClass) { + State->MaxEventClass = EvtClass; + } + + // Copy the event data to the log data + LibAmdMemCopy ( + DataParam, + (VOID *)EventData, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + // Log the event + PutEventLog ( + EvtClass, + Event, + DataParam[0], + DataParam[1], + DataParam[2], + DataParam[3], + State->ConfigHandle + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_HW_SYNCFLOOD + * + * @param[in] Node The node on which the fault is reported + * @param[in] Link The link from that node + * @param[in] State our State + * + */ +VOID +NotifyAlertHwSyncFlood ( + IN UINT8 Node, + IN UINT8 Link, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_HW_SYNCFLOOD Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + IDS_HDT_CONSOLE (HT_TRACE, "Sync Flood on Node %d Link %d.\n", Node, Link); + Evt.Node = Node; + Evt.Link = Link; + setEventNotify (AGESA_ALERT, + HT_EVENT_HW_SYNCFLOOD, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_HW_HTCRC + * + * @param[in] Node The node on which the error is reported + * @param[in] Link The link from that node + * @param[in] LaneMask The lanes which had CRC + * @param[in] State our State + * + */ +VOID +NotifyAlertHwHtCrc ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 LaneMask, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_HW_HT_CRC Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + IDS_HDT_CONSOLE (HT_TRACE, "CRC Error on Node %d Link %d lanes %x.\n", Node, Link, LaneMask); + Evt.Node = Node; + Evt.Link = Link; + Evt.LaneMask = LaneMask; + setEventNotify (AGESA_ALERT, + HT_EVENT_HW_HTCRC, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_NCOH_BUS_MAX_EXCEED + * + * @param[in] Node The node on which the chain is located + * @param[in] Link The link from that node + * @param[in] Bus The bus number to assign + * @param[in] State our State + * + */ +VOID +NotifyErrorNcohBusMaxExceed ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Bus, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_NCOH_BUS_MAX_EXCEED Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.Node = Node; + Evt.Link = Link; + Evt.Bus = Bus; + setEventNotify (AGESA_ERROR, + HT_EVENT_NCOH_BUS_MAX_EXCEED, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_NCOH_CFG_MAP_EXCEED + * + * @param[in] Node The node on which the chain is located + * @param[in] Link The link from that node + * @param[in] State our State + * + */ +VOID +NotifyErrorNcohCfgMapExceed ( + IN UINT8 Node, + IN UINT8 Link, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_NCOH_CFG_MAP_EXCEED Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.Node = Node; + Evt.Link = Link; + setEventNotify (AGESA_ERROR, + HT_EVENT_NCOH_CFG_MAP_EXCEED, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_NCOH_BUID_EXCEED + * + * @param[in] Node The node on which the chain is located + * @param[in] Link The link from that node + * @param[in] Depth Position on chain + * @param[in] Id The Id which was attempted to assigned + * @param[in] Units The number of units in this device + * @param[in] State our State + * + */ +VOID +NotifyErrorNcohBuidExceed ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN UINT8 Id, + IN UINT8 Units, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_NCOH_BUID_EXCEED Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.Node = Node; + Evt.Link = Link; + Evt.Depth = Depth; + Evt.CurrentBuid = Id; + Evt.UnitCount = Units; + setEventNotify (AGESA_ERROR, + HT_EVENT_NCOH_BUID_EXCEED, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_NCOH_DEVICE_FAILED + * + * @param[in] Node The node on which the chain is located + * @param[in] Link The link from that node + * @param[in] Depth Position on chain + * @param[in] Id The Id which was attempted to assigned + * @param[in] State our State + * + */ +VOID +NotifyErrorNcohDeviceFailed ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN UINT8 Id, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_NCOH_DEVICE_FAILED Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.Node = Node; + Evt.Link = Link; + Evt.Depth = Depth; + Evt.AttemptedBuid = Id; + setEventNotify (AGESA_ERROR, + HT_EVENT_NCOH_DEVICE_FAILED, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_NCOH_AUTO_DEPTH + * + * @param[in] Node The node on which the chain is located + * @param[in] Link The link from that node + * @param[in] Depth Position on chain + * @param[in] State our State + * + */ +VOID +NotifyInfoNcohAutoDepth ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_NCOH_AUTO_DEPTH Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.Node = Node; + Evt.Link = Link; + Evt.Depth = Depth; + setEventNotify (AGESA_SUCCESS, + HT_EVENT_NCOH_AUTO_DEPTH, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_OPT_REQUIRED_CAP_RETRY + * + * @param[in] Node The node on which the chain is located + * @param[in] Link The link from that node + * @param[in] Depth Position on chain + * @param[in] State our State + * + */ +VOID +NotifyWarningOptRequiredCapRetry ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_OPT_REQUIRED_CAP Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.Node = Node; + Evt.Link = Link; + Evt.Depth = Depth; + setEventNotify (AGESA_WARNING, + HT_EVENT_OPT_REQUIRED_CAP_RETRY, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_OPT_REQUIRED_CAP_GEN3 + * + * @param[in] Node The node on which the chain is located + * @param[in] Link The link from that node + * @param[in] Depth Position on chain + * @param[in] State our State + * + */ +VOID +NotifyWarningOptRequiredCapGen3 ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_OPT_REQUIRED_CAP Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.Node = Node; + Evt.Link = Link; + Evt.Depth = Depth; + setEventNotify (AGESA_WARNING, + HT_EVENT_OPT_REQUIRED_CAP_GEN3, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_OPT_UNUSED_LINKS + * + * @param[in] NodeA One of the nodes connected + * @param[in] NodeB The other connected node + * @param[in] LinkA its unusable link + * @param[in] LinkB its unusable link + * @param[in] State our State + * + */ +VOID +NotifyWarningOptUnusedLinks ( + IN UINT32 NodeA, + IN UINT32 LinkA, + IN UINT32 NodeB, + IN UINT32 LinkB, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_OPT_UNUSED_LINKS Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.NodeA = NodeA; + Evt.LinkA = LinkA; + Evt.NodeB = NodeB; + Evt.LinkB = LinkB; + setEventNotify (AGESA_WARNING, + HT_EVENT_OPT_UNUSED_LINKS, + (UINT8 *)&Evt, State); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_OPT_LINK_PAIR_EXCEED + * + * @param[in] NodeA One of the nodes connected + * @param[in] NodeB The other connected node + * @param[in] MasterLink its unusable Masterlink + * @param[in] AltLink its unusable Alternate link + * @param[in] State our State + * + */ +VOID +NotifyWarningOptLinkPairExceed ( + IN UINT32 NodeA, + IN UINT32 NodeB, + IN UINT32 MasterLink, + IN UINT32 AltLink, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_OPT_LINK_PAIR_EXCEED Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + Evt.NodeA = NodeA; + Evt.MasterLink = MasterLink; + Evt.NodeB = NodeB; + Evt.AltLink = AltLink; + setEventNotify (AGESA_WARNING, + HT_EVENT_OPT_LINK_PAIR_EXCEED, + (UINT8 *)&Evt, State); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_COH_NO_TOPOLOGY + * + * @param[in] Nodes The total number of nodes found so far + * @param[in] State our State + * + */ +VOID +NotifyErrorCohNoTopology ( + IN UINT8 Nodes, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_COH_NO_TOPOLOGY Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + IDS_HDT_CONSOLE (HT_TRACE, "No Topology Matched system with %d nodes found.\n", Nodes); + Evt.TotalNodes = Nodes; + setEventNotify (AGESA_ERROR, + HT_EVENT_COH_NO_TOPOLOGY, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_COH_PROCESSOR_TYPE_MIX + * + * @param[in] Node The node from which a new node was discovered + * @param[in] Link The link from that node + * @param[in] Nodes The total number of nodes found so far + * @param[in] State our State + * + */ +VOID +NotifyFatalCohProcessorTypeMix ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Nodes, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_COH_PROCESSOR_TYPE_MIX Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + IDS_HDT_CONSOLE (HT_TRACE, "Illegal Processor Type Mix.\n"); + Evt.Node = Node; + Evt.Link = Link; + Evt.TotalNodes = Nodes; + setEventNotify (AGESA_CRITICAL, + HT_EVENT_COH_PROCESSOR_TYPE_MIX, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_COH_NODE_DISCOVERED + * + * @param[in] Node Node from which a new node was discovered + * @param[in] Link The link to that new node + * @param[in] NewNode The new node's id + * @param[in] TempRoute Temporarily, during discovery, the new node is accessed at this id. + * @param[in] State our State + * + */ +VOID +NotifyInfoCohNodeDiscovered ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 NewNode, + IN UINT8 TempRoute, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_COH_NODE_DISCOVERED Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + IDS_HDT_CONSOLE (HT_TRACE, "Adding Node %d.\n", NewNode); + Evt.Node = Node; + Evt.Link = Link; + Evt.NewNode = NewNode; + Evt.TempRoute = TempRoute; + setEventNotify (AGESA_SUCCESS, + HT_EVENT_COH_NODE_DISCOVERED, + (UINT8 *)&Evt, State); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * For event HT_EVENT_COH_MPCAP_MISMATCH + * + * @param[in] Node The node from which a new node was discovered + * @param[in] Link The link from that node + * @param[in] Cap The aggregate system MP Capability + * @param[in] Nodes The total number of nodes found so far + * @param[in] State our State + * + */ +VOID +NotifyFatalCohMpCapMismatch ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Cap, + IN UINT8 Nodes, + IN STATE_DATA *State + ) +{ + HT_EVENT_DATA_COH_MP_CAP_MISMATCH Evt; + // Zero out the event data + LibAmdMemFill ( + &Evt, + 0, + (sizeof(UINT32) * NUMBER_OF_EVENT_DATA_PARAMS), + State->ConfigHandle + ); + + IDS_HDT_CONSOLE (HT_TRACE, "Mp Capability Mismatch.\n"); + Evt.Node = Node; + Evt.Link = Link; + Evt.SysMpCap = Cap; + Evt.TotalNodes = Nodes; + setEventNotify (AGESA_CRITICAL, + HT_EVENT_COH_MPCAP_MISMATCH, + (UINT8 *)&Evt, State); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.h new file mode 100644 index 0000000000..58d0cbe534 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htNotify.h @@ -0,0 +1,297 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * HT Notify interface. + * + * This file provides internal interface to event and status + * notification. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _HT_NOTIFY_H_ +#define _HT_NOTIFY_H_ + +/*----------------------------------------------------------------------------------------*/ +/* Event specific event data definitions. + * All structures must be 4 UINT32's in size, no more, no less. + */ + +/// For event ::HT_EVENT_HW_SYNCFLOOD +typedef struct { + UINT32 Node; ///< The Node on which observed + UINT32 Link; ///< The Link on that Node which reported synch flood + UINT32 Reserved1; ///< Reserved. + UINT32 Reserved2; ///< Reserved. +} HT_EVENT_DATA_HW_SYNCFLOOD; + +/// For event ::HT_EVENT_HW_HTCRC +typedef struct { + UINT32 Node; ///< The Node on which event is observed + UINT32 Link; ///< The Link on that Node which reported CRC error + UINT32 LaneMask; ///< The CRC lane mask for the Link + UINT32 Reserved1; ///< Reserved. +} HT_EVENT_DATA_HW_HT_CRC; + +/// For event ::HT_EVENT_NCOH_BUS_MAX_EXCEED +typedef struct { + UINT32 Node; ///< the Node with this non-coherent chain + UINT32 Link; ///< the Link on that Node to this chain + UINT32 Bus; ///< the current bus number + UINT32 Reserved1; ///< Reserved. +} HT_EVENT_DATA_NCOH_BUS_MAX_EXCEED; + +/// For event ::HT_EVENT_NCOH_CFG_MAP_EXCEED +typedef struct { + UINT32 Node; ///< the Node with this non-coherent chain + UINT32 Link; ///< the Link on that Node to this chain + UINT32 Reserved1; ///< Reserved. + UINT32 Reserved2; ///< Reserved. +} HT_EVENT_DATA_NCOH_CFG_MAP_EXCEED; + +/// For event ::HT_EVENT_NCOH_BUID_EXCEED +typedef struct { + UINT32 Node; ///< the Node with this non-coherent chain + UINT32 Link; ///< the Link on that Node to this chain + UINT32 Depth; ///< the position on the chain, zero is CPU host + UINT16 CurrentBuid; ///< the current available BUID + UINT16 UnitCount; ///< the number of ids which would be consumed by this device +} HT_EVENT_DATA_NCOH_BUID_EXCEED; + +/// For event ::HT_EVENT_NCOH_DEVICE_FAILED +typedef struct { + UINT32 Node; ///< the Node with this non-coherent chain + UINT32 Link; ///< the Link on that Node to this chain + UINT32 Depth; ///< the position on the chain, zero is CPU host + UINT32 AttemptedBuid; ///< the BUID we tried to assign to that device +} HT_EVENT_DATA_NCOH_DEVICE_FAILED; + +/// For event ::HT_EVENT_NCOH_AUTO_DEPTH +typedef struct { + UINT32 Node; ///< the Node with this non-coherent chain + UINT32 Link; ///< the Link on that Node to this chain + UINT32 Depth; ///< the position on the chain of the last device, zero is CPU host + UINT32 Reserved1; ///< Reserved. +} HT_EVENT_DATA_NCOH_AUTO_DEPTH; + +/// For event ::HT_EVENT_OPT_REQUIRED_CAP_RETRY, +/// ::HT_EVENT_OPT_REQUIRED_CAP_GEN3. +typedef struct { + UINT32 Node; ///< the Node with this non-coherent chain + UINT32 Link; ///< the Link on that Node to this chain + UINT32 Depth; ///< the position on the chain, zero is CPU host + UINT32 Reserved1; ///< Reserved. +} HT_EVENT_DATA_OPT_REQUIRED_CAP; + +/// For event ::HT_EVENT_OPT_UNUSED_LINKS +typedef struct { + UINT32 NodeA; ///< One of the nodes connected + UINT32 LinkA; ///< its unusable link + UINT32 NodeB; ///< The other connected node + UINT32 LinkB; ///< its unusable link +} HT_EVENT_DATA_OPT_UNUSED_LINKS; + +/// For event ::HT_EVENT_OPT_LINK_PAIR_EXCEED +typedef struct { + UINT32 NodeA; ///< One of the nodes connected + UINT32 NodeB; ///< The other connected node + UINT32 MasterLink; ///< NodeA's unusable Master link + UINT32 AltLink; ///< NodeA's unusable Alternatelink +} HT_EVENT_DATA_OPT_LINK_PAIR_EXCEED; + +/// For event ::HT_EVENT_COH_NO_TOPOLOGY. +/// There is no routing for this system's topology. +typedef struct { + UINT32 TotalNodes; ///< the number of Nodes in the unmatched topology + UINT32 Reserved1; ///< Reserved. + UINT32 Reserved2; ///< Reserved. + UINT32 Reserved3; ///< Reserved. +} HT_EVENT_DATA_COH_NO_TOPOLOGY; + +/// For event ::HT_EVENT_COH_PROCESSOR_TYPE_MIX +typedef struct { + UINT32 Node; ///< the Node from which the incompatible family was found + UINT32 Link; ///< the Link to the incompatible Node + UINT32 TotalNodes; ///< the number of Nodes found at that point + UINT32 Reserved1; ///< Reserved. +} HT_EVENT_DATA_COH_PROCESSOR_TYPE_MIX; + +/// For event ::HT_EVENT_COH_NODE_DISCOVERED +typedef struct { + UINT32 Node; ///< the Node from which the new Node was found + UINT32 Link; ///< the Link to the new Node + UINT32 NewNode; ///< the Node id of the newly discovered Node + UINT32 TempRoute; ///< the new Node is temporarily at this id +} HT_EVENT_DATA_COH_NODE_DISCOVERED; + +/// For event ::HT_EVENT_COH_MPCAP_MISMATCH +typedef struct { + UINT32 Node; ///< the Node from which condition was observed + UINT32 Link; ///< the Link on the current Node + UINT32 SysMpCap; ///< the current aggregate system capability (the minimum found so far) + UINT32 TotalNodes; ///< the number of Nodes found, before this was observed +} HT_EVENT_DATA_COH_MP_CAP_MISMATCH; + +/*----------------------------------------------------------------------------------------*/ +/* Event specific Notify functions. + */ + +VOID +NotifyAlertHwSyncFlood ( + IN UINT8 Node, + IN UINT8 Link, + IN STATE_DATA *State + ); + +VOID +NotifyAlertHwHtCrc ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 LaneMask, + IN STATE_DATA *State + ); + +VOID +NotifyErrorNcohBusMaxExceed ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Bus, + IN STATE_DATA *State + ); + +VOID +NotifyErrorNcohCfgMapExceed ( + IN UINT8 Node, + IN UINT8 Link, + IN STATE_DATA *State + ); + +VOID +NotifyErrorNcohBuidExceed ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN UINT8 Id, + IN UINT8 Units, + IN STATE_DATA *State + ); + +VOID +NotifyErrorNcohDeviceFailed ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN UINT8 Id, + IN STATE_DATA *State + ); + +VOID +NotifyInfoNcohAutoDepth ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN STATE_DATA *State + ); + +VOID +NotifyWarningOptRequiredCapRetry ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN STATE_DATA *State + ); + +VOID +NotifyWarningOptRequiredCapGen3 ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Depth, + IN STATE_DATA *State + ); + +VOID +NotifyWarningOptUnusedLinks ( + IN UINT32 NodeA, + IN UINT32 LinkA, + IN UINT32 NodeB, + IN UINT32 LinkB, + IN STATE_DATA *State + ); + +VOID +NotifyWarningOptLinkPairExceed ( + IN UINT32 NodeA, + IN UINT32 NodeB, + IN UINT32 MasterLink, + IN UINT32 AltLink, + IN STATE_DATA *State + ); + +VOID +NotifyErrorCohNoTopology ( + IN UINT8 Nodes, + IN STATE_DATA *State + ); + +VOID +NotifyFatalCohProcessorTypeMix ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Nodes, + IN STATE_DATA *State + ); + +VOID +NotifyInfoCohNodeDiscovered ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 NewNode, + IN UINT8 TempRoute, + IN STATE_DATA *State + ); + +VOID +NotifyFatalCohMpCapMismatch ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT8 Cap, + IN UINT8 Nodes, + IN STATE_DATA *State + ); + +#endif /* _HT_NOTIFY_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/HT/htTopologies.h b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htTopologies.h new file mode 100644 index 0000000000..421d39868a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/HT/htTopologies.h @@ -0,0 +1,71 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Provide selection of available topologies. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +#ifndef _HT_TOPOLOGIES_H_ +#define _HT_TOPOLOGIES_H_ + +extern CONST UINT8 ROMDATA amdHtTopologySingleNode[]; +extern CONST UINT8 ROMDATA amdHtTopologyDualNode[]; +extern CONST UINT8 ROMDATA amdHtTopologyThreeLine[]; +extern CONST UINT8 ROMDATA amdHtTopologyTriangle[]; +extern CONST UINT8 ROMDATA amdHtTopologyFourLine[]; +extern CONST UINT8 ROMDATA amdHtTopologyFourStar[]; +extern CONST UINT8 ROMDATA amdHtTopologyFourDegenerate[]; +extern CONST UINT8 ROMDATA amdHtTopologyFourSquare[]; +extern CONST UINT8 ROMDATA amdHtTopologyFourKite[]; +extern CONST UINT8 ROMDATA amdHtTopologyFourFully[]; +extern CONST UINT8 ROMDATA amdHtTopologyFiveFully[]; +extern CONST UINT8 ROMDATA amdHtTopologyFiveTwistedLadder[]; +extern CONST UINT8 ROMDATA amdHtTopologySixFully[]; +extern CONST UINT8 ROMDATA amdHtTopologySixDoubloonLower[]; +extern CONST UINT8 ROMDATA amdHtTopologySixDoubloonUpper[]; +extern CONST UINT8 ROMDATA amdHtTopologySixTwistedLadder[]; +extern CONST UINT8 ROMDATA amdHtTopologySevenFully[]; +extern CONST UINT8 ROMDATA amdHtTopologySevenTwistedLadder[]; +extern CONST UINT8 ROMDATA amdHtTopologyEightFully[]; +extern CONST UINT8 ROMDATA amdHtTopologyEightDoubloon[]; +extern CONST UINT8 ROMDATA amdHtTopologyEightTwistedLadder[]; +extern CONST UINT8 ROMDATA amdHtTopologyEightStraightLadder[]; +extern CONST UINT8 ROMDATA amdHtTopologySixTwinTriangles[]; +extern CONST UINT8 ROMDATA amdHtTopologyEightTwinFullyFourWays[]; + +#endif // _HT_TOPOLOGIES_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Control/IdsLib32.asm b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Control/IdsLib32.asm new file mode 100644 index 0000000000..6d2c0b1362 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Control/IdsLib32.asm @@ -0,0 +1,335 @@ +;/** +; * @file +; * +; * Ids Assembly library 32bit +; * +; * @xrefitem bom "File Content Label" "Release Content" +; * @e project: AGESA +; * @e sub-project: IDS +; * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ +; */ +;***************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +.586p +.model flat +ASSUME FS:NOTHING +.code +public IdsDelay +IdsDelay PROC NEAR C USES EAX EDX +Local targetedx:dword, targeteax:dword + rdtsc +;set target time + add eax,1500000000 + adc edx,0 + mov targetedx,edx + mov targeteax,eax + + rdtsc +;set "Si!=0" skip below loop + .while(1) + .if(si != 0) + jmp delay_exit + .endif + .if(edx > targetedx) + jmp delay_exit + .elseif (edx == targetedx) + .if(eax > targeteax) + jmp delay_exit + .endif + .endif + rdtsc + .endw +delay_exit: + ret +IdsDelay ENDP +;/*++ +; +;Routine Description: +; +; IdsErrorStop -- Function for Assert +; +;Arguments: +; Filecode +; +;Returns: +; +; None +; +;--*/ +public IdsErrorStop +IdsErrorStop PROC NEAR C filecode:dword +local tmpebx:dword,tmpedx:dword + pushad + + mov si,0 ; Si is used as control flag, "Si!=0" skip postcode loop +; send debug port 1st, then fire SimNow breakpoint + mov ax, 0deadh + out 0e0h, ax + mov eax, filecode + out 84h, eax + mov eax, 0BACCD00Bh ; Backdoor in SimNow + mov ebx, 2 ; Select breakpoint feature + cpuid + + mov ebx,0dead0000h + mov edx,filecode + ror edx,16 + mov bx,dx + mov dx,0 +;ebx:edx = deadxxxxyyyy0000 xxxx is the filecode yyyy is the line num + mov tmpebx,ebx + mov tmpedx,edx + + xor eax,eax + mov cl,6 + + .while((cl != 0) && (si == 0)) + .if(cl <= 2) + shld eax,edx,8 + shl edx,8 + .else + shld eax,ebx,8 + shl ebx,8 + .endif + + out 80h,eax + call IdsDelay + dec cl + .if(cl == 0) + mov cl,6 + mov ebx,tmpebx + mov edx,tmpedx + .endif + .endw + + popad + xor eax,eax + ret +IdsErrorStop endp + +;/*---------------------------------------------------------------------------------------*/ +;/** +; * Stop CPU +; * +; * +; * +; */ +IDS_STOP_HERE MACRO +@@: + jmp short @b +ENDM + +;====================================================================== +; IdsExceptionHandler: Simply performs a jmp $ and IRET. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +PUBLIC _IdsExceptionHandler +PUBLIC _SizeIdtDescriptor +PUBLIC _SizeTotalIdtDescriptors + +; Size of each exception MUST be the same +Exception00: + push eax + mov al, 00h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception01: + push eax + mov al, 01h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception02: + push eax + mov al, 02h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception03: + push eax + mov al, 03h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception04: + push eax + mov al, 04h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception05: + push eax + mov al, 05h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception06: + push eax + mov al, 06h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception07: + push eax + mov al, 07h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception08: + push eax + mov al, 08h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception09: + push eax + mov al, 09h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception10: + push eax + mov al, 10h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception11: + push eax + mov al, 11h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception12: + push eax + mov al, 12h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception13: + push eax + mov al, 13h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception14: + push eax + mov al, 14h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception15: + push eax + mov al, 15h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception16: + push eax + mov al, 16h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception17: + push eax + mov al, 17h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception18: + push eax + mov al, 18h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception19: + push eax + mov al, 19h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception20: + push eax + mov al, 20h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception21: + push eax + mov al, 21h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception22: + push eax + mov al, 22h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception23: + push eax + mov al, 23h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception24: + push eax + mov al, 24h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception25: + push eax + mov al, 25h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception26: + push eax + mov al, 26 + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception27: + push eax + mov al, 27h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception28: + push eax + mov al, 28h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception29: + push eax + mov al, 29h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception30: + push eax + mov al, 30h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception31: + push eax + mov al, 31h + jmp near ptr CommonHandler +CommonHandler: + out 80h, al + pop eax + IDS_STOP_HERE + iretd + +_IdsExceptionHandler dq offset Exception00 +_SizeIdtDescriptor dd (offset Exception01 - offset Exception00) +_SizeTotalIdtDescriptors dd (offset CommonHandler - offset Exception00) + +END diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Control/IdsLib64.asm b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Control/IdsLib64.asm new file mode 100644 index 0000000000..a6a97a2680 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Control/IdsLib64.asm @@ -0,0 +1,342 @@ +;/** +; * @file +; * +; * Ids Assembly library 64bit +; * +; * +; * @xrefitem bom "File Content Label" "Release Content" +; * @e project: AGESA +; * @e sub-project: IDS +; * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ +; */ +;***************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + +.code +IdsDelay PROC + push rax + push rdx + push rbx + xor rax,rax + xor rdx,rdx + rdtsc +;set target time + add eax,1500000000 + adc edx,0 + shl rdx,32 + add rdx,rax + mov rbx,rdx +;rbx store the target +;set "Si!=0" skip below loop +__loop: + cmp si,0 + jnz __loopexit + rdtsc + shl rdx,32 + add rdx,rax + cmp rdx,rbx + jae __loopexit + jmp __loop +__loopexit: + pop rbx + pop rdx + pop rax + ret +IdsDelay ENDP +;/*++ +; +;Routine Description: +; +; IdsErrorStop -- Function for Assert +; +;Arguments: +; Filecode +; +;Returns: +; +; None +; +;--*/ +public IdsErrorStop +IdsErrorStop PROC +;As x64 calling convention RCX is used as input parameters + push rcx + push rbx + push si + push dx + push rbx + + mov si,0 ; Si is used as control flag, "Si!=0" skip postcode loop +; send debug port 1st, then fire SimNow breakpoint + mov ax, 0deadh + out 0e0h, ax + mov eax, ecx + out 84h, eax + mov eax, 0BACCD00Bh ; Backdoor in SimNow + mov ebx, 2 ; Select breakpoint feature + cpuid + + mov rax,0dead00000000h + or rcx,rax +;rcx= 0dead__FILECODE + shl rcx,16 +;rcx= 0dead__FILECODE__0000 + mov rbx,rcx + + xor rax,rax + mov dl,6 + +IdsErrorStopLoop: + cmp dl,0 + jz IdsErrorStopExit + cmp si,0 + jnz IdsErrorStopExit + + shld rax,rcx,8 + shl rcx,8 + out 80h,eax + call IdsDelay + + dec dl + cmp dl,0 + jnz _nextloop + mov dl,6 + mov rcx,rbx +_nextloop: + jmp IdsErrorStopLoop +IdsErrorStopExit: + pop rbx + pop dx + pop si + pop rbx + pop rcx + xor rax,rax + ret +IdsErrorStop endp + +;/*---------------------------------------------------------------------------------------*/ +;/** +; * Stop CPU +; * +; * +; * +; */ +IDS_STOP_HERE MACRO +@@: + jmp short @b +ENDM + +;====================================================================== +; IdsExceptionHandler: Simply performs a jmp $ and IRET. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +PUBLIC IdsExceptionHandler +PUBLIC SizeIdtDescriptor +PUBLIC SizeTotalIdtDescriptors + +; Size of each exception MUST be the same +Exception00: + push rax + mov al, 00h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception01: + push rax + mov al, 01h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception02: + push rax + mov al, 02h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception03: + push rax + mov al, 03h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception04: + push rax + mov al, 04h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception05: + push rax + mov al, 05h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception06: + push rax + mov al, 06h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception07: + push rax + mov al, 07h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception08: + push rax + mov al, 08h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception09: + push rax + mov al, 09h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception10: + push rax + mov al, 10h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception11: + push rax + mov al, 11h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception12: + push rax + mov al, 12h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception13: + push rax + mov al, 13h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception14: + push rax + mov al, 14h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception15: + push rax + mov al, 15h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception16: + push rax + mov al, 16h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception17: + push rax + mov al, 17h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception18: + push rax + mov al, 18h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception19: + push rax + mov al, 19h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception20: + push rax + mov al, 20h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception21: + push rax + mov al, 21h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception22: + push rax + mov al, 22h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception23: + push rax + mov al, 23h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception24: + push rax + mov al, 24h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception25: + push rax + mov al, 25h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception26: + push rax + mov al, 26 + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception27: + push rax + mov al, 27h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception28: + push rax + mov al, 28h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception29: + push rax + mov al, 29h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception30: + push rax + mov al, 30h + jmp near ptr CommonHandler +; Size of each exception MUST be the same +Exception31: + push rax + mov al, 31h + jmp near ptr CommonHandler +CommonHandler: + out 80h, al + pop rax + IDS_STOP_HERE + iretq + +IdsExceptionHandler dq offset Exception00 +SizeIdtDescriptor dd (offset Exception01 - offset Exception00) +SizeTotalIdtDescriptors dd (offset CommonHandler - offset Exception00) + +END + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebug.c b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebug.c new file mode 100644 index 0000000000..d75bf3e084 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebug.c @@ -0,0 +1,211 @@ +/** + * @file + * + * AMD Integrated Debug Debug_library Routines + * + * Contains AMD AGESA debug macros and library functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + /*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "IdsLib.h" +#include "amdlib.h" +#include "AMD.h" +#include "heapManager.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "IdsDebugPrint.h" +#include "IdsDpHdtout.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_IDS_DEBUG_IDSDEBUG_FILECODE + +VOID +AmdIdsDebugPrintAssert ( + IN UINT32 FileCode + ); + + +/*--------------------------------------------------------------------------------------*/ +/** + * IDS back-end code for AGESA_TESTPOINT + * + * @param[in] TestPoint Progress indicator value, see @ref AGESA_TP + * @param[in,out] StdHeader The Pointer of AGESA Header + * + **/ +/*--------------------------------------------------------------------------------------*/ +VOID +IdsAgesaTestPoint ( + IN AGESA_TP TestPoint, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + if ((TestPoint != TpIfBeforeGetIdsData) && (TestPoint != TpIfAfterGetIdsData)) { + // AmdIdsCtrlInitialize uses too much stack. Piping out TEST_POINT inside that function would corrupt stack + IDS_HDT_CONSOLE (TEST_POINT, "\n[TP:%02x]\n", TestPoint); + } + LibAmdIoWrite (AccessWidth8, IDS_DEBUG_PORT, &TestPoint, StdHeader); +} + +/** + * + * HDT out Function for Assert. + * + * fire a HDTOUT Command of assert to let hdtout script do corresponding things. + * + * @param[in,out] FileCode FileCode of the line + * + **/ +VOID +AmdIdsDebugPrintAssert ( + IN UINT32 FileCode + ) +{ +// if (AmdIdsHdtOutSupport ()) { +// IdsOutPort (HDTOUT_ASSERT, FileCode, 0); +// } +} + + +/** + * IDS Backend Function for ASSERT + * + * Halt execution with stop code display. Stop Code is displayed on port 80, with rotation so that + * it is visible on 8, 16, or 32 bit display. The stop code is alternated with 0xDEAD on the display, + * to help distinguish the stop code from a post code loop. + * Additional features may be available if using simulation. + * + * @param[in] FileCode File code(define in FILECODE.h) mix with assert Line num. + * + * @retval TRUE No error + **/ +BOOLEAN +IdsAssert ( + IN UINT32 FileCode + ) +{ + UINT32 file; + UINT32 line; + + file = (FileCode >> 16); + line = (FileCode & 0xFFFF); + IDS_HDT_CONSOLE (MAIN_FLOW, "ASSERT on File[%x] Line[%x]\n", (UINTN) file, (UINTN) line); + IDS_HDT_CONSOLE_FLUSH_BUFFER (NULL); + IDS_HDT_CONSOLE_ASSERT (FileCode); +// IdsErrorStop (FileCode); + return TRUE; +} + +/** + * IDS Backend Function for Memory timeout control + * + * This function is used to override Memory timeout control. + * + * @param[in,out] DataPtr The Pointer of UINT8. + * + **/ +VOID +IdsMemTimeOut ( + IN OUT VOID *DataPtr + ) +{ + UINTN i; + + IDS_DEBUG_PRINT **DebugPrintList; + + GetDebugPrintList ((CONST IDS_DEBUG_PRINT ***)&DebugPrintList); + + for (i = 0; DebugPrintList[i] != NULL; i++) { + if (DebugPrintList[i]->support ()) { + // Turn timeout off if any Debug service is on + *((UINT8 *)DataPtr) = (UINT8)0; + } + } +} + +/** + * + * IDS Debug Function to check the sentinels are intact + * + * This function complete heap walk and check to be performed at any time. + * + * @param[in] StdHeader Config handle for library and services. + * + * @retval TRUE No error + * + **/ +BOOLEAN +AmdHeapIntactCheck ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return TRUE; +} + +/** + * Check for CAR Corruption, the performance monitor number three programed to log the CAR Corruption. + * Check to see if control register is enabled and then check the preformance counter and stop the system by executing + * IDS_ERROR_TRAP if counter has any value other than zero. + * + * @param[in,out] StdHeader The Pointer of Standard Header. + * + * + **/ +VOID +IdsCarCorruptionCheck ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + + UINT64 Perf_Msr; + + LibAmdMsrRead (MSR_PERF_CONTROL3, (UINT64*)&Perf_Msr, StdHeader); + if ((Perf_Msr & PERF_RESERVE_BIT_MASK) == PERF_CAR_CORRUPTION_EVENT) { + LibAmdMsrRead (MSR_PERF_COUNTER3, (UINT64*)&Perf_Msr, StdHeader); + if ((Perf_Msr != 0)) { + IDS_ERROR_TRAP; + } + } +} + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.c b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.c new file mode 100644 index 0000000000..4163d828de --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.c @@ -0,0 +1,654 @@ +/** + * @file + * + * AMD Integrated Debug Print Routines + * + * Contains all functions related to IDS Debug Print + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + /*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "IdsLib.h" +#include "amdlib.h" +#include "IdsDebugPrint.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_IDS_DEBUG_IDSDEBUGPRINT_FILECODE + +// +// Also support coding convention rules for var arg macros +// +#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1)) +typedef CHAR8 *VA_LIST; +#undef VA_START +#undef VA_ARG +#undef VA_END +#define VA_START(ap, v) (ap = (VA_LIST) & (v) + _INT_SIZE_OF (v)) +#define VA_ARG(ap, t) (*(t *) ((ap += _INT_SIZE_OF (t)) - _INT_SIZE_OF (t))) +#define VA_END(ap) (ap = (VA_LIST) 0) + +#define LEFT_JUSTIFY 0x01 +#define PREFIX_SIGN 0x02 +#define PREFIX_BLANK 0x04 +#define COMMA_TYPE 0x08 +#define LONG_TYPE 0x10 +#define PREFIX_ZERO 0x20 + +#define MAX_LOCAL_BUFFER_SIZE 512 +#define BUFFER_OVERFLOW 0xFFFF + +/** + * Check If any print service is enabled. + * + * @param[in] DebugPrintList The Pointer to print service list + * + * @retval TRUE At least on print service is enabled + * @retval FALSE All print service is disabled + * + **/ +STATIC BOOLEAN +AmdIdsDebugPrintCheckSupportAll ( + IN IDS_DEBUG_PRINT **DebugPrintList + ) +{ + BOOLEAN IsSupported; + UINTN i; + IsSupported = FALSE; + for (i = 0; DebugPrintList[i] != NULL; i++) { + if (DebugPrintList[i]->support ()) { + IsSupported = TRUE; + } + } + return IsSupported; +} + +/** + * Parses flag and width information from theFormat string and returns the next index + * into the Format string that needs to be parsed. See file headed for details of Flag and Width. + * + * @param[in] Format Current location in the AvSPrint format string. + * @param[out] Flags Returns flags + * @param[out] Width Returns width of element + * @param[out] Marker Vararg list that may be partially consumed and returned. + * + * @retval Pointer indexed into the Format string for all the information parsed by this routine. + * + **/ +STATIC CHAR8 * +GetFlagsAndWidth ( + IN CHAR8 *Format, + OUT UINTN *Flags, + OUT UINTN *Width, + IN OUT VA_LIST *Marker + ) +{ + UINTN Count; + BOOLEAN Done; + + *Flags = 0; + *Width = 0; + for (Done = FALSE; !Done; ) { + Format++; + + switch (*Format) { + + case '-': + *Flags |= LEFT_JUSTIFY; + break; + case '+': + *Flags |= PREFIX_SIGN; + break; + case ' ': + *Flags |= PREFIX_BLANK; + break; + case ',': + *Flags |= COMMA_TYPE; + break; + case 'L': + case 'l': + *Flags |= LONG_TYPE; + break; + + case '*': + *Width = VA_ARG (*Marker, UINTN); + break; + + case '0': + *Flags |= PREFIX_ZERO; + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + Count = 0; + do { + Count = (Count * 10) + *Format - '0'; + Format++; + } while ((*Format >= '0') && (*Format <= '9')); + Format--; + *Width = Count; + break; + + default: + Done = TRUE; + } + } + return Format; +} + +CHAR8 STATIC HexStr[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; +extern CONST IDS_DEBUG_PRINT* ROMDATA IdsDebugPrint[]; + +/** + * + * @param[in,out] Value - Hex value to convert to a string in Buffer. + * + * + */ +VOID +GetDebugPrintList ( + IN OUT CONST IDS_DEBUG_PRINT ***pIdsDebugPrintListPtr + ) +{ + *pIdsDebugPrintListPtr = &IdsDebugPrint[0]; +} + +/** + * + * @param[in,out] Buffer Location to place ascii hex string of Value. + * @param[in] Value - Hex value to convert to a string in Buffer. + * @param[in] Flags - Flags to use in printing Hex string, see file header for details. + * @param[in] Width - Width of hex value. + * @param[in,out] BufferSize - Size of input buffer + * + * @retval Number of characters printed. + **/ + +STATIC UINTN +ValueToHexStr ( + IN OUT CHAR8 *Buffer, + IN UINT64 Value, + IN UINTN Flags, + IN UINTN Width, + IN OUT UINTN *BufferSize + ) +{ + CHAR8 TempBuffer[30]; + CHAR8 *TempStr; + CHAR8 Prefix; + CHAR8 *BufferPtr; + UINTN Count; + UINTN Index; + + TempStr = TempBuffer; + BufferPtr = Buffer; + // + // Count starts at one since we will null terminate. Each iteration of the + // loop picks off one nibble. Oh yea TempStr ends up backwards + // + Count = 0; + do { + *(TempStr++) = HexStr[Value & 0x0f]; + Value >>= 4; + Count++; + } while (Value != 0); + + if (Flags & PREFIX_ZERO) { + Prefix = '0'; + } else if (!(Flags & LEFT_JUSTIFY)) { + Prefix = ' '; + } else { + Prefix = 0x00; + } + for (Index = Count; Index < Width; Index++) { + *(TempStr++) = Prefix; + } + + // + // Reverse temp string into Buffer. + // + while (TempStr != TempBuffer) { + (*BufferSize)--; + if (*BufferSize == 0) { + return BUFFER_OVERFLOW; + } + *(BufferPtr++) = *(--TempStr); + } + + *BufferPtr = 0; + return Index; +} + +/** + * Prints a Value as a decimal number in Buffer + * + * @param[in] Buffer Location to place ascii decimal number string of Value. + * @param[in] Value Decimal value to convert to a string in Buffer. + * @param[in] Flags Flags to use in printing decimal string, see file header for details. + * @param[in,out] BufferSize Size of input buffer + * + * @retval Number of characters printed. + * +**/ + +STATIC UINTN +ValueToString ( + IN OUT CHAR8 *Buffer, + IN INT32 Value, + IN UINTN Flags, + IN OUT UINTN *BufferSize + ) +{ + CHAR8 TempBuffer[30]; + CHAR8 *TempStr; + CHAR8 *BufferPtr; + UINTN Count; + UINTN Remainder; + + ASSERT (*BufferSize); + TempStr = TempBuffer; + BufferPtr = Buffer; + Count = 0; + + if (Value < 0) { + (*BufferSize)--; + if (*BufferSize == 0) { + return BUFFER_OVERFLOW; + } + *(BufferPtr++) = '-'; + Value = - Value; + Count++; + } + + do { + Remainder = Value % 10; + Value /= 10; + *(TempStr++) = (CHAR8)(Remainder + '0'); + Count++; + if ((Flags & COMMA_TYPE) == COMMA_TYPE) { + if (Count % 3 == 0) { + *(TempStr++) = ','; + } + } + } while (Value != 0); + + // + // Reverse temp string into Buffer. + // + while (TempStr != TempBuffer) { + (*BufferSize)--; + if (*BufferSize == 0) { + return BUFFER_OVERFLOW; + } + *(BufferPtr++) = *(--TempStr); + } + + *BufferPtr = 0; + return Count; +} + +/** + * Worker function for print string to buffer + * + * @param[in] Flag - filter flag + * @param[in] *Format - format string + * @param[in] Marker - Variable parameter + * @param[in] Buffer - Point to input buffer + * @param[in] BufferSize - Buffer size + * @param[out] OutputStringLen - output string length, include '\0' at the end + * + * @retval IDS_DEBUG_PRINT_SUCCESS succeed + * @retval IDS_DEBUG_PRINT_BUFFER_OVERFLOW input buffer overflow +**/ +STATIC IDS_DEBUG_PRINT_STATUS +AmdIdsDebugPrintWorker ( + IN CHAR8 *Format, + IN VA_LIST Marker, + IN CHAR8 *Buffer, + IN UINTN BufferSize, + OUT UINTN *OutputStringLen + ) +{ + UINTN Index; + UINTN Length; + UINTN Flags; + UINTN Width; + UINT64 Value; + CHAR8 *AsciiStr; + + //Init the default Value + Index = 0; + // + // Process format string + // + for (; (*Format != '\0') && (BufferSize > 0); Format++) { + if (*Format != '%') { + Buffer[Index++] = *Format; + BufferSize--; + } else { + Format = GetFlagsAndWidth (Format, &Flags, &Width, &Marker); + switch (*Format) { + case 'X': + Flags |= PREFIX_ZERO; + Width = sizeof (UINT64) * 2; + // + // break skipped on purpose + // + case 'x': + if ((Flags & LONG_TYPE) == LONG_TYPE) { + Value = VA_ARG (Marker, UINT64); + } else { + Value = VA_ARG (Marker, UINTN); + } + Length = ValueToHexStr (&Buffer[Index], Value, Flags, Width, &BufferSize); + if (Length != BUFFER_OVERFLOW) { + Index += Length; + } else { + return IDS_DEBUG_PRINT_BUFFER_OVERFLOW; + } + break; + + case 'd': + Value = (UINTN)VA_ARG (Marker, UINT32); + Length = ValueToString (&Buffer[Index], (UINT32)Value, Flags, &BufferSize); + if (Length != BUFFER_OVERFLOW) { + Index += Length; + } else { + return IDS_DEBUG_PRINT_BUFFER_OVERFLOW; + } + + break; + + case 's': + case 'S': + AsciiStr = (CHAR8 *)VA_ARG (Marker, CHAR8 *); + while (*AsciiStr != '\0') { + BufferSize--; + if (BufferSize == 0) { + return IDS_DEBUG_PRINT_BUFFER_OVERFLOW; + } + Buffer[Index++] = *AsciiStr++; + } + break; + + case 'c': + BufferSize--; + if (BufferSize == 0) { + return IDS_DEBUG_PRINT_BUFFER_OVERFLOW; + } + Buffer[Index++] = (CHAR8)VA_ARG (Marker, UINTN); + break; + + case 'v': + ASSERT (FALSE); // %v is no longer supported + break; + + case '%': + BufferSize--; + if (BufferSize == 0) { + return IDS_DEBUG_PRINT_BUFFER_OVERFLOW; + } + Buffer[Index++] = *Format; + break; + + default: + // + // if the type is unknown print it to the screen + // + BufferSize--; + if (BufferSize == 0) { + return IDS_DEBUG_PRINT_BUFFER_OVERFLOW; + } + Buffer[Index++] = '%'; + + BufferSize--; + if (BufferSize == 0) { + return IDS_DEBUG_PRINT_BUFFER_OVERFLOW; + } + Buffer[Index++] = *Format; + break; + } + } + } + if (BufferSize == 0) { + return IDS_DEBUG_PRINT_BUFFER_OVERFLOW; + } + //Mark the end of word + Buffer[Index] = 0; + *OutputStringLen = Index; + return IDS_DEBUG_PRINT_SUCCESS; +} + + +/** + * Insert Overflow warning to the tail of output + * + * @param[in] Buffer - Point to input buffer + * @param[in] BufferSize - Buffer size + * +**/ +STATIC VOID +InsertOverflowWarningMessage ( + IN CHAR8 *Buffer, + IN UINTN BufferSize + ) +{ + CHAR8 *Destination; + CHAR8 WarningString[] = "\n#BUFFER OVERFLOW#\n"; + AMD_CONFIG_PARAMS StdHeader; + + Destination = Buffer + BufferSize - sizeof (WarningString); + LibAmdMemCopy (Destination, WarningString, sizeof (WarningString), &StdHeader); +} + +/** + * Process debug string + * + * @param[in] Flag - filter flag + * @param[in] *Format - format string + * @param[in] Marker - Variable parameter + * +**/ +STATIC VOID +AmdIdsDebugPrintProcess ( + IN UINT64 Flag, + IN CHAR8 *Format, + IN VA_LIST Marker + ) +{ + UINT64 Filter; + CHAR8 LocalBuffer[MAX_LOCAL_BUFFER_SIZE]; + UINTN OutPutStringLen; + IDS_DEBUG_PRINT **DebugPrintList; + IDS_DEBUG_PRINT_PRIVATE_DATA debugPrintPrivate; + UINT8 i; + + + GetDebugPrintList ((CONST IDS_DEBUG_PRINT ***)&DebugPrintList); + if (AmdIdsDebugPrintCheckSupportAll (DebugPrintList)) { + if (AmdIdsDebugPrintWorker (Format, Marker, &LocalBuffer[0], sizeof (LocalBuffer), &OutPutStringLen) == IDS_DEBUG_PRINT_BUFFER_OVERFLOW) { + InsertOverflowWarningMessage (&LocalBuffer[0], sizeof (LocalBuffer)); + OutPutStringLen = sizeof (LocalBuffer); + } + + //init input + debugPrintPrivate.saveContext = FALSE; + + for (i = 0; DebugPrintList[i] != NULL; i++) { + if (DebugPrintList[i]->support ()) { + Filter = IDS_DEBUG_PRINT_MASK; + //Get Customize filter (Option) + DebugPrintList[i]->customfilter (&Filter); + if (Flag & Filter) { + //Init Private Date (Option) + DebugPrintList[i]->InitPrivateData (Flag, &debugPrintPrivate); + //Print Physical Layer + DebugPrintList[i]->print (&LocalBuffer[0], OutPutStringLen, &debugPrintPrivate); + } + } + } + } +} + +/** + * Prints string to debug host like printf in C + * + * @param[in] Flag - filter flag + * @param[in] *Format - format string + * @param[in] ... Variable parameter + * +**/ +VOID +AmdIdsDebugPrint ( + IN UINT64 Flag, + IN CONST CHAR8 *Format, + IN ... + ) +{ + VA_LIST Marker; + VA_START (Marker, Format); //init marker to 1st dynamic parameters. + AmdIdsDebugPrintProcess (Flag, (CHAR8 *)Format, Marker); + VA_END (Marker); +} + +/** + * Prints memory debug strings + * + * @param[in] *Format - format string + * @param[in] ... Variable parameter + * +**/ +VOID +AmdIdsDebugPrintMem ( + IN CHAR8 *Format, + IN ... + ) +{ + VA_LIST Marker; + VA_START (Marker, Format); //init marker to 1st dynamic parameters. + AmdIdsDebugPrintProcess (MEM_FLOW, Format, Marker); + VA_END (Marker); +} + +/** + * Prints CPU debug strings + * + * @param[in] *Format - format string + * @param[in] ... Variable parameter + * +**/ +VOID +AmdIdsDebugPrintCpu ( + IN CHAR8 *Format, + IN ... + ) +{ + VA_LIST Marker; + VA_START (Marker, Format); //init marker to 1st dynamic parameters. + AmdIdsDebugPrintProcess (CPU_TRACE, Format, Marker); + VA_END (Marker); +} + + +/** + * Prints HT debug strings + * + * @param[in] *Format - format string + * @param[in] ... Variable parameter + * +**/ +VOID +AmdIdsDebugPrintHt ( + IN CHAR8 *Format, + IN ... + ) +{ + VA_LIST Marker; + VA_START (Marker, Format); //init marker to 1st dynamic parameters. + AmdIdsDebugPrintProcess (HT_TRACE, Format, Marker); + VA_END (Marker); +} + + +/** + * Prints GNB debug strings + * + * @param[in] *Format - format string + * @param[in] ... Variable parameter + * +**/ +VOID +AmdIdsDebugPrintGnb ( + IN CHAR8 *Format, + IN ... + ) +{ + VA_LIST Marker; + VA_START (Marker, Format); //init marker to 1st dynamic parameters. + AmdIdsDebugPrintProcess (GNB_TRACE, Format, Marker); + VA_END (Marker); +} + +/** + * Prints debug strings in any condition + * + * @param[in] *Format - format string + * @param[in] ... Variable parameter + * +**/ +VOID +AmdIdsDebugPrintAll ( + IN CHAR8 *Format, + IN ... + ) +{ + VA_LIST Marker; + VA_START (Marker, Format); //init marker to 1st dynamic parameters. + AmdIdsDebugPrintProcess (TRACE_MASK_ALL, Format, Marker); + VA_END (Marker); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.h b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.h new file mode 100644 index 0000000000..fc1ac8dbcd --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDebugPrint.h @@ -0,0 +1,80 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Integrated Debug Print Routines + * + * Contains all functions related to IDS Debug Print + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#ifndef _IDS_DEBUGPRINT_H_ +#define _IDS_DEBUGPRINT_H_ + +///Debug String End flag +#define DEBUG_STRING_END_FLAG (0x0) +/// return status for debug print +typedef enum { + IDS_DEBUG_PRINT_SUCCESS = 0, ///< success + IDS_DEBUG_PRINT_BUFFER_OVERFLOW, ///< Bufer overflow +} IDS_DEBUG_PRINT_STATUS; + +/// Private datas for debug print +typedef struct _IDS_DEBUG_PRINT_PRIVATE_DATA { + BOOLEAN saveContext; /// save context +} IDS_DEBUG_PRINT_PRIVATE_DATA; + +typedef BOOLEAN (*PF_IDS_DEBUG_PRINT_SUPPORT) (VOID); +typedef BOOLEAN (*PF_IDS_DEBUG_PRINT_FILTER) (UINT64 *Filter); +typedef VOID (*PF_IDS_DEBUG_PRINT_PRINT) (CHAR8 *Buffer, UINTN BufferSize, IDS_DEBUG_PRINT_PRIVATE_DATA *debugPrintPrivate); +typedef VOID (*PF_IDS_DEBUG_INIT_PRIVATE_DATA) (UINT64 flag, IDS_DEBUG_PRINT_PRIVATE_DATA *debugPrintPrivate); + +/// Debug print Hw layer service class +typedef struct _IDS_DEBUG_PRINT { + PF_IDS_DEBUG_PRINT_SUPPORT support; ///Check if support + PF_IDS_DEBUG_PRINT_FILTER customfilter; ///Get if any customize filters + PF_IDS_DEBUG_INIT_PRIVATE_DATA InitPrivateData; ///Init private data + PF_IDS_DEBUG_PRINT_PRINT print; ///Print data to Hw layer +} IDS_DEBUG_PRINT; + + +VOID +GetDebugPrintList ( + IN OUT CONST IDS_DEBUG_PRINT ***pIdsDebugPrintListPtr + ); + + +#endif //_IDS_DEBUGPRINT_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.c b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.c new file mode 100644 index 0000000000..bde0514528 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.c @@ -0,0 +1,755 @@ +/** + * @file + * + * AMD Integrated Debug Debug_library Routines + * + * Contains all functions related to HDTOUT + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + /*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "IdsLib.h" +#include "amdlib.h" +#include "AMD.h" +#include "heapManager.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "IdsDebugPrint.h" +#include "IdsDpHdtout.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_IDS_DEBUG_IDSDPHDTOUT_FILECODE + +/** + * Check if String contain the substring + * + * @param[in] String Pointer of string. + * @param[in] Substr Pointer of sub string. + * + * @retval TRUE S2 is substring of S1 + * @retval FALSE S2 isn't substring of S1 + * +**/ +STATIC BOOLEAN +AmdIdsSubStr ( + IN CHAR8 *String, + IN CHAR8 *Substr + ) +{ + UINT16 i; + UINT16 j; + + for (i = 0; String[i] != 0 ; i++) { + for (j = 0; (Substr[j] != 0) && (Substr[j] == String[i + j]); j++) { + } + if (Substr[j] == 0) { + return TRUE; + } + } + + return FALSE; +} + +/** + * Determine whether IDS console is enabled. + * + * @param[in,out] pHdtoutHeader Address of hdtout header pointer + * @param[in,out] StdHeader The Pointer of AGESA Header + * + * @retval TRUE pHdtoutHeader Non zero + * @retval FALSE pHdtoutHeader is NULL + * + **/ +STATIC BOOLEAN +AmdIdsHdtoutGetHeader ( + IN OUT HDTOUT_HEADER **pHdtoutHeaderPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Dr3Reg; + HDTOUT_HEADER *HdtoutHeaderPtr; + LibAmdReadCpuReg (DR3_REG, &Dr3Reg); + HdtoutHeaderPtr = (HDTOUT_HEADER *) (UINTN) Dr3Reg; + if ((HdtoutHeaderPtr != NULL) && (HdtoutHeaderPtr->Signature == HDTOUT_HEADER_SIGNATURE)) { + *pHdtoutHeaderPtr = HdtoutHeaderPtr; + return TRUE; + } else { + return FALSE; + } +} +/** + * Determine whether IDS console is enabled. + * + * @param[in,out] IdsConsole The Pointer of Ids console data + * + * @retval TRUE Ids console is enabled. + * @retval FALSE Ids console is disabled. + * + **/ +BOOLEAN +AmdIdsHdtOutSupport ( + VOID + ) +{ + BOOLEAN Result; + UINT32 DR2reg; + + Result = FALSE; + + LibAmdReadCpuReg (DR2_REG, &DR2reg); + if (DR2reg == 0x99CC) { + Result = TRUE; + } + + return Result; +} + +/** + * Get HDTOUT customize Filter + * + * @param[in,out] Filter Filter do be filled + * + * @retval TRUE Alway return true, for HDTOUT has its own filter mechanism + * + **/ +STATIC BOOLEAN +AmdIdsHdtOutGetFilter ( + IN OUT UINT64 *Filter + ) +{ + HDTOUT_HEADER *HdtoutHeaderPtr; + + if (AmdIdsHdtoutGetHeader (&HdtoutHeaderPtr, NULL) == TRUE) { + *Filter = HdtoutHeaderPtr->ConsoleFilter; + } + return TRUE; +} + +/** + * + * Initial register setting used for HDT out Function. + * + * + * @param[in,out] StdHeader The Pointer of AGESA Header + * + **/ +STATIC VOID +AmdIdsHdtOutRegisterRestore ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CR4reg; + UINT64 SMsr; + + LibAmdMsrRead (0xC001100A, (UINT64 *)&SMsr, StdHeader); + SMsr &= ~BIT0; + LibAmdMsrWrite (0xC001100A, (UINT64 *)&SMsr, StdHeader); + + LibAmdWriteCpuReg (DR2_REG, 0); + LibAmdWriteCpuReg (DR3_REG, 0); + LibAmdWriteCpuReg (DR7_REG, 0); + + LibAmdReadCpuReg (CR4_REG, &CR4reg); + LibAmdWriteCpuReg (CR4_REG, CR4reg & (~BIT3)); + +} + +/** + * + * Restore register setting used for HDT out Function. + * + * + * @param[in,out] StdHeader The Pointer of AGESA Header + * + **/ +STATIC VOID +AmdIdsHdtOutRegisterInit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CR4reg; + UINT64 SMsr; + + LibAmdMsrRead (0xC001100A, (UINT64 *)&SMsr, StdHeader); + SMsr |= 1; + LibAmdMsrWrite (0xC001100A, (UINT64 *)&SMsr, StdHeader); + + LibAmdWriteCpuReg (DR2_REG, 0x99CC); + + LibAmdWriteCpuReg (DR7_REG, 0x02000420); + + LibAmdReadCpuReg (CR4_REG, &CR4reg); + LibAmdWriteCpuReg (CR4_REG, CR4reg | ((UINT32)1 << 3)); +} + +/** + * + * Initial function for HDT out Function. + * + * Init required Debug register & heap, and will also fire a HDTOUT + * Command to let hdtout script do corresponding things. + * + * @param[in,out] StdHeader The Pointer of AGESA Header + * + **/ +VOID +AmdIdsHdtOutInit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + ALLOCATE_HEAP_PARAMS AllocHeapParams; + HDTOUT_HEADER HdtoutHeader; + UINT8 Persist; + AGESA_STATUS IgnoreSts; + HDTOUT_HEADER *pHdtoutHeader; + + IDS_FUNCLIST_EXTERN (); + if (AmdIdsHdtOutSupport ()) { + AmdIdsHdtOutRegisterInit (StdHeader); + // Initialize HDTOUT Header + HdtoutHeader.Signature = HDTOUT_HEADER_SIGNATURE; + HdtoutHeader.Version = HDTOUT_VERSION; + HdtoutHeader.BufferSize = HDTOUT_DEFAULT_BUFFER_SIZE; + HdtoutHeader.DataIndex = 0; + HdtoutHeader.PrintCtrl = HDTOUT_PRINTCTRL_ON; + HdtoutHeader.NumBreakpointUnit = 0; + HdtoutHeader.FuncListAddr = (UINT32) IDS_FUNCLIST_ADDR; + HdtoutHeader.StatusStr[0] = 0; + HdtoutHeader.OutBufferMode = HDTOUT_BUFFER_MODE_ON; + HdtoutHeader.EnableMask = 0; + HdtoutHeader.ConsoleFilter = IDS_DEBUG_PRINT_MASK; + + // Trigger HDTOUT breakpoint to get inputs from script + IdsOutPort (HDTOUT_INIT, (UINT32) &HdtoutHeader, 0); + // Disable AP HDTOUT if set BspOnlyFlag + if (HdtoutHeader.BspOnlyFlag == HDTOUT_BSP_ONLY) { + if (!IsBsp (StdHeader, &IgnoreSts)) { + AmdIdsHdtOutRegisterRestore (StdHeader); + return; + } + } + // Convert legacy EnableMask to new ConsoleFilter + HdtoutHeader.ConsoleFilter |= HdtoutHeader.EnableMask; + + // Disable the buffer if the size is not large enough + if (HdtoutHeader.BufferSize < 128) { + HdtoutHeader.BufferSize = 0; + HdtoutHeader.OutBufferMode = HDTOUT_BUFFER_MODE_OFF; + } else { + HdtoutHeader.OutBufferMode = HDTOUT_BUFFER_MODE_ON; + } + + // Check if Hdtout header have been initialed, if so it must 2nd time come here + if (AmdIdsHdtoutGetHeader (&pHdtoutHeader, StdHeader)) { + Persist = HEAP_SYSTEM_MEM; + } else { + Persist = HEAP_LOCAL_CACHE; + } + + // Allocate heap + do { + AllocHeapParams.RequestedBufferSize = HdtoutHeader.BufferSize + sizeof (HdtoutHeader) - 2; + AllocHeapParams.BufferHandle = IDS_HDT_OUT_BUFFER_HANDLE; + AllocHeapParams.Persist = Persist; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + break; + } else { + IdsOutPort (HDTOUT_ERROR, HDTOUT_ERROR_HEAP_ALLOCATION, AllocHeapParams.RequestedBufferSize); + HdtoutHeader.BufferSize -= 256; + } + } while ((HdtoutHeader.BufferSize & 0x8000) == 0); + // If the buffer have been successfully allocated? + if ((HdtoutHeader.BufferSize & 0x8000) == 0) { + LibAmdWriteCpuReg (DR3_REG, (UINT32) AllocHeapParams.BufferPtr); + LibAmdMemCopy (AllocHeapParams.BufferPtr, &HdtoutHeader, sizeof (HdtoutHeader) - 2, StdHeader); + } else { + /// Clear DR3_REG + IdsOutPort ((UINT32)HDTOUT_ERROR, (UINT32)HDTOUT_ERROR_HEAP_AllOCATE_FAIL, (UINT32)IDS_DEBUG_PRINT_MASK); + LibAmdWriteCpuReg (DR3_REG, 0); + } + } +} + +/** + * + * Flush all HDTOUT buffer data before HOB transfer + * + * @param[in,out] StdHeader The Pointer of AGESA Header + * + **/ +VOID +AmdIdsHdtOutBufferFlush ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + HDTOUT_HEADER *HdtoutHeaderPtr ; + + if (AmdIdsHdtOutSupport ()) { + if (AmdIdsHdtoutGetHeader (&HdtoutHeaderPtr, StdHeader)) { + if ((HdtoutHeaderPtr->PrintCtrl == HDTOUT_PRINTCTRL_ON) && + (HdtoutHeaderPtr->OutBufferMode == HDTOUT_BUFFER_MODE_ON)) { + IdsOutPort (HDTOUT_PRINT, (UINT32) HdtoutHeaderPtr->Data, HdtoutHeaderPtr->DataIndex); + HdtoutHeaderPtr->DataIndex = 0; + } + } + } +} + +/** + * Exit function for HDT out Function for each cores + * + * @param[in] Ignored no used + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * + * @retval AGESA_SUCCESS Success + * @retval AGESA_ERROR meet some error + * + **/ +STATIC AGESA_STATUS +AmdIdsHdtOutExitCoreTask ( + IN VOID *Ignored, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + HDTOUT_HEADER *HdtoutHeaderPtr; + + if (AmdIdsHdtoutGetHeader (&HdtoutHeaderPtr, StdHeader)) { + if ((HdtoutHeaderPtr->PrintCtrl == HDTOUT_PRINTCTRL_ON) && + (HdtoutHeaderPtr->OutBufferMode == HDTOUT_BUFFER_MODE_ON)) { + IdsOutPort (HDTOUT_PRINT, (UINT32) HdtoutHeaderPtr->Data, HdtoutHeaderPtr->DataIndex); + } + } + IdsOutPort (HDTOUT_EXIT, (UINT32) HdtoutHeaderPtr, 0); + + AmdIdsHdtOutRegisterRestore (StdHeader); + + return AGESA_SUCCESS; +} +/** + * + * Exit function for HDT out Function. + * + * Restore debug register and Deallocate heap, and will also fire a HDTOUT + * Command to let hdtout script do corresponding things. + * + * @param[in,out] StdHeader The Pointer of AGESA Header + * + **/ +VOID +AmdIdsHdtOutExit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + IDSAPLATETASK IdsApLateTask; + if (AmdIdsHdtOutSupport ()) { + IdsApLateTask.ApTask = (PF_IDS_AP_TASK) AmdIdsHdtOutExitCoreTask; + IdsApLateTask.ApTaskPara = NULL; + IdsAgesaRunFcnOnAllCoresLate (&IdsApLateTask, StdHeader); + HeapDeallocateBuffer (IDS_HDT_OUT_BUFFER_HANDLE, StdHeader); + } +} + +/** + * + * Exit function for HDT out Function of S3 Resume + * + * Restore debug register and Deallocate heap, and will also fire a HDTOUT + * Command to let hdtout script do corresponding things. + * + * @param[in,out] StdHeader The Pointer of AGESA Header + * + **/ +VOID +AmdIdsHdtOutS3Exit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS AgesaStatus; + + if (AmdIdsHdtOutSupport ()) { + //Ap debug print exit have been done at the end of AmdInitResume, so we only BSP at here + AmdIdsHdtOutExitCoreTask (NULL, StdHeader); + if (IsBsp (StdHeader, &AgesaStatus)) { + HeapDeallocateBuffer (IDS_HDT_OUT_BUFFER_HANDLE, StdHeader); + } + } +} +/** + * + * Exit function for HDT out Function of S3 Resume + * + * Restore debug register and Deallocate heap, and will also fire a HDTOUT + * Command to let hdtout script do corresponding things. + * + * @param[in,out] StdHeader The Pointer of AGESA Header + * + **/ +VOID +AmdIdsHdtOutS3ApExit ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + UINT32 Ignored; + UINT32 BscSocket; + UINT32 BscCoreNum; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + AGESA_STATUS IgnoredSts; + + if (AmdIdsHdtOutSupport ()) { + // run code on all APs except BSP + TaskPtr.FuncAddress.PfApTaskI = (PF_AP_TASK_I)AmdIdsHdtOutExitCoreTask; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.DataTransfer.DataPtr = NULL; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + + NumberOfSockets = GetPlatformNumberOfSockets (); + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredSts); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCoreNum)) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); + } + } + } + } + } + } +} + +/** + * Print formated string with accerate buffer + * Flow out only when buffer will full + * + * @param[in] Buffer - Point to input buffer + * @param[in] BufferSize - Buffer size + * @param[in] HdtoutHeaderPtr - Point to Hdtout Header + * +**/ +STATIC VOID +AmdIdsHdtOutPrintWithBuffer ( + IN CHAR8 *Buffer, + IN UINTN BufferSize, + IN HDTOUT_HEADER *HdtoutHeaderPtr + ) +{ + if ((HdtoutHeaderPtr == NULL) || (Buffer == NULL)) { + ASSERT (FALSE); + return; + } + + while (BufferSize--) { + if (HdtoutHeaderPtr->DataIndex >= HdtoutHeaderPtr->BufferSize) { + //Flow out current buffer, and clear the index + IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) &HdtoutHeaderPtr->Data[0], HdtoutHeaderPtr->BufferSize); + HdtoutHeaderPtr->DataIndex = 0; + } + HdtoutHeaderPtr->Data[HdtoutHeaderPtr->DataIndex++] = *(Buffer++); + } +} +/** + * Save HDTOUT context, use for break point function + * + * @param[in] Buffer - Point to input buffer + * @param[in] BufferSize - Buffer size + * @param[in] HdtoutHeaderPtr - Point to Hdtout Header + * +**/ +STATIC VOID +AmdIdsHdtOutSaveContext ( + IN CHAR8 *Buffer, + IN UINTN BufferSize, + IN HDTOUT_HEADER *HdtoutHeaderPtr + ) +{ + UINTN i; + UINTN j; + UINTN ArrayIndex; + UINTN unusedPrefix; + UINTN ArrayLength; + BOOLEAN SaveStatus; + + ArrayLength = 0; + + // Look for the start of the first ASCII + for (i = 0; i < BufferSize - 1; i++) { + if ((Buffer[i] > 32) && (Buffer[i] < 127)) { + break; + } + } + + unusedPrefix = i; + //ASSERT if no "\n" in status string + ASSERT (AmdIdsSubStr (&Buffer[i], (CHAR8 *)"\n")); + + if (i < (BufferSize - 1)) { + // Match the first word in StatusStr + SaveStatus = FALSE; + for (j = 0; !SaveStatus && (HdtoutHeaderPtr->StatusStr[j] != 0); j++) { + for (; (Buffer[i] == HdtoutHeaderPtr->StatusStr[j]) && (i < BufferSize); i++, j++) { + ArrayLength++; + if (Buffer[i] == ' ') { + ArrayIndex = j; + for (; HdtoutHeaderPtr->StatusStr[j] != '\n'; j++) { + ArrayLength++; + } + // Remove old entry if it's size does not fit + if (ArrayLength != ((UINT32) BufferSize - unusedPrefix)) { + for (++j; HdtoutHeaderPtr->StatusStr[j] != 0; j++) { + HdtoutHeaderPtr->StatusStr[j - ArrayLength] = HdtoutHeaderPtr->StatusStr[j]; + } + j = j - ArrayLength - 1; + i = unusedPrefix; + // Mark the end of string + HdtoutHeaderPtr->StatusStr[j + BufferSize - unusedPrefix + 1] = 0; + } else { + j = ArrayIndex - 1; + } + + // Word match, exit for saving + SaveStatus = TRUE; + break; + } + } + } + + // Copy string to StatusStr + if ((HdtoutHeaderPtr->StatusStr[j] == 0) || SaveStatus) { + for (; i < BufferSize; j++, i++) { + HdtoutHeaderPtr->StatusStr[j] = Buffer[i]; + } + } + + if (!SaveStatus) { + // Mark the end of string if not done so + HdtoutHeaderPtr->StatusStr[j] = 0; + } + } +} + +STATIC BOOLEAN +AmdIdsHdtOutBreakPointUnit ( + IN OUT BREAKPOINT_UNIT **pBpunitptr, + IN OUT UINT32 *numBp, + IN HDTOUT_HEADER *HdtoutHeaderPtr, + IN CHAR8 *Buffer + ) +{ + BOOLEAN isMatched; + CHAR8 *PCmpStr; + CHAR8 *Pbpstr; + BREAKPOINT_UNIT *pBpunit; + + pBpunit = *pBpunitptr; + if ((pBpunit == NULL) || + (numBp == NULL) || + (HdtoutHeaderPtr == NULL) || + (*numBp == 0)) { + ASSERT (FALSE); + return FALSE; + } + //Get to be compared string + if (pBpunit->BpFlag == IDS_HDTOUT_BPFLAG_FORMAT_STR) { + PCmpStr = Buffer; + } else { + PCmpStr = HdtoutHeaderPtr->StatusStr; + } + //Get BreakPoint string + Pbpstr = HdtoutHeaderPtr->BreakpointList + pBpunit->BpStrOffset; + isMatched = AmdIdsSubStr (PCmpStr, Pbpstr); + //Point to next one, and decrease the numbp + *pBpunitptr = ++pBpunit; + (*numBp)--; + return isMatched; +} +/** + * Process HDTOUT breakpoint + * + * @param[in] Buffer - Point to input buffer + * @param[in] BufferSize - Buffer size + * @param[in] HdtoutHeaderPtr - Point to Hdtout Header + * +**/ +STATIC VOID +AmdIdsHdtOutBreakPoint ( + IN CHAR8 *Buffer, + IN UINTN BufferSize, + IN HDTOUT_HEADER *HdtoutHeaderPtr + ) +{ + UINT32 numBp; + BREAKPOINT_UNIT *Pbpunit; + BOOLEAN isMatched; + UINT32 i; + Pbpunit = (BREAKPOINT_UNIT *) &HdtoutHeaderPtr->BreakpointList[0]; + numBp = HdtoutHeaderPtr->NumBreakpointUnit; + + for (;;) { + if (Pbpunit->AndFlag == IDS_HDTOUT_BP_AND_ON) { + isMatched = TRUE; + do { + isMatched &= AmdIdsHdtOutBreakPointUnit (&Pbpunit, &numBp, HdtoutHeaderPtr, Buffer); + } while ((Pbpunit->AndFlag == IDS_HDTOUT_BP_AND_ON) && + (isMatched == TRUE) && + (numBp > 0)); + //Next one is IDS_HDTOUT_BP_AND_OFF + if (numBp > 0) { + if (isMatched == TRUE) { + isMatched &= AmdIdsHdtOutBreakPointUnit (&Pbpunit, &numBp, HdtoutHeaderPtr, Buffer); + } else { + Pbpunit++; + numBp--; + } + } + } else { + isMatched = AmdIdsHdtOutBreakPointUnit (&Pbpunit, &numBp, HdtoutHeaderPtr, Buffer); + } + if ((isMatched == TRUE) || (numBp == 0)) { + break; + } + } + //Do action + if (isMatched) { +// AmdIdsSerialPrint (Buffer, BufferSize, NULL); + Pbpunit--; + switch (Pbpunit->Action) { + case HDTOUT_BP_ACTION_HALT: + i = (UINT32) (Pbpunit - ((BREAKPOINT_UNIT *) &HdtoutHeaderPtr->BreakpointList[0])); + IdsOutPort (HDTOUT_BREAKPOINT, (UINT32) (UINTN) Buffer, ( i << 16) | (UINT32) BufferSize); + break; + case HDTOUT_BP_ACTION_PRINTON: + if (HdtoutHeaderPtr->PrintCtrl != 1) { + HdtoutHeaderPtr->PrintCtrl = 1; + if (HdtoutHeaderPtr->OutBufferMode == HDTOUT_BUFFER_MODE_ON) { + AmdIdsHdtOutPrintWithBuffer (Buffer, BufferSize, HdtoutHeaderPtr); + } else { + IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) Buffer, (UINT32) BufferSize); + } + } + break; + case HDTOUT_BP_ACTION_PRINTOFF: + if (HdtoutHeaderPtr->PrintCtrl != 0) { + HdtoutHeaderPtr->PrintCtrl = 0; + IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) Buffer, (UINT32)BufferSize); + } + break; + default: + ASSERT (FALSE); + } + } +} + + +/** + * Print formated string to HDTOUT + * + * @param[in] Buffer - Point to input buffer + * @param[in] BufferSize - Buffer size + * @param[in] debugPrintPrivate - Option + * +**/ +STATIC VOID +AmdIdsHdtOutPrint ( + IN CHAR8 *Buffer, + IN UINTN BufferSize, + IN IDS_DEBUG_PRINT_PRIVATE_DATA *debugPrintPrivate + ) +{ + HDTOUT_HEADER *HdtoutHeaderPtr; + if (AmdIdsHdtoutGetHeader (&HdtoutHeaderPtr, NULL)) { + //Print Function + if (HdtoutHeaderPtr->PrintCtrl == HDTOUT_PRINTCTRL_ON) { + if (HdtoutHeaderPtr->OutBufferMode == HDTOUT_BUFFER_MODE_ON) { + AmdIdsHdtOutPrintWithBuffer (Buffer, BufferSize, HdtoutHeaderPtr); + } else { + IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) Buffer, (UINT32) BufferSize); + } + } + //Check BreakPoint + if (HdtoutHeaderPtr->NumBreakpointUnit) { + AmdIdsHdtOutBreakPoint (Buffer, BufferSize, HdtoutHeaderPtr); + if (debugPrintPrivate->saveContext) { + AmdIdsHdtOutSaveContext (Buffer, BufferSize, HdtoutHeaderPtr); + debugPrintPrivate->saveContext = FALSE; + } + } + } else { + //No HDTOUT header found print directly without buffer + IdsOutPort (HDTOUT_PRINT, (UINT32) (UINTN) Buffer, (UINT32) BufferSize); + } +} + +/** + * Init local private data for HDTOUT + * + * @param[in] Flag - filter flag + * @param[in] debugPrintPrivate - Point to debugPrintPrivate + * +**/ +STATIC VOID +AmdIdsHdtOutInitPrivateData ( + IN UINT64 Flag, + IN IDS_DEBUG_PRINT_PRIVATE_DATA *debugPrintPrivate + ) +{ + if (Flag == MEM_STATUS) { + debugPrintPrivate->saveContext = TRUE; + } +} + +CONST IDS_DEBUG_PRINT ROMDATA IdsDebugPrintHdtoutInstance = +{ + AmdIdsHdtOutSupport, + AmdIdsHdtOutGetFilter, + AmdIdsHdtOutInitPrivateData, + AmdIdsHdtOutPrint +}; + + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.h b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.h new file mode 100644 index 0000000000..ff41fb5e87 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpHdtout.h @@ -0,0 +1,119 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Integrated Debug Debug_library Routines + * + * Contains all functions related to HDTOUT + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#ifndef _IDS_HDTOUT_H_ +#define _IDS_HDTOUT_H_ + +#define HDTOUT_VERSION 0x0200 + +/// HDTOUT command +#define HDTOUT_COMMAND 0x99cc +#define HDTOUT_INIT (0x10BF0000ul | HDTOUT_COMMAND) +#define HDTOUT_ASSERT (0xA0BF0000ul | HDTOUT_COMMAND) +#define HDTOUT_EXIT (0xE0BF0000ul | HDTOUT_COMMAND) +#define HDTOUT_PRINT (0xC0BF0000ul | HDTOUT_COMMAND) +#define HDTOUT_TIME_ANALYSE (0xD0BF0000ul | HDTOUT_COMMAND) +#define HDTOUT_BREAKPOINT (0xB0BF0000ul | HDTOUT_COMMAND) +#define HDTOUT_ERROR (0x1EBF0000ul | HDTOUT_COMMAND) + + +#define HDTOUT_ERROR_HEAP_ALLOCATION 0x1 +#define HDTOUT_ERROR_HEAP_AllOCATE_FAIL 0x2 + +#define HDTOUT_PRINTCTRL_OFF 0 +#define HDTOUT_PRINTCTRL_ON 1 +#define HDTOUT_ALL_CORES 0 +#define HDTOUT_BSP_ONLY 1 +#define HDTOUT_BUFFER_MODE_OFF 0 +#define HDTOUT_BUFFER_MODE_ON 1 + +#define HDTOUT_HEADER_SIGNATURE 0xDB1099CCul +#define HDTOUT_DEFAULT_BUFFER_SIZE 0x1000 +/// HDTOUT Header. +typedef struct _HDTOUT_HEADER { + UINT32 Signature; ///< 0xDB1099CC + UINT16 Version; ///< HDTOUT version. + UINT16 BufferSize; ///< Size in bytes. + UINT16 DataIndex; ///< Data Index. + UINT8 PrintCtrl; ///< 0 off no print 1 on print + UINT8 NumBreakpointUnit; ///< default 0 no bp unit others number of bp unit + UINT32 FuncListAddr; ///< 32 bit address to the list of functions that script can execute + UINT8 ConsoleType; ///< Console type - deprecated + UINT8 Event; ///< Event type. - deprecated + UINT8 OutBufferMode; ///< Off:stack mode, On: heap mode - deprecated + UINT32 EnableMask; ///< Bitmap to select which part should be streamed out + UINT64 ConsoleFilter; ///< Filter use to select which part should be streamed out + UINT8 BspOnlyFlag; ///< 1 Only Enable Bsp output, 0 enable On All cores + UINT8 Reserved[56 - 32]; ///< Reserved for header expansion + + CHAR8 BreakpointList[300]; ///< Breakpoint list + CHAR8 StatusStr[156]; ///< Shows current node, DCT, CS,... + CHAR8 Data[2]; ///< HDTOUT content. Its size will be determined by BufferSize. +} HDTOUT_HEADER; + +#define IDS_HDTOUT_BP_AND_OFF 0 +#define IDS_HDTOUT_BP_AND_ON 1 + +#define IDS_HDTOUT_BPFLAG_FORMAT_STR 0 +#define IDS_HDTOUT_BPFLAG_STATUS_STR 1 + +#define HDTOUT_BP_ACTION_HALT 1 +#define HDTOUT_BP_ACTION_PRINTON 2 +#define HDTOUT_BP_ACTION_PRINTONE 3 +#define HDTOUT_BP_ACTION_PRINTOFF 4 + +///breakpoint unit of HDTOUT +typedef struct _BREAKPOINT_UNIT { + UINT8 AndFlag : 1; ///< Next string is ANDed to current string + UINT8 BpFlag : 1; ///< Format string or Status string + UINT8 Action : 4; ///< Halt, start HDTOUT, or stop HDT,... + UINT8 BpStrOffset; ///< Offset from BreakpointList to the breakpoint string +} BREAKPOINT_UNIT; + + +BOOLEAN +AmdIdsHdtOutSupport ( + VOID + ); + +#endif //_IDS_HDTOUT_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpSerial.c b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpSerial.c new file mode 100644 index 0000000000..43d6bf647f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Debug/IdsDpSerial.c @@ -0,0 +1,185 @@ +/** + * @file + * + * AMD Integrated Debug Debug_library Routines + * + * Contains all functions related to HDTOUT + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ + + /*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "IdsLib.h" +#include "amdlib.h" +#include "AMD.h" +#include "IdsDebugPrint.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_IDS_DEBUG_IDSDPSERIAL_FILECODE + + +/** + * Determine whether IDS console is enabled. + * + * + * @retval TRUE Alway return true + * + **/ +STATIC BOOLEAN +AmdIdsSerialSupport ( + VOID + ) +{ + + return TRUE; +} + +/** + * Get Serial customize Filter + * + * @param[in,out] Filter Filter do be filled + * + * @retval FALSE Alway return FALSE + * + **/ +STATIC BOOLEAN +AmdIdsSerialGetFilter ( + IN OUT UINT64 *Filter + ) +{ + return FALSE; +} + + +#define IDS_SERIAL_PORT_LSR (IDS_SERIAL_PORT + 5) +#define IDS_LSR_TRANSMIT_HOLDING_REGISTER_EMPTY_MASK BIT5 +/** + * Send byte to Serial Port + * + * Before use this routine, please make sure Serial Communications Chip have been initialed + * + * @param[in] ByteSended Byte to be sended + * + * @retval TRUE Byte sended successfully + * @retval FALSE Byte sended failed + * + **/ +STATIC BOOLEAN +AmdIdsSerialSendByte ( + IN CHAR8 ByteSended + ) +{ + UINT32 RetryCount; + UINT8 Value; + + //Wait until LSR.Bit5 (Transmitter holding register Empty) + RetryCount = 200; + do { + LibAmdIoRead (AccessWidth8, IDS_SERIAL_PORT_LSR, &Value, NULL); + RetryCount--; + } while (((Value & IDS_LSR_TRANSMIT_HOLDING_REGISTER_EMPTY_MASK) == 0) && + (RetryCount > 0)); + + if (RetryCount == 0) { + //Time expired + return FALSE; + } else { + LibAmdIoWrite (AccessWidth8, IDS_SERIAL_PORT, &ByteSended, NULL); + return TRUE; + } +} + + +/** + * Print formated string + * + * @param[in] Buffer - Point to input buffer + * @param[in] BufferSize - Buffer size + * @param[in] debugPrintPrivate - Option + * +**/ +STATIC VOID +AmdIdsSerialPrint ( + IN CHAR8 *Buffer, + IN UINTN BufferSize, + IN IDS_DEBUG_PRINT_PRIVATE_DATA *debugPrintPrivate + ) +{ + BOOLEAN SendStatus; + UINT32 RetryCount; + RetryCount = 200; + while (BufferSize--) { + do { + if (*Buffer == '\n') { + SendStatus = AmdIdsSerialSendByte ('\r'); + } + SendStatus = AmdIdsSerialSendByte (*Buffer); + RetryCount--; + } while ((SendStatus == FALSE) && (RetryCount > 0)); + Buffer ++; + } +} + +/** + * Init local private data + * + * @param[in] Flag - filter flag + * @param[in] debugPrintPrivate - Point to debugPrintPrivate + * +**/ +STATIC VOID +AmdIdsSerialInitPrivateData ( + IN UINT64 Flag, + IN IDS_DEBUG_PRINT_PRIVATE_DATA *debugPrintPrivate + ) +{ + +} + +CONST IDS_DEBUG_PRINT ROMDATA IdsDebugPrintSerialInstance = +{ + AmdIdsSerialSupport, + AmdIdsSerialGetFilter, + AmdIdsSerialInitPrivateData, + AmdIdsSerialPrint +}; + + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c new file mode 100644 index 0000000000..fddf8eb403 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c @@ -0,0 +1,308 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Integrated Debug Option Specific Routines for common F16 + * + * Contains AMD AGESA debug macros and library functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "IdsLib.h" +#include "cpuFamilyTranslation.h" +#include "cpuF16PowerMgmt.h" +#include "F16KbPowerMgmt.h" +#include "IdsF16KbAllService.h" +#include "IdsF16KbNvDef.h" +#include "Gnb.h" +#include "GnbGfx.h" +#include "GnbRegistersKB.h" +#include "GnbPcie.h" +#include "GnbHandleLib.h" +#include "GnbRegisterAccKB.h" +#include "IdsRegAcc.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_IDS_FAMILY_0X16_KB_IDSF16KBALLSERVICE_FILECODE + +/** + * IDS F16 Backend Function for HTC Controls + * + * This function is used to override HTC control Parameter. + * + * @param[in,out] DataPtr The Pointer of HTC register. + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * @param[in] IdsNvPtr The Pointer of NV Table. + * + * @retval IDS_SUCCESS Backend function is called successfully. + * @retval IDS_UNSUPPORTED No Backend function is found. + * + **/ +STATIC IDS_STATUS +IdsSubHTCControlF16Kb ( + IN OUT VOID *DataPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN IDS_NV_ITEM *IdsNvPtr + ) +{ + HTC_REGISTER *PHtcReg; + IDS_STATUS NvValue; + + PHtcReg = (HTC_REGISTER *) DataPtr; + IDS_NV_READ_SKIP (NvValue, AGESA_IDS_NV_HTC_EN, IdsNvPtr, StdHeader) { + switch (NvValue) { + case IdsNvThermalHTCEnDisabled: + PHtcReg->HtcEn = 0; + break; + case IdsNvThermalHTCEnEnabled: + PHtcReg->HtcEn = 1; + break; + case IdsNvThermalHTCEnAuto: + break; + default: + ASSERT (FALSE); + break; + } + } + + IDS_NV_READ_SKIP (NvValue, AGESA_IDS_NV_HTC_OVERRIDE, IdsNvPtr, StdHeader) { + switch (NvValue) { + case IdsNvThermalHTCOverrideDisabled: + break; + case IdsNvThermalHTCOverrideEnabled: + IDS_NV_READ_SKIP (NvValue, AGESA_IDS_NV_HTC_PSTATE_LIMIT, IdsNvPtr, StdHeader) { + ASSERT ((NvValue >= IdsNvThermalHtcPstateLimitMin) && (NvValue <= IdsNvThermalHtcPstateLimitMax)); + PHtcReg->HtcPstateLimit = NvValue; + } + + IDS_NV_READ_SKIP (NvValue, AGESA_IDS_NV_HTC_TEMP_HYS, IdsNvPtr, StdHeader) { + ASSERT ((NvValue >= IdsNvThermalHTCTempHysMin) && (NvValue <= IdsNvThermalHTCTempHysMax)); + PHtcReg->HtcHystLmt = NvValue; + } + + IDS_NV_READ_SKIP (NvValue, AGESA_IDS_NV_HTC_ACT_TEMP, IdsNvPtr, StdHeader) { + ASSERT ((NvValue >= IdsNvThermalHTCActTempMin) && (NvValue <= IdsNvThermalHTCActTempMax)); + PHtcReg->HtcTmpLmt = NvValue; + } + break; + default: + ASSERT (FALSE); + break; + } + } + return IDS_SUCCESS; +} + +/** + * IDS Backend Function for Memory Mapping + * + * This function is used to override the following setting. + * EnableBankIntlv, ChannelIntlvMode, EnableNodeIntlv, MemHole, + * EnablePowerDown, PowerDownMode, EnableBurstLen32, BankSwizzle, + * UserTimingMode, MemClockValue, EnableParity, DqsTrainCtl, AllMemClks, + * and EnableClkHZAltVidC3. + * + * @param[in,out] DataPtr The Pointer of AMD_POST_PARAMS. + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * @param[in] IdsNvPtr The Pointer of NV Table. + * + * @retval IDS_SUCCESS Backend function is called successfully. + * @retval IDS_UNSUPPORTED No Backend function is found. + * + **/ +STATIC IDS_STATUS +IdsSubMemoryMappingF16Kb ( + IN OUT VOID *DataPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN IDS_NV_ITEM *IdsNvPtr + ) +{ + AMD_POST_PARAMS *PostParamsPtr; + MEM_PARAMETER_STRUCT *RefPtr; + IDS_STATUS NvValue; + MEM_DATA_STRUCT * memdataptr; + + PostParamsPtr = (AMD_POST_PARAMS *)DataPtr; + memdataptr = PostParamsPtr->MemConfig.MemData; + RefPtr = memdataptr->ParameterListPtr; + IDS_NV_READ_SKIP (NvValue, AGESA_IDS_NV_BANK_INTERLEAVE, IdsNvPtr, StdHeader) { + switch (NvValue) { + case IdsNvMemMappingBankInterleaveDisabled: + RefPtr->EnableBankIntlv = FALSE; + break; + case IdsNvMemMappingBankInterleaveAuto: + RefPtr->EnableBankIntlv = TRUE; + break; + default: + ASSERT (FALSE); + break; + } + } + return IDS_SUCCESS; +} + +/** + * IDS Backend Function for override GNB platform config + * + * @param[in,out] DataPtr The Pointer of BOOLEAN. + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * @param[in] IdsNvPtr The Pointer of NV Table. + * + * @retval IDS_SUCCESS Backend function is called successfully. + * @retval IDS_UNSUPPORTED No Backend function is found. + * + **/ +STATIC IDS_STATUS +IdsSubGnbPlatformCfgF16Kb ( + IN OUT VOID *DataPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN IDS_NV_ITEM *IdsNvPtr + ) +{ + GFX_PLATFORM_CONFIG *PGfx; + IDS_STATUS NvValue; + + PGfx = (GFX_PLATFORM_CONFIG*) DataPtr; + //NB Azalia + IDS_NV_READ_SKIP (NvValue, AGESA_IDS_NV_GNBHDAUDIOEN, IdsNvPtr, StdHeader) { + switch (NvValue) { + //Auto + case IdsNvGnbGfxNbAzaliaAuto: + break; + //Disabled + case IdsNvGnbGfxNbAzaliaDisabled: + PGfx->GnbHdAudio = 0; + break; + //Enabled + case IdsNvGnbGfxNbAzaliaEnabled: + PGfx->GnbHdAudio = 1; + break; + default: + ASSERT (FALSE); + break; + } + } + return IDS_SUCCESS; +} +/** + * IDS Family specific Function for programming GMMX register + * + * @param[in,out] DataPtr The Pointer of BOOLEAN. + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * @param[in] IdsNvPtr The Pointer of NV Table. + * + * @retval IDS_SUCCESS Backend function is called successfully. + * + **/ +STATIC IDS_STATUS +IdsRegSetGmmxF16Kb ( + IN OUT VOID *DataPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN IDS_NV_ITEM *IdsNvPtr + ) +{ + IdsRegAcc132_STRUCT *PIdsRegGmmx; + UINT32 Value; + GNB_HANDLE *GnbHandle; + + PIdsRegGmmx = (IdsRegAcc132_STRUCT *) DataPtr; + GnbHandle = GnbGetHandle (StdHeader); + + GnbRegisterReadKB ( + GnbHandle, + 0x12, + PIdsRegGmmx->Offset, + &Value, + 0, + StdHeader); + + IdsLibDataMaskSet32 (&Value, PIdsRegGmmx->AndMask, PIdsRegGmmx->OrMask); + + GnbRegisterWriteKB ( + GnbHandle, + 0x12, + PIdsRegGmmx->Offset, + &Value, + 0, + StdHeader); + + return IDS_SUCCESS; +} + +CONST IDS_FAMILY_FEAT_STRUCT ROMDATA IdsFeatHtcControlBlockF16Kb = +{ + IDS_FEAT_HTC_CTRL, + IDS_ALL_CORES, + IDS_HTC_CTRL, + AMD_FAMILY_16_KB, + IdsSubHTCControlF16Kb +}; + + +CONST IDS_FAMILY_FEAT_STRUCT ROMDATA IdsFeatMemoryMappingPostBeforeBlockF16Kb = +{ + IDS_FEAT_MEMORY_MAPPING, + IDS_ALL_CORES, + IDS_INIT_POST_BEFORE, + AMD_FAMILY_16_KB, + IdsSubMemoryMappingF16Kb +}; + +CONST IDS_FAMILY_FEAT_STRUCT ROMDATA IdsFeatGnbPlatformCfgBlockF16Kb = +{ + IDS_FEAT_GNB_PLATFORMCFG, + IDS_ALL_CORES, + IDS_GNB_PLATFORMCFG_OVERRIDE, + AMD_FAMILY_16_KB, + IdsSubGnbPlatformCfgF16Kb +}; + +// For register access +CONST IDS_FAMILY_FEAT_STRUCT ROMDATA IdsFeatRegGmmxF16Kb = + MAKE_IDS_FAMILY_FEAT_ALL_CORES ( + dummy210, + AMD_FAMILY_16_KB, + IdsRegSetGmmxF16Kb + ); + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.h b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.h new file mode 100644 index 0000000000..3288143832 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.h @@ -0,0 +1,49 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD IDS Routines + * + * Contains AMD AGESA IDS Translation + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +#ifndef _IDS_F16_KB_ALLSERVICE_H_ +#define _IDS_F16_KB_ALLSERVICE_H_ +#ifdef __IDS_EXTENDED__ + #include IDS_EXT_INCLUDE_F16_KB (IdsIntF16KbAllService) +#endif + +#endif //_IDS_F16_KB_ALLSERVICE_H_ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbNvDef.h b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbNvDef.h new file mode 100644 index 0000000000..c08bdb3ce3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbNvDef.h @@ -0,0 +1,287 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * IDS NV definition for F16Kb + * + * Auto generated from CBS XML file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS F16Kb + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + + +#ifndef _IDSF16KBNVDEF_H_ +#define _IDSF16KBNVDEF_H_ +///HTC Enable +///Enable or disable Hardware Thermal Control. D18F3x64[0] +typedef enum { + IdsNvThermalHTCEnDisabled = 0,///AHCI + IdsNvFchSataClassAHCI_as_ID_0x7804 = 5,///AHCI as ID 0x7804 +} IdsNvFchSataClass; + +///OnChip IDE +///Select OnChip IDE controller mode +typedef enum { + IdsNvFchSataIdeModeLegacy_IDE = 0,///IdsNvTableOffset; + } + return status; +} + +/** + * + * Get IDS Override Image Base Address + * + * @param[in,out] IdsImageBase The Base Address of IDS Override Image. + * @param[in,out] StdHeader The Pointer of Standard Header. + * + * @retval AGESA_SUCCESS Success to get the pointer of NV Table. + * @retval AGESA_ERROR Fail to get the pointer of NV Table. + * + **/ +AGESA_STATUS +AmdGetIdsImagebase ( + IN OUT UINT64 *IdsImageBase, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS status; + LOCATE_HEAP_PTR LocateHeapStructPtr; + IDS_CONTROL_STRUCT *IdsCtrlPtr; + + LocateHeapStructPtr.BufferHandle = IDS_CONTROL_HANDLE; + LocateHeapStructPtr.BufferPtr = NULL; + status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader); + if (status == AGESA_SUCCESS) { + IdsCtrlPtr = (IDS_CONTROL_STRUCT *) LocateHeapStructPtr.BufferPtr; + *IdsImageBase = IdsCtrlPtr->IdsImageBase; + } + return status; +} + +/** + * + * Read IDS NV value in NV table. + * + * It searches the table until the Nv Id is found and return the NV value + * in the table. Otherwise, return IDS_UNSUPPORTED. + * + * @param[in] IdsNvId IDS NV ID + * @param[in] NvTablePtr NV Table pointer. + * @param[in,out] StdHeader The Pointer of Standard Header. + * + * @retval IDS_UNSUPPORTED NV ID is not found in the table + * Other Value The NV value + * + **/ +IDS_STATUS +AmdIdsNvReader ( + IN UINT16 IdsNvId, + IN IDS_NV_ITEM *NvTablePtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + IDS_STATUS Status; + IDS_NV_ITEM *NvPtr; + BOOLEAN IgnoreIdsDefault; + AGESA_STATUS status; + LOCATE_HEAP_PTR LocateHeapStructPtr; + IDS_CONTROL_STRUCT *IdsCtrlPtr; + + IgnoreIdsDefault = FALSE; + Status = IDS_UNSUPPORTED; + NvPtr = NvTablePtr; + + if (NvPtr != NULL) { + while (NvPtr->IdsNvId != AGESA_IDS_NV_END) { + if (NvPtr->IdsNvId == IdsNvId) { + break; + } else { + NvPtr ++; + } + } + if ((NvPtr->IdsNvId != AGESA_IDS_NV_END)) { + //Get IgnoreIdsDefault from heap + LocateHeapStructPtr.BufferHandle = IDS_CONTROL_HANDLE; + LocateHeapStructPtr.BufferPtr = NULL; + status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader); + if (status == AGESA_SUCCESS) { + IdsCtrlPtr = (IDS_CONTROL_STRUCT *) LocateHeapStructPtr.BufferPtr; + IgnoreIdsDefault = IdsCtrlPtr->IgnoreIdsDefault; + } + + if (IgnoreIdsDefault || (NvPtr->IdsNvValue != AGESA_IDS_DFT_VAL)) { + Status = NvPtr->IdsNvValue; + } + } + } + return Status; +} + +/** + * IDS function for only return IDS_SUCCESS + * + * + * @param[in,out] DataPtr meaningless data pointer + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * @param[in] IdsNvPtr The Pointer of NV Table. + * + * @retval IDS_SUCCESS Always succeeds. + * + **/ +IDS_STATUS +IdsCommonReturn ( + IN OUT VOID *DataPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader, + IN IDS_NV_ITEM *IdsNvPtr + ) +{ + return IDS_SUCCESS; +} + + +/** + * IDS function for ap run specific task after amdinitpost + * + * + * @param[in] ApicIdOfCore apic id of specific AP + * @param[in] ApLateTaskPtr The Pointer of IDSAPLATETASK. + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * + * @retval AGESA_SUCCESS Success + * @retval AGESA_ERROR meet some error + * + **/ +AGESA_STATUS +IdsAgesaRunFcnOnApLate ( + IN UINTN ApicIdOfCore, + IN IDSAPLATETASK *ApLateTaskPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + AP_EXE_PARAMS LaunchApParams; + +//init AgesaRunFcnOnAp parameters + LaunchApParams.FunctionNumber = IDS_LATE_RUN_AP_TASK_ID; + LaunchApParams.RelatedBlockLength = SIZE_IN_DWORDS (IDSAPLATETASK); + LaunchApParams.RelatedDataBlock = ApLateTaskPtr; + LaunchApParams.StdHeader = *StdHeader; + + AGESA_TESTPOINT (TpIfBeforeRunApFromIds, StdHeader); + Status = AgesaRunFcnOnAp ((UINTN) ApicIdOfCore, &LaunchApParams); + AGESA_TESTPOINT (TpIfAfterRunApFromIds, StdHeader); + + return Status; +} + +/** + * IDS function force all cores run specific task after amdinitpost + * + * + * @param[in] ApLateTaskPtr The Pointer of IDSAPLATETASK. + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * + * @retval AGESA_SUCCESS Success + * @retval AGESA_ERROR meet some error + * + **/ +AGESA_STATUS +IdsAgesaRunFcnOnAllCoresLate ( + IN IDSAPLATETASK *ApLateTaskPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_EXE_PARAMS LaunchApParams; + AGESA_STATUS Status; + +//init AgesaRunFcnOnAp parameters + Status = AGESA_SUCCESS; + LaunchApParams.FunctionNumber = IDS_LATE_RUN_AP_TASK_ID; + LaunchApParams.RelatedBlockLength = SIZE_IN_DWORDS (IDSAPLATETASK); + LaunchApParams.RelatedDataBlock = ApLateTaskPtr; + LaunchApParams.StdHeader = *StdHeader; + + Status = RunLateApTaskOnAllAPs (&LaunchApParams, StdHeader); + +//do it on Bsp + Status = ApLateTaskPtr->ApTask (ApLateTaskPtr->ApTaskPara, StdHeader); + return Status; +} + +/** + * IDS call-back function for ApDispatchTable + * + * @param[in] AmdApExeParams AP_EXE_PARAMS. + * + * @retval AGESA_SUCCESS Success + * @retval AGESA_ERROR meet some error + * + **/ +AGESA_STATUS +AmdIdsRunApTaskLate ( + IN AP_EXE_PARAMS *AmdApExeParams + ) +{ + IDSAPLATETASK *ApLateTaskPtr; + AGESA_STATUS Status; + + ApLateTaskPtr = (IDSAPLATETASK *)AmdApExeParams->RelatedDataBlock; + Status = ApLateTaskPtr->ApTask (ApLateTaskPtr->ApTaskPara, &AmdApExeParams->StdHeader); + return Status; +} + +/** + * + * + * IDS Common routine for run code on AP for both ealry & later stage + * This routine can only be used when AP service have been established + * + * @param[in] PIdsRuncodeParams Point to parameters structure + * @param[in,out] StdHeader - The Pointer of AGESA Header + * + */ +VOID +IdsRunCodeOnCores ( + IN IDS_RUNCODE_PARAMS *PIdsRuncodeParams, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK ApTask; + IDSAPLATETASK IdsLateTask; + UINT32 NumberOfCores; + UINT8 StartSocket; + UINT8 EndSocket; + UINT8 Socket; + UINT8 StartCore; + UINT8 EndCore; + UINT8 Core; + UINT32 BscCoreNum; + UINT32 BscSocket; + UINT32 IgnoredModule; + UINT32 ApicIdOfCore; + AGESA_STATUS IgnoredSts; + IDS_AP_RUN_CODE_TIMEPOINT TimePoint; + + TimePoint = PIdsRuncodeParams->TimePoint; + ASSERT ((TimePoint == IDS_AP_RUN_CODE_EARLY) || + (TimePoint == IDS_AP_RUN_CODE_POST) || + (TimePoint == IDS_AP_RUN_CODE_LATE)); + + IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &BscCoreNum, &IgnoredSts); + IdsGetStartEndSocket (PIdsRuncodeParams->Socket, &StartSocket, &EndSocket); + //TaskPtr for both IDS_AP_RUN_CODE_EARLY, IDS_AP_RUN_CODE_POST + ApTask.FuncAddress.PfApTaskIO = PIdsRuncodeParams->ApTask; + ApTask.ExeFlags = WAIT_FOR_CORE; + ApTask.DataTransfer.DataSizeInDwords = PIdsRuncodeParams->ParamsDataSizeInDwords; + ApTask.DataTransfer.DataPtr = PIdsRuncodeParams->ParamsDataPtr; + ApTask.DataTransfer.DataTransferFlags = 0; + + for (Socket = StartSocket; Socket <= EndSocket; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + if (PIdsRuncodeParams->Core == IDS_ALL_CORE) { + StartCore = 0; + EndCore = (UINT8)NumberOfCores - 1; + } else { + StartCore = PIdsRuncodeParams->Core; + EndCore = PIdsRuncodeParams->Core; + } + for (Core = StartCore; (Core <= EndCore) && (Core <= (NumberOfCores - 1)); Core++) { + if ((Core == BscCoreNum) && (Socket == BscSocket)) { + //Call function directly + PIdsRuncodeParams->ApTask (PIdsRuncodeParams->ParamsDataPtr, StdHeader); + } else { + if (IsProcessorPresent (Socket, StdHeader)) { + if (TimePoint == IDS_AP_RUN_CODE_EARLY) { + // At early stage, the AP's task has to be called by core 0, not by bsc + IdsRunCodeOnCoreEarly (Socket, Core, &ApTask, StdHeader); + } else if (TimePoint == IDS_AP_RUN_CODE_POST) { + ApUtilRunCodeOnSocketCore (Socket, Core, &ApTask, StdHeader); + } else if (TimePoint == IDS_AP_RUN_CODE_LATE) { + IdsLateTask.ApTask = (PF_IDS_AP_TASK)PIdsRuncodeParams->ApTask; + IdsLateTask.ApTaskPara = PIdsRuncodeParams->ParamsDataPtr; + GetLocalApicIdForCore (Socket, Core, &ApicIdOfCore, StdHeader); + IdsAgesaRunFcnOnApLate (ApicIdOfCore, &IdsLateTask, StdHeader); + } + } + } + } + } + } +} + +/** + * Get the number of P-State to support + * + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * + * @retval num The number of P-State to support. + * + **/ +UINT8 +IdsGetNumPstatesFamCommon ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 pstatesnum; + UINT8 i; + UINT8 IgnoredByte; + UINT32 Ignored; + BOOLEAN PStateEnabled; + UINT32 TempVar_c; + PSTATE_CPU_FAMILY_SERVICES *FamilyServices; + + pstatesnum = 0; + GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + FamilyServices->GetPstateMaxState (FamilyServices, &TempVar_c, &IgnoredByte, StdHeader); + for (i = 0; i <= TempVar_c; i++) { + // Check if PState is enabled + FamilyServices->GetPstateRegisterInfo ( FamilyServices, + (UINT32) i, + &PStateEnabled, + &Ignored, + &Ignored, + &Ignored, + StdHeader); + if (PStateEnabled) { + pstatesnum++; + } + } + return pstatesnum; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Runs the given task on all cores (including self) on the socket of the executing + * core 0. + * + * This function is used to invoke all APs on the socket of the executing core 0 to + * run a specified AGESA procedure. + * + * @param[in] TaskPtr Function descriptor + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +IdsApRunCodeOnAllLocalCores ( + IN AP_TASK *TaskPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Core; + UINT32 BscCoreNum; + UINT32 Socket; + UINT32 BscSocket; + UINT32 IgnoredModule; + UINT32 NumberOfCores; + UINT32 NumberOfSockets; + AGESA_STATUS IgnoredSts; + + IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &BscCoreNum, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != (UINT32) BscSocket) || (Core != (UINT32) BscCoreNum)) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, TaskPtr, StdHeader); + } + } + } + } + // BSP codes + ApUtilTaskOnExecutingCore (TaskPtr, StdHeader, NULL); +} + +/** + * IdsMakePciRegEntry + * + * + * @param[in,out] TableEntry The Pointer of TableEntry +* @param[in] Family Family +* @param[in] Revision Revision +* @param[in] PciAddr PCI address +* @param[in] Data Or Mask +* @param[in] Mask And Mask + * + * + */ +VOID +IdsMakePciRegEntry ( + IN OUT TABLE_ENTRY_FIELDS **TableEntry, + IN UINT64 Family, + IN UINT64 Revision, + IN UINT32 PciAddr, + IN UINT32 Data, + IN UINT32 Mask + ) +{ + (*TableEntry)->EntryType = PciRegister; + (*TableEntry)->CpuRevision.Family = Family; + (*TableEntry)->CpuRevision.Revision = Revision; + (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; + (*TableEntry)->Entry.PciEntry.Address.AddressValue = PciAddr; + (*TableEntry)->Entry.PciEntry.Data = Data; + (*TableEntry)->Entry.PciEntry.Mask = Mask; + (*TableEntry)++; +} + +/** + * IdsMakeHtLinkPciRegEntry + * + * + * @param[in,out] TableEntry The Pointer of TableEntry +* @param[in] Family Family +* @param[in] Revision Revision +* @param[in] HtHostFeat HtHostFeat +* @param[in] PciAddr PCI address +* @param[in] Data Or Mask +* @param[in] Mask And Mask + * + * + */ +VOID +IdsMakeHtLinkPciRegEntry ( + IN OUT TABLE_ENTRY_FIELDS **TableEntry, + IN UINT64 Family, + IN UINT64 Revision, + IN UINT32 HtHostFeat, + IN UINT32 PciAddr, + IN UINT32 Data, + IN UINT32 Mask + ) +{ + (*TableEntry)->EntryType = HtLinkPciRegister; + (*TableEntry)->CpuRevision.Family = Family; + (*TableEntry)->CpuRevision.Revision = Revision; + (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; + (*TableEntry)->Entry.HtLinkPciEntry.LinkFeats.HtHostValue = HtHostFeat; + (*TableEntry)->Entry.HtLinkPciEntry.PciEntry.Address.AddressValue = PciAddr; + (*TableEntry)->Entry.HtLinkPciEntry.PciEntry.Data = Data; + (*TableEntry)->Entry.HtLinkPciEntry.PciEntry.Mask = Mask; + (*TableEntry)++; +} +/** + * IdsMakeHtFeatPciRegEntry + * + * + * @param[in,out] TableEntry The Pointer of TableEntry +* @param[in] Family Family +* @param[in] Revision Revision +* @param[in] HtHostFeat HtHostFeat +* @param[in] PackageType PackageType +* @param[in] PciAddr PCI address +* @param[in] Data Or Mask +* @param[in] Mask And Mask + * + * + */ +VOID +IdsMakeHtFeatPciRegEntry ( + IN OUT TABLE_ENTRY_FIELDS **TableEntry, + IN UINT64 Family, + IN UINT64 Revision, + IN UINT32 HtHostFeat, + IN UINT32 PackageType, + IN UINT32 PciAddr, + IN UINT32 Data, + IN UINT32 Mask + ) +{ + (*TableEntry)->EntryType = HtFeatPciRegister; + (*TableEntry)->CpuRevision.Family = Family; + (*TableEntry)->CpuRevision.Revision = Revision; + (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; + (*TableEntry)->Entry.HtFeatPciEntry.LinkFeats.HtHostValue = HtHostFeat; + (*TableEntry)->Entry.HtFeatPciEntry.PackageType.PackageTypeValue = PackageType; + (*TableEntry)->Entry.HtFeatPciEntry.PciEntry.Address.AddressValue = PciAddr; + (*TableEntry)->Entry.HtFeatPciEntry.PciEntry.Data = Data; + (*TableEntry)->Entry.HtFeatPciEntry.PciEntry.Mask = Mask; + (*TableEntry)++; +} +/** + * IdsMakeHostPciRegEntry + * + * + * @param[in,out] TableEntry The Pointer of TableEntry +* @param[in] Family Family +* @param[in] Revision Revision +* @param[in] HtHostFeat HtHostFeat +* @param[in] PciAddr PCI address +* @param[in] Data Or Mask +* @param[in] Mask And Mask + * + * + */ +VOID +IdsMakeHtHostPciRegEntry ( + IN OUT TABLE_ENTRY_FIELDS **TableEntry, + IN UINT64 Family, + IN UINT64 Revision, + IN UINT32 HtHostFeat, + IN UINT32 PciAddr, + IN UINT32 Data, + IN UINT32 Mask + ) +{ + (*TableEntry)->EntryType = HtHostPciRegister; + (*TableEntry)->CpuRevision.Family = Family; + (*TableEntry)->CpuRevision.Revision = Revision; + (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; + (*TableEntry)->Entry.HtHostEntry.TypeFeats.HtHostValue = HtHostFeat; + (*TableEntry)->Entry.HtHostEntry.Address.AddressValue = PciAddr; + (*TableEntry)->Entry.HtHostEntry.Data = Data; + (*TableEntry)->Entry.HtHostEntry.Mask = Mask; + (*TableEntry)++; +} +/** + * IdsMakeHtPhyRegEntry + * + * + * @param[in,out] TableEntry The Pointer of TableEntry +* @param[in] Family Family +* @param[in] Revision Revision +* @param[in] HtPhyLinkFeat HtPhyLinkFeat +* @param[in] Address PCI address +* @param[in] Data Or Mask +* @param[in] Mask And Mask + * + * + */ +VOID +IdsMakeHtPhyRegEntry ( + IN OUT TABLE_ENTRY_FIELDS **TableEntry, + IN UINT64 Family, + IN UINT64 Revision, + IN UINT32 HtPhyLinkFeat, + IN UINT32 Address, + IN UINT32 Data, + IN UINT32 Mask + ) +{ + (*TableEntry)->EntryType = HtPhyRegister; + (*TableEntry)->CpuRevision.Family = Family; + (*TableEntry)->CpuRevision.Revision = Revision; + (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; + (*TableEntry)->Entry.HtPhyEntry.TypeFeats.HtPhyLinkValue = HtPhyLinkFeat; + (*TableEntry)->Entry.HtPhyEntry.Address = Address; + (*TableEntry)->Entry.HtPhyEntry.Data = Data; + (*TableEntry)->Entry.HtPhyEntry.Mask = Mask; + (*TableEntry)++; +} + +/** + * IdsOptionCallout + * + * Description + * Call the host environment interface to provide a user hook opportunity. + * + * @param[in] CallOutId This parameter indicates the IDS Call-Out-function desired. + * @param[in,out] DataPtr The pointer for callout function use + * @param[in,out] StdHeader Config handle for library and services + * + * @retval AGESA_SUCCESS Success + * @retval AGESA_ERROR meet some error + * + */ +AGESA_STATUS +IdsOptionCallout ( + IN UINTN CallOutId, + IN OUT VOID *DataPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + IDS_CALLOUT_STRUCT IdsCalloutData; + IDS_NV_ITEM NullEntry; + + NullEntry.IdsNvId = 0xFFFF; + NullEntry.IdsNvValue = 0xFFFF; + IdsCalloutData.StdHeader = *StdHeader; + IdsCalloutData.IdsNvPtr = &NullEntry; + IdsCalloutData.Reserved = (UINTN) DataPtr; + + return AgesaGetIdsData (CallOutId, &IdsCalloutData); + +} + +/** + * Ids Write PCI register to All node + * + * + * @param[in] PciAddress Pci address + * @param[in] Highbit High bit position of the field in DWORD + * @param[in] Lowbit Low bit position of the field in DWORD + * @param[in] Value Pointer to input value + * @param[in] StdHeader Standard configuration header + * + */ +VOID +IdsLibPciWriteBitsToAllNode ( + IN PCI_ADDR PciAddress, + IN UINT8 Highbit, + IN UINT8 Lowbit, + IN UINT32 *Value, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + AGESA_STATUS IgnoreStatus; + PCI_ADDR PciAddr; + + + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddr, &IgnoreStatus)) { + PciAddr.Address.Function = PciAddress.Address.Function; + PciAddr.Address.Register = PciAddress.Address.Register; + LibAmdPciWriteBits (PciAddr, Highbit, Lowbit, Value, StdHeader); + } + } + } +} + +/** + * + * + * Core 0 task to run local ap task at early + * + * @param[in] PEarlyApTask - point to IDS_EARLY_AP_TASK structure + * @param[in,out] StdHeader - The Pointer of AGESA Header + * + */ + +STATIC VOID +IdsCmnTaskCore0Early ( + IN IDS_EARLY_AP_TASK *PEarlyApTask, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 IgnoredModule; + UINT32 IgnoredCore; + AGESA_STATUS IgnoredSts; + + ASSERT (PEarlyApTask->Ap_Task0.Core != 0); + + PEarlyApTask->Ap_Task0.ApTask.DataTransfer.DataPtr = &PEarlyApTask->Parameters[0]; + IdentifyCore (StdHeader, &Socket, &IgnoredModule, &IgnoredCore, &IgnoredSts); + ApUtilRunCodeOnSocketCore ((UINT8)Socket, PEarlyApTask->Ap_Task0.Core, &PEarlyApTask->Ap_Task0.ApTask, StdHeader); +} + +/** + * + * + * BSC task to run Core0 task at early, must only run on BSC + * + * @param[in] Socket - Socket which run the task + * @param[in] Core - Core which run the task + * @param[in] ApTask - Task for AP + * @param[in,out] StdHeader - The Pointer of AGESA Header + * + */ +VOID +IdsRunCodeOnCoreEarly ( + IN UINT8 Socket, + IN UINT8 Core, + IN AP_TASK* ApTask, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 BscSocket; + UINT32 BscCoreNum; + UINT32 IgnoredModule; + AGESA_STATUS IgnoredSts; + AP_TASK Core0Task; + IDS_EARLY_AP_TASK IdsEarlyTask; + + IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &BscCoreNum, &IgnoredSts); + ASSERT (~((Socket == BscSocket) && (Core == BscCoreNum))); + if ((Socket == BscSocket) || (Core == 0)) { + ApUtilRunCodeOnSocketCore (Socket, Core, ApTask, StdHeader); + } else { + //Init IDS_EARLY_AP_TASK for Core 0 + IdsEarlyTask.Ap_Task0.ApTask = *ApTask; + IdsEarlyTask.Ap_Task0.Core = Core; + //Init Parameter buffer, Target core can't get the parameter from pointer, which point to Host Core memory space + ASSERT ((ApTask->DataTransfer.DataSizeInDwords * sizeof (UINT32)) <= IDS_EARLY_AP_TASK_PARA_NUM); + LibAmdMemCopy (&IdsEarlyTask.Parameters[0], ApTask->DataTransfer.DataPtr, sizeof (UINT32) * ApTask->DataTransfer.DataSizeInDwords, StdHeader); + if ((ApTask->DataTransfer.DataSizeInDwords * sizeof (UINT32)) <= IDS_EARLY_AP_TASK_PARA_NUM) { + //Lauch Core0 1st + Core0Task.FuncAddress.PfApTaskI = (PF_AP_TASK_I)IdsCmnTaskCore0Early; + Core0Task.ExeFlags = WAIT_FOR_CORE; + Core0Task.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (IDS_EARLY_AP_TASK0) + ApTask->DataTransfer.DataSizeInDwords; + Core0Task.DataTransfer.DataPtr = &IdsEarlyTask; + Core0Task.DataTransfer.DataTransferFlags = 0; + ApUtilRunCodeOnSocketCore (Socket, 0, &Core0Task, StdHeader); + } + } +} + +/** + * + * + * This function get start end Module according to input ModuleId + * + * @param[in] ModuleId - 0xFF means all nodes, other value Specifies real NodeId + * @param[in,out] StartModule - Point to start Node + * @param[in,out] EndModule - Point to end Node + * + */ +VOID +IdsGetStartEndModule ( + IN UINT8 ModuleId, + IN OUT UINT8 *StartModule, + IN OUT UINT8 *EndModule + ) +{ + if (ModuleId == 0xFF) { + *StartModule = 0; + *EndModule = (UINT8) (GetPlatformNumberOfSockets () * GetPlatformNumberOfModules () - 1); + if (*EndModule > 7) { + *EndModule = 7; + } + } else { + *StartModule = ModuleId; + *EndModule = ModuleId; + } +} + +/** + * + * + * This function get start end socket according to input SocketId + * + * @param[in] SocketId - 0xFF means all sockets, other value Specifies real SokcetId + * @param[in,out] StartSocket - Point to start Socket + * @param[in,out] EndSocket - Point to end Socket + * + */ +VOID +IdsGetStartEndSocket ( + IN UINT8 SocketId, + IN OUT UINT8 *StartSocket, + IN OUT UINT8 *EndSocket + ) +{ + if (SocketId == IDS_ALL_SOCKET) { + *StartSocket = 0; + *EndSocket = (UINT8) (GetPlatformNumberOfSockets () - 1); + } else { + *StartSocket = SocketId; + *EndSocket = SocketId; + } +} + +/** + * + * + * This function transfer input High low bit to Mask + * + * @param[in] RegVal - Regval want to set + * @param[in] Highbit - (0~63) + * @param[in] Lowbit - (0~63) + * @param[in,out] AndMask - point value contain output AndMask + * @param[in,out] OrMask - point value contain output OrMask + * + */ +VOID +IdsGetMask64bits ( + IN UINT64 RegVal, + IN UINT8 Highbit, + IN UINT8 Lowbit, + IN OUT UINT64 *AndMask, + IN OUT UINT64 *OrMask + ) +{ + UINT64 Mask; + + if ((Highbit - Lowbit) != 63) { + Mask = (((UINT64) 1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT64) 0xFFFFFFFFFFFFFFFF; + } + *AndMask = ~(Mask << Lowbit); + *OrMask = (RegVal & Mask) << Lowbit; +} +/** + * + * + * This function transfer input High low bit to Mask + * + * @param[in] RegVal - Regval want to set + * @param[in] Highbit - (0~31) + * @param[in] Lowbit - (0~31) + * @param[in,out] AndMask - point value contain output AndMask + * @param[in,out] OrMask - point value contain output OrMask + * + */ + +VOID +IdsGetMask32bits ( + IN UINT32 RegVal, + IN UINT8 Highbit, + IN UINT8 Lowbit, + IN OUT UINT32 *AndMask, + IN OUT UINT32 *OrMask + ) +{ + UINT32 Mask; + + if ((Highbit - Lowbit) != 31) { + Mask = (((UINT32) 1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT32) 0xFFFFFFFF; + } + *AndMask = ~(Mask << Lowbit); + *OrMask = (RegVal & Mask) << Lowbit; + +} +/** + * + * + * This function transfer input High low bit to Mask + * + * @param[in] RegVal - Regval want to set + * @param[in] Highbit - (0~15) + * @param[in] Lowbit - (0~15) + * @param[in,out] AndMask - point value contain output AndMask + * @param[in,out] OrMask - point value contain output OrMask + * + */ + +VOID +IdsGetMask16bits ( + IN UINT16 RegVal, + IN UINT8 Highbit, + IN UINT8 Lowbit, + IN OUT UINT32 *AndMask, + IN OUT UINT32 *OrMask + ) +{ + UINT16 Mask; + + if ((Highbit - Lowbit) != 15) { + Mask = (((UINT16) 1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT16) 0xFFFF; + } + *AndMask = ~(Mask << Lowbit); + *OrMask = (RegVal & Mask) << Lowbit; +} + +/** + * + * + * IdsCheckPciExisit + * Use to check is the PCI device exisit of given address + * + * @param[in] PciAddr - Given PCI address + * @param[in,out] StdHeader - The Pointer of AGESA Header + * + * @retval TRUE The PCI device exisit + * @retval FALSE The PCI device doesn't exisit + * + * + */ +BOOLEAN +IdsCheckPciExisit ( + IN PCI_ADDR PciAddr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR _pciaddr; + UINT32 _pcidata; + BOOLEAN status; + + status = FALSE; + _pciaddr = PciAddr; + _pciaddr.Address.Register = 0; + LibAmdPciRead (AccessWidth32, _pciaddr, &_pcidata, StdHeader); + if (_pcidata != 0xFFFFFFFF || _pcidata != 0) { + status = TRUE; + } + return status; +} + +/** + * + * + * This function transfer input High low bit to Mask + * + * @param[in,out] Value - Regval want to And Or with Mask + * @param[in] AndMask - AndMask + * @param[in] OrMask - OrMask + * + */ + +VOID +IdsLibDataMaskSet32 ( + IN OUT UINT32 *Value, + IN UINT32 AndMask, + IN UINT32 OrMask + ) +{ + *Value &= AndMask; + *Value |= OrMask; +} + + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Library/IdsRegAcc.h b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Library/IdsRegAcc.h new file mode 100644 index 0000000000..1b9e02c49c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Library/IdsRegAcc.h @@ -0,0 +1,169 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD Integrated Debug library Routines + * + * Contains AMD AGESA debug macros and library functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ****************************************************************************** + */ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#ifndef _IDSREGACC_H_ +#define _IDSREGACC_H_ +#include "mm.h" +#include "mn.h" + +///Structure define for MSR register +typedef struct _IDS_REG_MSR { + IDS_AP_RUN_CODE_TIMEPOINT TimePoint; ///< TimePoint + UINT8 Socket; ///< Socket + UINT8 Core; ///< Core + UINT32 MsrAddr; ///< Address of MSR Register + UINT64 AndMask; ///< And Mask + UINT64 OrMask; ///< Or Mask +} IDS_REG_MSR; + +///Structure define for DR register +typedef struct _IDS_REG_DR { + IDS_AP_RUN_CODE_TIMEPOINT TimePoint; ///< TimePoint + UINT8 Socket; ///< Socket + UINT8 Core; ///< Core + UINT8 Drindex; ///< Debug register index from 0-7 + UINT64 AndMask; ///< And Mask + UINT64 OrMask; ///< Or Mask +} IDS_REG_DR; + +///Enum for Mem Register access Type +typedef enum { + IDS_REG_MEM_NB, ///< PCI access + IDS_REG_MEM_PHY, ///< Memory Phy access + IDS_REG_MEM_EXTRA, ///< Memory Extra register access + IDS_REG_MEM_END, ///< End +} IDS_REG_MEM_ACCESS_TYPE; + +///Structure define for Mem register +typedef struct _IDS_REG_MEM { + IDS_REG_MEM_ACCESS_TYPE Type; ///< Type + UINT8 Module; ///< Module + UINT8 Dct; ///< Dct + union { + struct { + UINT8 Func; ///< PCI function + UINT16 Offset; ///< PCI offset + } PciAddr; ///< Pci Address + UINT32 Index; ///< index of indirect access + } Addr; ///< address + UINT32 AndMask; ///< And Mask + UINT32 OrMask; ///< Or Mask +} IDS_REG_MEM; + +///Family register type +typedef enum { + dummy0, + IDS_FAM_REG_TYPE_END, ///< End +} IDS_FAM_REG_TYPE; + +typedef struct _IDS_REG_GMMX { + UINT32 Offset; + UINT32 AndMask; + UINT32 OrMask; +} IdsRegAcc132_STRUCT; + +///Structure define for family specific register +typedef struct _IDS_FAM_REG { + IDS_FAM_REG_TYPE Type; ///< Register type + union { + IdsRegAcc132_STRUCT IDS_FAM_REG_dum0; + } Reg; +} IDS_FAM_REG; + +///Structure define for PCI indirect register +typedef struct _IDS_REG_PCI_INDIRECT { + ACCESS_WIDTH Width; ///< access width + UINT32 PciAddr; ///< PCI address + UINT32 IndirectRegOff; ///< PCI indirect register offset + UINT32 WriteEnBit; ///< Write Enable bit + UINT32 AndMask; ///< And Mask + UINT32 OrMask; ///< Or Mask +} IDS_REG_PCI_INDIRECT; + +VOID +IdsRegSetMsrCmnTask ( + IN IDS_REG_MSR *PRegMsr, + IN OUT AMD_CONFIG_PARAMS *StdHeader +); + +VOID +IdsRegSetMsr ( + IN IDS_REG_MSR *PMsrReg, + IN OUT AMD_CONFIG_PARAMS *StdHeader +); + +AGESA_STATUS +IdsRegSetMemBitField ( + IN IDS_REG_MEM *PMemReg, + IN OUT MEM_NB_BLOCK *NBPtr +); + +VOID +IdsFamRegAccess ( + IN IDS_FAM_REG *PFamReg, + IN OUT AMD_CONFIG_PARAMS *StdHeader +); + +VOID +IdsRegSetPciIndirect ( + IN IDS_REG_PCI_INDIRECT *PPciIndirectReg, + IN OUT AMD_CONFIG_PARAMS *StdHeader +); + +VOID +IdsRegSetDrCmnTask ( + IN IDS_REG_DR *PRegDr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +IdsRegSetDr ( + IN IDS_REG_DR *PDrReg, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + + +#endif //_IDSREGACC_H_ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/OptionsIds.h b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/OptionsIds.h new file mode 100644 index 0000000000..10c2e4acd5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/OptionsIds.h @@ -0,0 +1,92 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * IDS Option File + * + * This file is used to switch on/off IDS features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Core + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ +#ifndef _OPTION_IDS_H_ +#define _OPTION_IDS_H_ + +/** + * + * This file generates the defaults tables for the Integrated Debug Support + * Module. The documented build options are imported from a user controlled + * file for processing. The build options for the Integrated Debug Support + * Module are listed below: + * + * IDSOPT_IDS_ENABLED + * IDSOPT_ERROR_TRAP_ENABLED + * IDSOPT_CONTROL_ENABLED + * + * Warning: When you enable the IDSOPT_CONTROL_NV_TO_CMOS feature. + * please make the cmos region defined by IDS_OPT_CMOS_REGION_START & + * IDS_OPT_CMOS_REGION_END can be touched between IDS HOOK point + * IDS_CPU_Early_Override and IDS_BEFORE_AP_EARLY_HALT of BSP + * + * IDSOPT_CONTROL_NV_TO_CMOS + * IDS_OPT_CMOS_INDEX_PORT + * IDS_OPT_CMOS_DATA_PORT + * IDS_OPT_CMOS_REGION_START + * IDS_OPT_CMOS_REGION_END + * + * IDSOPT_TRACING_ENABLED + * IDSOPT_TRACING_CONSOLE_HDTOUT + * IDSOPT_TRACING_CONSOLE_SERIALPORT + * IDSOPT_SERIAL_PORT (default 0x3F8) + * IDSOPT_TRACING_CONSOLE_REDIRECT_IO + * IDSOPT_DEBUG_PRINT_IO_PORT (default 0x80) + * IDSOPT_TRACING_CONSOLE_RAM + * IDSOPT_DPRAM_BASE + * IDSOPT_DPRAM_SIZE + * IDSOPT_DPRAM_STOP_LOGGING_WHEN_BUFFER_FULL (default FALSE) + * IDSOPT_CUSTOMIZE_TRACING_SERVICE + * IDSOPT_CUSTOMIZE_TRACING_SERVICE_INIT + * IDSOPT_CUSTOMIZE_TRACING_SERVICE_EXIT + * + * IDSOPT_TRACE_BLD_CFG + * IDSOPT_PERF_ANALYSIS + * IDSOPT_ASSERT_ENABLED + * IDS_DEBUG_PORT + * IDSOPT_CAR_CORRUPTION_CHECK_ENABLED + * IDSOPT_DEBUG_CODE_ENABLED + * IDSOPT_IDT_EXCEPTION_TRAP + * IDSOPT_C_OPTIMIZATION_DISABLED + * + **/ + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ardk/ma.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ardk/ma.c new file mode 100644 index 0000000000..664409e01f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ardk/ma.c @@ -0,0 +1,145 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * ma.c + * + * Initializes ARDK Block + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ardk) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "ma.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_ARDK_MA_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This is the default return function of the ARDK block. The function always + * returns AGESA_UNSUPPORTED + * + * @param[in,out] *MemData Pointer to MEM_DATA_STRUCTURE + * @param[in] SocketID Socket number + * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT + * + * @return AGESA_UNSUPPORTED AGESA status indicating that default is unsupported + * + */ + +AGESA_STATUS +MemAGetPsCfgDef ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ) +{ + return AGESA_UNSUPPORTED; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns the rank type map of a channel. + * + * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT + * + * @return UINT16 - The map of rank type. + * + */ +UINT16 +MemAGetPsRankType ( + IN CH_DEF_STRUCT *CurrentChannel + ) +{ + UINT8 i; + UINT16 DIMMRankType; + + DIMMRankType = 0; + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) { + if (CurrentChannel->MCTPtr->Status[SbLrdimms]) { + if ((CurrentChannel->LrDimmPresent & (UINT8) 1 << i) != 0) { + DIMMRankType |= (UINT16) 1 << (i << 2); + } + } else { + if ((CurrentChannel->DimmQrPresent & (UINT8) 1 << i) != 0) { + if (i < 2) { + DIMMRankType |= (UINT16) 4 << (i << 2); + } + } else if ((CurrentChannel->DimmDrPresent & (UINT8) 1 << i) != 0) { + DIMMRankType |= (UINT16) 2 << (i << 2); + } else if ((CurrentChannel->DimmSRPresent & (UINT8) 1 << i) != 0) { + DIMMRankType |= (UINT16) 1 << (i << 2); + } + } + } + return DIMMRankType; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CRAT/mfCrat.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CRAT/mfCrat.h new file mode 100644 index 0000000000..e7f9267864 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CRAT/mfCrat.h @@ -0,0 +1,95 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfCrat.h + * + * Feature CRAT table support + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + +#ifndef _MFCRAT_H_ +#define _MFCRAT_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/// DCT Select Interleaving Address Mapping +typedef struct { + UINT8 DctSelIntLvAddr; ///< F2x110 DctSelIntLvAddr + UINT8 DctSelFunctionBit; ///< Lowest function bit to select DCT for interleaving +} DCTSELBIT_ENTRY; + +/// CRAT Memory Affinity Info Header +typedef struct { + UINT8 NumOfMemAffinityInfoEntries; ///< Integer that represents the proximity domain to + UINT32 MemoryWidth; ///< Specifies the number of parallel bits of the memory interface +} CRAT_MEMORY_AFFINITY_INFO_HEADER; + +/// CRAT Memory Affinity Info Entry +typedef struct { + UINT8 Domain; ///< Integer that represents the proximity domain to + ///< which the memory belongs + UINT32 BaseAddressLow; ///< Low 32Bits of the Base Address of the memory range + UINT32 BaseAddressHigh; ///< High 32Bits of the Base Address of the memory range + UINT32 LengthLow; ///< Low 32Bits of the length of the memory range + UINT32 LengthHigh; ///< High 32Bits of the length of the memory range +} CRAT_MEMORY_AFFINITY_INFO_ENTRY; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +#endif /* _MFCRAT_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.c new file mode 100644 index 0000000000..8baba277e6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.c @@ -0,0 +1,357 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfcsi.c + * + * Feature bank interleaving support (AKA Chip Select Interleaving ) + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/Csintlv) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + +/* This file contains functions for Chip Select interleaving */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mfcsi.h" +#include "Ids.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_CSINTLV_MFCSI_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +STATIC +MemFDctInterleaveBanks ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +STATIC +CsIntSwap ( + IN OUT UINT32 *BaseMaskRegPtr, + IN UINT8 EnChipSels, + IN UINT8 LoBit, + IN UINT8 HiBit + ); + +BOOLEAN +MemFUndoInterleaveBanks ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function Applies DIMM bank (chip-select) interleaving if enabled + * and if all criteria are met. Interleaves chip-selects on page boundaries. + * This function calls subfunctions that sets up CS interleaving on multiple Sockets + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ + +BOOLEAN +MemFInterleaveBanks ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + BOOLEAN RetFlag; + + ASSERT (NBPtr != NULL); + + RetFlag = FALSE; + if (NBPtr->RefPtr->EnableBankIntlv) { + if (NBPtr->MCTPtr->NodeMemSize) { + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + RetFlag |= MemFDctInterleaveBanks (NBPtr); + } + } + } + return RetFlag; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function checks if bank interleaving has been enabled or not. If yes, it will + * undo bank interleaving. Otherwise, it does nothing. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - Bank interleaving has been enabled. + * @return FALSE - Bank interleaving has not been enabled. + */ + +BOOLEAN +MemFUndoInterleaveBanks ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Cs; + UINT8 Dct; + UINT32 CSMask; + BOOLEAN CSIntlvEnabled; + BOOLEAN RetFlag; + + ASSERT (NBPtr != NULL); + + RetFlag = FALSE; + + if (NBPtr->RefPtr->EnableBankIntlv) { + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize) { + CSIntlvEnabled = FALSE; + for (Cs = 0; Cs < MAX_CS_PER_CHANNEL; Cs++) { + if ((NBPtr->GetBitField (NBPtr, BFCSBaseAddr0Reg + Cs) & 1) != 0) { + CSMask = NBPtr->GetBitField (NBPtr, BFCSMask0Reg + (Cs / 2)); + if (((CSMask >> 5) & 0x1FF) != 0x1FF) { + CSIntlvEnabled = TRUE; + break; + } + } + } + if (CSIntlvEnabled) { + MemFDctInterleaveBanks (NBPtr); + RetFlag = TRUE; + } + } + } + } + return RetFlag; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function Applies DIMM bank (chip-select) interleaving if enabled + * and if all criteria are met. Interleaves chip-selects on page boundaries. + * This function is run once per Socket + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - Register bits have been swapped. + * @return FALSE - Register bits have not been swapped. + * + */ + +BOOLEAN +STATIC +MemFDctInterleaveBanks ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Cs; + UINT8 EnChipSels; + UINT8 BankEncd; + UINT8 BankEncd0; + UINT8 i; + UINT8 j; + UINT32 BankAddrReg; + UINT32 BaseRegS0; + UINT32 BaseRegS1; + UINT32 MaskReg; + UINT8 Offset; + UINT8 Dct; + + ASSERT (NBPtr != NULL); + + Dct = NBPtr->Dct; + + // Check if CS interleaving can be enabled + EnChipSels = 0; + BankEncd0 = 0xFF; + Offset = 0; + for (Cs = 0; Cs < MAX_CS_PER_CHANNEL; Cs++) { + if ((NBPtr->GetBitField (NBPtr, BFCSBaseAddr0Reg + Cs) & 3) != 0) { + BankAddrReg = NBPtr->GetBitField (NBPtr, BFDramBankAddrReg); + BankEncd = (UINT8) ((BankAddrReg >> ((Cs / 2) * 4)) & 0xF); + if (BankEncd0 == 0xFF) { + BankEncd0 = BankEncd; + } else if (BankEncd0 != BankEncd) { + break; + } + if ((NBPtr->GetBitField (NBPtr, BFCSBaseAddr0Reg + Cs) & 1) != 0) { + EnChipSels++; + } + } + } + + // Swap Dram Base/Mask Addr to enable CS interleaving + if ((Cs == MAX_CS_PER_CHANNEL) && ((EnChipSels == 2) || (EnChipSels == 4) || (EnChipSels == 8))) { + NBPtr->TechPtr->GetCSIntLvAddr (BankEncd0, &i, &j); + NBPtr->DCTPtr->BankAddrMap = BankEncd0; + NBPtr->DCTPtr->EnabledChipSels = EnChipSels; + // Family specific CS interleaving low address adjustment + NBPtr->FamilySpecificHook[AdjustCSIntLvLowAddr] (NBPtr, &i); + + if (NBPtr->MCTPtr->Status[Sb128bitmode]) { + i++; + j++; + } + + for (Cs = 0; Cs < MAX_CS_PER_CHANNEL; Cs += 2) { + // + // LRDIMMS - Add an offset to the bit positions specified based on D18F2x[6C:60]_dct[1:0][RankDef] as follows: + // RankDef=0xb: 0 RankDef=10b: 1 RankDef=11b: 2 + // Using RankMult information: Lo/HiBit <<= (Mult >> 1) + // + if (NBPtr->MCTPtr->Status[SbLrdimms]) { + Offset = ((NBPtr->ChannelPtr->LrDimmRankMult[Cs >> 1]) >> 1); + } + BaseRegS0 = NBPtr->GetBitField (NBPtr, BFCSBaseAddr0Reg + Cs); + BaseRegS1 = NBPtr->GetBitField (NBPtr, BFCSBaseAddr0Reg + Cs + 1); + if (((BaseRegS0 | BaseRegS1) & 1) != 0) { + // Swap Mask register bits + MaskReg = NBPtr->GetBitField (NBPtr, BFCSMask0Reg + (Cs / 2)); + CsIntSwap (&MaskReg, EnChipSels, (i + Offset), (j + Offset)); + NBPtr->SetBitField (NBPtr, BFCSMask0Reg + (Cs / 2), MaskReg); + + // Swap Base register bits + CsIntSwap (&BaseRegS0, EnChipSels, (i + Offset), (j + Offset)); + NBPtr->SetBitField (NBPtr, BFCSBaseAddr0Reg + Cs, BaseRegS0); + CsIntSwap (&BaseRegS1, EnChipSels, (i + Offset), (j + Offset)); + NBPtr->SetBitField (NBPtr, BFCSBaseAddr0Reg + Cs + 1, BaseRegS1); + } + } + // + // Bank Interleaving is requested and has been enabled as well + // + NBPtr->MCTPtr->DctData[Dct].BkIntDis = FALSE; + return TRUE; + } else { + // + // Bank Interleaving is requested but cannot be enabled + // + PutEventLog (AGESA_WARNING, MEM_WARNING_BANK_INTERLEAVING_NOT_ENABLED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_WARNING, NBPtr->MCTPtr); + NBPtr->MCTPtr->DctData[Dct].BkIntDis = TRUE; + } + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This supporting function swaps Chip selects + * + * @param[in,out] *BaseMaskRegPtr - Pointer to the Mask Register + * @param[in] *EnChipSels - Chip Selects to Enable + * @param[in] *LoBit - Lowest Bit + * @param[in] *HiBit - Highest Bit + * + * + */ + +VOID +STATIC +CsIntSwap ( + IN OUT UINT32 *BaseMaskRegPtr, + IN UINT8 EnChipSels, + IN UINT8 LoBit, + IN UINT8 HiBit + ) +{ + UINT8 BitDelta; + UINT32 TempHi; + UINT32 TempLo; + UINT32 AddrLoMask; + UINT32 AddrHiMask; + + ASSERT (BaseMaskRegPtr != NULL); + ASSERT (HiBit > LoBit); + + BitDelta = HiBit - LoBit; + AddrLoMask = (((UINT32)EnChipSels) - 1) << LoBit; + AddrHiMask = AddrLoMask << BitDelta; + + TempHi = TempLo = *BaseMaskRegPtr; + TempLo &= AddrLoMask; + TempLo <<= BitDelta; // move lower bits to upper bit position + TempHi &= AddrHiMask; + TempHi >>= BitDelta; // move upper bits to lower bit position + + *BaseMaskRegPtr &= ~AddrLoMask; + *BaseMaskRegPtr &= ~AddrHiMask; + *BaseMaskRegPtr |= TempLo | TempHi; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.h new file mode 100644 index 0000000000..b660f05d55 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/CSINTLV/mfcsi.h @@ -0,0 +1,80 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfcsi.h + * + * Memory Controller + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + +#ifndef _MFCSI_H_ +#define _MFCSI_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemFInterleaveBanks ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +#endif /* _MFCSI_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c new file mode 100644 index 0000000000..af7bdaf357 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/DMI/mfDMI.c @@ -0,0 +1,721 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfDMI.c + * + * Memory DMI table support. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "Ids.h" +#include "heapManager.h" +#include "cpuServices.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_DMI_MFDMI_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +#define MAX_DCTS_PER_DIE 2 + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +UINT64 +MemFGetNodeMemBase ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 NodeLimit + ); + +UINT64 +MemFGetDctMemBase ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 DctLimit + ); + +UINT64 +MemFGetDctInterleavedMemSize ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +UINT64 +MemFGetDctInterleavedLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct, + IN UINT64 DctMemBase, + IN UINT64 DctInterleavedMemSize + ); + +BOOLEAN +MemFDMISupport3 ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets DDR3 DMI information from SPD buffer and stores the info into heap + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + */ +BOOLEAN +MemFDMISupport3 ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 i; + UINT8 Dimm; + UINT8 Socket; + UINT8 NodeId; + UINT8 Dct; + UINT8 Channel; + UINT8 temp; + UINT16 LocalHandle; + UINT8 MaxPhysicalDimms; + UINT8 MaxLogicalDimms; + UINT8 NumLogicalDimms; + UINT32 *TotalMemSizePtr; + UINT8 *DmiTable; + UINT8 MaxChannelsPerSocket; + UINT8 MaxDimmsPerChannel; + UINT8 FormFactor; + UINT16 TotalWidth; + UINT16 Capacity; + UINT16 Width; + UINT16 Rank; + UINT16 BusWidth; + UINT64 ManufacturerIdCode; + UINT32 MaxSockets; + UINT32 Address; + UINT8 ChipSelectPairScale; + UINT32 TotalSize; + UINT32 DimmSize; + UINT32 CsBaseAddrReg0; + UINT32 CsBaseAddrReg1; + UINT64 AddrValue; + UINT64 DctMemBase; + UINT64 NodeMemBase; + UINT64 SysMemSize; + INT32 MTB_ps; + INT32 FTB_ps; + INT32 Value32; + BOOLEAN DctInterleaveEnabled; + UINT64 DctInterleavedMemSize; + BOOLEAN NodeInterleaveEnabled; + UINT16 T17HandleMatrix[MAX_SOCKETS_SUPPORTED][MAX_CHANNELS_PER_SOCKET][MAX_DIMMS_PER_CHANNEL]; + + MEM_NB_BLOCK *NBPtr; + MEM_PARAMETER_STRUCT *RefPtr; + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + CH_DEF_STRUCT *ChannelPtr; + SPD_DEF_STRUCT *SpdDataStructure; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + MEM_DMI_PHYSICAL_DIMM_INFO *DmiPhysicalDimmInfoTable; + MEM_DMI_LOGICAL_DIMM_INFO *DmiLogicalDimmInfoTable; + DMI_T17_MEMORY_TYPE *DmiType17MemTypePtr; + + NBPtr = MemMainPtr->NBPtr; + MemPtr = MemMainPtr->MemPtr; + SpdDataStructure = MemPtr->SpdDataStructure; + MCTPtr = NBPtr->MCTPtr; + RefPtr = MemPtr->ParameterListPtr; + + // Initialize local variables + LocalHandle = 1; + MaxPhysicalDimms = 0; + MaxLogicalDimms = 0; + NumLogicalDimms = 0; + TotalSize = 0; + NodeMemBase = 0; + SysMemSize = 0; + + AGESA_TESTPOINT (TpProcMemDmi, &MemPtr->StdHeader); + + ASSERT (NBPtr != NULL); + + MaxSockets = (UINT8) (0x000000FF & GetPlatformNumberOfSockets ()); + for (Socket = 0; Socket < MaxSockets; Socket++) { + for (Channel = 0; Channel < GetMaxChannelsPerSocket (RefPtr->PlatformMemoryConfiguration, Socket, &MemPtr->StdHeader); Channel++) { + temp = (UINT8) GetMaxDimmsPerChannel (RefPtr->PlatformMemoryConfiguration, Socket, Channel); + MaxPhysicalDimms = MaxPhysicalDimms + temp; + MaxLogicalDimms += MAX_DIMMS_PER_CHANNEL; + } + } + + // Allocate heap for memory DMI table 16, 17, 19, 20 + AllocHeapParams.RequestedBufferSize = sizeof (UINT8) + // Storage for MaxPhysicalDimms + sizeof (UINT8) + // Storage for Type Detail + sizeof (UINT32) + // Storage for Total Memory Size + sizeof (DMI_T17_MEMORY_TYPE) + + MaxPhysicalDimms * sizeof (MEM_DMI_PHYSICAL_DIMM_INFO) + + sizeof (UINT8) + // Storage for MaxLogicalDimms + MaxLogicalDimms * sizeof (MEM_DMI_LOGICAL_DIMM_INFO); + + AllocHeapParams.BufferHandle = AMD_DMI_MEM_DEV_INFO_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (AGESA_SUCCESS != HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader)) { + PutEventLog (AGESA_CRITICAL, MEM_ERROR_HEAP_ALLOCATE_FOR_DMI_TABLE_DDR3, NBPtr->Node, 0, 0, 0, &MemPtr->StdHeader); + SetMemError (AGESA_CRITICAL, MCTPtr); + // Could not allocate heap for memory DMI table 16,17,19 and 20 for DDR3 + ASSERT (FALSE); + return FALSE; + } + + DmiTable = (UINT8 *) AllocHeapParams.BufferPtr; + // Max number of physical DIMMs + *DmiTable = MaxPhysicalDimms; + DmiTable ++; + // Type Detail; + *DmiTable = 0; + DmiTable ++; + // Pointer to total memory size + TotalMemSizePtr = (UINT32 *) DmiTable; + DmiTable += sizeof (UINT32); + // Memory Type + DmiType17MemTypePtr = (DMI_T17_MEMORY_TYPE *) DmiTable; + *DmiType17MemTypePtr = Ddr3MemType; + DmiType17MemTypePtr ++; + DmiTable = (UINT8 *) DmiType17MemTypePtr; + // Pointer to DMI info of Physical DIMMs + DmiPhysicalDimmInfoTable = (MEM_DMI_PHYSICAL_DIMM_INFO *) DmiTable; + + // + // Gather physical DIMM DMI info + // + for (Socket = 0; Socket < MaxSockets; Socket ++) { + MaxChannelsPerSocket = GetMaxChannelsPerSocket (RefPtr->PlatformMemoryConfiguration, Socket, &MemPtr->StdHeader); + DctMemBase = 0; + for (Channel = 0; Channel < MaxChannelsPerSocket; Channel ++) { + // + // Get Node number and Dct number for this channel + // + ChannelPtr = MemPtr->SocketList[Socket].ChannelPtr[Channel]; + NodeId = ChannelPtr->MCTPtr->NodeId; + NBPtr = MemMainPtr->NBPtr; + Dct = ChannelPtr->Dct; + NBPtr = &NBPtr[NodeId]; + NBPtr->SwitchDCT (NBPtr, Dct); + + MaxDimmsPerChannel = GetMaxDimmsPerChannel (RefPtr->PlatformMemoryConfiguration, Socket, Channel); + for (Dimm = 0; Dimm < MaxDimmsPerChannel; Dimm ++, SpdDataStructure ++, LocalHandle++) { + // + // Initialize default value for DMI fields + // + DmiPhysicalDimmInfoTable->DimmPresent = 0; + DmiPhysicalDimmInfoTable->Socket = Socket; + DmiPhysicalDimmInfoTable->Channel = Channel; + DmiPhysicalDimmInfoTable->Dimm = Dimm; + DmiPhysicalDimmInfoTable->TotalWidth = 0xFFFF; + DmiPhysicalDimmInfoTable->DataWidth = 0xFFFF; + DmiPhysicalDimmInfoTable->MemorySize = 0; + DmiPhysicalDimmInfoTable->Speed = 0; + DmiPhysicalDimmInfoTable->ManufacturerIdCode = 0; + DmiPhysicalDimmInfoTable->Attributes = 0; + DmiPhysicalDimmInfoTable->ConfigSpeed = 0; + DmiPhysicalDimmInfoTable->ExtSize = 0; + DmiPhysicalDimmInfoTable->FormFactor = UnknowFormFactor; + DmiPhysicalDimmInfoTable->Handle = LocalHandle; + T17HandleMatrix[Socket][Channel][Dimm] = LocalHandle; + + for (i = 0; i < 4; i++) { + DmiPhysicalDimmInfoTable->SerialNumber[i] = 0xFF; + } + + for (i = 0; i < 18; i++) { + DmiPhysicalDimmInfoTable->PartNumber[i] = 0x0; + } + + if (SpdDataStructure->DimmPresent) { + // Total Width (offset 08h) & Data Width (offset 0Ah) + TotalWidth = (UINT16) SpdDataStructure->Data[8]; + if ((TotalWidth & 0x18) == 0) { + // non ECC + if ((TotalWidth & 0x07) == 0) { + DmiPhysicalDimmInfoTable->TotalWidth = 8; // 8 bits + } else if ((TotalWidth & 0x07) == 1) { + DmiPhysicalDimmInfoTable->TotalWidth = 16; // 16 bits + } else if ((TotalWidth & 0x07) == 2) { + DmiPhysicalDimmInfoTable->TotalWidth = 32; // 32 bits + } else if ((TotalWidth & 0x07) == 3) { + DmiPhysicalDimmInfoTable->TotalWidth = 64; // 64 bits + } + DmiPhysicalDimmInfoTable->DataWidth = DmiPhysicalDimmInfoTable->TotalWidth ; + } else { + // ECC + if ((TotalWidth & 0x07) == 0) { + DmiPhysicalDimmInfoTable->TotalWidth = 8 + 8; // 8 bits + } else if ((TotalWidth & 0x07) == 1) { + DmiPhysicalDimmInfoTable->TotalWidth = 16 + 8; // 16 bits + } else if ((TotalWidth & 0x07) == 2) { + DmiPhysicalDimmInfoTable->TotalWidth = 32 + 8; // 32 bits + } else if ((TotalWidth & 0x07) == 3) { + DmiPhysicalDimmInfoTable->TotalWidth = 64 + 8; // 64 bits + } + DmiPhysicalDimmInfoTable->DataWidth = DmiPhysicalDimmInfoTable->TotalWidth - 8; + } + + // Memory Size (offset 0Ch) + Capacity = 0; + BusWidth = 0; + Width = 0; + Rank = 0; + temp = (UINT8) SpdDataStructure->Data[4]; + if ((temp & 0x0F) == 0) { + Capacity = 0x0100; // 256M + } else if ((temp & 0x0F) == 1) { + Capacity = 0x0200; // 512M + } else if ((temp & 0x0F) == 2) { + Capacity = 0x0400; // 1G + } else if ((temp & 0x0F) == 3) { + Capacity = 0x0800; // 2G + } else if ((temp & 0x0F) == 4) { + Capacity = 0x1000; // 4G + } else if ((temp & 0x0F) == 5) { + Capacity = 0x2000; // 8G + } else if ((temp & 0x0F) == 6) { + Capacity = 0x4000; // 16G + } + + temp = (UINT8) SpdDataStructure->Data[8]; + if ((temp & 0x07) == 0) { + BusWidth = 8; // 8 bits + } else if ((temp & 0x07) == 1) { + BusWidth = 16; // 16 bits + } else if ((temp & 0x07) == 2) { + BusWidth = 32; // 32 bits + } else if ((temp & 0x07) == 3) { + BusWidth = 64; // 64 bits + } + + temp = (UINT8) SpdDataStructure->Data[7]; + if ((temp & 0x07) == 0) { + Width = 4; // 4 bits + } else if ((temp & 0x07) == 1) { + Width = 8; // 8 bits + } else if ((temp & 0x07) == 2) { + Width = 16; // 16 bits + } else if ((temp & 0x07) == 3) { + Width = 32; // 32 bits + } + + temp = (UINT8) SpdDataStructure->Data[7]; + if (((temp >> 3) & 0x07) == 0) { + Rank = 1; // 4 bits + DmiPhysicalDimmInfoTable->Attributes = 1; // Single Rank Dimm + } else if (((temp >> 3) & 0x07) == 1) { + Rank = 2; // 8 bits + DmiPhysicalDimmInfoTable->Attributes = 2; // Dual Rank Dimm + } else if (((temp >> 3) & 0x07) == 2) { + Rank = 3; // 16 bits + } else if (((temp >> 3) & 0x07) == 3) { + Rank = 4; // 32 bits + DmiPhysicalDimmInfoTable->Attributes = 4; // Quad Rank Dimm + } + + DimmSize = (UINT32) (Capacity / 8 * BusWidth / Width * Rank); + if (DimmSize < 0x7FFF) { + DmiPhysicalDimmInfoTable->MemorySize = (UINT16) DimmSize; + } else { + DmiPhysicalDimmInfoTable->MemorySize = 0x7FFF; + DmiPhysicalDimmInfoTable->ExtSize = DimmSize; + } + + // Form Factor (offset 0Eh) + FormFactor = (UINT8) SpdDataStructure->Data[3]; + if (((FormFactor & 0x0F) == 0x01) || ((FormFactor & 0x0F) == 0x02) || ((FormFactor & 0x0F) == 0x0B)) { + DmiPhysicalDimmInfoTable->FormFactor = 0x09; // RDIMM or UDIMM or LRDIMM + } else if ((FormFactor & 0x0F) == 0x03) { + DmiPhysicalDimmInfoTable->FormFactor = 0x0D; // SO-DIMM + } else { + DmiPhysicalDimmInfoTable->FormFactor = 0x02; // UNKNOWN + } + + // DIMM Present + DmiPhysicalDimmInfoTable->DimmPresent = 1; + + // Type Detail (offset 13h) + if (((FormFactor & 0x0F) == 0x01) || ((FormFactor & 0x0F) == 0x0B)) { + *((UINT8 *) (AllocHeapParams.BufferPtr) + 1) = 1; // Registered (Buffered) + } else { + *((UINT8 *) (AllocHeapParams.BufferPtr) + 1) = 2; // Unbuffered (Unregistered) + } + + // Speed (offset 15h) + MTB_ps = ((INT32) SpdDataStructure->Data[10] * 1000) / SpdDataStructure->Data[11]; + FTB_ps = (SpdDataStructure->Data[9] >> 4) / (SpdDataStructure->Data[9] & 0xF); + Value32 = (MTB_ps * SpdDataStructure->Data[12]) + (FTB_ps * (INT8) SpdDataStructure->Data[34]) ; + if (Value32 <= 938) { + DmiPhysicalDimmInfoTable->Speed = 1067; // DDR3-2133 + } else if (Value32 <= 1071) { + DmiPhysicalDimmInfoTable->Speed = 933; // DDR3-1866 + } else if (Value32 <= 1250) { + DmiPhysicalDimmInfoTable->Speed = 800; // DDR3-1600 + } else if (Value32 <= 1500) { + DmiPhysicalDimmInfoTable->Speed = 667; // DDR3-1333 + } else if (Value32 <= 1875) { + DmiPhysicalDimmInfoTable->Speed = 533; // DDR3-1066 + } else if (Value32 <= 2500) { + DmiPhysicalDimmInfoTable->Speed = 400; // DDR3-800 + } + + // Manufacturer (offset 17h) + ManufacturerIdCode = (UINT64) SpdDataStructure->Data[118]; + DmiPhysicalDimmInfoTable->ManufacturerIdCode = (ManufacturerIdCode << 8) | ((UINT64) SpdDataStructure->Data[117]); + + // Serial Number (offset 18h) + for (i = 0; i < 4; i++) { + DmiPhysicalDimmInfoTable->SerialNumber[i] = (UINT8) SpdDataStructure->Data[i + 122]; + } + // Part Number (offset 1Ah) + for (i = 0; i < 18; i++) { + DmiPhysicalDimmInfoTable->PartNumber[i] = (UINT8) SpdDataStructure->Data[i + 128]; + } + + // Configured Memory Clock Speed (offset 20h) + DmiPhysicalDimmInfoTable->ConfigSpeed = NBPtr->DCTPtr->Timings.Speed; + } // Dimm present + TotalSize += (UINT32) DmiPhysicalDimmInfoTable->MemorySize; + DmiPhysicalDimmInfoTable ++; + } // Dimm loop + } // Channel loop + } // Socket loop + + // Max number of logical DIMMs + DmiTable = (UINT8 *) DmiPhysicalDimmInfoTable; + *DmiTable = MaxLogicalDimms; + DmiTable ++; + + // Pointer to DMI info of Logical DIMMs + DmiLogicalDimmInfoTable = (MEM_DMI_LOGICAL_DIMM_INFO *) DmiTable; + + // Calculate the total memory size in the system + SysMemSize = MemFGetNodeMemBase (MemMainPtr->NBPtr, MemPtr->DieCount); + // + // Gather logical DIMM DMI info + // + for (Socket = 0; Socket < MaxSockets; Socket ++) { + MaxChannelsPerSocket = GetMaxChannelsPerSocket (RefPtr->PlatformMemoryConfiguration, Socket, &MemPtr->StdHeader); + DctMemBase = 0; + for (Channel = 0; Channel < MaxChannelsPerSocket; Channel ++) { + MaxDimmsPerChannel = GetMaxDimmsPerChannel (RefPtr->PlatformMemoryConfiguration, Socket, Channel); + // + // Get Node number and Dct number for this channel + // + ChannelPtr = MemPtr->SocketList[Socket].ChannelPtr[Channel]; + NodeId = ChannelPtr->MCTPtr->NodeId; + NBPtr = MemMainPtr->NBPtr; + Dct = ChannelPtr->Dct; + NodeMemBase = MemFGetNodeMemBase (NBPtr, NodeId); + NBPtr = &NBPtr[NodeId]; + + DctMemBase = MemFGetDctMemBase (NBPtr, Dct); + DctInterleavedMemSize = MemFGetDctInterleavedMemSize (NBPtr); + NBPtr->SwitchDCT (NBPtr, Dct); + NodeInterleaveEnabled = (NBPtr->GetBitField (NBPtr, BFDramIntlvEn) == 0) ? FALSE : TRUE; + DctInterleaveEnabled = (NBPtr->GetBitField (NBPtr, BFDctSelIntLvEn) == 0) ? FALSE : TRUE; + + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm ++, DmiLogicalDimmInfoTable ++) { + // + // Initialize default value for DMI fields + // + DmiLogicalDimmInfoTable->DimmPresent = 0; + DmiLogicalDimmInfoTable->Socket = Socket; + DmiLogicalDimmInfoTable->Channel = Channel; + DmiLogicalDimmInfoTable->Dimm = Dimm; + DmiLogicalDimmInfoTable->StartingAddr = 0; + DmiLogicalDimmInfoTable->EndingAddr = 0; + DmiLogicalDimmInfoTable->ExtStartingAddr = 0; + DmiLogicalDimmInfoTable->ExtEndingAddr = 0; + // + // Starting/Ending Address for each DIMM + // + // If Ending Address >= 0xFFFFFFFF, update Starting Address & Ending Address to 0xFFFFFFFF, + // and use the Extended Starting Address & Extended Ending Address instead. + // + CsBaseAddrReg0 = NBPtr->GetBitField (NBPtr, BFCSBaseAddr0Reg + 2 * Dimm); + CsBaseAddrReg1 = NBPtr->GetBitField (NBPtr, BFCSBaseAddr0Reg + 2 * Dimm + 1); + if ((CsBaseAddrReg0 & 1) != 0 || (CsBaseAddrReg1 & 1) != 0) { + ASSERT (NumLogicalDimms < MaxLogicalDimms); + NumLogicalDimms ++; + DmiLogicalDimmInfoTable->DimmPresent = 1; + if (Dimm < MaxDimmsPerChannel) { + // The logical DIMM is mapped from a SR/QR physical DIMM + DmiLogicalDimmInfoTable->MemoryDeviceHandle = T17HandleMatrix[Socket][Channel][Dimm]; + } else { + // The logical DIMM is mapped from a QR physical DIMM + DmiLogicalDimmInfoTable->MemoryDeviceHandle = T17HandleMatrix[Socket][Channel][Dimm - 2]; + } + // + // For DR and QR DIMMs, DIMM size should be scaled based on the CS pair presence + // + ChipSelectPairScale = ((CsBaseAddrReg0 & 1) != 0 && (CsBaseAddrReg1 & 1) != 0) ? 1 : 0; + Address = ((CsBaseAddrReg0 & 1) != 0 ? CsBaseAddrReg0 : CsBaseAddrReg1) & NBPtr->CsRegMsk; + Address = (Address & 0xFFFF0000) >> 2; + if (DctInterleaveEnabled) { + // + // When channel interleaving is enabled, all the DIMMs on the node share the same starting address + // + Address = (UINT32)NodeMemBase; + } else { + if (NBPtr->DCTPtr->BkIntDis == FALSE && NBPtr->RefPtr->EnableBankIntlv == TRUE) { + // + // When bank interleaving is enabled, all the chip selects share the same starting address + // + Address = (UINT32) (NodeMemBase + DctMemBase); + } else { + Address += (UINT32) (NodeMemBase + DctMemBase); + } + } + if (NodeInterleaveEnabled) { + // + // When node interleaving is enabled, all the DIMMs in the system share the same starting address + // + Address = 0; + } + DmiLogicalDimmInfoTable->StartingAddr = Address; + AddrValue = (UINT64) Address + + ((UINT64) ((NBPtr->GetBitField (NBPtr, BFCSMask0Reg + Dimm) & 0xFFFF0000) + 0x00080000) >> + (2 - ChipSelectPairScale) ) - 1; + if (NBPtr->DCTPtr->BkIntDis == FALSE && NBPtr->RefPtr->EnableBankIntlv == TRUE) { + // + // When bank interleaving is enabled, all the chip selects share the same ending address + // + AddrValue = NodeMemBase + DctMemBase + (NBPtr->DCTPtr->Timings.DctMemSize << 6) - 1; + } + if (DctInterleaveEnabled) { + // + // When channel interleaving is enabled, the interleaved range is accounted for in the ending address of each DCT + // + AddrValue = NodeMemBase + MemFGetDctInterleavedLimit (NBPtr, Dct, DctMemBase, DctInterleavedMemSize); + } + if (NodeInterleaveEnabled) { + // + // When node interleaving is enabled, all the DIMMs in the system share the same ending address + // + AddrValue = SysMemSize - 1; + } + if (AddrValue >= ((UINT64) 0xFFFFFFFF)) { + DmiLogicalDimmInfoTable->StartingAddr = 0xFFFFFFFFUL; + DmiLogicalDimmInfoTable->EndingAddr = 0xFFFFFFFFUL; + DmiLogicalDimmInfoTable->ExtStartingAddr = (UINT64) Address; + DmiLogicalDimmInfoTable->ExtEndingAddr = AddrValue; + } else { + DmiLogicalDimmInfoTable->EndingAddr = (UINT32) AddrValue; + } + } + } // Dimm loop + } // Channel loop + } // Socket loop + + // Max Capacity + *TotalMemSizePtr = TotalSize; + + return TRUE; +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/** + * + * + * This function obtains the memory size RJ6 contributed by the previous nodes + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] NodeLimit - Node number + * + */ +UINT64 +MemFGetNodeMemBase ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 NodeLimit + ) +{ + UINT8 Node; + UINT64 NodeMemBase; + + NodeMemBase = 0; + // Calculate the total memory size in the system + for (Node = 0; Node < NodeLimit; Node++) { + NodeMemBase += (NBPtr[Node].MCTPtr->NodeMemSize << 6); + } + + return NodeMemBase; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function obtains the memory size RJ6 contributed by the previous dcts on + * the current node + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] DctLimit - Dct number + * + */ +UINT64 +MemFGetDctMemBase ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 DctLimit + ) +{ + UINT8 Dct; + UINT64 DctMemBase; + + DctMemBase = 0; + // Calculate the total memory size in the system + for (Dct = 0; Dct < DctLimit; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + DctMemBase += (NBPtr->DCTPtr->Timings.DctMemSize << 6); + } + + return DctMemBase; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function obtains the interleaved memory size RJ6 contributed on the + * current dct + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +UINT64 +MemFGetDctInterleavedMemSize ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + UINT64 DctInterleavedMemSize; + + DctInterleavedMemSize = NBPtr->MCTPtr->NodeMemSize << 6; + // Find minimum memory size among the interleaved DCTs + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (DctInterleavedMemSize > (NBPtr->DCTPtr->Timings.DctMemSize << 6)) { + DctInterleavedMemSize = (NBPtr->DCTPtr->Timings.DctMemSize << 6); + } + } + + return DctInterleavedMemSize; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function obtains the memory ending address RJ6 contributed by a dct + * under channel interleaving + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Dct - Dct number + * @param[in] DctMemBase - Dct memory base + * @param[in] DctInterleavedMemSize - Dct interleaved memory size + * + */ +UINT64 +MemFGetDctInterleavedLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct, + IN UINT64 DctMemBase, + IN UINT64 DctInterleavedMemSize + ) +{ + UINT64 DctMemLimit; + UINT8 i; + + DctMemLimit = 0; + if (DctInterleavedMemSize == NBPtr->DCTPtr->Timings.DctMemSize << 6) { + // The whole memory range is interleaved for the DCTs with the minimum memory size + for (i = 0; i < NBPtr->DctCount; i++) { + DctMemLimit += DctInterleavedMemSize; + } + DctMemLimit -= 1; + } else { + // Part of the memory range is interleaved for the DCTs with memory size larger than + // the minimum. The remaining is treated as non-interleaved. + for (i = 0; i < NBPtr->DctCount - 1 - Dct; i++) { + DctMemLimit += DctInterleavedMemSize; + } + DctMemLimit += DctMemBase + (NBPtr->DCTPtr->Timings.DctMemSize << 6) - 1; + } + + return DctMemLimit; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.c new file mode 100644 index 0000000000..7ff3960971 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.c @@ -0,0 +1,290 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfecc.c + * + * Feature ECC initialization functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/ECC) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mfecc.h" +#include "Filecode.h" +#include "mfmemclr.h" +#include "GeneralServices.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_ECC_MFECC_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +InitECCOverriedeStruct ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT ECC_OVERRIDE_STRUCT *pecc_override_struct + ); + +BOOLEAN +MemFCheckECC ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function checks to see if ECC can be enabled on all nodes + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ + +BOOLEAN +MemFCheckECC ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + DIE_STRUCT *MCTPtr; + MEM_SHARED_DATA *SharedPtr; + BOOLEAN ErrorRecovery; + + ASSERT (NBPtr != NULL); + + MCTPtr = NBPtr->MCTPtr; + SharedPtr = NBPtr->SharedPtr; + + ErrorRecovery = TRUE; + IDS_OPTION_HOOK (IDS_MEM_ERROR_RECOVERY, &ErrorRecovery, &NBPtr->MemPtr->StdHeader); + + if (MCTPtr->NodeMemSize != 0) { + if (SharedPtr->AllECC && MCTPtr->Status[SbEccDimms] && (ErrorRecovery || (MCTPtr->ErrCode < AGESA_ERROR))) { + // Clear all MCA reports before using scrubber + // to initialize ECC check bits + // + NBPtr->McaNbCtlReg = NBPtr->GetBitField (NBPtr, BFMcaNbCtlReg); + NBPtr->SetBitField (NBPtr, BFMcaNbCtlReg, 0); + NBPtr->SetBitField (NBPtr, BFSyncOnUcEccEn, 0); + // In unganged mode, set DctDctIntlv + if (!NBPtr->Ganged) { + NBPtr->SetBitField (NBPtr, BFDctDatIntLv, 1); + } + // + // Set Ecc Symbol Size + // + NBPtr->SetEccSymbolSize (NBPtr); + // If ECC can be enabled on this node, + // set the master ECCen bit (according to setup) + // + NBPtr->SetBitField (NBPtr, BFDramEccEn, 1); + // Do mem clear on current node + MemFMctMemClr_Init (NBPtr); + return TRUE; + } else { + if (SharedPtr->AllECC) { + SharedPtr->AllECC = FALSE; + } + // ECC requested but cannot be enabled + MCTPtr->Status[SbEccDimms] = FALSE; + MCTPtr->ErrStatus[EsbDramECCDis] = TRUE; + PutEventLog (AGESA_WARNING, MEM_WARNING_ECC_DIS, NBPtr->Node, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_WARNING, MCTPtr); + } + } + return FALSE; +} + + /* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the ECC on all nodes + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ + +BOOLEAN +MemFInitECC ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Node; + UINT32 ScrubAddrRJ16; + DIE_STRUCT *MCTPtr; + MEM_SHARED_DATA *SharedPtr; + ECC_OVERRIDE_STRUCT ecc_override_struct; + BOOLEAN Flag; + + InitECCOverriedeStruct (NBPtr, &ecc_override_struct); + IDS_OPTION_HOOK (IDS_ECC, &ecc_override_struct, &(NBPtr->MemPtr->StdHeader)); + + ASSERT (NBPtr != NULL); + + MCTPtr = NBPtr->MCTPtr; + Node = MCTPtr->NodeId; + SharedPtr = NBPtr->SharedPtr; + Flag = TRUE; + + NBPtr->FamilySpecificHook[ScrubberErratum] (NBPtr, (VOID *) &Flag); + + if ((MCTPtr->Status[SbEccDimms]) && (SharedPtr->AllECC)) { + // Check if the input dram scrub rate is supported or not + ASSERT (ecc_override_struct.CfgScrubDramRate <= 0x16); + if (ecc_override_struct.CfgScrubDramRate != 0) { + // Program scrub address, + // let the scrub Addr be the Base of this Node + // Only enable Dram scrubber when there is memory on current node + // + NBPtr->SetBitField (NBPtr, BFScrubReDirEn, 0); + ScrubAddrRJ16 = (NBPtr->GetBitField (NBPtr, BFDramBaseReg0 + Node) & 0xFFFF0000) >> 8; + ScrubAddrRJ16 |= NBPtr->GetBitField (NBPtr, BFDramBaseHiReg0 + Node) << 24; + NBPtr->SetBitField (NBPtr, BFScrubAddrLoReg, ScrubAddrRJ16 << 16); + NBPtr->SetBitField (NBPtr, BFScrubAddrHiReg, ScrubAddrRJ16 >> 16); + NBPtr->SetBitField (NBPtr, BFDramScrub, ecc_override_struct.CfgScrubDramRate); + NBPtr->IsSupported[ScrubberEn] = TRUE; + } + } + // Scrub CTL for Dcache, L2, L3 + // Check if the input L2 scrub rate is supported or not + ASSERT (ecc_override_struct.CfgScrubL2Rate <= 0x16); + NBPtr->SetBitField (NBPtr, BFL2Scrub, ecc_override_struct.CfgScrubL2Rate); + // Check if the input Dcache scrub rate is supported or not + ASSERT (ecc_override_struct.CfgScrubDcRate <= 0x16); + NBPtr->SetBitField (NBPtr, BFDcacheScrub, ecc_override_struct.CfgScrubDcRate); + // Do not enable L3 Scrub if F3xE8[L3Capable] is 0 or F3x188[DisableL3] is 1 + if ((NBPtr->GetBitField (NBPtr, BFL3Capable) == 1) && (NBPtr->GetBitField (NBPtr, BFDisableL3) == 0)) { + // Check if input L3 scrub rate is supported or not + ASSERT (ecc_override_struct.CfgScrubL3Rate <= 0x16); + NBPtr->SetBitField (NBPtr, BFL3Scrub, ecc_override_struct.CfgScrubL3Rate); + } + + // Check if Dcache scrubber or L2 scrubber is enabled + if ((ecc_override_struct.CfgScrubL2Rate != 0) || (ecc_override_struct.CfgScrubDcRate!= 0)) { + // If ClkDivisor is deeper than divide-by-16 + if (NBPtr->GetBitField (NBPtr, BFC1ClkDivisor) > 4) { + // Set it to divide-by-16 + NBPtr->SetBitField (NBPtr, BFC1ClkDivisor, 4); + } + } + + NBPtr->SetBitField (NBPtr, BFScrubReDirEn, ecc_override_struct.CfgEccRedirection); + NBPtr->SetBitField (NBPtr, BFSyncOnUcEccEn, ecc_override_struct.CfgEccSyncFlood); + // Restore MCA reports after scrubber is done + // with initializing ECC check bits + NBPtr->SetBitField (NBPtr, BFMcaNbCtlReg, NBPtr->McaNbCtlReg); + + Flag = FALSE; + NBPtr->FamilySpecificHook[ScrubberErratum] (NBPtr, (VOID *) &Flag); + + return TRUE; +} + +VOID +STATIC +InitECCOverriedeStruct ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT ECC_OVERRIDE_STRUCT *pecc_override_struct + ) +{ + // + // If (D18F3x44[DramEccEn]==1) THEN 1 ELSE 0 ENDIF + // + if (NBPtr->GetBitField (NBPtr, BFDramEccEn) == 1) { + pecc_override_struct->CfgEccRedirection = 1; + } else { + pecc_override_struct->CfgEccRedirection = 0; + } + + pecc_override_struct->CfgEccSyncFlood = UserOptions.CfgEccSyncFlood; + pecc_override_struct->CfgScrubDcRate = UserOptions.CfgScrubDcRate; + + if (UserOptions.CfgScrubDramRate != 0xFF) { + pecc_override_struct->CfgScrubDramRate = UserOptions.CfgScrubDramRate; + } else { + if (NBPtr->MCTPtr->NodeMemSize <= 0x4000) { + pecc_override_struct->CfgScrubDramRate = 0x12; // 1 ~ 1 GB + } else if (NBPtr->MCTPtr->NodeMemSize <= 0x8000) { + pecc_override_struct->CfgScrubDramRate = 0x11; // 1 GB + 1 ~ 2 GB + } else if (NBPtr->MCTPtr->NodeMemSize <= 0x10000) { + pecc_override_struct->CfgScrubDramRate = 0x10; // 2 GB + 1 ~ 4 GB + } else if (NBPtr->MCTPtr->NodeMemSize <= 0x20000) { + pecc_override_struct->CfgScrubDramRate = 0x0F; // 4 GB + 1 ~ 8 GB + } else if (NBPtr->MCTPtr->NodeMemSize <= 0x40000) { + pecc_override_struct->CfgScrubDramRate = 0x0E; // 8 GB + 1 ~ 16 GB + } else { + pecc_override_struct->CfgScrubDramRate = 0x0D; //16 GB + 1 above + } + } + + pecc_override_struct->CfgScrubL2Rate = UserOptions.CfgScrubL2Rate; + pecc_override_struct->CfgScrubL3Rate = UserOptions.CfgScrubL3Rate; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.h new file mode 100644 index 0000000000..a25b12e6ab --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfecc.h @@ -0,0 +1,80 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfecc.h + * + * Feature ECC initialization functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + +#ifndef _MFECC_H_ +#define _MFECC_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemFInitECC ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +#endif /* _MFECC_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfemp.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfemp.c new file mode 100644 index 0000000000..54487d2a1b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ECC/mfemp.c @@ -0,0 +1,177 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfemp.c + * + * Feature EMP initialization functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/ECC) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + + + +#include "AGESA.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_ECC_MFEMP_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +IsPowerOfTwo ( + IN UINT32 TestNumber + ); + +BOOLEAN +MemFInitEMP ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes EMP (Enhanced Memory Protection) + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ + +BOOLEAN +MemFInitEMP ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_PARAMETER_STRUCT *RefPtr; + DIE_STRUCT *MCTPtr; + + ASSERT (NBPtr != NULL); + + RefPtr = NBPtr->RefPtr; + MCTPtr = NBPtr->MCTPtr; + if (RefPtr->EnableEccFeature) { + if (NBPtr->GetBitField (NBPtr, BFEnhMemProtCap) == 0) { + PutEventLog (AGESA_WARNING, MEM_WARNING_EMP_NOT_SUPPORTED, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + MCTPtr->ErrStatus[EsbEMPNotSupported] = TRUE; + } else if (RefPtr->EnableChannelIntlv || RefPtr->EnableBankIntlv || RefPtr->EnableBankSwizzle) { + PutEventLog (AGESA_WARNING, MEM_WARNING_EMP_CONFLICT, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + MCTPtr->ErrStatus[EsbEMPConflict] = TRUE; + } else if ((!MCTPtr->GangedMode) && + (!IsPowerOfTwo (MCTPtr->DctData[0].Timings.DctMemSize) && + !IsPowerOfTwo (MCTPtr->DctData[1].Timings.DctMemSize))) { + PutEventLog (AGESA_WARNING, MEM_WARNING_EMP_NOT_ENABLED, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + MCTPtr->ErrStatus[EsbEMPDis] = TRUE; + } else { + // Reduce memory size to 7/8 of the original memory size + ASSERT ((MCTPtr->NodeMemSize % 8) == 0); + NBPtr->SetBitField (NBPtr, BFDramHoleValid, 0); + MCTPtr->NodeMemSize = (MCTPtr->NodeMemSize / 8) * 7; + NBPtr->HtMemMapInit (NBPtr); + NBPtr->CpuMemTyping (NBPtr); + + // Enable EMP + NBPtr->SetBitField (NBPtr, BFDramEccEn, 1); + + // Scrub CTL settings for Dcache, L2 + NBPtr->SetBitField (NBPtr, BFL2Scrub, UserOptions.CfgScrubL2Rate); + NBPtr->SetBitField (NBPtr, BFDcacheScrub, UserOptions.CfgScrubDcRate); + + NBPtr->SetBitField (NBPtr, BFSyncOnUcEccEn, UserOptions.CfgEccSyncFlood); + return TRUE; + } + } + return FALSE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function checks to see if the input is power of two. + * + * @param[in] TestNumber - Value to check for power of two + * + * @return TRUE - is power of two + * FALSE - is not power of two + */ +BOOLEAN +STATIC +IsPowerOfTwo ( + IN UINT32 TestNumber + ) +{ + return (BOOLEAN) ((TestNumber & (TestNumber - 1)) == 0); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/EXCLUDIMM/mfdimmexclud.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/EXCLUDIMM/mfdimmexclud.c new file mode 100644 index 0000000000..475b04ffab --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/EXCLUDIMM/mfdimmexclud.c @@ -0,0 +1,206 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfdimmexclud.c + * + * Feature DIMM exclude. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/EXCLUDIMM) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Ids.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_EXCLUDIMM_MFDIMMEXCLUD_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemFRASExcludeDIMM ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * Check and disable Chip selects that fail training for each node. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ +BOOLEAN +MemFRASExcludeDIMM ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + UINT8 ReserveDCT; + UINT8 q; + BOOLEAN Flag; + BOOLEAN IsCSIntlvEnabled; + UINT16 CsTestFail; + DIE_STRUCT *MCTPtr; + BOOLEAN RetVal; + + ASSERT (NBPtr != NULL); + ReserveDCT = NBPtr->Dct; + CsTestFail = 0; + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.CsTestFail != 0) { + // When there is no new failed dimm that needs to be excluded, then no need to go through the process. + switch (NBPtr->SharedPtr->DimmExcludeFlag) { + case NORMAL: + // See there is new dimm that needs to be excluded + if ((NBPtr->DCTPtr->Timings.CsTestFail & NBPtr->DCTPtr->Timings.CsEnabled) != 0) { + CsTestFail |= NBPtr->DCTPtr->Timings.CsTestFail; + } + break; + case TRAINING: + // Do not do any dimm excluding during training + // Dimm exclude will be done at the end of training + break; + case END_TRAINING: + // Exclude all dimms that have failures during training + if ((NBPtr->DCTPtr->Timings.CsTrainFail != 0) || + ((NBPtr->DCTPtr->Timings.CsTestFail & NBPtr->DCTPtr->Timings.CsEnabled) != 0)) { + CsTestFail |= NBPtr->DCTPtr->Timings.CsTestFail; + } + break; + default: + IDS_ERROR_TRAP; + } + } + } + + if (CsTestFail != 0) { + IsCSIntlvEnabled = FALSE; + MCTPtr = NBPtr->MCTPtr; + MCTPtr->NodeMemSize = 0; + NBPtr->SharedPtr->NodeMap[NBPtr->Node].IsValid = FALSE; + NBPtr->SharedPtr->NodeMap[NBPtr->Node].SysBase = 0; + NBPtr->SharedPtr->NodeMap[NBPtr->Node].SysLimit = 0; + NBPtr->SetBitField (NBPtr, BFDramBaseAddr, 0); + NBPtr->SetBitField (NBPtr, BFDramLimitAddr, 0); + + if (MCTPtr->GangedMode) { + // if ganged mode, disable all pairs of CS that fail. + NBPtr->DCTPtr->Timings.CsTestFail |= CsTestFail; + } + + // if chip select interleaving has been enabled, need to undo it before remapping memory + if (NBPtr->FeatPtr->UndoInterleaveBanks (NBPtr)) { + IsCSIntlvEnabled = TRUE; + } + + Flag = TRUE; + NBPtr->FamilySpecificHook[BfAfExcludeDimm] (NBPtr, &Flag); + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (!MCTPtr->GangedMode || (MCTPtr->Dct == 0)) { + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + NBPtr->DCTPtr->Timings.DctMemSize = 0; + + NBPtr->DCTPtr->Timings.CsEnabled = 0; + for (q = 0; q < MAX_CS_PER_CHANNEL; q++) { + NBPtr->SetBitField (NBPtr, BFCSBaseAddr0Reg + q, 0); + } + + // Set F2x94[DisDramInterface] = 1 if all chip selects fail training on the DCT + if ((NBPtr->DCTPtr->Timings.CsPresent & ~NBPtr->DCTPtr->Timings.CsTestFail) == 0) { + NBPtr->DisableDCT (NBPtr); + } + + Flag = NBPtr->StitchMemory (NBPtr); + ASSERT (Flag == TRUE); + } + } + } + Flag = FALSE; + NBPtr->FamilySpecificHook[BfAfExcludeDimm] (NBPtr, &Flag); + + // Re-enable chip select interleaving when remapping is done. + if (IsCSIntlvEnabled) { + NBPtr->FeatPtr->InterleaveBanks (NBPtr); + } + + RetVal = TRUE; + } else { + RetVal = FALSE; + } + NBPtr->SwitchDCT (NBPtr, ReserveDCT); + return RetVal; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.c new file mode 100644 index 0000000000..6bd85214af --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.c @@ -0,0 +1,548 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfidendimm.c + * + * Translate physical system address to dimm identification. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat) + * @e \$Revision: 84482 $ @e \$Date: 2012-12-16 22:48:10 -0600 (Sun, 16 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "heapManager.h" +#include "mfidendimm.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_IDENDIMM_MFIDENDIMM_FILECODE +extern MEM_NB_SUPPORT memNBInstalled[]; + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define MAX_DCTS_PER_DIE 2 ///< Max DCTs per die +#define MAX_CHLS_PER_DCT 1 ///< Max Channels per DCT + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +STATIC +MemFTransSysAddrToCS ( + IN OUT AMD_IDENTIFY_DIMM *AmdDimmIdentify, + IN MEM_MAIN_DATA_BLOCK *mmPtr + ); + +UINT32 +STATIC +MemFGetPCI ( + IN MEM_NB_BLOCK *NBPtr, + IN UINT8 NodeID, + IN UINT8 DctNum, + IN BIT_FIELD_NAME BitFieldName + ); + +UINT8 +STATIC +MemFUnaryXOR ( + IN UINT32 address + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/*-----------------------------------------------------------------------------*/ +/** +* +* This function identifies the dimm on which the given memory address locates. +* +* @param[in, out] *AmdDimmIdentify - Pointer to the parameter structure AMD_IDENTIFY_DIMM +* +* @retval AGESA_SUCCESS - Successfully translate physical system address +* to dimm identification. +* AGESA_BOUNDS_CHK - Targeted address is out of bound. +* +*/ + +AGESA_STATUS +AmdIdentifyDimm ( + IN OUT AMD_IDENTIFY_DIMM *AmdDimmIdentify + ) +{ + UINT8 i; + AGESA_STATUS RetVal; + MEM_MAIN_DATA_BLOCK mmData; // Main Data block + MEM_NB_BLOCK *NBPtr; + MEM_DATA_STRUCT MemData; + LOCATE_HEAP_PTR LocHeap; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + UINT8 Node; + UINT8 Dct; + UINT8 Die; + UINT8 DieCount; + + LibAmdMemCopy (&(MemData.StdHeader), &(AmdDimmIdentify->StdHeader), sizeof (AMD_CONFIG_PARAMS), &(AmdDimmIdentify->StdHeader)); + mmData.MemPtr = &MemData; + RetVal = MemSocketScan (&mmData); + if (RetVal == AGESA_FATAL) { + return RetVal; + } + DieCount = mmData.DieCount; + + // Search for AMD_MEM_AUTO_HANDLE on the heap first. + // Only apply for space on the heap if cannot find AMD_MEM_AUTO_HANDLE on the heap. + LocHeap.BufferHandle = AMD_MEM_AUTO_HANDLE; + if (HeapLocateBuffer (&LocHeap, &AmdDimmIdentify->StdHeader) == AGESA_SUCCESS) { + // NB block has already been constructed by main block. + // No need to construct it here. + NBPtr = (MEM_NB_BLOCK *)LocHeap.BufferPtr; + mmData.NBPtr = NBPtr; + } else { + AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (MEM_NB_BLOCK))); + AllocHeapParams.BufferHandle = AMD_MEM_AUTO_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, &AmdDimmIdentify->StdHeader) != AGESA_SUCCESS) { + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_IDENTIFY_DIMM_MEM_NB_BLOCK, 0, 0, 0, 0, &AmdDimmIdentify->StdHeader); + ASSERT(FALSE); // Could not allocate heap space for NB block for Identify DIMM + return AGESA_FATAL; + } + NBPtr = (MEM_NB_BLOCK *)AllocHeapParams.BufferPtr; + mmData.NBPtr = NBPtr; + // Construct each die. + for (Die = 0; Die < DieCount; Die ++) { + i = 0; + while (memNBInstalled[i].MemIdentifyDimmConstruct != 0) { + if (memNBInstalled[i].MemIdentifyDimmConstruct (&NBPtr[Die], &MemData, Die)) { + break; + } + i++; + }; + if (memNBInstalled[i].MemIdentifyDimmConstruct == 0) { + PutEventLog (AGESA_FATAL, MEM_ERROR_NO_CONSTRUCTOR_FOR_IDENTIFY_DIMM, Die, 0, 0, 0, &AmdDimmIdentify->StdHeader); + ASSERT(FALSE); // No Identify DIMM constructor found + return AGESA_FATAL; + } + } + } + + if ((RetVal = MemFTransSysAddrToCS (AmdDimmIdentify, &mmData)) == AGESA_SUCCESS) { + // Translate Node, DCT and Chip select number to Socket, Channel and Dimm number. + Node = AmdDimmIdentify->SocketId; + Dct = AmdDimmIdentify->MemChannelId; + AmdDimmIdentify->SocketId = MemData.DiesPerSystem[Node].SocketId; + AmdDimmIdentify->MemChannelId = NBPtr[Node].GetSocketRelativeChannel (&NBPtr[Node], Dct, 0); + AmdDimmIdentify->DimmId /= 2; + } + + return RetVal; +} + + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*-----------------------------------------------------------------------------*/ +/** +* +* This function translates the given physical system address to +* a node, channel select, chip select, bank, row, and column address. +* +* @param[in, out] *AmdDimmIdentify - Pointer to the parameter structure AMD_IDENTIFY_DIMM +* @param[in, out] *mmPtr - Pointer to the MEM_MAIN_DATA_BLOCK +* +* @retval AGESA_SUCCESS - The chip select address is found +* @retval AGESA_BOUNDS_CHK - Targeted address is out of bound. +* +*/ +AGESA_STATUS +STATIC +MemFTransSysAddrToCS ( + IN OUT AMD_IDENTIFY_DIMM *AmdDimmIdentify, + IN MEM_MAIN_DATA_BLOCK *mmPtr + ) +{ + BOOLEAN CSFound; + BOOLEAN DctSelHiRngEn; + BOOLEAN DctSelIntLvEn; + BOOLEAN DctGangEn; + BOOLEAN HiRangeSelected; + BOOLEAN DramHoleValid; + BOOLEAN CSEn; + BOOLEAN SwapDone; + BOOLEAN IntLvRgnSwapEn; + UINT8 DctSelHi; + UINT8 DramEn; + UINT8 range; + UINT8 IntlvEn; + UINT8 IntlvSel; + UINT8 ILog; + UINT8 DctSelIntLvAddr; + UINT8 DctNum; + UINT8 cs; + UINT8 BadDramCs; + UINT8 spare; + UINT8 IntLvRgnBaseAddr; + UINT8 IntLvRgnLmtAddr; + UINT8 IntLvRgnSize; + UINT32 temp; + UINT32 DramHoleOffset; + UINT32 DramHoleBase; + UINT64 DramBase; + UINT64 DramLimit; + UINT64 DramLimitSysAddr; + UINT64 DctSelBaseAddr; + UINT64 DctSelBaseOffset; + UINT64 ChannelAddr; + UINT64 CSBase; + UINT64 CSMask; + UINT64 InputAddr; + UINT64 ChannelOffset; + MEM_NB_BLOCK *NBPtr; + UINT8 Die; + + UINT64 SysAddr; + UINT8 *NodeID; + UINT8 *ChannelSelect; + UINT8 *ChipSelect; + + SysAddr = AmdDimmIdentify->MemoryAddress; + NodeID = &(AmdDimmIdentify->SocketId); + ChannelSelect = &(AmdDimmIdentify->MemChannelId); + ChipSelect = &(AmdDimmIdentify->DimmId); + CSFound = FALSE; + ILog = 0; + NBPtr = mmPtr->NBPtr; + + NBPtr->FamilySpecificHook[FixupSysAddr] (NBPtr, &SysAddr); + + // Loop to determine the dram range + for (Die = 0; Die < mmPtr->DieCount; Die ++) { + range = NBPtr[Die].Node; + + // DRAM Base + temp = MemFGetPCI (NBPtr, 0, 0, BFDramBaseReg0 + range); + DramEn = (UINT8) (temp & 0x3); + IntlvEn = (UINT8) ((temp >> 8) & 0x7); + + DramBase = ((UINT64) (MemFGetPCI (NBPtr, 0, 0, BFDramBaseHiReg0 + range) & 0xFF) << 40) | + (((UINT64) temp & 0xFFFF0000) << 8); + + // DRAM Limit + temp = MemFGetPCI (NBPtr, 0, 0, BFDramLimitReg0 + range); + *NodeID = (UINT8) (temp & 0x7); + IntlvSel = (UINT8) ((temp >> 8) & 0x7); + DramLimit = ((UINT64) (MemFGetPCI (NBPtr, 0, 0, BFDramLimitHiReg0 + range) & 0xFF) << 40) | + (((UINT64) temp << 8) | 0xFFFFFF); + DramLimitSysAddr = (((UINT64) MemFGetPCI (NBPtr, *NodeID, 0, BFDramLimitAddr)) << 27) | 0x7FFFFFF; + ASSERT (DramLimit <= DramLimitSysAddr); + + if ((DramEn != 0) && (DramBase <= SysAddr) && (SysAddr <= DramLimitSysAddr) && + ((IntlvEn == 0) || (IntlvSel == ((SysAddr >> 12) & IntlvEn)))) { + // Determine the number of bit positions consumed by Node Interleaving + switch (IntlvEn) { + + case 0x0: + ILog = 0; + break; + + case 0x1: + ILog = 1; + break; + + case 0x3: + ILog = 2; + break; + + case 0x7: + ILog = 3; + break; + + default: + IDS_ERROR_TRAP; + } + + DramHoleOffset = MemFGetPCI (NBPtr, *NodeID, 0, BFDramHoleOffset) << 23; + DramHoleValid = (BOOLEAN) MemFGetPCI (NBPtr, *NodeID, 0, (mmPtr->DieCount == 1) ? BFDramMemHoistValid : BFDramHoleValid); + DramHoleBase = MemFGetPCI (NBPtr, *NodeID, 0, BFDramHoleBase) << 24; + // Address belongs to this node based on DramBase/Limit, + // but is in the memory hole so it doesn't map to DRAM + if (DramHoleValid && (DramHoleBase <= SysAddr) && (SysAddr < 0x100000000)) { + return AGESA_BOUNDS_CHK; + } + + // F2x10C Swapped Interleaved Region + IntLvRgnSwapEn = (BOOLEAN) MemFGetPCI (NBPtr, *NodeID, 0, BFIntLvRgnSwapEn); + if (IntLvRgnSwapEn) { + IntLvRgnBaseAddr = (UINT8) MemFGetPCI (NBPtr, *NodeID, 0, BFIntLvRgnBaseAddr); + IntLvRgnLmtAddr = (UINT8) MemFGetPCI (NBPtr, *NodeID, 0, BFIntLvRgnLmtAddr); + IntLvRgnSize = (UINT8) MemFGetPCI (NBPtr, *NodeID, 0, BFIntLvRgnSize); + ASSERT (IntLvRgnSize == (IntLvRgnLmtAddr - IntLvRgnBaseAddr + 1)); + if (((SysAddr >> 34) == 0) && + ((((SysAddr >> 27) >= IntLvRgnBaseAddr) && ((SysAddr >> 27) <= IntLvRgnLmtAddr)) + || ((SysAddr >> 27) < IntLvRgnSize))) { + SysAddr ^= (UINT64) IntLvRgnBaseAddr << 27; + } + } + + // Extract variables from F2x110 DRAM Controller Select Low Register + DctSelHiRngEn = (BOOLEAN) MemFGetPCI (NBPtr, *NodeID, 0, BFDctSelHiRngEn); + DctSelHi = (UINT8) MemFGetPCI (NBPtr, *NodeID, 0, BFDctSelHi); + DctSelIntLvEn = (BOOLEAN) MemFGetPCI (NBPtr, *NodeID, 0, BFDctSelIntLvEn); + DctGangEn = (BOOLEAN) MemFGetPCI (NBPtr, *NodeID, 0, BFDctGangEn); + DctSelIntLvAddr = (UINT8) MemFGetPCI (NBPtr, *NodeID, 0, BFDctSelIntLvAddr); + DctSelBaseAddr = (UINT64) MemFGetPCI (NBPtr, *NodeID, 0, BFDctSelBaseAddr) << 27; + DctSelBaseOffset = (UINT64) MemFGetPCI (NBPtr, *NodeID, 0, BFDctSelBaseOffset) << 26; + + + // Determine if high DCT address range is being selected + if (DctSelHiRngEn && !DctGangEn && (SysAddr >= DctSelBaseAddr)) { + HiRangeSelected = TRUE; + } else { + HiRangeSelected = FALSE; + } + + // Determine Channel + if (DctGangEn) { + *ChannelSelect = (UINT8) ((SysAddr >> 3) & 0x1); + } else if (HiRangeSelected) { + *ChannelSelect = DctSelHi; + } else if (DctSelIntLvEn && (DctSelIntLvAddr == 0)) { + *ChannelSelect = (UINT8) ((SysAddr >> 6) & 0x1); + } else if (DctSelIntLvEn && (((DctSelIntLvAddr >> 1) & 0x1) != 0)) { + temp = MemFUnaryXOR ((UINT32) ((SysAddr >> 16) & 0x1F)); + if ((DctSelIntLvAddr & 0x1) != 0) { + *ChannelSelect = (UINT8) (((SysAddr >> 9) & 0x1) ^ temp); + } else { + *ChannelSelect = (UINT8) (((SysAddr >> 6) & 0x1) ^ temp); + } + } else if (DctSelIntLvEn) { + *ChannelSelect = (UINT8) ((SysAddr >> (12 + ILog)) & 0x1); + } else if (DctSelHiRngEn) { + *ChannelSelect = ~DctSelHi & 0x1; + } else { + *ChannelSelect = 0; + } + ASSERT (*ChannelSelect < NBPtr[*NodeID].DctCount); + + // Determine base address offset + if (HiRangeSelected) { + if ((DctSelBaseAddr < DramHoleBase) && DramHoleValid && (SysAddr >= (UINT64) 0x100000000)) { + ChannelOffset = (UINT64) DramHoleOffset; + } else { + ChannelOffset = DctSelBaseOffset; + } + } else { + if (DramHoleValid && (SysAddr >= (UINT64) 0x100000000)) { + ChannelOffset = (UINT64) DramHoleOffset; + } else { + ChannelOffset = DramBase; + } + } + + // Remove hoisting offset and normalize to DRAM bus addresses + ChannelAddr = SysAddr - ChannelOffset; + + // Remove node interleaving + if (IntlvEn != 0) { + ChannelAddr = ((ChannelAddr >> (12 + ILog)) << 12) | (ChannelAddr & 0xFFF); + } + + // Remove channel interleave + if (DctSelIntLvEn && !HiRangeSelected && !DctGangEn) { + if ((DctSelIntLvAddr & 1) != 1) { + // A[6] Select or Hash 6 + ChannelAddr = ((ChannelAddr >> 7) << 6) | (ChannelAddr & 0x3F); + } else if (DctSelIntLvAddr == 1) { + // A[12] + ChannelAddr = ((ChannelAddr >> 13) << 12) | (ChannelAddr & 0xFFF); + } else { + // Hash 9 + ChannelAddr = ((ChannelAddr >> 10) << 9) | (ChannelAddr & 0x1FF); + } + } + + // Determine the Chip Select + for (cs = 0; cs < MAX_CS_PER_CHANNEL; ++ cs) { + DctNum = DctGangEn ? 0 : *ChannelSelect; + + // Obtain the CS Base + temp = MemFGetPCI (NBPtr, *NodeID, DctNum, BFCSBaseAddr0Reg + cs); + CSEn = (BOOLEAN) (temp & 0x1); + CSBase = ((UINT64) temp & NBPtr->CsRegMsk) << 8; + + // Obtain the CS Mask + CSMask = ((UINT64) MemFGetPCI (NBPtr, *NodeID, DctNum, BFCSMask0Reg + (cs >> 1)) & NBPtr->CsRegMsk) << 8; + + // Adjust the Channel Addr for easy comparison + InputAddr = ((ChannelAddr >> 8) & NBPtr->CsRegMsk) << 8; + + if (CSEn && ((InputAddr & ~CSMask) == (CSBase & ~CSMask))) { + CSFound = TRUE; + + *ChipSelect = cs; + + temp = MemFGetPCI (NBPtr, *NodeID, 0, BFOnLineSpareControl); + SwapDone = (BOOLEAN) ((temp >> (1 + 2 * (*ChannelSelect))) & 0x1); + BadDramCs = (UINT8) ((temp >> (4 + 4 * (*ChannelSelect))) & 0x7); + if (SwapDone && (cs == BadDramCs)) { + // Find the spare rank for the channel + for (spare = 0; spare < MAX_CS_PER_CHANNEL; ++spare) { + if ((MemFGetPCI (NBPtr, *NodeID, DctNum, BFCSBaseAddr0Reg + spare) & 0x2) != 0) { + *ChipSelect = spare; + break; + } + } + } + ASSERT (*ChipSelect < MAX_CS_PER_CHANNEL); + + break; + } + } + } + if (CSFound) { + break; + } + } + + // last ditch sanity check + ASSERT (!CSFound || ((*NodeID < mmPtr->DieCount) && (*ChannelSelect < NBPtr[*NodeID].DctCount) && (*ChipSelect < MAX_CS_PER_CHANNEL))); + if (CSFound) { + return AGESA_SUCCESS; + } else { + return AGESA_BOUNDS_CHK; + } + +} + + +/*-----------------------------------------------------------------------------*/ +/** +* +* This function is the interface to call the PCI register access function +* defined in NB block. +* +* @param[in] *NBPtr - Pointer to the parameter structure MEM_NB_BLOCK +* @param[in] NodeID - Node ID number of the target Northbridge +* @param[in] DctNum - DCT number if applicable, otherwise, put 0 +* @param[in] BitFieldName - targeted bitfield +* +* @retval UINT32 - 32 bits PCI register value +* +*/ +UINT32 +STATIC +MemFGetPCI ( + IN MEM_NB_BLOCK *NBPtr, + IN UINT8 NodeID, + IN UINT8 DctNum, + IN BIT_FIELD_NAME BitFieldName + ) +{ + MEM_NB_BLOCK *LocalNBPtr; + UINT8 Die; + + // Find NBBlock that associates with node NodeID + for (Die = 0; (Die < MAX_NODES_SUPPORTED) && (NBPtr[Die].Node != NodeID); Die ++); + ASSERT (Die < MAX_NODES_SUPPORTED); + + // Get the northbridge pointer for the targeted node. + LocalNBPtr = &NBPtr[Die]; + LocalNBPtr->FamilySpecificHook[DCTSelectSwitch] (LocalNBPtr, &DctNum); + LocalNBPtr->Dct = DctNum; + // The caller of this function will take care of the ganged/unganged situation. + // So Ganged is set to be false here, and do PCI read on the DCT specified by DctNum. + return LocalNBPtr->GetBitField (LocalNBPtr, BitFieldName); +} + +/*-----------------------------------------------------------------------------*/ +/** +* +* This function returns an even parity bit (making the total # of 1's even) +* {0, 1} = number of set bits in argument is {even, odd}. +* +* @param[in] address - the address on which the parity bit will be calculated +* +* @retval UINT8 - parity bit +* +*/ + +UINT8 +STATIC +MemFUnaryXOR ( + IN UINT32 address + ) +{ + UINT8 parity; + UINT8 index; + parity = 0; + for (index = 0; index < 32; ++ index) { + parity = (UINT8) (parity ^ (address & 0x1)); + address = address >> 1; + } + return parity; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.h new file mode 100644 index 0000000000..bf95ce0593 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/IDENDIMM/mfidendimm.h @@ -0,0 +1,72 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfidendimm.h + * + * Header file for address to dimm identification translator. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _MFIDENDIMM_H_ +#define _MFIDENDIMM_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +#endif //_MFIDENDIMM_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.c new file mode 100644 index 0000000000..9407f45b04 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.c @@ -0,0 +1,172 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * lvddr3.c + * + * Voltage change for DDR3 DIMMs. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/LVDDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_LVDDR3_MFLVDDR3_FILECODE +/* features */ +#include "mflvddr3.h" + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function calculate the common lowest voltage supported by all DDR3 + * DIMMs in the system. This function only needs to be called on BSP. + * + * @param[in, out] *NBPtr - Pointer to NB block + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ + +BOOLEAN +MemFLvDdr3 ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + CH_DEF_STRUCT *ChannelPtr; + MEM_TECH_BLOCK *TechPtr; + MEM_SHARED_DATA *mmSharedPtr; + UINT8 Dct; + UINT8 Channel; + UINT8 Dimm; + UINT8 *SpdBufferPtr; + UINT8 VDDByte; + UINT8 VoltageMap; + + mmSharedPtr = NBPtr->SharedPtr; + TechPtr = NBPtr->TechPtr; + VoltageMap = 0xFF; + + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + for (Channel = 0; Channel < NBPtr->ChannelCount; Channel++) { + NBPtr->SwitchChannel (NBPtr, Channel); + ChannelPtr = NBPtr->ChannelPtr; + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) { + if (TechPtr->GetDimmSpdBuffer (TechPtr, &SpdBufferPtr, Dimm)) { + // SPD byte 6: Module Nominal Voltage, VDD + // 1.5v - bit 0 + // 1.35v - bit 1 + // 1.2v - bit 2 + VDDByte = SpdBufferPtr[MNVVDD]; + IDS_HDT_CONSOLE (MEM_FLOW, "Node%d DCT%d Channel%d Dimm%d VDD Byte: 0x%02x\n", NBPtr->Node, Dct, Channel, Dimm, VDDByte); + + // Reverse the 1.5V operable bit. So its encoding can be consistent + // with that of 1.35V and 1.25V operable bit. + VDDByte ^= 1; + ASSERT (VDDByte != 0); + + if (mmSharedPtr->VoltageMap != 0) { + // Get the common supported voltage map + VoltageMap &= VDDByte; + } else { + // This is the second execution of all the loop as no common voltage is found + if (VDDByte == (1 << VOLT1_5_ENCODED_VAL)) { + // Always exclude 1.5V dimm if no common voltage is found + ChannelPtr->DimmExclude |= (UINT16) 1 << Dimm; + } + } + } + } + if (mmSharedPtr->VoltageMap == 0) { + NBPtr->DCTPtr->Timings.DimmExclude |= ChannelPtr->DimmExclude; + } + } + } + + if (mmSharedPtr->VoltageMap != 0) { + mmSharedPtr->VoltageMap &= VoltageMap; + } + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.h new file mode 100644 index 0000000000..93bc4f4aa4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/LVDDR3/mflvddr3.h @@ -0,0 +1,78 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mflvddr3.h + * + * Header file for DDR3 DIMMs voltage configuration. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _MFLVDDR3_H_ +#define _MFLVDDR3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define MNVVDD 6 +#define LOWEST_VOLT_BIT 2 + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemFLvDdr3 ( + IN OUT MEM_NB_BLOCK *NBPtr +); + +#endif //_MFLVDDR3_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/MEMCLR/mfmemclr.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/MEMCLR/mfmemclr.c new file mode 100644 index 0000000000..5a0c67584a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/MEMCLR/mfmemclr.c @@ -0,0 +1,153 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfmemclr.c + * + * Feature function for memory clear operation + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/Memclr) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + + + +#include "AGESA.h" +#include "mm.h" +#include "mn.h" +#include "mfmemclr.h" +#include "Ids.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_MEMCLR_MFMEMCLR_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Initiates memory clear operation on one node with Dram on it. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +BOOLEAN +MemFMctMemClr_Init ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + AGESA_TESTPOINT (TpProcMemMemClr, &NBPtr->MemPtr->StdHeader); + IDS_PERF_TIMESTAMP (TP_BEGINMEMFMCTMEMCLR_INIT, &(NBPtr->MemPtr->StdHeader)); + if (NBPtr->RefPtr->EnableMemClr == TRUE) { + if (NBPtr->MCTPtr->NodeMemSize != 0) { + if (!NBPtr->MemCleared) { + NBPtr->PollBitField (NBPtr, BFMemClrBusy, 0, SPECIAL_PCI_ACCESS_TIMEOUT, FALSE); + if (NBPtr->GetBitField (NBPtr, BFDramEnabled) == 1) { + NBPtr->FamilySpecificHook[BeforeMemClr] (NBPtr, NBPtr); + NBPtr->SetBitField (NBPtr, BFDramBaseAddr, 0); + NBPtr->SetBitField (NBPtr, BFMemClrInit, 1); + } + } + } + } + IDS_PERF_TIMESTAMP (TP_ENDNMEMFMCTMEMCLR_INIT, &(NBPtr->MemPtr->StdHeader)); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Ensures memory clear operation has completed on one node with Dram on it. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +BOOLEAN +MemFMctMemClr_Sync ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 MicroSecondToWait; + + MicroSecondToWait = 0; + if (NBPtr->RefPtr->EnableMemClr == TRUE) { + if (NBPtr->MCTPtr->NodeMemSize != 0) { + // Calculate Timeout value: + // Timeout (in microsecond) = Memory Size * 1.5 ns / 8 Byte * 4 (Margin) * 1000 (change millisecond to us) + // NodeMemSize is system address right shifted by 16, so shift it 4 bits to right to convert it to MB. + // 1.5 / 8 * 4 * 1000 = 750 + MicroSecondToWait = (NBPtr->MCTPtr->NodeMemSize >> 4) * 750; + + if (!NBPtr->MemCleared) { + NBPtr->PollBitField (NBPtr, BFMemClrBusy, 0, MicroSecondToWait, FALSE); + NBPtr->PollBitField (NBPtr, BFMemCleared, 1, MicroSecondToWait, FALSE); + NBPtr->SetBitField (NBPtr, BFDramBaseAddr, NBPtr->MCTPtr->NodeSysBase >> (27 - 16)); + NBPtr->MemCleared = TRUE; + } + } + } + return TRUE; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.c new file mode 100644 index 0000000000..41a14ae3f3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.c @@ -0,0 +1,179 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfodthermal.c + * + * On Dimm thermal management. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Ids.h" +#include "mfodthermal.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_ODTHERMAL_MFODTHERMAL_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/*-----------------------------------------------------------------------------*/ +/** + * + * This function does On-Dimm thermal management. + * + * @param[in, out] *NBPtr - Pointer to the MEM_NB_BLOCK. + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ + +BOOLEAN +MemFOnDimmThermal ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 i; + UINT8 Dct; + CH_DEF_STRUCT *ChannelPtr; + MEM_DATA_STRUCT *MemPtr; + UINT8 *SpdBufferPtr; + UINT8 ThermalOp; + BOOLEAN ODTSEn; + BOOLEAN ExtendTmp; + BOOLEAN FirstLoop; + + ODTSEn = FALSE; + ExtendTmp = FALSE; + FirstLoop = TRUE; + + ASSERT (NBPtr != NULL); + MemPtr = NBPtr->MemPtr; + AGESA_TESTPOINT (TpProcMemOnDimmThermal, &MemPtr->StdHeader); + if (NBPtr->MCTPtr->NodeMemSize != 0) { + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + // Only go through the DCT if it is not disabled. + if (NBPtr->GetBitField (NBPtr, BFDisDramInterface) == 0) { + ChannelPtr = NBPtr->ChannelPtr; + // If Ganged mode is enabled, need to go through all dram devices on both DCTs. + if (!NBPtr->Ganged || (NBPtr->Dct != 1)) { + if (!(NBPtr->IsSupported[CheckSetSameDctODTsEn]) || (NBPtr->IsSupported[CheckSetSameDctODTsEn] && (NBPtr->Dct != 1)) || + ((NBPtr->Dct != 0) && (FirstLoop == TRUE))) { + ODTSEn = TRUE; + ExtendTmp = TRUE; + } + } + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i ++) { + if (NBPtr->TechPtr->GetDimmSpdBuffer (NBPtr->TechPtr, &SpdBufferPtr, i)) { + // Check byte 31: thermal and refresh option. + ThermalOp = SpdBufferPtr[THERMAL_OPT]; + // Bit 3: ODTS readout + if (!((ThermalOp >> 3) & 1)) { + ODTSEn = FALSE; + } + // Bit 0: Extended Temperature Range. + if (!(ThermalOp & 1)) { + ExtendTmp = FALSE; + } + } + } + + if (!NBPtr->Ganged || (NBPtr->Dct == 1)) { + // If in ganged mode, need to switch back to DCT0 to set the registers. + if (NBPtr->Ganged || NBPtr->IsSupported[CheckSetSameDctODTsEn]) { + NBPtr->SwitchDCT (NBPtr, 0); + ChannelPtr = NBPtr->ChannelPtr; + } + // If all dram devices on support ODTS + NBPtr->SetBitField (NBPtr, BFODTSEn, (ODTSEn == TRUE) ? 1 : 0); + ChannelPtr->ExtendTmp = ExtendTmp; + } + FirstLoop = FALSE; + } else { + ODTSEn = FALSE; + ExtendTmp = FALSE; + } + IDS_HDT_CONSOLE (MEM_FLOW, "\tDct %d\n", Dct); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tODTSEn = %d\n", ODTSEn); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tExtendTmp = %d\n", ExtendTmp); + } + } + return TRUE; +} + + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.h new file mode 100644 index 0000000000..50945f3124 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/ODTHERMAL/mfodthermal.h @@ -0,0 +1,77 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfodthermal.h + * + * Header file for On-Dimm thermal management. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _MFODTHERMAL_H_ +#define _MFODTHERMAL_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemFOnDimmThermal ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +#endif //_MFODTHERMAL_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/PARTRN/mfParallelTraining.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/PARTRN/mfParallelTraining.c new file mode 100644 index 0000000000..2fd10c5e07 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/PARTRN/mfParallelTraining.c @@ -0,0 +1,288 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfParallelTraining.c + * + * This is the parallel training feature + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/PARTRN) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + + + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "mfParallelTraining.h" +#include "heapManager.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_PARTRN_MFPARALLELTRAINING_FILECODE + +/*----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ +extern MEM_TECH_CONSTRUCTOR* memTechInstalled[]; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This is the main function to perform parallel training on all nodes. + * This is the routine which will run on the remote AP. + * + * @param[in,out] *EnvPtr - Pointer to the Training Environment Data + * @param[in,out] *StdHeader - Pointer to the Standard Header of the AP + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ +BOOLEAN +MemFParallelTraining ( + IN OUT REMOTE_TRAINING_ENV *EnvPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + MEM_PARAMETER_STRUCT ParameterList; + MEM_NB_BLOCK NB; + MEM_TECH_BLOCK TB; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + UINT8 p; + UINT8 i; + UINT8 Dct; + UINT8 Channel; + UINT8 *BufferPtr; + UINT8 DctCount; + UINT8 ChannelCount; + UINT8 RowCount; + UINT8 ColumnCount; + UINT16 SizeOfNewBuffer; + AP_DATA_TRANSFER ReturnData; + + // + // Initialize Parameters + // + ReturnData.DataPtr = NULL; + ReturnData.DataSizeInDwords = 0; + ReturnData.DataTransferFlags = 0; + + ASSERT (EnvPtr != NULL); + // + // Replace Standard header of a AP + // + LibAmdMemCopy (StdHeader, &(EnvPtr->StdHeader), sizeof (AMD_CONFIG_PARAMS), &(EnvPtr->StdHeader)); + + + // + // Allocate buffer for training data + // + BufferPtr = (UINT8 *) (&EnvPtr->DieStruct); + DctCount = EnvPtr->DieStruct.DctCount; + BufferPtr += sizeof (DIE_STRUCT); + ChannelCount = ((DCT_STRUCT *) BufferPtr)->ChannelCount; + BufferPtr += DctCount * sizeof (DCT_STRUCT); + RowCount = ((CH_DEF_STRUCT *) BufferPtr)->RowCount; + ColumnCount = ((CH_DEF_STRUCT *) BufferPtr)->ColumnCount; + + SizeOfNewBuffer = sizeof (DIE_STRUCT) + + DctCount * ( + sizeof (DCT_STRUCT) + ( + ChannelCount * ( + sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK) + ( + RowCount * ColumnCount * NUMBER_OF_DELAY_TABLES + + (MAX_BYTELANES_PER_CHANNEL * MAX_CS_PER_CHANNEL * NUMBER_OF_FAILURE_MASK_TABLES) + + (MAX_DIMMS_PER_CHANNEL * MAX_NUMBER_LANES) + ) + ) + ) + ); + AllocHeapParams.RequestedBufferSize = SizeOfNewBuffer; + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_PAR_TRN_HANDLE, 0, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + BufferPtr = AllocHeapParams.BufferPtr; + LibAmdMemCopy ( BufferPtr, + &(EnvPtr->DieStruct), + sizeof (DIE_STRUCT) + DctCount * (sizeof (DCT_STRUCT) + ChannelCount * (sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK))), + StdHeader + ); + + // + // Fix up pointers + // + MCTPtr = (DIE_STRUCT *) BufferPtr; + BufferPtr += sizeof (DIE_STRUCT); + MCTPtr->DctData = (DCT_STRUCT *) BufferPtr; + BufferPtr += MCTPtr->DctCount * sizeof (DCT_STRUCT); + for (Dct = 0; Dct < MCTPtr->DctCount; Dct++) { + MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) BufferPtr; + BufferPtr += MCTPtr->DctData[Dct].ChannelCount * sizeof (CH_DEF_STRUCT); + for (Channel = 0; Channel < MCTPtr->DctData[Dct].ChannelCount; Channel++) { + MCTPtr->DctData[Dct].ChData[Channel].MCTPtr = MCTPtr; + MCTPtr->DctData[Dct].ChData[Channel].DCTPtr = &MCTPtr->DctData[Dct]; + } + } + NB.PSBlock = (MEM_PS_BLOCK *) BufferPtr; + BufferPtr += DctCount * ChannelCount * sizeof (MEM_PS_BLOCK); + + ReturnData.DataPtr = AllocHeapParams.BufferPtr; + ReturnData.DataSizeInDwords = (SizeOfNewBuffer + 3) / 4; + ReturnData.DataTransferFlags = 0; + + // + // Allocate Memory for the MEM_DATA_STRUCT we will use + // + AllocHeapParams.RequestedBufferSize = sizeof (MEM_DATA_STRUCT); + AllocHeapParams.BufferHandle = AMD_MEM_DATA_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + MemPtr = (MEM_DATA_STRUCT *)AllocHeapParams.BufferPtr; + + LibAmdMemCopy (&(MemPtr->StdHeader), &(EnvPtr->StdHeader), sizeof (AMD_CONFIG_PARAMS), StdHeader); + + // + // Copy Parameters from environment + // + ParameterList.HoleBase = EnvPtr->HoleBase; + ParameterList.BottomIo = EnvPtr->BottomIo; + ParameterList.UmaSize = EnvPtr->UmaSize; + ParameterList.SysLimit = EnvPtr->SysLimit; + ParameterList.TableBasedAlterations = EnvPtr->TableBasedAlterations; + ParameterList.PlatformMemoryConfiguration = EnvPtr->PlatformMemoryConfiguration; + MemPtr->ParameterListPtr = &ParameterList; + + for (p = 0; p < MAX_PLATFORM_TYPES; p++) { + MemPtr->GetPlatformCfg[p] = EnvPtr->GetPlatformCfg[p]; + } + + MemPtr->ErrorHandling = EnvPtr->ErrorHandling; + // + // Create Local NBBlock and Tech Block + // + EnvPtr->NBBlockCtor (&NB, MCTPtr, EnvPtr->FeatPtr); + NB.RefPtr = &ParameterList; + NB.MemPtr = MemPtr; + i = 0; + while (memTechInstalled[i] != NULL) { + if (memTechInstalled[i] (&TB, &NB)) { + break; + } + i++; + } + NB.TechPtr = &TB; + NB.TechBlockSwitch (&NB); + + // + // Setup CPU Mem Type MSRs on the AP + // + NB.CpuMemTyping (&NB); + + IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", NB.Node); + // + // Call Technology Specific Training routine + // + NB.TrainingFlow (&NB); + // + // Copy training data to ReturnData buffer + // + LibAmdMemCopy ( BufferPtr, + MCTPtr->DctData[0].ChData[0].RcvEnDlys, + ((DctCount * ChannelCount) * ( + (RowCount * ColumnCount * NUMBER_OF_DELAY_TABLES) + + (MAX_BYTELANES_PER_CHANNEL * MAX_CS_PER_CHANNEL * NUMBER_OF_FAILURE_MASK_TABLES) + + (MAX_DIMMS_PER_CHANNEL * MAX_NUMBER_LANES) + ) + ), + StdHeader); + + HeapDeallocateBuffer (AMD_MEM_DATA_HANDLE, StdHeader); + // + // Restore pointers + // + for (Dct = 0; Dct < MCTPtr->DctCount; Dct++) { + for (Channel = 0; Channel < MCTPtr->DctData[Dct].ChannelCount; Channel++) { + MCTPtr->DctData[Dct].ChData[Channel].MCTPtr = &EnvPtr->DieStruct; + MCTPtr->DctData[Dct].ChData[Channel].DCTPtr = &EnvPtr->DieStruct.DctData[Dct]; + + MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].RcvEnDlys; + MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].WrDqsDlys; + MCTPtr->DctData[Dct].ChData[Channel].RdDqsDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].RdDqsDlys; + MCTPtr->DctData[Dct].ChData[Channel].RdDqsDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].RdDqsDlys; + MCTPtr->DctData[Dct].ChData[Channel].WrDatDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].WrDatDlys; + MCTPtr->DctData[Dct].ChData[Channel].RdDqs2dDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].RdDqs2dDlys; + MCTPtr->DctData[Dct].ChData[Channel].RdDqsMinDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].RdDqsMinDlys; + MCTPtr->DctData[Dct].ChData[Channel].RdDqsMaxDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].RdDqsMaxDlys; + MCTPtr->DctData[Dct].ChData[Channel].WrDatMinDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].WrDatMinDlys; + MCTPtr->DctData[Dct].ChData[Channel].WrDatMaxDlys = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].WrDatMaxDlys; + MCTPtr->DctData[Dct].ChData[Channel].FailingBitMask = EnvPtr->DieStruct.DctData[Dct].ChData[Channel].FailingBitMask; + } + MCTPtr->DctData[Dct].ChData = EnvPtr->DieStruct.DctData[Dct].ChData; + } + MCTPtr->DctData = EnvPtr->DieStruct.DctData; + } + + // + // Signal to BSP that training is complete and Send Results + // + ASSERT (ReturnData.DataPtr != NULL); + ApUtilTransmitBuffer (EnvPtr->BspSocket, EnvPtr->BspCore, &ReturnData, StdHeader); + + // + // Clean up and exit. + // + HeapDeallocateBuffer (GENERATE_MEM_HANDLE (ALLOC_PAR_TRN_HANDLE, 0, 0, 0), StdHeader); + } else { + MCTPtr = &EnvPtr->DieStruct; + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_TRAINING_DATA, MCTPtr->NodeId, 0, 0, 0, StdHeader); + SetMemError (AGESA_FATAL, MCTPtr); + ASSERT(FALSE); // Could not allocate heap for buffer for parallel training data + } + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/PARTRN/mfStandardTraining.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/PARTRN/mfStandardTraining.c new file mode 100644 index 0000000000..654af0e235 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/PARTRN/mfStandardTraining.c @@ -0,0 +1,85 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfStandardTraining.c + * + * This is the standard training routine which performs all training from the BSP + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/PARTRN) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + + + +#include "AGESA.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "mfStandardTraining.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_FEAT_PARTRN_MFSTANDARDTRAINING_FILECODE +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This is the main function to perform memory training on all nodes from + * the BSP only. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - This feature is enabled. + * @return FALSE - This feature is not enabled. + */ +BOOLEAN +MemFStandardTraining ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + ASSERT (NBPtr != NULL); + + NBPtr->TrainingFlow (NBPtr); + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/KB/mfRdWr2DKb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/KB/mfRdWr2DKb.c new file mode 100644 index 0000000000..b355d6b093 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/KB/mfRdWr2DKb.c @@ -0,0 +1,348 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfRdWr2DKb.c + * + * KB - Specific funtion for 2D Read and write training feature + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/RdWr2DTraining/Kb) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "AdvancedApi.h" +#include "GeneralServices.h" +#include "Ids.h" +#include "heapManager.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mport.h" +#include "merrhdl.h" +#include "OptionMemory.h" +#include "mfRdWr2DTraining.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_FEAT_RDWR2DTRAINING_KB_MFRDWR2DKB_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemFRdWr2DTrainingInitKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +STATIC +MemFRdWr2DProgramVrefKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *VrefPtr + ); + +BOOLEAN +STATIC +MemFRdWr2DScaleVrefKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Vref + ); + +BOOLEAN +STATIC +MemFRdWr2DProgramIntExtVrefSelectKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +STATIC +MemFRdWr2DProgramDataPatternKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID* PatternIndexPtr + ); + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the 2D Read/Write Training Feature Hooks for KB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return BOOLEAN + * TRUE - Function was implemented + * + */ + +BOOLEAN +MemFRdWr2DTrainingInitKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + ASSERT (NBPtr != NULL); + NBPtr->FamilySpecificHook[RdWr2DTraining] = MemFAmdRdWr2DTraining; + NBPtr->FamilySpecificHook[CheckRdWr2DTrainingPerConfig] = MemFCheckRdWr2DTrainingPerConfig; + NBPtr->FamilySpecificHook[RdWr2DSelectIntExtVref] = MemFRdWr2DProgramIntExtVrefSelectKB; + NBPtr->FamilySpecificHook[RdWr2DProgramVref] = MemFRdWr2DProgramVrefKB; + NBPtr->FamilySpecificHook[RdWr2DScaleVref] = MemFRdWr2DScaleVrefKB; + NBPtr->FamilySpecificHook[RdWr2DProgramDelays] = MemFRdWr2DProgramDelays; + NBPtr->FamilySpecificHook[RdWr2DDataCollection] = MemFRdWr2DEyeRimSearch; + NBPtr->FamilySpecificHook[RdWr2DInitVictim] = MemFRdWr2DInitVictim; + NBPtr->FamilySpecificHook[RdWr2DInitVictimChipSel] = MemFRdWr2DInitVictimChipSel; + NBPtr->FamilySpecificHook[RdWr2DStartVictim] = MemFRdWr2DStartVictim; + NBPtr->FamilySpecificHook[RdWr2DFinalizeVictim] = MemFRdWr2DFinalizeVictim; + NBPtr->FamilySpecificHook[RdWr2DCompareInPhase] = MemFRdWr2DCompareInPhase; + NBPtr->FamilySpecificHook[RdWr2DCompare180Phase] = MemFRdWr2DCompare180Phase; + NBPtr->FamilySpecificHook[RdWr2DProgramDataPattern] = MemFRdWr2DProgramDataPatternKB; + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs Vref for 2D Read/Write Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *VrefPtr - Pointer to Vref value + * + * @return BOOLEAN + * TRUE - Success + * FAIL (External Callout only) + * + */ +BOOLEAN +STATIC +MemFRdWr2DProgramVrefKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *VrefPtr + ) +{ + AGESA_STATUS Status; + MEM_DATA_STRUCT *MemPtr; + ID_INFO CallOutIdInfo; + VOLTAGE_ADJUST Va; + UINT8 Vref; + + ASSERT (NBPtr != NULL); + ASSERT (VrefPtr != NULL); + MemPtr = NBPtr->MemPtr; + Vref = *(UINT8*)VrefPtr; + CallOutIdInfo.IdField.SocketId = NBPtr->MCTPtr->SocketId; + CallOutIdInfo.IdField.ModuleId = NBPtr->MCTPtr->DieId; + LibAmdMemCopy ((VOID *)&Va, (VOID *)MemPtr, (UINTN)sizeof (Va.StdHeader), &MemPtr->StdHeader); + Va.MemData = MemPtr; + Status = AGESA_SUCCESS; + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + if (NBPtr->RefPtr->ExternalVrefCtl == FALSE) { + // + // Internal vref control + // + ASSERT (Vref < 61); + if (Vref < 30) { + Vref = (62 - Vref); + } else { + Vref = (Vref - 30); + } + NBPtr->SetBitField (NBPtr, BFVrefDAC, Vref << 3); + } else { + // + // External vref control + // + AGESA_TESTPOINT (TpProcMemBefore2dTrainExtVrefChange, &(NBPtr->MemPtr->StdHeader)); + NBPtr->MemPtr->ParameterListPtr->ExternalVrefValue = Vref; + IDS_HDT_CONSOLE (MEM_FLOW, "\n2D Read Training External CPU Vref Callout \n"); + Va.VoltageType = VTYPE_CPU_VREF; + Va.AdjustValue = Vref = (Vref - 15) << 1; + Status = AgesaExternalVoltageAdjust ((UINTN)CallOutIdInfo.IdInformation, &Va); + AGESA_TESTPOINT (TpProcMemAfter2dTrainExtVrefChange, &(NBPtr->MemPtr->StdHeader)); + } + } else { + // + // DIMM Vref Control + // + Va.VoltageType = VTYPE_DIMM_VREF; + // + // Offset by 15 and multiply by 2. + // + Va.AdjustValue = Vref = (Vref - 15) << 1; + Status = AgesaExternalVoltageAdjust ((UINTN)CallOutIdInfo.IdInformation, &Va); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tDimm Vref = %c%d% ", (Va.AdjustValue < 0) ? '-':'+', (Va.AdjustValue < 0) ? (0 - Va.AdjustValue) : Va.AdjustValue ); + if (Status != AGESA_SUCCESS) { + IDS_HDT_CONSOLE (MEM_FLOW, "* Dimm Vref Callout Failed *"); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + return (Status == AGESA_SUCCESS) ? TRUE : FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function scales Vref from the range used in Data Collection to + * the range that is programmed into the register. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Vref - Pointer to UINT8 Vref Value to scale. + * + * @return BOOLEAN + * TRUE Function was implemented + * + */ +BOOLEAN +STATIC +MemFRdWr2DScaleVrefKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Vref + ) +{ + *(UINT8*)Vref = *(UINT8*)Vref * 2; + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs Vref to internal or external control for 2D Read + * or Write Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Unused + * + * @return BOOLEAN + * TRUE - External Vref was selected + * FALSE - Internal Vref was selected + * + */ +BOOLEAN +STATIC +MemFRdWr2DProgramIntExtVrefSelectKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + NBPtr->SetBitField (NBPtr, BFVrefSel, (NBPtr->RefPtr->ExternalVrefCtl ? 0x0002 : 0x0001)); + } + return NBPtr->RefPtr->ExternalVrefCtl; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the Data Pattern that will be sent and compared + * against. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *PatternIndexPtr - Pointer to a generic index used to + * determine which pattern to program. + * + * @return BOOLEAN + * TRUE + * + */ +BOOLEAN +STATIC +MemFRdWr2DProgramDataPatternKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID* PatternIndexPtr + ) +{ + UINT8 SeedCount; + UINT32 PrbsSeed; + CONST STATIC UINT32 CmdStreamLenTbl[4] = {13, 61, 127, 251}; + + ASSERT (NBPtr != 0); + ASSERT (PatternIndexPtr != NULL); + SeedCount = *(UINT8*)PatternIndexPtr; + ASSERT (SeedCount <= (NBPtr->MaxSeedCount - 1)); + MemNSetBitFieldNb (NBPtr, BFCmdStreamLen, CmdStreamLenTbl[SeedCount]); + PrbsSeed = 0x7EA05; + switch (SeedCount) { + case 0: + MemNSetBitFieldNb (NBPtr, BFDataPatGenSel, 0x01); + PrbsSeed = 0x7FFFF; + break; + case 1: + MemNSetBitFieldNb (NBPtr, BFDataPatGenSel, 0x04); + MemNSetBitFieldNb (NBPtr, BFXorPatOvr, 0xFF); + PrbsSeed = 0x7EA05; + break; + case 2: + MemNSetBitFieldNb (NBPtr, BFDataPatGenSel, 0x03); + MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern0, 0x55555549); + MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern1, 0x55555555); + MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern2, 0x55555555); + MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern3, 0x55555555); + break; + case 3: + MemNSetBitFieldNb (NBPtr, BFDataPatGenSel, 0x03); + MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern0, 0xA5A5A55A); + MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern1, 0xA5A5A5A5); + MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern2, 0xA5A5A5A5); + MemNSetBitFieldNb (NBPtr, BFDramUserDataPattern3, 0xA5A5A5A5); + break; + default: + ASSERT (FALSE); + } + ASSERT (PrbsSeed != 0); + // + // Program the PRBS Seed + // + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, PrbsSeed); + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdDqs2DTraining.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdDqs2DTraining.c new file mode 100644 index 0000000000..62bfb82366 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdDqs2DTraining.c @@ -0,0 +1,115 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfRdDqs2DTraining.c + * + * RD DQS 2 dimensional training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/RdWr2DTraining) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mport.h" +#include "mfRdWr2DTraining.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_FEAT_RDWR2DTRAINING_MFRDDQS2DTRAINING_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + /*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes 2D training for Read DQS + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors occurred + * + */ + +BOOLEAN +MemFAmdRdDqs2DTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemFAmdRdDqs2DTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + IDS_HDT_CONSOLE (MEM_STATUS, "\n\nStart Read DQS 2D training.\n\n"); + TechPtr->Direction = DQS_READ_DIR; + return TechPtr->NBPtr->FamilySpecificHook[RdWr2DTraining] (TechPtr->NBPtr, NULL); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DEyeRimSearch.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DEyeRimSearch.c new file mode 100644 index 0000000000..090a9379a9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DEyeRimSearch.c @@ -0,0 +1,1112 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfRdWr2DEyeRimSearch.c + * + * Eye Rim Sampling Algorithm for use in 2D Read DQS or 2D Write Data Training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/RdWr2DTraining) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "AdvancedApi.h" +#include "GeneralServices.h" +#include "Ids.h" +#include "heapManager.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mport.h" +#include "merrhdl.h" +#include "OptionMemory.h" +#include "mfRdWr2DTraining.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_FEAT_RDWR2DTRAINING_MFRDWR2DEYERIMSEARCH_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +STATIC +MemFInitializeEyeRimSearch ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +STATIC +MemTEyeFill ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +UINT8 +STATIC +DetermineSavedState ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ); + +UINT8 +STATIC +GetPassFailValue ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ); + +VOID +STATIC +SetPassFailValue ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN UINT8 result + ); + +VOID +STATIC +SetSavedState ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN UINT8 result + ); + +INT8 +STATIC +Get1DTrainedEyeCenter ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane + ); + +BOOLEAN +STATIC +CheckForFail ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ); + + +INT8 +STATIC +xlateY ( + IN INT8 y + ); + +BOOLEAN +STATIC +ClearSampledPassResults ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +UINT32 +STATIC +CompareInPhase ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +UINT32 +STATIC +Compare180Phase ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +STATIC +ProgramVref ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Vref + ); + +VOID +STATIC +StartAggressors ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BOOLEAN TurnOn + ); + +/* -----------------------------------------------------------------------------*/ +/** + * + * Initialize Eye Rim Search + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return BOOLEAN + * TRUE + */ +BOOLEAN +STATIC +MemFInitializeEyeRimSearch ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 lane; + UINT8 vref; + MEM_RD_WR_2D_ENTRY *Data; + MEM_RD_WR_2D_RIM_ENTRY *RimData; + + ASSERT (NBPtr != NULL); + TechPtr = NBPtr->TechPtr; + Data = TechPtr->RdWr2DData; + RimData = Data->SavedData; + // + // Set Boundaries + // + RimData->xMax = Data->MaxRdWrSweep - 1; + RimData->yMax = (NBPtr->TotalMaxVrefRange / 2) - 1; + RimData->xMin = RimData->xMax * -1; + RimData->yMin = RimData->yMax * -1; + + RimData->ParallelSampling = EYERIM_PARALLEL_SAMPLING; + RimData->BroadcastDelays = EYERIM_BROADCAST_DELAYS; + RimData->Dirs[0] = 1; + RimData->Dirs[1] = -1; + + RimData->SampleCount = 0; + RimData->VrefUpdates = 0; + RimData->RdWrDlyUpdates = 0; + for (lane = 0; lane < MemFRdWr2DGetMaxLanes (NBPtr); lane ++ ) { + for ( vref = 0; vref < NBPtr->TotalMaxVrefRange; vref ++ ) { + // 00b = state not saved + // 01b = state saved + RimData->LaneSaved[lane].Vref[vref].PosRdWrDly = 0; + RimData->LaneSaved[lane].Vref[vref].NegRdWrDly = 0; + // 00b = Fail + // 01b = Pass + Data->Lane[lane].Vref[vref].PosRdWrDly = 0; + Data->Lane[lane].Vref[vref].NegRdWrDly = 0; + } + } + if (TechPtr->Direction == DQS_READ_DIR) { + NBPtr->MaxSeedCount = MAX_2D_RD_SEED_COUNT; + } else { + // + // Set the seed count in terms of the Total desired bit times + // + NBPtr->MaxSeedCount = (UINT8) (NBPtr->TotalBitTimes2DWrTraining / (256 * 8 * MIN ( 1, NBPtr->MaxAggressorDimms[NBPtr->Dct]))); + }; + TechPtr->DqsRdWrPosSaved = 0; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\tTotal Bit Times: %d Max Seed Count: %d\n",(TechPtr->Direction == DQS_READ_DIR) ? NBPtr->TotalBitTimes2DRdTraining:NBPtr->TotalBitTimes2DWrTraining,NBPtr->MaxSeedCount); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * This function collects data for Eye Rim Search + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Not Used + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors occurred + * + */ +BOOLEAN +MemFRdWr2DEyeRimSearch ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID * OptParam + ) +{ + UINT8 lane; + UINT8 j; + UINT8 k; + INT8 ydir; + INT8 xdir; + INT8 xi; + INT8 yi; + INT8 x; + INT8 y; + INT8 xmax; + INT8 ymax; + INT8 xmin; + INT8 ymin; + INT8 xo; + INT8 xt; + INT8 yo; + INT8 yt; + UINT8 slane; + UINT8 result; + INT8 states[2]; + UINT8 InitialCS; + UINT8 ChipSel; + UINT8 Aggr; + UINT8 SeedCount; + UINT32 InPhaseResult; + UINT32 PhaseResult180; + UINT32 Result; + MEM_RD_WR_2D_ENTRY *Data; + MEM_RD_WR_2D_RIM_ENTRY RimData; + MEM_TECH_BLOCK *TechPtr; + RD_WR_2D *VrefPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + ASSERT (NBPtr != NULL); + TechPtr = NBPtr->TechPtr; + Data = TechPtr->RdWr2DData; + // + // Allocate Storage for Rim Search + // + AllocHeapParams.RequestedBufferSize = MemFRdWr2DGetMaxLanes (NBPtr) * NBPtr->TotalMaxVrefRange * sizeof (RD_WR_2D); + AllocHeapParams.BufferHandle = AMD_MEM_2D_RD_WR_RIM_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &NBPtr->MemPtr->StdHeader) == AGESA_SUCCESS) { + VrefPtr = (RD_WR_2D *) AllocHeapParams.BufferPtr; + } else { + SetMemError (AGESA_FATAL, NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_2D, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + return FALSE; + } + for (lane = 0; lane < MemFRdWr2DGetMaxLanes (NBPtr); lane++) { + RimData.LaneSaved[lane].Vref = &VrefPtr[lane * NBPtr->TotalMaxVrefRange]; + } + Data->SavedData = &RimData; + + MemFInitializeEyeRimSearch (NBPtr); + NBPtr->FamilySpecificHook[RdWr2DSelectIntExtVref] (NBPtr, NULL); + InitialCS = TechPtr->ChipSel; + NBPtr->FamilySpecificHook[Adjust2DPhaseMaskBasedOnEcc] (NBPtr, &NBPtr); + NBPtr->FamilySpecificHook[RdWr2DInitVictim] (NBPtr, NULL); + // + // EnableDisable continuous writes on the agressor channels + // + + for (Aggr = 0; Aggr < MAX (1 , NBPtr->MaxAggressorDimms[NBPtr->Dct]) ; Aggr += (NBPtr->IsSupported[PerDimmAggressors2D] ? 2 : NBPtr->CsPerDelay) ) { + ClearSampledPassResults (NBPtr); + // + // Enable continuous writes on the aggressors + // + StartAggressors (NBPtr, TRUE); + for (ChipSel = InitialCS; ChipSel < (InitialCS + NBPtr->CsPerDelay); ChipSel++) { + xmax = RimData.xMax; + xmin = RimData.xMin; + ymax = RimData.yMax; + ymin = RimData.yMin; + if ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) != 0) { + TechPtr->ChipSel = ChipSel; + Data->RdWrDly = Data->MaxRdWrSweep; + for (lane = 0; lane < MemFRdWr2DGetMaxLanes (NBPtr); lane ++ ) { + // + // Two loops to handle each quadrant from the trained point + // + for ( j = 0; j < 2; j++) { + ydir = RimData.Dirs[j]; + for ( k = 0; k < 2; k++) { + xdir = RimData.Dirs[k]; + // + // Sample Loops - stay w/n the defined quadrant + // assume xmax = -1 * xmin, ymax = -1 * ymin + // initial point must always pass + // end point - boundary or two consecutive fails along the y-axis + // + // Initial dx, dy step state + // Starting dy at 8 to reduce samples necessary searching for the eye height + states[0] = 0; + states[1] = 8; + // xi and yi are inital trained points, assumed to be inside the eye + // These set the coordinate syst em for the quadrants + xi = Get1DTrainedEyeCenter (NBPtr, lane); + yi = 0; // Initial center is always at Vref nominal + x = xi; + y = yi; + while ( + ((xdir > 0 && x >= xi && x <= xmax) || + (xdir < 0 && x <= xi && x >= xmin)) && + ((ydir > 0 && y >= yi && y <= ymax) || + (ydir < 0 && y <= yi && y >= ymin)) && + !(y == yi && (xdir * (xi - x) >= 2)) + ) { + // + // Decide if result is already sampled, or need to take the sample + // + if (0 == DetermineSavedState (NBPtr, lane, y, x)) { + RimData.SampleCount++; + // + // Result for this point is not in the cache, sample it + // + for (slane = 0; slane < MemFRdWr2DGetMaxLanes (NBPtr); slane ++ ) { + if (!RimData.ParallelSampling && ( slane != lane)) { + continue; + } + // + // Calculate the relative offset from the initial trained position for this lane + // + xo = Get1DTrainedEyeCenter (NBPtr, slane); + yo = 0; + xt = xo + (x - xi); + yt = yo + (y - yi); + if (xt > xmax || xt < xmin || yt > ymax || yt < ymin) { + continue; + } + // + // Update the vref and lane delays (yt, xt) + // + if (slane == lane) { + // + // For processors w/ a single Vref per channel, only set Vref once + // + if ( NBPtr->Vref != xlateY (yt)) { + // + // If not already set + // + RimData.VrefUpdates++; + NBPtr->Vref = xlateY (yt); + ProgramVref (NBPtr, NBPtr->Vref); + } + } + if (RimData.BroadcastDelays) { + // + // When BroadcastDelays, only set RdDqs once + // + if (slane == lane) { + // + // If current lane + // + if ( Data->RdWrDly != (UINT8) (xt & RimData.xMax)) { + // + // If the not already set + // Account for rollover. + // + RimData.RdWrDlyUpdates++; + Data->RdWrDly = (UINT8) (xt & RimData.xMax); + NBPtr->FamilySpecificHook[RdWr2DProgramDelays] (NBPtr, &Data->RdWrDly); + } + } + } else { + // + // For Reads, Program all RdDqs Delay Values the same + // For Writes, Program all WrDat Values with same value offset by WrDqs for that lane. + // + if ( Data->RdWrDly != (UINT8) (xt & RimData.xMax)) { + // + // If the not already set + // Account for rollover. + // + RimData.RdWrDlyUpdates++; + Data->RdWrDly = (UINT8) (xt & RimData.xMax); + MemTSetDQSDelayAllCSR (TechPtr, (UINT8) (xt & RimData.xMax)); + } + } + } + // + // Perform Memory RW test + // + InPhaseResult = 0; + PhaseResult180 = 0; + NBPtr->FamilySpecificHook[RdWr2DInitVictimChipSel] (NBPtr, NULL); + for (SeedCount = 0; SeedCount < NBPtr->MaxSeedCount; SeedCount++) { + // + // Begin continuous reads and writes on the victim channels + // + NBPtr->FamilySpecificHook[RdWr2DStartVictim] (NBPtr, &SeedCount); + // + // Occasionally check if all trained lanes have already failed + // + if ((NBPtr->MaxSeedCount < 4) || ((SeedCount % (NBPtr->MaxSeedCount / 4)) == 0)) { + InPhaseResult |= CompareInPhase (NBPtr); + PhaseResult180 |= Compare180Phase (NBPtr); + if (((InPhaseResult & NBPtr->PhaseLaneMask) == NBPtr->PhaseLaneMask) && + ((PhaseResult180& NBPtr->PhaseLaneMask) == NBPtr->PhaseLaneMask)) { + break; + } + } + } + // + // Obtain the results + // + for (slane = 0; slane < MemFRdWr2DGetMaxLanes (NBPtr); slane ++ ) { + if (!RimData.ParallelSampling && (slane != lane)) { + continue; + } + // + // Calculate the relative offset from legacy trained + // + xo = Get1DTrainedEyeCenter (NBPtr, RimData.BroadcastDelays?lane:slane); + yo = 0; + xt = xo + (x - xi); + yt = yo + (y - yi); + if (xt > xmax || xt < xmin || yt > ymax || yt < ymin) { + continue; + } + // + // In this example, data{}{}{} = 1 is a Fail, 0 is a Pass + // In-Phase Results + // + if (CheckForFail (NBPtr, slane, yt, xt)) { + // + // Don't overwrite a fail + // + if (xt >= 0) { + if ((NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // x8, so combine "Nibble X" and "Nibble X+1" results + Result = (InPhaseResult >> (slane * 2)) & 0x03; + } else { + // x4, so use "Nibble" results + Result = (InPhaseResult >> slane) & 0x01; + } + SetPassFailValue (NBPtr, slane, yt, xt, (UINT8) (Result & 0x0F)); + SetSavedState (NBPtr, slane, yt, xt, (UINT8) (Result & 0x0F)); + } else { + if ((NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // x8, so combine "Nibble X" and "Nibble X+1" results + Result = (PhaseResult180 >> (slane * 2)) & 0x03; + } else { + // x4, so use "Nibble" results + Result = (PhaseResult180 >> slane) & 0x01; + } + SetPassFailValue (NBPtr, slane, yt, xt, (UINT8) (Result & 0x0F)); + SetSavedState (NBPtr, slane, yt, xt, (UINT8) (Result & 0x0F)); + } + } + } + } + // Decide the next sample point based on the result of the current lane + result = GetPassFailValue (NBPtr, lane, y, x); + InPhaseResult = 0; + PhaseResult180 = 0; + // States && comments are relative to the ++ Quadrant + if (result == 3) { + // Current Pass + if (states[0] > 0 || states[1] > 0) { + if (states[1] > 1 && y * ydir <= ymax - states[1]) { + // Current Pass, Continue searching up by leaps + states[0] = 0; + } else if (states[1] > 1 && y * ydir <= ymax - 4) { + // Current Pass, Continue searching up by leaps + states[0] = 0; + states[1] = 4; + } else if (states[1] > 1 && y * ydir <= ymax - 2) { + // Current Pass, Continue searching up by leaps + states[0] = 0; + states[1] = 2; + } else if (y * ydir <= ymax - 1) { + // Current Pass, Continue searching up by one + states[0] = 0; + states[1] = 1; + } else if (y * ydir == ymax) { + // Current Pass and at the top edge, Move right + states[0] = 1; + states[1] = 0; + } else { + ASSERT (FALSE); + } + } else { + // Move right one + states[0] = 1; + states[1] = 0; + } + } else if (result == 2) { + // Current Fail + if (states[0] > 0) { + // Search down and left + states[0] = -1; + states[1] = -1; + } else if (states[1] > 1 || states[1] < 0) { + // Search down + states[0] = 0; + states[1] = -1; + } else if (states[1] == 1) { + // Move down and right + states[0] = 1; + states[1] = -1; + } else { + ASSERT (FALSE); + } + } else { + ASSERT (FALSE); + } + // Update the coordinates based on the new state and quadrant direction + x += xdir * states[0]; + y += ydir * states[1]; + } + } + } + } + } + } + // + // Disable continuous writes on the agressor channels + // + StartAggressors (NBPtr, FALSE); + } + IDS_HDT_CONSOLE (MEM_FLOW,"\n\tSampleCount:%d",RimData.SampleCount); + IDS_HDT_CONSOLE (MEM_FLOW,"\t\tVref Updates:%d",RimData.VrefUpdates); + IDS_HDT_CONSOLE (MEM_FLOW,"\t\tRdDqs Dly Updates:%d\n",RimData.RdWrDlyUpdates); + // + // Finilazing Victim Continuous writes + // + NBPtr->FamilySpecificHook[RdWr2DFinalizeVictim] (NBPtr, NULL); + TechPtr->ChipSel = InitialCS; + // + // Fill eye based on Rim Search results + // + MemTEyeFill (NBPtr); + // + // Display the results the completed eye + // + MemFRdWr2DDisplaySearch (NBPtr, Data); + // + // Restore environment settings after training + // + if (HeapDeallocateBuffer (AMD_MEM_2D_RD_WR_RIM_HANDLE, &NBPtr->MemPtr->StdHeader) != AGESA_SUCCESS) { + SetMemError (AGESA_FATAL, NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_DEALLOCATE_FOR_2D, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + } + return TRUE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * Fill the data eye + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +STATIC +MemTEyeFill ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + INT8 x; + INT8 y; + UINT8 lane; + UINT8 result; + INT8 yLastPass; + UINT8 xMax; + UINT8 yMax; + UINT8 xMin; + UINT8 yMin; + BOOLEAN FirstPassFound; + MEM_RD_WR_2D_RIM_ENTRY *SavedData; + + ASSERT (NBPtr != NULL); + SavedData = ((MEM_RD_WR_2D_ENTRY*)NBPtr->TechPtr->RdWr2DData)->SavedData; + + xMax = SavedData->xMax; + yMax = SavedData->yMax; + xMin = SavedData->xMin; + yMin = SavedData->yMin; + for (lane = 0; lane < MemFRdWr2DGetMaxLanes (NBPtr); lane++) { + for (x = xMin ; x <= xMax ; x++) { + FirstPassFound = FALSE; + yLastPass = yMin; + // + // Scan for the last passing value + // + for (y = yMax ; y >= yLastPass ; y--) { + result = GetPassFailValue (NBPtr, lane, y, x); + if (result == 0) { + // + // Not Saved, Mark it as FAIL. (Should already be cleared) + // + } else if (result == 2) { + // + // FAIL, so Mark as FAIL (Do nothing) + // + } else if (result == 3) { + // + // PASS, Mark it and save y value (This will end the loop) + // + SetPassFailValue (NBPtr, lane, y, x, result); + yLastPass = y; + } else { + ASSERT (FALSE); + } + } + // + // Scan for the first pass, the fill until the last pass + // + for (y = yMin ; y < yLastPass ; y++) { + result = GetPassFailValue (NBPtr, lane, y, x); + if (result == 0) { + // + // Not Saved, if we've already found a first Passing value, mark it as a PASS + // otherwise, mark it as FAIL. (Should already be cleared) + // + if (FirstPassFound == TRUE) { + SetPassFailValue (NBPtr, lane, y, x, result); + } + } else if (result == 2) { + // + // FAIL, so Mark as FAIL (Do nothing) + // + } else if (result == 3) { + // + // PASS, Mark it and set FirstPassFound + // + SetPassFailValue (NBPtr, lane, y, x, result); + FirstPassFound = TRUE; + } else { + ASSERT (FALSE); + } + } // y Loop + } //x Loop + } // Lane Loop +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Get the 1D trained center + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] lane - UINT8 of current lane + * + * @return INT8 - Eye Center + */ +INT8 +STATIC +Get1DTrainedEyeCenter ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane + ) +{ + MEM_TECH_BLOCK *TechPtr; + ASSERT (NBPtr != NULL); + TechPtr = NBPtr->TechPtr; + if (TechPtr->Direction == DQS_READ_DIR) { + if ((NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // Program Byte based for x8 and x16 + return (INT8)NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + lane]; + } else { + return (INT8)NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + (lane >> 1)]; + } + } else { + return (INT8) (NBPtr->ChannelPtr->WrDatDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + lane] - + NBPtr->ChannelPtr->WrDqsDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + lane]); + } +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * Determine if a Byte Lane result has been saved + * + * @param[in,out] *NBPtr - Pointer to MEM_NB_BLOCK + * @param[in] lane - Current lane + * @param[in] y - Vref value + * @param[in] x - Delay + * + * @return UINT8 + * 1 - value saved + * 0 - value not saved + */ +UINT8 +STATIC +DetermineSavedState ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ) +{ + MEM_RD_WR_2D_RIM_ENTRY *SavedData; + + ASSERT (NBPtr != NULL); + SavedData = ((MEM_RD_WR_2D_ENTRY*)NBPtr->TechPtr->RdWr2DData)->SavedData; + + if (x >= 0) { + return (UINT8) (SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1); + } else { + return (UINT8) (SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1); + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Determine if a failure has occured + * + * @param[in,out] *NBPtr - Pointer to MEM_NB_BLOCK + * @param[in] lane - Current lane + * @param[in] y - Vref value + * @param[in] x - Delay Value + * + * @return BOOLEAN + * FALSE - Fail + * TRUE - Pass + */ +BOOLEAN +STATIC +CheckForFail ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ) +{ + MEM_RD_WR_2D_RIM_ENTRY *SavedData; + + ASSERT (NBPtr != NULL); + SavedData = ((MEM_RD_WR_2D_ENTRY*)NBPtr->TechPtr->RdWr2DData)->SavedData; + + if (x >= 0) { + if ((SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1) == 0) { + // value not saved, so it is not fail + return TRUE; + } else { + // value saved, so examine result + if ((SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1) == 0) { + // result = fail + return FALSE; + } else { + // result = pass + return TRUE; + } + } + } else { + if ((SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1) == 0) { + // value not saved, so it is not fail + return TRUE; + } else { + // value saved, so examine result + if ((SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1) == 0) { + // result = fail + return FALSE; + } else { + // result = pass + return TRUE; + } + } + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Get pass fail state of lane + * + * @param[in,out] *NBPtr - Pointer to MEM_NB_BLOCK + * @param[in] lane - Current lane + * @param[in] y - Vref value + * @param[in] x - Delay Value + * + * @return UINT8 + * 0 - Value not saved, + * 2 - Fail, + * 3 - Pass + */ +UINT8 +STATIC +GetPassFailValue ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ) +{ + MEM_TECH_BLOCK *TechPtr; + MEM_RD_WR_2D_ENTRY* RdWr2DData; + MEM_RD_WR_2D_RIM_ENTRY *SavedData; + + ASSERT (NBPtr != NULL); + TechPtr = NBPtr->TechPtr; + RdWr2DData = TechPtr->RdWr2DData; + SavedData = RdWr2DData->SavedData; + + if (x >= 0) { + if ((SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1) == 0) { + // value not saved + return 0; + } else { + // value saved, so return pass/fail + return ((RdWr2DData->Lane[lane].Vref[xlateY (y)].PosRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1) == 0) ? 2 : 3; + } + } else { + if ((SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1) == 0) { + // value not saved + return 0; + } else { + // value saved, so return pass/fail + return ((RdWr2DData->Lane[lane].Vref[xlateY (y)].NegRdWrDly >> (SavedData->xMax - (x & SavedData->xMax)) & 0x1) == 0) ? 2 : 3; + } + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Set the Pass/Fail state of lane + * + * @param[in,out] *NBPtr - Pointer to MEM_NB_BLOCK + * @param[in] lane - Current lane + * @param[in] y - Vref value + * @param[in] x - Delay Value + * @param[in] result - result value + * + */ +VOID +STATIC +SetPassFailValue ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN UINT8 result + ) +{ + MEM_TECH_BLOCK *TechPtr; + MEM_RD_WR_2D_ENTRY* RdWr2DData; + MEM_RD_WR_2D_RIM_ENTRY *SavedData; + + ASSERT (NBPtr != NULL); + TechPtr = NBPtr->TechPtr; + RdWr2DData = TechPtr->RdWr2DData; + SavedData = RdWr2DData->SavedData; + + if (x >= 0) { + RdWr2DData->Lane[lane].Vref[xlateY (y)].PosRdWrDly |= (result == 0) ? (1 << (SavedData->xMax - (x & SavedData->xMax))) : 0; + } else { + RdWr2DData->Lane[lane].Vref[xlateY (y)].NegRdWrDly |= (result == 0) ? (1 << (SavedData->xMax - (x & SavedData->xMax))) : 0; + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Set the save state of lane + * + * @param[in,out] *NBPtr - Pointer to MEM_NB_BLOCK + * @param[in] lane - Current lane + * @param[in] y - Vref value + * @param[in] x - Delay Value + * @param[in] result - result value + * + */ +VOID +STATIC +SetSavedState ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN UINT8 result + ) +{ + MEM_RD_WR_2D_RIM_ENTRY *SavedData; + + ASSERT (NBPtr != NULL); + SavedData = ((MEM_RD_WR_2D_ENTRY*)NBPtr->TechPtr->RdWr2DData)->SavedData; + + if (x >= 0) { + SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdWrDly |= (1 << (SavedData->xMax - (x & SavedData->xMax))); + } else { + SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdWrDly |= (1 << (SavedData->xMax - (x & SavedData->xMax))); + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Translate Vref into a positive, linear value that can be used as an + * array index. + * + * @param[in] y - INT8 of the (signed) Vref value + * + * @return UINT8 - Translated Value + */ +INT8 +STATIC +xlateY ( + IN INT8 y + ) +{ + ASSERT ( y > -0x10); + ASSERT ( y < 0x10); + return (y + 0xF) & 0x1F; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Re-walk the eye rim for each aggressor combination, which invalidates + * previous Passes in the sample array. Previous Fails in the sample array + * remain valid. Knowledge of previous fails and speeds sampling for the + * subsequent walks, esp. when used in conjunction w/ ParallelSampling. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return BOOLEAN + * TRUE + */ +BOOLEAN +STATIC +ClearSampledPassResults ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 lane; + UINT8 vref; + MEM_RD_WR_2D_ENTRY *Data; + MEM_RD_WR_2D_RIM_ENTRY *RimData; + + ASSERT (NBPtr != NULL); + + Data = (MEM_RD_WR_2D_ENTRY*)NBPtr->TechPtr->RdWr2DData; + RimData = Data->SavedData; + + for (lane = 0; lane < MemFRdWr2DGetMaxLanes (NBPtr); lane ++ ) { + for ( vref = 0; vref < NBPtr->TotalMaxVrefRange; vref ++ ) { + RimData->LaneSaved[lane].Vref[vref].PosRdWrDly &= ~(Data->Lane[lane].Vref[vref].PosRdWrDly); + Data->Lane[lane].Vref[vref].PosRdWrDly = 0; + RimData->LaneSaved[lane].Vref[vref].NegRdWrDly &= ~(Data->Lane[lane].Vref[vref].NegRdWrDly); + Data->Lane[lane].Vref[vref].NegRdWrDly = 0; + } + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Perform in-phase comparison + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return UINT32 - Bitmap of results of comparison + * 1 = FAIL + * 0 = PASS + */ + +UINT32 +STATIC +CompareInPhase ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 Result; + Result = 0; + NBPtr->FamilySpecificHook[RdWr2DCompareInPhase] (NBPtr, &Result); + return Result; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Perform 180 Degree out-of-phase comparison + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return UINT32 - Bitmap of results of comparison + * 1 = FAIL + * 0 = PASS + */ + +UINT32 +STATIC +Compare180Phase ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 Result; + Result = 0; + NBPtr->FamilySpecificHook[RdWr2DCompare180Phase] (NBPtr, &Result); + return Result; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Program Vref after scaling to accomodate the register definition + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Vref - UINT8 value of Vref relative to the sample point + * + */ + +VOID +STATIC +ProgramVref ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Vref + ) +{ + UINT8 ScaledVref; + ScaledVref = Vref; + NBPtr->FamilySpecificHook[RdWr2DScaleVref] (NBPtr, &ScaledVref); + NBPtr->FamilySpecificHook[RdWr2DProgramVref] (NBPtr, &ScaledVref); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Turn Aggressor Channels On or Off + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TurnOn - BOOLEAN + * TRUE - Turn On, False = Turn Off. + */ + +VOID +STATIC +StartAggressors ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BOOLEAN TurnOn + ) +{ + NBPtr->FamilySpecificHook[TurnOnAggressorChannels] (NBPtr, &TurnOn); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DPatternGeneration.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DPatternGeneration.c new file mode 100644 index 0000000000..b8d8429822 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DPatternGeneration.c @@ -0,0 +1,424 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfRdWr2DPatternGeneration.c + * + * Common Northbridge features + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/RdWr2DTraining) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mport.h" +#include "PlatformMemoryConfiguration.h" +#include "merrhdl.h" +#include "OptionMemory.h" +#include "mfRdWr2DTraining.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_FEAT_RDWR2DTRAINING_MFRDWR2DPATTERNGENERATION_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + /* -----------------------------------------------------------------------------*/ +/** + * + * This function Initializes the Victim for 2D RdDqs Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Unused + * + * @return BOOLEAN + * TRUE + */ +BOOLEAN +MemFRdWr2DInitVictim ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + RRW_SETTINGS *Rrw; + UINT8 InitialCS; + UINT8 ChipSel; + UINT8 SeedCount; + BOOLEAN OptPatWr2D; + + OptPatWr2D = (NBPtr->IsSupported[OptimizedPatternWrite2D]) && (NBPtr->TechPtr->Direction == DQS_READ_DIR); + InitialCS = NBPtr->TechPtr->ChipSel; + Rrw = &NBPtr->RrwSettings; + // Program the Bubble Count and CmdStreamLen + NBPtr->SetBitField (NBPtr, BFBubbleCnt, 32); + NBPtr->SetBitField (NBPtr, BFBubbleCnt2, 0); + NBPtr->SetBitField (NBPtr, BFCmdStreamLen, 63); + // Set Comparison Masks + NBPtr->SetBitField (NBPtr, BFDramDqMaskLow, Rrw->CompareMaskLow); + NBPtr->SetBitField (NBPtr, BFDramDqMaskHigh, Rrw->CompareMaskHigh); + // If All Dimms are ECC Capable Test ECC. Otherwise, mask it off + NBPtr->SetBitField (NBPtr, BFDramEccMask, (NBPtr->MCTPtr->Status[SbEccDimms] == TRUE) ? Rrw->CompareMaskEcc : 0xFF); + // Program the Starting Address + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA); + NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB); + NBPtr->SetBitField (NBPtr, BFTgtAddressB, Rrw->TgtColAddressB); + NBPtr->SetBitField (NBPtr, BFCmdTgt, CMD_TGT_AB); + // Wait for RRW Engine to be ready and turn it on + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1); + for (ChipSel = InitialCS; ChipSel < (InitialCS + NBPtr->CsPerDelay); ChipSel++) { + // Ensure that Odd and Even CS are trained + if ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) == 0) { + continue; + } + NBPtr->TechPtr->ChipSel = ChipSel; + for (SeedCount = 0; SeedCount < (OptPatWr2D ? NBPtr->MaxSeedCount : 1 ); SeedCount++) { + if (OptPatWr2D) { + // + // Set BankAddress according to seed + // + ASSERT (NBPtr->MaxSeedCount <= 4); + Rrw->TgtBankAddressA = (SeedCount * 2) + CPG_BANK_ADDRESS_A; + Rrw->TgtBankAddressB = (SeedCount * 2) + CPG_BANK_ADDRESS_B; + } + // + // Send ACTIVATE to all Banks + // + // Set Chip select + MemNSetBitFieldNb (NBPtr, BFCmdChipSelect, (1 << NBPtr->TechPtr->ChipSel)); + // Set Bank Address + MemNSetBitFieldNb (NBPtr, BFCmdBank, Rrw->TgtBankAddressA); + // Set Row Address + MemNSetBitFieldNb (NBPtr, BFCmdAddress, Rrw->TgtRowAddressA); + // Send the command + MemNSetBitFieldNb (NBPtr, BFSendActCmd, 1); + // Wait for command complete + MemNPollBitFieldNb (NBPtr, BFSendActCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + // Set Chip select + MemNSetBitFieldNb (NBPtr, BFCmdChipSelect, (1 << NBPtr->TechPtr->ChipSel)); + // Set Bank Address + MemNSetBitFieldNb (NBPtr, BFCmdBank, Rrw->TgtBankAddressB); + // Set Row Address + MemNSetBitFieldNb (NBPtr, BFCmdAddress, Rrw->TgtRowAddressB); + // Send the command + MemNSetBitFieldNb (NBPtr, BFSendActCmd, 1); + // Wait for command complete + MemNPollBitFieldNb (NBPtr, BFSendActCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + + if (OptPatWr2D) { + // + // Write the Pattern to the bank pairs for each seed. + // + NBPtr->FamilySpecificHook[RdWr2DInitVictimChipSel] (NBPtr, NULL); + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB); + // Program the PRBS Seed + NBPtr->FamilySpecificHook[RdWr2DProgramDataPattern] (NBPtr, &SeedCount); + // + // Enable continuous writes on the victim channels + // + // Set the Command Count + NBPtr->SetBitField (NBPtr, BFCmdCount, 256); + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // Wait for TestStatus = 1 and CmdSendInProg = 0. + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + } + } + } + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + // + // Do not use LFSR Rollover during Wr Training + // + NBPtr->SetBitField (NBPtr, BFLfsrRollOver, 1); + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function Initializes the Victim chipSelects for 2D Read or Write + * Training Continuous Writes + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Unused + * + * @return BOOLEAN + * TRUE + */ +BOOLEAN +MemFRdWr2DInitVictimChipSel ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, NBPtr->TechPtr->ChipSel); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectB, NBPtr->TechPtr->ChipSel); + NBPtr->SetBitField (NBPtr, BFResetAllErr, 1); + return TRUE; +} + + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function checks the In Phase Error status bits for comparison + * results for RD/WR 2D training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[out] *Result - Pointer to UINT32 for storing results + * + * @return BOOLEAN + * TRUE + * + */ +BOOLEAN +MemFRdWr2DCompareInPhase ( + IN OUT MEM_NB_BLOCK *NBPtr, + OUT VOID *Result + ) +{ + *(UINT32*)Result = NBPtr->GetBitField (NBPtr, BFNibbleErrSts); + return TRUE; +} + + /*-----------------------------------------------------------------------------*/ +/** + * + * This function checks the 180 Error status bits for RD/WR 2D training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[out] *Result - Pointer to UINT32 for storing results + * + * @return BOOLEAN + * TRUE + * + */ +BOOLEAN +MemFRdWr2DCompare180Phase ( + IN OUT MEM_NB_BLOCK *NBPtr, + OUT VOID *Result + ) +{ + *(UINT32*)Result = NBPtr->GetBitField (NBPtr, BFNibbleErr180Sts); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function starts the Victim for 2D RdDqs Training Continuous Writes + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] SeedCountPtr - UINT8 Pointer to Seed count + * + * @return BOOLEAN + * TRUE + * + */ +BOOLEAN +MemFRdWr2DStartVictim ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *SeedCountPtr + ) +{ + BOOLEAN OptPatWr2D; + UINT32 CommandCount; + UINT8 SeedCount; + + ASSERT (NBPtr != NULL); + ASSERT (SeedCountPtr != NULL); + + SeedCount = *(UINT8*)SeedCountPtr; + + OptPatWr2D = FALSE; + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + OptPatWr2D = (NBPtr->IsSupported[OptimizedPatternWrite2D]); + CommandCount = NBPtr->TotalBitTimes2DRdTraining / (8 * NBPtr->MaxSeedCount * NBPtr->MaxAggressorDimms[NBPtr->Dct]); + } else { + CommandCount = 256; + } + + // Program the PRBS Seed + NBPtr->FamilySpecificHook[RdWr2DProgramDataPattern] (NBPtr, &SeedCount); + if (OptPatWr2D) { + // + // Set BankAddress according to seed + // + NBPtr->SetBitField (NBPtr, BFTgtBankA, (SeedCount * 2) + CPG_BANK_ADDRESS_A); + NBPtr->SetBitField (NBPtr, BFTgtBankB, (SeedCount * 2) + CPG_BANK_ADDRESS_B); + } else { + // + // Enable continuous writes on the victim channels + // + // Set the Command Count + NBPtr->SetBitField (NBPtr, BFCmdCount, 256); + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // Wait for TestStatus = 1 and CmdSendInProg = 0. + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + } + // + // Enable continuous reads on the victim channels + // + // Set the Command Count + ASSERT (NBPtr->MaxAggressorDimms[NBPtr->Dct] != 0); + // + NBPtr->SetBitField (NBPtr, BFCmdCount, CommandCount ); + // Reset All Errors and Disable StopOnErr + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_READ); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // Wait for TestStatus = 1 and CmdSendInProg = 0 + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + //} + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finalizes the Victim for 2D RdDqs Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Unused + * + * @return BOOLEAN + * TRUE - Success + */ +BOOLEAN +MemFRdWr2DFinalizeVictim ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 InitialCS; + UINT8 ChipSel; + InitialCS = NBPtr->TechPtr->ChipSel; + NBPtr->SetBitField (NBPtr, BFLfsrRollOver, 0); + for (ChipSel = InitialCS; ChipSel < (InitialCS + NBPtr->CsPerDelay); ChipSel++) { + // Ensure that Odd and Even CS are precharged + if ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) == 0) { + continue; + } + NBPtr->TechPtr->ChipSel = ChipSel; + // Send the Precharge All Command + MemNRrwPrechargeCmd (NBPtr, ChipSel, PRECHARGE_ALL_BANKS); + } + // Turn Off the RRW Engine + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the Data Pattern that will be sent and compared + * against. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *PatternIndexPtr - Pointer to a generic index used to + * determine which pattern to program. + * + * @return BOOLEAN + * TRUE + * + */ +BOOLEAN +MemFRdWr2DProgramDataPattern ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID* PatternIndexPtr + ) +{ + UINT8 SeedCount; + UINT32 PrbsSeed; + CONST STATIC UINT32 PrbsSeedTbl[4] = {0x7ea05, 0x44443, 0x22b97, 0x3f167}; + CONST STATIC UINT32 CmdStreamLenTbl[4] = {13, 61, 127, 251}; + + ASSERT (NBPtr != 0); + ASSERT (PatternIndexPtr != NULL); + SeedCount = *(UINT8*)PatternIndexPtr; + ASSERT (SeedCount <= (NBPtr->MaxSeedCount - 1)); + // + // Program the Command Stream Length + // + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + NBPtr->SetBitField (NBPtr, BFCmdStreamLen, CmdStreamLenTbl[SeedCount]); + } else { + NBPtr->SetBitField (NBPtr, BFCmdStreamLen, 63); + } + PrbsSeed = PrbsSeedTbl[SeedCount % GET_SIZE_OF (PrbsSeedTbl)]; + ASSERT (PrbsSeed != 0); + // + // Program the PRBS Seed + // + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, PrbsSeed); + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.c new file mode 100644 index 0000000000..6a9e873e94 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.c @@ -0,0 +1,1368 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfRdWr2DTraining.c + * + * Common Read/Write 2D Training Feature Function + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/RdWr2DTraining) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "AdvancedApi.h" +#include "GeneralServices.h" +#include "heapManager.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mport.h" +#include "merrhdl.h" +#include "OptionMemory.h" +#include "mfRdWr2DTraining.h" +#include "Filecode.h" + +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_FEAT_RDWR2DTRAINING_MFRDWR2DTRAINING_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemFRdWr2DScaleVref ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Vref + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + extern MEM_PSC_FLOW_BLOCK* memPlatSpecFlowArray[]; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the 2D Read/Write Training Feature Hooks. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return BOOLEAN + * TRUE - Function was implemented + */ + +BOOLEAN +MemFRdWr2DTrainingInit ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + ASSERT (NBPtr != NULL); + NBPtr->FamilySpecificHook[RdWr2DTraining] = MemFAmdRdWr2DTraining; + NBPtr->FamilySpecificHook[CheckRdWr2DTrainingPerConfig] = MemFCheckRdWr2DTrainingPerConfig; + NBPtr->FamilySpecificHook[RdWr2DSelectIntExtVref] = MemFRdWr2DProgramIntExtVrefSelect; + NBPtr->FamilySpecificHook[RdWr2DProgramVref] = MemFRdWr2DProgramVref; + NBPtr->FamilySpecificHook[RdWr2DScaleVref] = MemFRdWr2DScaleVref; + NBPtr->FamilySpecificHook[RdWr2DProgramDelays] = MemFRdWr2DProgramDelays; + NBPtr->FamilySpecificHook[RdWr2DDataCollection] = MemFRdWr2DEyeRimSearch; + NBPtr->FamilySpecificHook[RdWr2DInitVictim] = MemFRdWr2DInitVictim; + NBPtr->FamilySpecificHook[RdWr2DInitVictimChipSel] = MemFRdWr2DInitVictimChipSel; + NBPtr->FamilySpecificHook[RdWr2DStartVictim] = MemFRdWr2DStartVictim; + NBPtr->FamilySpecificHook[RdWr2DFinalizeVictim] = MemFRdWr2DFinalizeVictim; + NBPtr->FamilySpecificHook[RdWr2DCompareInPhase] = MemFRdWr2DCompareInPhase; + NBPtr->FamilySpecificHook[RdWr2DCompare180Phase] = MemFRdWr2DCompare180Phase; + NBPtr->FamilySpecificHook[RdWr2DProgramDataPattern] = MemFRdWr2DProgramDataPattern; + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes 2D training for Read DQS or Write DQ + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Unused + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors occurred + */ + +BOOLEAN +MemFAmdRdWr2DTraining ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID* OptParam + ) +{ + MEM_TECH_BLOCK *TechPtr; + MEM_DATA_STRUCT *MemPtr; + MEM_RD_WR_2D_ENTRY Data; + RD_WR_2D *VrefPtr; + PSO_TABLE *PsoTable; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + UINT8 Dct; + UINT8 ChipSel; + UINT8 Lane; + UINT8 Vref; + UINT8 MaxLanes; + UINT8 TmpLanes; + UINT8 TotalDlyRange; + BOOLEAN Status; + // + // Initialize Pointers + // + ASSERT (NBPtr != NULL); + TechPtr = NBPtr->TechPtr; + MemPtr = NBPtr->MemPtr; + PsoTable = MemPtr->ParameterListPtr->PlatformMemoryConfiguration; + // + // Set environment settings before training + // + AGESA_TESTPOINT (TpProcMem2dRdDqsTraining, &(MemPtr->StdHeader)); + MemTBeginTraining (TechPtr); + // + // Allocate heap for the 2D RdWR/Vref Data structure + // + MaxLanes = 0; + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + TmpLanes = MemFRdWr2DGetMaxLanes (NBPtr); + MaxLanes = MAX (MaxLanes, TmpLanes); + } + + AllocHeapParams.RequestedBufferSize = MaxLanes * NBPtr->TotalMaxVrefRange * sizeof (RD_WR_2D); + AllocHeapParams.BufferHandle = AMD_MEM_2D_RD_WR_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) == AGESA_SUCCESS) { + VrefPtr = (RD_WR_2D *) AllocHeapParams.BufferPtr; + } else { + SetMemError (AGESA_FATAL, NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_2D, 0, 0, 0, 0, &MemPtr->StdHeader); + return TRUE; + } + for (Lane = 0; Lane < MaxLanes; Lane++) { + Data.Lane[Lane].Vref = &VrefPtr[Lane * NBPtr->TotalMaxVrefRange]; + } + // + // Setup hardware training engine + // + TechPtr->TrainingType = TRN_DQS_POSITION; + NBPtr->FamilySpecificHook[SetupHwTrainingEngine] (NBPtr, &TechPtr->TrainingType); + + Data.Vnom = NBPtr->TotalMaxVrefRange / 2; // Set Nominal Vref + TotalDlyRange = (TechPtr->Direction == DQS_READ_DIR) ? NBPtr->TotalRdDQSDlyRange : NBPtr->TotalWrDatDlyRange; + Data.MaxRdWrSweep = TotalDlyRange / 2; // Set Max Sweep Size + ASSERT (TotalDlyRange <= MAX_RD_WR_DLY_ENTRIES); + // + // Execute 2d Rd DQS training for all Dcts/Chipselects + // + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + NBPtr->Vref = 0xFF; + Status = FALSE; + if (NBPtr->FamilySpecificHook[CheckRdWr2DTrainingPerConfig] (NBPtr, NULL)) { + for (ChipSel = 0; ChipSel < NBPtr->CsPerChannel; ChipSel = ChipSel + NBPtr->CsPerDelay ) { + if ( (NBPtr->MCTPtr->Status[SbLrdimms]) ? ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0) : + ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) != 0) ) { + // + //Initialize storage + // + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + for (Vref = 0; Vref < NBPtr->TotalMaxVrefRange; Vref++) { + Data.Lane[Lane].Vref[Vref].PosRdWrDly = 0; + Data.Lane[Lane].Vref[Vref].NegRdWrDly = 0; + } + } + TechPtr->ChipSel = ChipSel; + IDS_HDT_CONSOLE (MEM_FLOW,"\tChip Select: %02x \n", TechPtr->ChipSel); + // + // 1. Sample the data eyes for each channel: + // + TechPtr->RdWr2DData = &Data; + if (NBPtr->FamilySpecificHook[RdWr2DDataCollection] (NBPtr, NULL)) { + // + // 2. Process the array of results with a diamond convolution mask, summing the number passing sample points. + // + // Determine Diamond Mask Height + if (MemFRdWr2DHeight (NBPtr, &Data)) { + // + // Apply Mask + // + if (MemFRdWr2DApplyMask (NBPtr, &Data)) { + // + // Convolution + // + if (MemFRdWr2DProcessConvolution (NBPtr, &Data)) { + // + // 3. Program the final DQS delay values. + // + if (MemFRdWr2DProgramMaxDelays (NBPtr, &Data)) { + // + // Find the Smallest Positive or Negative Margin for current CS + // + if (MemFRdWr2DFindCsVrefMargin (NBPtr, &Data)) { + Status = TRUE; + } + } + } + } + } + } + if (Status == FALSE) { + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + PutEventLog (AGESA_ERROR, (TechPtr->Direction == DQS_READ_DIR) ? MEM_ERROR_2D_DQS_ERROR : MEM_ERROR_2D_WRDAT_ERROR, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + } + } + } + // + // Find the Max and Min Vref values for each DCT + // + if (Status == TRUE) { + if (MemFRdWr2DFinalVrefMargin (NBPtr, &Data)) { + // + // Program the Max Vref value + // + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tProgramming Final Vref for channel\n"); + NBPtr->FamilySpecificHook[RdWr2DProgramVref] (NBPtr, &NBPtr->ChannelPtr->MaxVref); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tActual Vref programmed = %02x\n", + ( NBPtr->GetBitField (NBPtr, BFVrefDAC) >> TSEFO_END (NBPtr->NBRegTable[BFVrefDAC])) ); + Status = TRUE; + } else { + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + PutEventLog (AGESA_ERROR, (TechPtr->Direction == DQS_READ_DIR) ? MEM_ERROR_2D_DQS_VREF_MARGIN_ERROR: MEM_ERROR_2D_WRDAT_VREF_MARGIN_ERROR, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + } + } + } + } + // + // Restore environment settings after training + // + if (HeapDeallocateBuffer (AMD_MEM_2D_RD_WR_HANDLE, &MemPtr->StdHeader) != AGESA_SUCCESS) { + SetMemError (AGESA_FATAL, NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_DEALLOCATE_FOR_2D, 0, 0, 0, 0, &MemPtr->StdHeader); + } + IDS_HDT_CONSOLE (MEM_STATUS, "\tEnd\n"); + MemTEndTraining (TechPtr); + + IDS_HDT_CONSOLE (MEM_FLOW, "\n\nEnd %s 2D training\n\n",(TechPtr->Direction == DQS_READ_DIR) ? "Read DQS":"Write DQ"); + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines whether the current configuration is a valid + * config for applying 2D Training + * @todo: Update to work for 2D WR and 2D RD training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Unused + * + * @return BOOLEAN + * TRUE - Configuration valid + * FALSE - Configuration invalid + * + */ +BOOLEAN +MemFCheckRdWr2DTrainingPerConfig ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 i; + if (NBPtr->RefPtr->ForceTrainMode == FORCE_TRAIN_AUTO) { + i = 0; + while (memPlatSpecFlowArray[i] != NULL) { + if ((memPlatSpecFlowArray[i])->S2D (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + return TRUE; + } + i++; + } + } + return FALSE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines the maximum number of lanes for puposes of 2D + * Read or Write training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return UINT8 - Max Number of Lanes + * + */ +UINT8 +MemFRdWr2DGetMaxLanes ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 MaxLanes; + + TechPtr = NBPtr->TechPtr; + if ((TechPtr->Direction == DQS_READ_DIR) && ((NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) != 0)) { + // Per Nibble + MaxLanes = (NBPtr->MCTPtr->Status[SbEccDimms] && (NBPtr->IsSupported[EccByteTraining] == TRUE)) ? 18 : 16; + } else { + // Per Byte + MaxLanes = (NBPtr->MCTPtr->Status[SbEccDimms] && (NBPtr->IsSupported[EccByteTraining] == TRUE)) ? 9 : 8; + } + return MaxLanes; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs Vref to internal or external control for 2D Read + * or Write Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Unused + * + * @return BOOLEAN + * TRUE - External Vref was selected + * FALSE - Internal Vref was selected + * + */ +BOOLEAN +MemFRdWr2DProgramIntExtVrefSelect ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + NBPtr->SetBitField (NBPtr, BFVrefSel, (NBPtr->RefPtr->ExternalVrefCtl ? 0x0000 : 0x0001)); + } + return NBPtr->RefPtr->ExternalVrefCtl; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function scales Vref from the range used in Data Collection to + * the range that is programmed into the register. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Vref - Pointer to UINT8 Vref Value to scale. + * + * @return BOOLEAN + * TRUE Function was implemented + * + */ +BOOLEAN +STATIC +MemFRdWr2DScaleVref ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Vref + ) +{ + *(UINT8*)Vref = *(UINT8*)Vref * 2; + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs Vref for 2D Read/Write Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *VrefPtr - Pointer to Vref value + * + * @return BOOLEAN + * TRUE - Success + * FAIL (External Callout only) + * + */ +BOOLEAN +MemFRdWr2DProgramVref ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *VrefPtr + ) +{ + AGESA_STATUS Status; + MEM_DATA_STRUCT *MemPtr; + ID_INFO CallOutIdInfo; + VOLTAGE_ADJUST Va; + UINT8 Vref; + + ASSERT (NBPtr != NULL); + ASSERT (VrefPtr != NULL); + MemPtr = NBPtr->MemPtr; + Vref = *(UINT8*)VrefPtr; + CallOutIdInfo.IdField.SocketId = NBPtr->MCTPtr->SocketId; + CallOutIdInfo.IdField.ModuleId = NBPtr->MCTPtr->DieId; + LibAmdMemCopy ((VOID *)&Va, (VOID *)MemPtr, (UINTN)sizeof (Va.StdHeader), &MemPtr->StdHeader); + Va.MemData = MemPtr; + Status = AGESA_SUCCESS; + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + if (NBPtr->RefPtr->ExternalVrefCtl == FALSE) { + // + // Internal vref control + // + // This is 1/2 VrefDAC value Sign bit is shifted into place. + // + ASSERT (Vref < 32); + if (Vref < 15) { + Vref = (31 - Vref) << 1; + } else { + Vref = (Vref - 15) << 1; + } + NBPtr->SetBitField (NBPtr, BFVrefDAC, Vref << 2); + } else { + // External vref control + AGESA_TESTPOINT (TpProcMemBefore2dTrainExtVrefChange, &(NBPtr->MemPtr->StdHeader)); + NBPtr->MemPtr->ParameterListPtr->ExternalVrefValue = Vref; + IDS_HDT_CONSOLE (MEM_FLOW, "\n2D Read Training External CPU Vref Callout \n"); + Va.VoltageType = VTYPE_CPU_VREF; + Va.AdjustValue = Vref = (Vref - 15) << 1; + Status = AgesaExternalVoltageAdjust ((UINTN)CallOutIdInfo.IdInformation, &Va); + AGESA_TESTPOINT (TpProcMemAfter2dTrainExtVrefChange, &(NBPtr->MemPtr->StdHeader)); + } + } else { + // + // DIMM Vref Control + // + Va.VoltageType = VTYPE_DIMM_VREF; + // + // Offset by 15 and multiply by 2. + // + Va.AdjustValue = Vref = (Vref - 15) << 1; + Status = AgesaExternalVoltageAdjust ((UINTN)CallOutIdInfo.IdInformation, &Va); + if (Status != AGESA_SUCCESS) { + IDS_HDT_CONSOLE (MEM_FLOW, "* Dimm Vref Callout Failed *"); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + return (Status == AGESA_SUCCESS) ? TRUE : FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs Read DQS or Write DQ Delay values for Read/Write + * Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Delay - Pointer to UINT8 containing Delay value + * + * @return BOOLEAN + * TRUE + * + */ + +BOOLEAN +MemFRdWr2DProgramDelays ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *Delay + ) +{ + UINT32 RdDqsTime; + UINT8 RdWrDly; + + ASSERT (NBPtr != 0); + ASSERT (Delay != 0); + RdWrDly = *(UINT8*) Delay; + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + // This function should only be used for read training + ASSERT (NBPtr->TechPtr->Direction == DQS_READ_DIR); + // Program BL registers for both nibble (x4) and bytes (x8, x16) + RdDqsTime = 0; + RdDqsTime = (RdWrDly & 0x1F) << 8; + RdDqsTime = RdDqsTime | (RdWrDly & 0x1F); + if ((NBPtr->TechPtr->ChipSel / NBPtr->CsPerDelay) == 0) { + NBPtr->SetBitField (NBPtr, BFDataByteRxDqsDLLDimm0Broadcast, RdDqsTime); + } else if ((NBPtr->TechPtr->ChipSel / NBPtr->CsPerDelay) == 1) { + NBPtr->SetBitField (NBPtr, BFDataByteRxDqsDLLDimm1Broadcast, RdDqsTime); + } else if ((NBPtr->TechPtr->ChipSel / NBPtr->CsPerDelay) == 2) { + NBPtr->SetBitField (NBPtr, BFDataByteRxDqsDLLDimm2Broadcast, RdDqsTime); + } else if ((NBPtr->TechPtr->ChipSel / NBPtr->CsPerDelay) == 3) { + NBPtr->SetBitField (NBPtr, BFDataByteRxDqsDLLDimm3Broadcast, RdDqsTime); + } + } else { + MemTSetDQSDelayAllCSR (NBPtr->TechPtr, RdWrDly); + } + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function stores data for 2D Read DQS and Write DQ Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * @param[in] *InPhaseResult[] - Array of inphase results + * @param[in] *PhaseResult180[] - Array of Phase 180 results + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors ccurred + */ +VOID +MemFRdWr2DStoreResult ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data, + IN UINT32 InPhaseResult[], + IN UINT32 PhaseResult180[] + ) +{ + UINT8 Lane; + UINT8 Vref; + UINT8 RdWrDly; + UINT32 Result; + UINT32 Result180; + UINT8 Index; + Vref = NBPtr->Vref; + RdWrDly = Data->RdWrDly; + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + for (RdWrDly = 0; RdWrDly < Data->MaxRdWrSweep; RdWrDly++) { + if ((NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (NBPtr->TechPtr->ChipSel >> 1))) == 0) { + // x8, so combine "Nibble X" and "Nibble X+1" results + Index = Lane * 2; + Result = (InPhaseResult[RdWrDly] >> Index) & 0x03; + Result180 = (PhaseResult180[RdWrDly] >> Index) & 0x03; + } else { + // x4, so use "Nibble" results + Result = (InPhaseResult[RdWrDly] >> Lane) & 0x01; + Result180 = (PhaseResult180[RdWrDly] >> Lane) & 0x01; + } + Data->Lane[Lane].Vref[Vref].PosRdWrDly |= (Result == 0) ? (1 << (Data->MaxRdWrSweep - 1 - RdWrDly)) : 0; + Data->Lane[Lane].Vref[Vref].NegRdWrDly |= (Result180 == 0) ? (1 << (Data->MaxRdWrSweep - 1 - RdWrDly)) : 0; + } + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines the height of data for 2D Read and Write training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return BOOLEAN + * TRUE - No Errors occurred + */ +BOOLEAN +MemFRdWr2DHeight ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ) +{ + UINT8 Lane; + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + Data->Lane[Lane].HalfDiamondHeight = 0x0F; + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t Lane: "); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Lane); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tHeight: "); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", (2*(Data->Lane[Lane].HalfDiamondHeight) + 1)); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + ); + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets the width for 2D RdDQS and WrDat training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return UINT8 Width + */ +UINT8 +MemFGetRdWr2DWidth ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ) +{ + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + return NBPtr->DiamondWidthRd; + } else { + return NBPtr->DiamondWidthWr; + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets the step height for the diamond mask for 2D RdDQS or + * WrDat Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * @param[in] Vref - current Vref value + * @param[in] Lane - current Lane + * + * @return BOOLEAN + * TRUE - Step found and value should be updated + * FALSE - Step not found and value should not be updated + * + */ +BOOLEAN +MemFCheckRdWr2DDiamondMaskStep ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data, + IN UINT8 Vref, + IN UINT8 Lane + ) +{ + UINT8 M; + UINT8 VrefVal; + UINT8 width; + UINT8 i; + BOOLEAN status; + // m = -1 * height/width + // (y-b)/m = x + status = FALSE; + if (Vref > (Data->Vnom - 1)) { + VrefVal = (Vref + 1) - Data->Vnom; + } else { + VrefVal = Vref; + } + width = (MemFGetRdWr2DWidth (NBPtr, Data) - 1) / 2; + M = Data->Lane[Lane].HalfDiamondHeight / width; + i = 1; + while (i <= Data->Lane[Lane].HalfDiamondHeight) { + i = i + M; + if (VrefVal == i) { + status = TRUE; + } + } + return status; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function applies a mask for 2D RdDQS or WrDat training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors ccurred + * + */ +BOOLEAN +MemFRdWr2DApplyMask ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 RdWrDly; + UINT8 Lane; + UINT8 Height; + UINT8 Width; + UINT32 PosNegData; + UINT8 Vref; + UINT8 count; + UINT8 Dly; + UINT8 endWidth; + UINT8 startWidth; + UINT8 origEndWidth; + UINT8 origStartWidth; + UINT8 maxOverLapWidth; + UINT8 startOverLapWidth; + UINT8 TotalDlyRange; + BOOLEAN maxHeightExceeded; + BOOLEAN negVrefComplete; + BOOLEAN PosRdWrToNegRdWr; + BOOLEAN NegRdWrToPosRdWr; + + TechPtr = NBPtr->TechPtr; + TotalDlyRange = (TechPtr->Direction == DQS_READ_DIR) ? NBPtr->TotalRdDQSDlyRange : NBPtr->TotalWrDatDlyRange; + // + // Initialize Convolution + // + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + for (RdWrDly = 0; RdWrDly < TotalDlyRange; RdWrDly++) { + Data->Lane[Lane].Convolution[RdWrDly] = 0; + NBPtr->FamilySpecificHook[Adjust2DDelayStepSize] (NBPtr, &RdWrDly); + } + } + endWidth = 0; + startWidth = 0; + origEndWidth = 0; + origStartWidth = 0; + startOverLapWidth = 0; + maxOverLapWidth = 0; + maxHeightExceeded = FALSE; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tDetermining Width"); + // + // Get the Width of Diamond + // + Width = MemFGetRdWr2DWidth (NBPtr, Data); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\tWidth: %02x\n", Width); + ASSERT (Width != 0); + + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tExecuting convolution function\n"); + // + // Perform the convolution by sweeping the mask function centered at nominal Vref. Results in a one + // dimensional array with FOM values at each delay for each lane. Choose the delay setting at the peak + // FOM value. + // + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + Height = Data->Lane[Lane].HalfDiamondHeight; + ASSERT (Height < Data->Vnom); + // + // RdWrDly is divided around "Data->MaxRdWrSweep" into positive and negative directions + // Positive direction -> RdWrDly = 0 to (Data->MaxRdWrSweep - 1) + // Negative direction -> RdWrDly = Data->MaxRdWrSweep to (TotalDlyRange - 1) + // + for (RdWrDly = 0; RdWrDly < TotalDlyRange; RdWrDly++) { + // Vref loop is divided around "Data->Vnom - 1" into positive and negative directions + // Negative direction -> Vref = 0 ("Data->Vnom - 1") to Height("Data->Vnom - 1" - Height) + // Positive direction -> Vref = "Data->Vnom" to Height("Data->Vnom" + Height) + // + negVrefComplete = FALSE; + PosRdWrToNegRdWr = FALSE; + NegRdWrToPosRdWr = FALSE; + for (Vref = 0; Vref < (NBPtr->TotalMaxVrefRange - 1); Vref++) { + // Initial negative direction where Vref = 0 ("Data->Vnom - 1"), so we need to set + // initial startWidth and endWidth for +/- RdDqs + // + // Create common delay based on +/- RdDqs + if (RdWrDly > (Data->MaxRdWrSweep - 1)) { + Dly = RdWrDly - Data->MaxRdWrSweep; + } else { + Dly = RdWrDly; + } + if (Vref == 0 ) { + // Initialize -Vref + maxHeightExceeded = FALSE; // reset for start of -Vref + // Case 1: if +RdDqs - Check for lower bound (Width/2 > RdDqs > 0) + // : if -RdDqs - Check for lower bound (Width/2 + Data->MaxRdDqsSweep > RdDqs > Data->MaxRdDqsSweep) + if (Dly < Width / 2) { + endWidth = Dly + Width / 2 + 1; + startWidth = 0; + } else if ((Dly + Width / 2) > (Data->MaxRdWrSweep - 1)) { + // Case 2: if +RdWr - Check for upper bound ((Data->MaxRdWrSweep - 1) < RdWr < ((Data->MaxRdWrSweep - 1) - Width/2)) + // : if -RdWr - Check for lower bound ((DatNBPtr->TotalRdWrDlyRange - 1) < RdWr < ((NBPtr->TotalRdWrDlyRange - 1) - Width/2)) + endWidth = Data->MaxRdWrSweep; + startWidth = Dly - Width / 2; + } else { + // Set the initial "startWidth" and "endWidth" for +/- RdDqs + endWidth = Dly + Width / 2 + 1; + startWidth = Dly - Width / 2; + } + origEndWidth = endWidth; + origStartWidth = startWidth; + } else if (Vref == Data->Vnom) { + // Initialize +Vref + endWidth = origEndWidth; + startWidth = origStartWidth; + maxHeightExceeded = FALSE; // reset for start of +Vref + negVrefComplete = TRUE; + } else if ((Vref > (Data->Vnom + Height)) && negVrefComplete == TRUE) { + break; //switch to next RdDqs Dly if height exceeded for +vref and -vref complete + } else { + if (startWidth >= endWidth) { + if (RdWrDly == (TotalDlyRange - 1)) { + // Special condition for end of -RdDqs range + startWidth = Data->MaxRdWrSweep - 1; + endWidth = Data->MaxRdWrSweep; + } else { + // Width = 0, but Height not reached, + startWidth = Dly; + endWidth = Dly + 1; + } + } else { + // Check for Case 1 and Case 2 above + if ((RdWrDly + Width / 2) > (TotalDlyRange - 1)) { + endWidth = origEndWidth; + } + } + maxHeightExceeded = FALSE; + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + if (Lane == 0) { + if (RdWrDly == (Data->MaxRdWrSweep - (Width / 2)) ) { + Data->DiamondLeft[Vref] = startWidth; + Data->DiamondRight[Vref] = endWidth - 1; + } + } + ); + // + // Determine the correct Delay (+/-) and Vref (+/-)direction + // + if (maxHeightExceeded == FALSE) { + if (RdWrDly < Data->MaxRdWrSweep) { + if (Vref > (Data->Vnom - 1)) { + PosNegData = Data->Lane[Lane].Vref[Vref].PosRdWrDly; // +RdWr Dly, +Vref + } else { + PosNegData = Data->Lane[Lane].Vref[(Data->Vnom - 1) - Vref].PosRdWrDly; // +RdDqs Dly, -Vref + } + } else { + if (Vref > (Data->Vnom - 1)) { + PosNegData = Data->Lane[Lane].Vref[Vref].NegRdWrDly; // -RdWr Dly, +Vref + } else { + PosNegData = Data->Lane[Lane].Vref[(Data->Vnom - 1) - Vref].NegRdWrDly; // -RdWr Dly, -Vref + } + } + // + // Case 1: Non-overlap condition: + // Count the number of passes from "startWidth" to "endWidth" + // + for (count = startWidth; count < endWidth; count++) { + Data->Lane[Lane].Convolution[RdWrDly] = (UINT8) ((PosNegData >> count) & 0x1) + Data->Lane[Lane].Convolution[RdWrDly]; + } + // Case 2: Overlay between +RdWr and -RdWr starting from +RdWr + // Count the number of passes from "startWidth" to "endWidth" + // + if ((RdWrDly <= (Data->MaxRdWrSweep - 1) && (RdWrDly > ((Data->MaxRdWrSweep - 1) - Width / 2)))) { + startOverLapWidth = 0; + if (Vref == 0 || Vref == Data->Vnom) { + maxOverLapWidth = (RdWrDly + Width / 2) - (Data->MaxRdWrSweep - 1); // Initial overlap max width size + } else if (maxOverLapWidth == 0) { + maxOverLapWidth = startOverLapWidth; // Stop counting after overlap region complete + } + // Ensure that +/- vref is set correctly + if (Vref > (Data->Vnom - 1)) { + PosNegData = Data->Lane[Lane].Vref[Vref].NegRdWrDly; + } else { + PosNegData = Data->Lane[Lane].Vref[(Data->Vnom - 1) - Vref].NegRdWrDly; + } + // Need to count the number of passes when range extends from Pos RdDqs to Neg RdDqs + for (count = startOverLapWidth; count < maxOverLapWidth; count++) { + Data->Lane[Lane].Convolution[RdWrDly] = (UINT8) ((PosNegData >> count) & 0x1) + Data->Lane[Lane].Convolution[RdWrDly]; + } + if (maxOverLapWidth > 0) { + if (MemFCheckRdWr2DDiamondMaskStep (NBPtr, Data, Vref, Lane) || (Vref == 1) || (Vref == Data->Vnom)) { + maxOverLapWidth--; // Reduce overlap width outside of diamond mask + } + PosRdWrToNegRdWr = TRUE; + } + } + if (((RdWrDly - Data->MaxRdWrSweep) < Width / 2) && (RdWrDly > (Data->MaxRdWrSweep - 1))) { + // + // Case 3: Overlay between -RdDqs and +RdDqs starting from -RdDqs + // Count the number of passes from "startWidth" to "endWidth" + // + maxOverLapWidth = Data->MaxRdWrSweep; + if (Vref == 0 || Vref == Data->Vnom) { + startOverLapWidth = RdWrDly - Width / 2; // Initial overlap start point + } else if (startOverLapWidth > maxOverLapWidth) { + maxOverLapWidth = maxOverLapWidth - 1; // Continue to count until MaxHeight excceded + } + // Ensure that vref + or - is set correctly + if (Vref > (Data->Vnom - 1)) { + PosNegData = Data->Lane[Lane].Vref[Vref].PosRdWrDly; + } else { + PosNegData = Data->Lane[Lane].Vref[(Data->Vnom - 1) - Vref].PosRdWrDly; + } + // Need to count the number of passes when range extends from Pos RdDqs to Neg RdDqs + for (count = startOverLapWidth; count < maxOverLapWidth; count++) { + Data->Lane[Lane].Convolution[RdWrDly] = (UINT8) ((PosNegData >> count) & 0x1) + Data->Lane[Lane].Convolution[RdWrDly]; + } + if (startOverLapWidth < maxOverLapWidth) { + if (MemFCheckRdWr2DDiamondMaskStep (NBPtr, Data, Vref, Lane) || (Vref == 1) || (Vref == Data->Vnom)) { + startOverLapWidth++; // Reduce overlap width outside of diamond mask + } + NegRdWrToPosRdWr = TRUE; + } + } + } + if (MemFCheckRdWr2DDiamondMaskStep (NBPtr, Data, Vref, Lane) || (Vref == 1) || (Vref == Data->Vnom)) { + if (PosRdWrToNegRdWr) { + startWidth++; + endWidth = Data->MaxRdWrSweep; + PosRdWrToNegRdWr = FALSE; + } else if (NegRdWrToPosRdWr) { + startWidth = 0; + endWidth--; + NegRdWrToPosRdWr = FALSE; + } else { + startWidth++; + endWidth--; + } + } + NBPtr->FamilySpecificHook[Adjust2DVrefStepSize] (NBPtr, &Vref); + } + NBPtr->FamilySpecificHook[Adjust2DDelayStepSize] (NBPtr, &RdWrDly); + } + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t Diamond Shape: \n"); + for (Vref = 0; Vref < (NBPtr->TotalMaxVrefRange - 1); Vref++) { + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + for (RdWrDly = (Data->MaxRdWrSweep - Width); RdWrDly < Data->MaxRdWrSweep; RdWrDly++) { + if (Vref < (Data->Vnom - 1)) { + if (RdWrDly == Data->DiamondLeft[(NBPtr->TotalMaxVrefRange - 2) - Vref]) { + IDS_HDT_CONSOLE (MEM_FLOW, " | "); + } else if (RdWrDly == Data->DiamondRight[(NBPtr->TotalMaxVrefRange - 2) - Vref]) { + IDS_HDT_CONSOLE (MEM_FLOW, " | -> Width = %02x", (Data->DiamondRight[(NBPtr->TotalMaxVrefRange - 2) - Vref]) - (Data->DiamondLeft[(NBPtr->TotalMaxVrefRange - 2) - Vref])); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " "); + } + } else { + if (RdWrDly == Data->DiamondLeft[Vref - (Data->Vnom - 1)]) { + IDS_HDT_CONSOLE (MEM_FLOW, " | "); + } else if (RdWrDly == Data->DiamondRight[Vref - (Data->Vnom - 1)]) { + IDS_HDT_CONSOLE (MEM_FLOW, " | -> Width = %02x", (Data->DiamondRight[Vref - (Data->Vnom - 1)]) - (Data->DiamondLeft[Vref - (Data->Vnom - 1)])); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " "); + } + } + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t Convolution results after processing raw data:\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t Delay: "); + for (RdWrDly = 0; RdWrDly < TotalDlyRange; RdWrDly++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %02x ", RdWrDly <= (Data->MaxRdWrSweep - 1) ? (Data->MaxRdWrSweep - 1) - RdWrDly : (TotalDlyRange - 1) - RdWrDly); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tLane: %02x\n", Lane); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tConv: "); + for (RdWrDly = 0; RdWrDly < TotalDlyRange; RdWrDly++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", Data->Lane[Lane].Convolution[RdWrDly]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + ); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function Examines the convolution function and determines the Max Delay + * for 2D RdDQS and WrDat training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors ccurred + */ + +BOOLEAN +MemFRdWr2DProcessConvolution ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 RdWrDly; + UINT8 Lane; + UINT16 MaxFOM; + UINT8 MaxRange; + UINT8 CurrRange; + UINT8 TotalDlyRange; + BOOLEAN status; + + ASSERT (NBPtr != NULL); + TechPtr = NBPtr->TechPtr; + TotalDlyRange = (TechPtr->Direction == DQS_READ_DIR) ? NBPtr->TotalRdDQSDlyRange : NBPtr->TotalWrDatDlyRange; + status = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tDetermining Delay based on Convolution function\n"); + // Determine the Max RdDqs or WrDat Dly for the convolution function + // - Choose the delay setting at the peak FOM value. + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + // Find largest value as MaxFOM + MaxFOM = 0; + for (RdWrDly = 0; RdWrDly < TotalDlyRange; RdWrDly++) { + if (Data->Lane[Lane].Convolution[RdWrDly] > MaxFOM) { + MaxFOM = Data->Lane[Lane].Convolution[RdWrDly]; + } + } + status = MaxFOM > 0 ? TRUE : FALSE; // It is an error if all convolution points are zero + + // Then find the midpoint of the largest consecutive window w/ that MaxFOM + // In cases of an even number of consecutive points w/ that MaxFOM exists, + // choose the midpoint to the right + // All things being equal, favor the right side of a bi-modal eye + // Stressful SSO patterns shift the eye right! + MaxRange = 0; + CurrRange = 0; + for (RdWrDly = 0; (MaxFOM > 0) && RdWrDly < TotalDlyRange; RdWrDly++) { + if (Data->Lane[Lane].Convolution[RdWrDly] == MaxFOM) { + CurrRange++; + if (CurrRange >= MaxRange) { + Data->Lane[Lane].MaxRdWrDly = RdWrDly - ((CurrRange - 1) / 2); + MaxRange = CurrRange; + } + } else { + CurrRange = 0; + } + } + + if (Data->Lane[Lane].MaxRdWrDly > Data->MaxRdWrSweep) { + status = FALSE; // Error + } + // Set Actual register value + if (Data->Lane[Lane].MaxRdWrDly < Data->MaxRdWrSweep) { + Data->Lane[Lane].MaxRdWrDly = (Data->MaxRdWrSweep - 1) - Data->Lane[Lane].MaxRdWrDly; + } else { + status = FALSE; // Error + } + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t Cs %d Lane: ", TechPtr->ChipSel); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Lane); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t Max %s Delay: ", TechPtr->Direction == DQS_READ_DIR ? "Rd Dqs" : "Wr DQ"); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Data->Lane[Lane].MaxRdWrDly); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t1D Trained %s Delay: ", TechPtr->Direction == DQS_READ_DIR ? "Rd Dqs" : "Wr DQ"); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + if (TechPtr->Direction == DQS_READ_DIR) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + Lane]); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", (NBPtr->ChannelPtr->WrDatDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + Lane] - \ + NBPtr->ChannelPtr->WrDqsDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + Lane])); + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + ); + + if (status == FALSE) { + SetMemError (AGESA_FATAL, NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_INVALID_2D_RDDQS_VALUE, 0, 0, 0, 0, &TechPtr->NBPtr->MemPtr->StdHeader); + } + return status; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the Max Rd Dqs or Max Wr DQ for 2D training from + * convolution + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors ccurred + */ +BOOLEAN +MemFRdWr2DProgramMaxDelays ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 Lane; + UINT8 LaneHighRdDqs2dDlys; + UINT8 LaneLowRdDqs2dDlys; + UINT8 MaxWrDatDly; + TechPtr = NBPtr->TechPtr; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tProgramming Max %s Delay per Lane\n\n", TechPtr->Direction == DQS_READ_DIR ? "Rd Dqs" : "Wr DQ"); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + if ( TechPtr->Direction == DQS_WRITE_DIR || (NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // Program Byte based for x8 and x16 + if ( TechPtr->Direction == DQS_READ_DIR) { + // + // Read DQS Training + // + NBPtr->SetTrainDly (NBPtr, AccessRdDqsDly, DIMM_BYTE_ACCESS ((TechPtr->ChipSel / NBPtr->CsPerDelay), Lane), (UINT16)Data->Lane[Lane].MaxRdWrDly); + NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + Lane] = Data->Lane[Lane].MaxRdWrDly; + } else { + // + // Write DQ Training + // + MaxWrDatDly = (UINT8) (Data->Lane[Lane].MaxRdWrDly + TechPtr->NBPtr->ChannelPtr->WrDqsDlys[(TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * MAX_DELAYS + Lane]); + NBPtr->SetTrainDly (NBPtr, AccessWrDatDly, DIMM_BYTE_ACCESS ((TechPtr->ChipSel / NBPtr->CsPerDelay), Lane), MaxWrDatDly); + NBPtr->ChannelPtr->WrDatDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + Lane] = MaxWrDatDly; + } + } else { + ASSERT (TechPtr->Direction == DQS_READ_DIR); + // Program nibble based x4, so use "Nibble" + NBPtr->SetTrainDly (NBPtr, AccessRdDqs2dDly, DIMM_NBBL_ACCESS ((TechPtr->ChipSel / NBPtr->CsPerDelay), Lane), (UINT16)Data->Lane[Lane].MaxRdWrDly); + NBPtr->ChannelPtr->RdDqs2dDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_NUMBER_LANES + Lane] = Data->Lane[Lane].MaxRdWrDly; + // For each pair of nibbles (high (Odd Nibble) and Low (Even nibble)), find the largest and use that as the RdDqsDly value + if ((Lane & 0x1) == 0) { + LaneHighRdDqs2dDlys = Data->Lane[Lane + 1].MaxRdWrDly; + LaneLowRdDqs2dDlys = Data->Lane[Lane].MaxRdWrDly; + if (LaneHighRdDqs2dDlys > LaneLowRdDqs2dDlys) { + NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + (Lane >> 1)] = LaneHighRdDqs2dDlys; + } else { + NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / NBPtr->CsPerDelay) * MAX_DELAYS + (Lane >> 1)] = LaneLowRdDqs2dDlys; + } + } + NBPtr->DctCachePtr->Is2Dx4 = TRUE; + } + } + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the Positive and negative Vref Margin for the current CS + * for 2D RdDQS or WrDat training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors ccurred + */ +BOOLEAN +MemFRdWr2DFindCsVrefMargin ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ) +{ + UINT8 SmallestMaxVrefNeg; + UINT8 Lane; + UINT8 RdWrDly; + UINT8 Vref; + UINT8 MaxVrefPositive; + UINT8 MaxVrefNegative; + UINT8 SmallestMaxVrefPos; + UINT32 PosNegData; + SmallestMaxVrefPos = 0xFF; + SmallestMaxVrefNeg = 0; + MaxVrefPositive = 0; + MaxVrefNegative = 0xFF; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFinding Smallest Max Positive and Negative Vref\n\n"); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + RdWrDly = (Data->MaxRdWrSweep - 1) - Data->Lane[Lane].MaxRdWrDly; + for (Vref = 0; Vref < (Data->Vnom - 1); Vref++) { + // Neg Vref - (searching from top of array down) + PosNegData = Data->Lane[Lane].Vref[Vref].PosRdWrDly; + if ((UINT8) ((PosNegData >> RdWrDly) & 0x1) == 1) { + MaxVrefNegative = Vref; + break; + } + NBPtr->FamilySpecificHook[Adjust2DVrefStepSize] (NBPtr, &Vref); + } + for (Vref = (Data->Vnom - 1); Vref < (NBPtr->TotalMaxVrefRange - 1); Vref++) { + // Pos Vref - (searching from Vnom + 1 of array down) + PosNegData = Data->Lane[Lane].Vref[Vref].PosRdWrDly; + if ((UINT8) ((PosNegData >> RdWrDly) & 0x1) == 0) { + // Convert to register setting + MaxVrefPositive = Vref - 1;// - Data->Vnom; + break; + } else { + // If Vref = 1F passes, then smallest Vref = 0x1F + if (Vref == ((NBPtr->TotalMaxVrefRange - 1) - 1)) { + MaxVrefPositive = 0x1E; + break; + } + } + NBPtr->FamilySpecificHook[Adjust2DVrefStepSize] (NBPtr, &Vref); + } + if (MaxVrefPositive < SmallestMaxVrefPos) { + // Find the smallest Max Pos Vref + SmallestMaxVrefPos = MaxVrefPositive; + } + if (MaxVrefNegative > SmallestMaxVrefNeg) { + // Find the largest Max Neg Vref + SmallestMaxVrefNeg = MaxVrefNegative; + } + } + if (SmallestMaxVrefPos != (Data->Vnom - 2)) { + Data->SmallestPosMaxVrefperCS[NBPtr->TechPtr->ChipSel] = SmallestMaxVrefPos - Data->Vnom + 1; + } else { + Data->SmallestPosMaxVrefperCS[NBPtr->TechPtr->ChipSel] = 0; + } + Data->SmallestNegMaxVrefperCS[NBPtr->TechPtr->ChipSel] = (Data->Vnom - 1) - SmallestMaxVrefNeg; + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSmallest Max Positive Vref Offset from V-Nom for ChipSel %02x = + %02x\n", NBPtr->TechPtr->ChipSel, Data->SmallestPosMaxVrefperCS[NBPtr->TechPtr->ChipSel]); + if (Data->SmallestPosMaxVrefperCS[NBPtr->TechPtr->ChipSel] == 0) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSmallest Max Negative Vref Offset from V-Nom for ChipSel %02x = 00\n"); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSmallest Max Negative Vref Offset from V-Nom for ChipSel %02x = - %02x\n", NBPtr->TechPtr->ChipSel, Data->SmallestNegMaxVrefperCS[NBPtr->TechPtr->ChipSel]); + } + ); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the final Vref Margin for 2D RdDQS or WrDat training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return BOOLEAN + * TRUE - No Errors occurred + * FALSE - Errors ccurred + */ +BOOLEAN +MemFRdWr2DFinalVrefMargin ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ) +{ + UINT8 ChipSel; + UINT8 SmallestMaxPosVref; + UINT8 SmallestMaxNegVref; + UINT8 OffsetFromVref; + UINT8 Vnom; + SmallestMaxNegVref = 0x7F; + SmallestMaxPosVref = 0x7F; + Vnom = (Data->Vnom - 1); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFinding Final Vref for channel\n\n"); + for (ChipSel = 0; ChipSel < NBPtr->CsPerChannel; ChipSel = ChipSel + NBPtr->CsPerDelay ) { + if ( (NBPtr->MCTPtr->Status[SbLrdimms]) ? ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0) : + ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) != 0) ) { + if (Data->SmallestPosMaxVrefperCS[ChipSel] < SmallestMaxPosVref) { + SmallestMaxPosVref = Data->SmallestPosMaxVrefperCS[ChipSel]; + } + if (Data->SmallestNegMaxVrefperCS[ChipSel] < SmallestMaxNegVref) { + SmallestMaxNegVref = Data->SmallestNegMaxVrefperCS[ChipSel]; + } + } + } + // + // Synchronize minimum and Maximums with other Vref values + // + if (NBPtr->TechPtr->Direction == DQS_WRITE_DIR) { + if (NBPtr->SharedPtr->CommonSmallestMaxNegVref < SmallestMaxNegVref) { + SmallestMaxNegVref = NBPtr->SharedPtr->CommonSmallestMaxNegVref; + } else { + NBPtr->SharedPtr->CommonSmallestMaxNegVref = SmallestMaxNegVref; + } + if (NBPtr->SharedPtr->CommonSmallestMaxPosVref < SmallestMaxPosVref) { + SmallestMaxPosVref = NBPtr->SharedPtr->CommonSmallestMaxPosVref; + } else { + NBPtr->SharedPtr->CommonSmallestMaxPosVref = SmallestMaxPosVref; + } + } + NBPtr->FamilySpecificHook[RdWr2DScaleVref] (NBPtr, &SmallestMaxPosVref); + NBPtr->FamilySpecificHook[RdWr2DScaleVref] (NBPtr, &SmallestMaxNegVref); + NBPtr->FamilySpecificHook[RdWr2DScaleVref] (NBPtr, &Vnom); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tScaled Smallest Max Positive = + %02x\n", SmallestMaxPosVref); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tScaled Smallest Max Negative =%s%02x\n", ((SmallestMaxNegVref != 0) ? " - " : " "), SmallestMaxNegVref); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tScaled Vnom = %02x\n", Vnom); + + if (SmallestMaxPosVref > SmallestMaxNegVref) { + OffsetFromVref = (SmallestMaxPosVref - SmallestMaxNegVref) / 2; + NBPtr->ChannelPtr->MaxVref = Vnom + OffsetFromVref; + } else { + OffsetFromVref = (SmallestMaxNegVref - SmallestMaxPosVref) / 2; + NBPtr->ChannelPtr->MaxVref = Vnom - OffsetFromVref; + } + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tFinal Vref Offset From Vnom =%s%02x\n", + ((OffsetFromVref != 0) ? ((SmallestMaxPosVref > SmallestMaxNegVref) ? " + ":" - "):" "), OffsetFromVref); + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function displays ther results of the 2D search + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + */ +VOID +MemFRdWr2DDisplaySearch ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ) +{ + IDS_HDT_CONSOLE_DEBUG_CODE ( + UINT8 Lane; + INT8 Vref; + // Display data collected + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDisplaying Data collected\n\n"); + for (Lane = 0; Lane < MemFRdWr2DGetMaxLanes (NBPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tLane: %02x\n", Lane); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t Vref %s\n", (NBPtr->TechPtr->Direction == DQS_READ_DIR) ? "NegRdDqs PosRdDqs" : "PosWrDat"); + for (Vref = NBPtr->TotalMaxVrefRange - 2; Vref >= 0; Vref--) { + if (Vref < (Data->Vnom - 1)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t - "); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", ((Data->Vnom -1) - Vref)); + } else if (Vref == (Data->Vnom - 1)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t 00 "); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t + "); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Vref - (Data->Vnom - 1)); + } + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + IDS_HDT_CONSOLE (MEM_FLOW, "%08x", Data->Lane[Lane].Vref[Vref].NegRdWrDly); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " "); + } + IDS_HDT_CONSOLE (MEM_FLOW, "%08x \n", Data->Lane[Lane].Vref[Vref].PosRdWrDly); + NBPtr->FamilySpecificHook[Adjust2DVrefStepSize] (NBPtr, &Vref); + } + } + ) +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.h new file mode 100644 index 0000000000..a2a4b02dda --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/RDWR2DTRAINING/mfRdWr2DTraining.h @@ -0,0 +1,266 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mf2DRdWrTraining.h + * + * Common Definitions ot support 2D Read/Write Training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/2DRdWrTraining) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MFRDWR2DTRAINING_H_ +#define _MFRDWR2DTRAINING_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ +#define MAX_2D_VREF_ENTRIES 0x20 ///< Maximum number of vref entries +#define MAX_RD_WR_DLY_ENTRIES 0x40 ///< Maximum number of RD/WR Delay Entries +#define VREF_ADDITIONAL_STEP_SIZE 0x0 ///< Vref Additional Step size +#define RDDQS_ADDITIONAL_STEP_SIZE 0x0 ///< RdDqs Additional Step size +#define MAX_2D_RD_SEED_COUNT 4 ///< Max Seed count +#define MAX_2D_RD_WR_CS_PER_CHANNEL 8 ///< Max CS per Rd Wr delay group + +#define EYERIM_PARALLEL_SAMPLING TRUE +#define EYERIM_BROADCAST_DELAYS TRUE + +/// Structure for RD DQS 2D training RDDQS delays. +typedef struct { + UINT32 PosRdWrDly; ///< Positive RdDQS Delay + UINT32 NegRdWrDly; ///< Negative RdDQS Delay +} RD_WR_2D; + +/// Structure for RD DQS 2D training Vref delays +typedef struct { + RD_WR_2D *Vref; ///< Pointer to Vref Entries + UINT16 Convolution[MAX_RD_WR_DLY_ENTRIES]; ///< Total number of passes in each mask + UINT8 PosHeight[MAX_RD_WR_DLY_ENTRIES / 2]; ///< Positive Vref height Height per Delay + UINT8 NegHeight[MAX_RD_WR_DLY_ENTRIES / 2]; ///< Negative Vref height Height per Delay + UINT8 HalfDiamondHeight; ///< Half of the Height per BL (height of pos/neg vref) + UINT8 MaxRdWrDly; ///< Max RdWrDly from convolution function +} VREF_RD_WR_2D; + +/// Structure for RD DQS 2D training Nibbles +typedef struct { + VREF_RD_WR_2D Lane[MAX_NUMBER_LANES]; ///< Bytelane or Nibble + UINT8 Vnom; ///< Nominal Vref value + UINT8 MaxRdWrSweep; ///< Maximum RdDqs or WrDat Sweep size + UINT8 SmallestPosMaxVrefperCS[MAX_2D_RD_WR_CS_PER_CHANNEL]; ///< Smallest Positive Max Vref per CS + UINT8 SmallestNegMaxVrefperCS[MAX_2D_RD_WR_CS_PER_CHANNEL]; ///< Smallest Negative Max Vref per CS + UINT8 DiamondLeft[MAX_2D_VREF_ENTRIES]; ///< Left edge of Diamond for shape display + UINT8 DiamondRight[MAX_2D_VREF_ENTRIES]; ///< Left edge of Diamond for shape display + UINT8 RdWrDly; ///< RdDQS or WrDat Dly setting + VOID* SavedData; ///< Algorithm-specific saved data +} MEM_RD_WR_2D_ENTRY; + +/// Structure used for RD WR 2D Eye Rim Search Algorithm +typedef struct { + VREF_RD_WR_2D LaneSaved[MAX_NUMBER_LANES]; ///< Bytelane or Nibble that was saved + INT8 xMin; ///< Minimum value for RdDqs delays + INT8 xMax; ///< Maximum value for RdDqs delays + INT8 yMin; ///< Minimum value for vref delays + INT8 yMax; ///< Maximum value for vref delays + BOOLEAN ParallelSampling; ///< Flag to indicate parallel sampling feature + BOOLEAN BroadcastDelays; ///< Flag to indicate if delays will be broadcast + UINT32 SampleCount; ///< Count of samples taken + UINT32 VrefUpdates; ///< Count of updates to Vref + UINT32 RdWrDlyUpdates; ///< Count of updates to RdWrDly + INT8 Dirs[2]; ///< List of directions to search for each axis +} MEM_RD_WR_2D_RIM_ENTRY; + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +BOOLEAN +MemFAmdRdWr2DTraining ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID* OptParam + ); + +BOOLEAN +MemFCheckRdWr2DTrainingPerConfig ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemFRdWr2DProgramIntExtVrefSelect ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemFRdWr2DProgramVref ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *VrefPtr + ); + +BOOLEAN +MemFRdWr2DProgramDelays ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *Delay + ); + +VOID +MemFRdWr2DStoreResult ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data, + IN UINT32 InPhaseResult[], + IN UINT32 PhaseResult180[] + ); + +BOOLEAN +MemFRdWr2DHeight ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ); + +UINT8 +MemFGetRdWr2DWidth ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ); + +BOOLEAN +MemFCheckRdWr2DDiamondMaskStep ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data, + IN UINT8 Vref, + IN UINT8 Lane + ); +BOOLEAN +MemFRdWr2DApplyMask ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ); + +BOOLEAN +MemFRdWr2DProcessConvolution ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ); + +BOOLEAN +MemFRdWr2DProgramMaxDelays ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ); + +BOOLEAN +MemFRdWr2DFindCsVrefMargin ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ); + +BOOLEAN +MemFRdWr2DFinalVrefMargin ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ); + +UINT8 +MemFRdWr2DGetMaxLanes ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemFRdWr2DTrainingInit ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemFRdWr2DEyeRimSearch ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *OptParam + ); + +VOID +MemFRdWr2DDisplaySearch ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_RD_WR_2D_ENTRY *Data + ); + +/******************************* +* Pattern Generation Functions +*******************************/ +BOOLEAN +MemFRdWr2DCompareInPhase ( + IN OUT MEM_NB_BLOCK *NBPtr, + OUT VOID *Result + ); + +BOOLEAN +MemFRdWr2DCompare180Phase ( + IN OUT MEM_NB_BLOCK *NBPtr, + OUT VOID *Result + ); + +BOOLEAN +MemFRdWr2DInitVictim ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemFRdWr2DInitVictimChipSel ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemFRdWr2DStartVictim ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *SeedCountPtr + ); + +BOOLEAN +MemFRdWr2DFinalizeVictim ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemFRdWr2DProgramDataPattern ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID* PatternIndexPtr + ); + +#endif /* _MFRDWR2DTRAINING_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/S3/mfs3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/S3/mfs3.c new file mode 100644 index 0000000000..e6914a7d5a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/S3/mfs3.c @@ -0,0 +1,718 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfs3.c + * + * Main S3 resume memory Entrypoint file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/FEAT/S3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "S3.h" +#include "mfs3.h" +#include "heapManager.h" +#include "amdlib.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_S3_MFS3_FILECODE + +extern MEM_NB_SUPPORT memNBInstalled[]; + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function is the main memory entry point for the S3 resume sequence + * Requirements: + * + * Run-Time Requirements: + * 1. Complete Hypertransport Bus Configuration + * 4. BSP in Big Real Mode + * 5. Stack available + * + * @param[in] *StdHeader - Config handle for library and services + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +AmdMemS3Resume ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS RetVal; + MEM_MAIN_DATA_BLOCK mmData; + S3_MEM_NB_BLOCK *S3NBPtr; + MEM_DATA_STRUCT *MemData; + UINT8 Die; + UINT8 DieCount; + + //--------------------------------------------- + // Creation of NB Block for S3 resume + //--------------------------------------------- + RetVal = MemS3InitNB (&S3NBPtr, &MemData, &mmData, StdHeader); + if (RetVal == AGESA_FATAL) { + return RetVal; + } + DieCount = mmData.DieCount; + + //--------------------------------------------- + //1. Errata Before resume sequence + //2. S3 Resume sequence + //3. Errata After resume sequence + //--------------------------------------------- + for (Die = 0; Die < DieCount; Die ++) { + if (!S3NBPtr[Die].MemS3Resume (&S3NBPtr[Die], Die)) { + return AGESA_FATAL; + } + S3NBPtr[Die].MemS3RestoreScrub (S3NBPtr[Die].NBPtr, Die); + } + + HeapDeallocateBuffer (AMD_MEM_S3_DATA_HANDLE, StdHeader); + return AGESA_SUCCESS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function deallocates heap space allocated in memory S3 resume. + * + * @param[in] *StdHeader - Config handle for library and services + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemS3Deallocate ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS RetVal; + AGESA_STATUS tempRetVal; + UINT8 Tab; + + RetVal = AGESA_SUCCESS; + for (Tab = 0; Tab < NumberOfNbRegTables; Tab++) { + HeapDeallocateBuffer (GENERATE_MEM_HANDLE (ALLOC_NB_REG_TABLE, Tab, 0, 0), StdHeader); + } + + tempRetVal = HeapDeallocateBuffer (GENERATE_MEM_HANDLE (ALLOC_DIE_STRUCT_HANDLE, 0, 0, 0), StdHeader); + if (tempRetVal > RetVal) { + RetVal = tempRetVal; + } + tempRetVal = HeapDeallocateBuffer (AMD_MEM_AUTO_HANDLE, StdHeader); + if (tempRetVal > RetVal) { + RetVal = tempRetVal; + } + RetVal = HeapDeallocateBuffer (AMD_MEM_S3_NB_HANDLE, StdHeader); + if (tempRetVal > RetVal) { + RetVal = tempRetVal; + } + RetVal = HeapDeallocateBuffer (AMD_MEM_DATA_HANDLE, StdHeader); + if (tempRetVal > RetVal) { + RetVal = tempRetVal; + } + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function is the entrance to get device list for memory registers. + * + * @param[in, out] **DeviceBlockHdrPtr - Pointer to the memory containing the + * device descriptor list + * @param[in] *StdHeader - Config handle for library and services + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemFS3GetDeviceList ( + IN OUT DEVICE_BLOCK_HEADER **DeviceBlockHdrPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT16 BufferSize; + UINT64 BufferOffset; + S3_MEM_NB_BLOCK *S3NBPtr; + MEM_DATA_STRUCT *MemData; + MEM_MAIN_DATA_BLOCK mmData; + UINT8 Die; + UINT8 DieCount; + AGESA_STATUS RetVal; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + DESCRIPTOR_GROUP DeviceDescript[MAX_NODES_SUPPORTED]; + BufferSize = 0; + + //--------------------------------------------- + // Creation of NB Block for S3 resume + //--------------------------------------------- + RetVal = MemS3InitNB (&S3NBPtr, &MemData, &mmData, StdHeader); + if (RetVal == AGESA_FATAL) { + return RetVal; + } + DieCount = mmData.DieCount; + + // Get the mask bit and the register list for node that presents + for (Die = 0; Die < DieCount; Die ++) { + S3NBPtr->MemS3GetConPCIMask (S3NBPtr[Die].NBPtr, (VOID *)&DeviceDescript[Die]); + S3NBPtr->MemS3GetConMSRMask (S3NBPtr[Die].NBPtr, (VOID *)&DeviceDescript[Die]); + BufferSize = BufferSize + S3NBPtr->MemS3GetRegLstPtr (S3NBPtr[Die].NBPtr, (VOID *)&DeviceDescript[Die]); + } + + // Base on the size of the device list, apply for a buffer for it. + AllocHeapParams.RequestedBufferSize = BufferSize + sizeof (DEVICE_BLOCK_HEADER); + AllocHeapParams.BufferHandle = AMD_S3_NB_INFO_BUFFER_HANDLE; + AllocHeapParams.Persist = HEAP_S3_RESUME; + AGESA_TESTPOINT (TpIfBeforeAllocateMemoryS3SaveBuffer, StdHeader); + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) != AGESA_SUCCESS) { + return AGESA_FATAL; + } + AGESA_TESTPOINT (TpIfAfterAllocateMemoryS3SaveBuffer, StdHeader); + + *DeviceBlockHdrPtr = (DEVICE_BLOCK_HEADER *) AllocHeapParams.BufferPtr; + (*DeviceBlockHdrPtr)->RelativeOrMaskOffset = (UINT16) AllocHeapParams.RequestedBufferSize; + + // Copy device list on the stack to the heap. + BufferOffset = sizeof (DEVICE_BLOCK_HEADER) + (UINT64) (UINTN) AllocHeapParams.BufferPtr; + for (Die = 0; Die < DieCount; Die ++) { + for (i = PRESELFREF; i <= POSTSELFREF; i ++) { + // Copy PCI device descriptor to the heap if it exists. + if (DeviceDescript[Die].PCIDevice[i].RegisterListID != 0xFFFFFFFF) { + LibAmdMemCopy ((VOID *) (UINTN) BufferOffset, &(DeviceDescript[Die].PCIDevice[i]), sizeof (PCI_DEVICE_DESCRIPTOR), StdHeader); + (*DeviceBlockHdrPtr)->NumDevices ++; + BufferOffset += sizeof (PCI_DEVICE_DESCRIPTOR); + } + // Copy conditional PCI device descriptor to the heap if it exists. + if (DeviceDescript[Die].CPCIDevice[i].RegisterListID != 0xFFFFFFFF) { + LibAmdMemCopy ((VOID *) (UINTN) BufferOffset, &(DeviceDescript[Die].CPCIDevice[i]), sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR), StdHeader); + (*DeviceBlockHdrPtr)->NumDevices ++; + BufferOffset += sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR); + } + // Copy MSR device descriptor to the heap if it exists. + if (DeviceDescript[Die].MSRDevice[i].RegisterListID != 0xFFFFFFFF) { + LibAmdMemCopy ((VOID *) (UINTN) BufferOffset, &(DeviceDescript[Die].MSRDevice[i]), sizeof (MSR_DEVICE_DESCRIPTOR), StdHeader); + (*DeviceBlockHdrPtr)->NumDevices ++; + BufferOffset += sizeof (MSR_DEVICE_DESCRIPTOR); + } + // Copy conditional MSR device descriptor to the heap if it exists. + if (DeviceDescript[Die].CMSRDevice[i].RegisterListID != 0xFFFFFFFF) { + LibAmdMemCopy ((VOID *) (UINTN) BufferOffset, &(DeviceDescript[Die].PCIDevice[i]), sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR), StdHeader); + (*DeviceBlockHdrPtr)->NumDevices ++; + BufferOffset += sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR); + } + } + } + + return RetVal; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initialize the northbridge block and apply for heap space + * before any function call is made to memory component during S3 resume. + * + * @param[in] *StdHeader - Config handle for library and services + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemS3ResumeInitNB ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS RetVal; + MEM_MAIN_DATA_BLOCK mmData; + S3_MEM_NB_BLOCK *S3NBPtr; + MEM_DATA_STRUCT *MemData; + UINT8 Die; + UINT8 DieCount; + UINT8 SpecialCaseHeapSize; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + S3_SPECIAL_CASE_HEAP_HEADER SpecialHeapHeader[MAX_NODES_SUPPORTED]; + + SpecialCaseHeapSize = 0; + + //--------------------------------------------- + // Creation of NB Block for S3 resume + //--------------------------------------------- + RetVal = MemS3InitNB (&S3NBPtr, &MemData, &mmData, StdHeader); + if (RetVal == AGESA_FATAL) { + return RetVal; + } + DieCount = mmData.DieCount; + + //-------------------------------------------------- + // Apply for heap space for special case registers + //-------------------------------------------------- + for (Die = 0; Die < DieCount; Die ++) { + // Construct the header for the special case heap. + SpecialHeapHeader[Die].Node = S3NBPtr[Die].NBPtr->Node; + SpecialHeapHeader[Die].Offset = SpecialCaseHeapSize + (DieCount * (sizeof (S3_SPECIAL_CASE_HEAP_HEADER))); + SpecialCaseHeapSize = SpecialCaseHeapSize + S3NBPtr->MemS3SpecialCaseHeapSize; + } + AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (S3_SPECIAL_CASE_HEAP_HEADER))) + SpecialCaseHeapSize; + AllocHeapParams.BufferHandle = AMD_MEM_S3_DATA_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) != AGESA_SUCCESS) { + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_S3_SPECIAL_CASE_REGISTERS, S3NBPtr[Die].NBPtr->Node, 0, 0, 0, StdHeader); + SetMemError (AGESA_FATAL, S3NBPtr[Die].NBPtr->MCTPtr); + ASSERT(FALSE); // Could not allocate heap space for "S3_SPECIAL_CASE_HEAP_HEADER" + return AGESA_FATAL; + } + LibAmdMemCopy ((VOID *) AllocHeapParams.BufferPtr, (VOID *) SpecialHeapHeader, (sizeof (S3_SPECIAL_CASE_HEAP_HEADER) * DieCount), StdHeader); + return AGESA_SUCCESS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the PCI device register list according to the register + * list ID. + * + * @param[in] *Device - pointer to the PCI_DEVICE_DESCRIPTOR + * @param[out] **RegisterHdr - pointer to the address of the register list + * @param[in] *StdHeader - Config handle for library and services + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemFS3GetPciDeviceRegisterList ( + IN PCI_DEVICE_DESCRIPTOR *Device, + OUT PCI_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS RetVal; + S3_MEM_NB_BLOCK *S3NBPtr; + VOID *RegisterHeader; + LOCATE_HEAP_PTR LocHeap; + AGESA_BUFFER_PARAMS LocBufferParams; + LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE; + + LibAmdMemCopy (&LocBufferParams.StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader); + LocBufferParams.BufferHandle = AMD_MEM_S3_NB_HANDLE; + + AGESA_TESTPOINT (TpIfBeforeLocateS3PciBuffer, StdHeader); + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr; + } else { + ASSERT(FALSE) ; // No match for heap status, but could not locate "AMD_MEM_S3_NB_HANDLE" in heap for S3GetMsr + return AGESA_FATAL; + } + AGESA_TESTPOINT (TpIfAfterLocateS3PciBuffer, StdHeader); + + // NB block has already been constructed by main block. + // No need to construct it here. + RetVal = S3NBPtr[Device->Node].MemS3GetDeviceRegLst (Device->RegisterListID, &RegisterHeader); + *RegisterHdr = (PCI_REGISTER_BLOCK_HEADER *)RegisterHeader; + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the conditional PCI device register list according + * to the register list ID. + * + * @param[in] *Device - pointer to the CONDITIONAL_PCI_DEVICE_DESCRIPTOR + * @param[out] **RegisterHdr - pointer to the address of the register list + * @param[in] *StdHeader - Config handle for library and services + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemFS3GetCPciDeviceRegisterList ( + IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device, + OUT CPCI_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS RetVal; + S3_MEM_NB_BLOCK *S3NBPtr; + VOID *RegisterHeader; + LOCATE_HEAP_PTR LocHeap; + AGESA_BUFFER_PARAMS LocBufferParams; + + LibAmdMemCopy (&LocBufferParams.StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader); + LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE; + LocBufferParams.BufferHandle = AMD_MEM_S3_NB_HANDLE; + + AGESA_TESTPOINT (TpIfBeforeLocateS3CPciBuffer, StdHeader); + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr; + } else { + ASSERT(FALSE) ; // No match for heap status, but could not locate "AMD_MEM_S3_NB_HANDLE" in heap for S3GetMsr + return AGESA_FATAL; + } + AGESA_TESTPOINT (TpIfAfterLocateS3CPciBuffer, StdHeader); + + // NB block has already been constructed by main block. + // No need to construct it here. + RetVal = S3NBPtr[Device->Node].MemS3GetDeviceRegLst (Device->RegisterListID, &RegisterHeader); + *RegisterHdr = (CPCI_REGISTER_BLOCK_HEADER *)RegisterHeader; + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the MSR device register list according to the register + * list ID. + * + * @param[in] *Device - pointer to the MSR_DEVICE_DESCRIPTOR + * @param[out] **RegisterHdr - pointer to the address of the register list + * @param[in] *StdHeader - Config handle for library and services + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemFS3GetMsrDeviceRegisterList ( + IN MSR_DEVICE_DESCRIPTOR *Device, + OUT MSR_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS RetVal; + S3_MEM_NB_BLOCK *S3NBPtr; + VOID *RegisterHeader; + LOCATE_HEAP_PTR LocHeap; + AGESA_BUFFER_PARAMS LocBufferParams; + + LibAmdMemCopy (&LocBufferParams.StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader); + LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE; + LocBufferParams.BufferHandle = AMD_MEM_S3_NB_HANDLE; + + AGESA_TESTPOINT (TpIfBeforeLocateS3MsrBuffer, StdHeader); + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr; + } else { + ASSERT(FALSE) ; // No match for heap status, but could not locate "AMD_MEM_S3_NB_HANDLE" in heap for S3GetMsr + return AGESA_FATAL; + } + AGESA_TESTPOINT (TpIfAfterLocateS3MsrBuffer, StdHeader); + + // NB block has already been constructed by main block. + // No need to construct it here. + RetVal = S3NBPtr[BSP_DIE].MemS3GetDeviceRegLst (Device->RegisterListID, &RegisterHeader); + *RegisterHdr = (MSR_REGISTER_BLOCK_HEADER *)RegisterHeader; + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the conditional MSR device register list according + * to the register list ID. + * + * @param[in] *Device - pointer to the CONDITIONAL_PCI_DEVICE_DESCRIPTOR + * @param[out] **RegisterHdr - pointer to the address of the register list + * @param[in] *StdHeader - Config handle for library and services + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemFS3GetCMsrDeviceRegisterList ( + IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, + OUT CMSR_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS RetVal; + S3_MEM_NB_BLOCK *S3NBPtr; + VOID *RegisterHeader; + LOCATE_HEAP_PTR LocHeap; + AGESA_BUFFER_PARAMS LocBufferParams; + + LibAmdMemCopy (&LocBufferParams.StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader); + LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE; + LocBufferParams.BufferHandle = AMD_MEM_S3_NB_HANDLE; + + + AGESA_TESTPOINT (TpIfBeforeLocateS3CMsrBuffer, StdHeader); + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr; + } else { + ASSERT(FALSE) ; // No match for heap status, but could not locate "AMD_MEM_S3_NB_HANDLE" in heap for S3GetMsr + return AGESA_FATAL; + } + AGESA_TESTPOINT (TpIfAfterLocateS3CMsrBuffer, StdHeader); + + // NB block has already been constructed by main block. + // No need to construct it here. + RetVal = S3NBPtr[BSP_DIE].MemS3GetDeviceRegLst (Device->RegisterListID, &RegisterHeader); + *RegisterHdr = (CMSR_REGISTER_BLOCK_HEADER *)RegisterHeader; + return RetVal; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initialize needed data structures for S3 resume. + * + * @param[in, out] **S3NBPtr - Pointer to the pointer of northbridge block. + * @param[in, out] *MemPtr - Pointer to MEM_DATA_STRUCT. + * @param[in, out] *mmData - Pointer to MEM_MAIN_DATA_BLOCK. + * @param[in] *StdHeader - Config handle for library and services. + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemS3InitNB ( + IN OUT S3_MEM_NB_BLOCK **S3NBPtr, + IN OUT MEM_DATA_STRUCT **MemPtr, + IN OUT MEM_MAIN_DATA_BLOCK *mmData, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + AGESA_STATUS RetVal; + LOCATE_HEAP_PTR LocHeap; + MEM_NB_BLOCK *NBPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + UINT8 Die; + UINT8 DieCount; + BOOLEAN SkipScan; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + SkipScan = FALSE; + LocHeap.BufferHandle = AMD_MEM_DATA_HANDLE; + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + // NB block has already been constructed by main block. + // No need to construct it here. + *MemPtr = (MEM_DATA_STRUCT *)LocHeap.BufferPtr; + SkipScan = TRUE; + } else { + AllocHeapParams.RequestedBufferSize = sizeof (MEM_DATA_STRUCT); + AllocHeapParams.BufferHandle = AMD_MEM_DATA_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) != AGESA_SUCCESS) { + ASSERT(FALSE); // Allocate failed for MEM_DATA_STRUCT + return AGESA_FATAL; + } + *MemPtr = (MEM_DATA_STRUCT *)AllocHeapParams.BufferPtr; + LibAmdMemCopy (&(*MemPtr)->StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader); + + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &(*MemPtr)->StdHeader); + FamilySpecificServices->GetTscRate (FamilySpecificServices, &(*MemPtr)->TscRate, &(*MemPtr)->StdHeader); + + } + mmData->MemPtr = *MemPtr; + + if (!SkipScan) { + RetVal = MemSocketScan (mmData); + if (RetVal == AGESA_FATAL) { + return RetVal; + } + } else { + // We already have initialize data block, no need to do it again. + mmData->DieCount = mmData->MemPtr->DieCount; + } + DieCount = mmData->DieCount; + + //--------------------------------------------- + // Creation of NB Block for S3 resume + //--------------------------------------------- + // Search for AMD_MEM_AUTO_HANDLE on the heap first. + // Only apply for space on the heap if cannot find AMD_MEM_AUTO_HANDLE on the heap. + LocHeap.BufferHandle = AMD_MEM_S3_NB_HANDLE; + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + // NB block has already been constructed by main block. + // No need to construct it here. + *S3NBPtr = (S3_MEM_NB_BLOCK *)LocHeap.BufferPtr; + } else { + AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (S3_MEM_NB_BLOCK))); + AllocHeapParams.BufferHandle = AMD_MEM_S3_NB_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) != AGESA_SUCCESS) { + ASSERT(FALSE); // Could not allocate space for "S3_MEM_NB_BLOCK" + return AGESA_FATAL; + } + *S3NBPtr = (S3_MEM_NB_BLOCK *)AllocHeapParams.BufferPtr; + + LocHeap.BufferHandle = AMD_MEM_AUTO_HANDLE; + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + // NB block has already been constructed by main block. + // No need to construct it here. + NBPtr = (MEM_NB_BLOCK *)LocHeap.BufferPtr; + } else { + AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (MEM_NB_BLOCK))); + AllocHeapParams.BufferHandle = AMD_MEM_AUTO_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) != AGESA_SUCCESS) { + ASSERT(FALSE); // Allocate failed for "MEM_NB_BLOCK" + return AGESA_FATAL; + } + NBPtr = (MEM_NB_BLOCK *)AllocHeapParams.BufferPtr; + } + // Construct each die. + for (Die = 0; Die < DieCount; Die ++) { + i = 0; + ((*S3NBPtr)[Die]).NBPtr = &NBPtr[Die]; + while (memNBInstalled[i].MemS3ResumeConstructNBBlock != 0) { + if (memNBInstalled[i].MemS3ResumeConstructNBBlock ((VOID *)&((*S3NBPtr)[Die]), *MemPtr, Die)) { + break; + } + i++; + }; + if (memNBInstalled[i].MemS3ResumeConstructNBBlock == 0) { + ASSERT(FALSE); // S3 resume NB constructor not found + return AGESA_FATAL; + } + } + } + return AGESA_SUCCESS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Waits specified number of 10ns cycles + * @param[in,out] MemPtr - pointer to MEM_DATA_STRUCTURE + * @param[in] Count - Number of 10ns cycles to wait + * + * ---------------------------------------------------------------------------- + */ + +VOID +MemFS3Wait10ns ( + IN UINT32 Count, + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + UINT64 TargetTsc; + UINT64 CurrentTsc; + + ASSERT (Count <= 1000000); + + LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader); + TargetTsc = CurrentTsc + ((Count * MemPtr->TscRate + 99) / 100); + do { + LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader); + } while (CurrentTsc < TargetTsc); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/TABLE/mftds.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/TABLE/mftds.c new file mode 100644 index 0000000000..accc96b0ec --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Feat/TABLE/mftds.c @@ -0,0 +1,401 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mftds.c + * + * Northbridge table drive support file for DR + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/TABLE) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mftds.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_FEAT_TABLE_MFTDS_FILECODE +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define MAX_BYTELANES_PER_CHANNEL (8 + 1) ///< Max Bytelanes per channel + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +VOID +SetTableValues ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_TABLE_ALIAS MTPtr + ); + +VOID +SetTableValuesLoop ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_TABLE_ALIAS *MTPtr, + IN UINT8 time + ); + +/*----------------------------------------------------------------------------- + * + * This function initializes bit field translation table + * + * @param[in,out] *NBPtr - Pointer to the MEM_TABLE_ALIAS structure + * @param[in] time - Indicate the timing for the register which is written. + * + * @return None + * ---------------------------------------------------------------------------- + */ +VOID +MemFInitTableDrive ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 time + ) +{ + MEM_TABLE_ALIAS *MTPtr; + MEM_TABLE_ALIAS *IdsMTPtr; + + ASSERT (NBPtr != NULL); + IdsMTPtr = NULL; + IDS_HDT_CONSOLE (MEM_FLOW, "MemFInitTableDrive [%X] Start\n", time); + MTPtr = (MEM_TABLE_ALIAS *) NBPtr->RefPtr->TableBasedAlterations; + + IDS_SKIP_HOOK (IDS_GET_DRAM_TABLE, &IdsMTPtr, &(NBPtr->MemPtr->StdHeader)) { + IDS_OPTION_HOOK (IDS_INIT_DRAM_TABLE, NBPtr, &(NBPtr->MemPtr->StdHeader)); + IDS_OPTION_HOOK (IDS_GET_DRAM_TABLE, &IdsMTPtr, &(NBPtr->MemPtr->StdHeader)); + } + + SetTableValuesLoop (NBPtr, MTPtr, time); + SetTableValuesLoop (NBPtr, IdsMTPtr, time); + + IDS_OPTION_HOOK (IDS_MT_BASE + time, NBPtr, &(NBPtr->MemPtr->StdHeader)); + IDS_HDT_CONSOLE (MEM_FLOW, "MemFInitTableDrive End\n"); +} + +/*----------------------------------------------------------------------------- + * + * This function initializes bit field translation table + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *MTPtr - Pointer to the MEM_TABLE_ALIAS structure + * @param[in] time - Indicate the timing for the register which is written. + * + * @return None + * ---------------------------------------------------------------------------- + */ +VOID +SetTableValuesLoop ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_TABLE_ALIAS *MTPtr, + IN UINT8 time + ) +{ + UINT8 i; + UINT8 CurDct; + + if (MTPtr != NULL) { + CurDct = NBPtr->Dct; + for (i = 0; MTPtr[i].time != MTEnd; i++) { + if ((MTPtr[i].attr != MTAuto) && (MTPtr[i].time == time)) { + SetTableValues (NBPtr, MTPtr[i]); + } + } + NBPtr->SwitchDCT (NBPtr, CurDct); + } +} + +/*----------------------------------------------------------------------------- + * + * Engine for setting Table Value. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] MTPtr - Pointer to the MEM_TABLE_ALIAS structure + * + * @return None + * ---------------------------------------------------------------------------- + */ +VOID +SetTableValues ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_TABLE_ALIAS MTPtr + ) +{ + UINT8 AccessType; + UINT16 ByteLane; + UINT8 Dct; + UINT8 i; + UINT8 j; + UINT32 TempVal[36]; + UINT32 Temp2Val[72]; + UINT8 *DqsSavePtr; + UINT8 DqsOffset; + BOOLEAN SaveDqs; + + AccessType = 0; + DqsSavePtr = NULL; + SaveDqs = TRUE; + + ASSERT (MTPtr.time <= MTValidTimePointLimit); + ASSERT (MTPtr.attr <= MTOr); + ASSERT (MTPtr.node <= MTNodes); + ASSERT (MTPtr.dct <= MTDcts); + ASSERT (MTPtr.dimm <= MTDIMMs); + ASSERT (MTPtr.data.s.bytelane <= MTBLs); + + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + if ((MTPtr.dct == MTDcts) || (MTPtr.dct == Dct)) { + NBPtr->SwitchDCT (NBPtr, Dct); + switch (MTPtr.bfindex) { + case BFRcvEnDly: + AccessType = AccessRcvEnDly; + DqsSavePtr = NULL; + break; + case BFWrDatDly: + AccessType = AccessWrDatDly; + DqsSavePtr = NBPtr->ChannelPtr->WrDatDlys; + break; + case BFRdDqsDly: + AccessType = AccessRdDqsDly; + DqsSavePtr = NBPtr->ChannelPtr->RdDqsDlys; + break; + case BFWrDqsDly: + AccessType = AccessWrDqsDly; + DqsSavePtr = NBPtr->ChannelPtr->WrDqsDlys; + break; + case BFRdDqs2dDly: + AccessType = AccessRdDqs2dDly; + DqsSavePtr = NBPtr->ChannelPtr->RdDqs2dDlys; + break; + case BFPhRecDly: + AccessType = AccessPhRecDly; + SaveDqs = FALSE; + break; + default: + AccessType = 0xFF; + break; + } + if (AccessType == 0xFF) { + if (MTPtr.attr == MTOverride) { + NBPtr->SetBitField (NBPtr, MTPtr.bfindex, MTPtr.data.s.value); + } + if (MTPtr.attr == MTSubtract) { + NBPtr->SetBitField (NBPtr, MTPtr.bfindex, NBPtr->GetBitField (NBPtr, MTPtr.bfindex) - MTPtr.data.s.value); + } + if (MTPtr.attr == MTAdd) { + NBPtr->SetBitField (NBPtr, MTPtr.bfindex, NBPtr->GetBitField (NBPtr, MTPtr.bfindex) + MTPtr.data.s.value); + } + if (MTPtr.attr == MTAnd) { + NBPtr->SetBitField (NBPtr, MTPtr.bfindex, (NBPtr->GetBitField (NBPtr, MTPtr.bfindex) & MTPtr.data.s.value)); + } + if (MTPtr.attr == MTOr) { + NBPtr->SetBitField (NBPtr, MTPtr.bfindex, (NBPtr->GetBitField (NBPtr, MTPtr.bfindex) | MTPtr.data.s.value)); + } + } else { + // Store the DQS data first + for (i = 0; i < NBPtr->CsPerChannel; i = i + NBPtr->CsPerDelay) { + if (AccessType == AccessRdDqs2dDly) { + for (j = 0; j < MAX_NUMBER_LANES; j++) { + Temp2Val[i * MAX_NUMBER_LANES + j] = NBPtr->GetTrainDly (NBPtr, AccessType, DIMM_NBBL_ACCESS (i, j)); + } + } else { + for (j = 0; j < MAX_BYTELANES_PER_CHANNEL; j++) { + TempVal[i / NBPtr->CsPerDelay * MAX_BYTELANES_PER_CHANNEL + j] = NBPtr->GetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (i / NBPtr->CsPerDelay, j)); + } + } + } + // + // Single Value with Bytleane mask option + // Indicated by the vtype flag + // + if (MTPtr.vtype == VT_MSK_VALUE) { + // set the value which defined in Memory table. + for (i = 0; i < NBPtr->CsPerChannel; i = i + NBPtr->CsPerDelay) { + ByteLane = MTPtr.data.s.bytelane; + if ((MTPtr.dimm == MTDIMMs) || ((MTPtr.dimm * NBPtr->CsPerDelay) == i)) { + if (AccessType == AccessRdDqs2dDly) { + for (j = 0; j < MAX_NUMBER_LANES; j++) { + DqsOffset = (i * MAX_NUMBER_LANES + j); + if ((ByteLane & (UINT16)1) != 0) { + if (MTPtr.attr == MTOverride) { + Temp2Val[DqsOffset] = (UINT16)MTPtr.data.s.value; + } + if (MTPtr.attr == MTSubtract) { + Temp2Val[DqsOffset] -= (UINT16)MTPtr.data.s.value; + } + if (MTPtr.attr == MTAdd) { + Temp2Val[DqsOffset] += (UINT16)MTPtr.data.s.value; + } + NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_NBBL_ACCESS (i, j), (UINT16)Temp2Val[DqsOffset]); + if (SaveDqs) { + if (DqsSavePtr == NULL) { + NBPtr->ChannelPtr->RcvEnDlys[DqsOffset] = (UINT16)Temp2Val[DqsOffset]; + } else { + DqsSavePtr[DqsOffset] = (UINT8)Temp2Val[DqsOffset]; + } + } + } + ByteLane = ByteLane >> (UINT16)1; + } + } else { + for (j = 0; j < MAX_BYTELANES_PER_CHANNEL; j++) { + DqsOffset = (i / NBPtr->CsPerDelay * MAX_BYTELANES_PER_CHANNEL + j); + if ((ByteLane & (UINT16)1) != 0) { + if (MTPtr.attr == MTOverride) { + TempVal[DqsOffset] = (UINT16)MTPtr.data.s.value; + } + if (MTPtr.attr == MTSubtract) { + TempVal[DqsOffset] -= (UINT16)MTPtr.data.s.value; + } + if (MTPtr.attr == MTAdd) { + TempVal[DqsOffset] += (UINT16)MTPtr.data.s.value; + } + NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (i / NBPtr->CsPerDelay, j), (UINT16)TempVal[DqsOffset]); + if (SaveDqs) { + if (DqsSavePtr == NULL) { + NBPtr->ChannelPtr->RcvEnDlys[DqsOffset] = (UINT16)TempVal[DqsOffset]; + } else { + DqsSavePtr[DqsOffset] = (UINT8)TempVal[DqsOffset]; + } + } + } + ByteLane = ByteLane >> (UINT16)1; + } + } + } + } + } else { + // Multiple values specified in a byte array + for (i = 0; i < NBPtr->CsPerChannel; i = i + NBPtr->CsPerDelay) { + if ((MTPtr.dimm == MTDIMMs) || ((MTPtr.dimm * NBPtr->CsPerDelay) == i)) { + if (AccessType == AccessRdDqs2dDly) { + for (j = 0; j < MAX_NUMBER_LANES; j++) { + DqsOffset = (i * MAX_NUMBER_LANES + j); + if (MTPtr.attr == MTOverride) { + Temp2Val[DqsOffset] = MTPtr.data.bytelanevalue[j]; + } + if (MTPtr.attr == MTSubtract) { + Temp2Val[DqsOffset] -= MTPtr.data.bytelanevalue[j]; + } + if (MTPtr.attr == MTAdd) { + Temp2Val[DqsOffset] += MTPtr.data.bytelanevalue[j]; + } + NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_NBBL_ACCESS (i, j), (UINT16)Temp2Val[DqsOffset]); + if (SaveDqs) { + if (DqsSavePtr == NULL) { + NBPtr->ChannelPtr->RcvEnDlys[DqsOffset] = (UINT16)Temp2Val[DqsOffset]; + } else { + DqsSavePtr[DqsOffset] = (UINT8)Temp2Val[DqsOffset]; + } + } + } + } else { + for (j = 0; j < MAX_BYTELANES_PER_CHANNEL; j++) { + DqsOffset = (i / NBPtr->CsPerDelay * MAX_BYTELANES_PER_CHANNEL + j); + if (MTPtr.attr == MTOverride) { + TempVal[DqsOffset] = MTPtr.data.bytelanevalue[j]; + } + if (MTPtr.attr == MTSubtract) { + TempVal[DqsOffset] -= MTPtr.data.bytelanevalue[j]; + } + if (MTPtr.attr == MTAdd) { + TempVal[DqsOffset] += MTPtr.data.bytelanevalue[j]; + } + NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (i / NBPtr->CsPerDelay, j), (UINT16)TempVal[DqsOffset]); + if (SaveDqs) { + if (DqsSavePtr == NULL) { + NBPtr->ChannelPtr->RcvEnDlys[DqsOffset] = (UINT16)TempVal[DqsOffset]; + } else { + DqsSavePtr[DqsOffset] = (UINT8)TempVal[DqsOffset]; + } + } + } + } + } + } + } + // set the DQS value to left DIMMs. + i = MTPtr.dimm; + if (i != MTDIMMs) { + i = i * NBPtr->CsPerDelay + NBPtr->CsPerDelay; + while (i < NBPtr->CsPerChannel) { + if (AccessType == AccessRdDqs2dDly) { + for (j = 0; j < MAX_NUMBER_LANES; j++) { + NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_NBBL_ACCESS (i, j), (UINT16)Temp2Val[i * MAX_BYTELANES_PER_CHANNEL + j]); + } + } else { + for (j = 0; j < MAX_BYTELANES_PER_CHANNEL; j++) { + NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (i / NBPtr->CsPerDelay, j), (UINT16)TempVal[i / NBPtr->CsPerDelay * MAX_BYTELANES_PER_CHANNEL + j]); + } + } + i = i + NBPtr->CsPerDelay; + } + } + } + } + } +} + + + + + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/KB/mmflowkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/KB/mmflowkb.c new file mode 100644 index 0000000000..558bc62ae4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/KB/mmflowkb.c @@ -0,0 +1,388 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmflowkb.c + * + * Main Memory initialization sequence for TN + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main/TN) + * @e \$Revision: 85859 $ @e \$Date: 2013-01-14 02:57:14 -0600 (Mon, 14 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mnkb.h" +#include "mt.h" +#include "mmlvddr3.h" +#include "cpuFamilyTranslation.h" +#include "IdsF16KbAllService.h" +#include "Filecode.h" +#include "GeneralServices.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_MEM_MAIN_KB_MMFLOWKB_FILECODE +/* features */ +#include "mftds.h" + +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; +extern OPTION_MEM_FEATURE_MAIN MemMS3Save; + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +MemMFlowKB ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function defines the memory initialization flow for + * systems that only support KB processors. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return AGESA_STATUS + * - AGESA_FATAL + * - AGESA_CRITICAL + * - AGESA_SUCCESS + */ +AGESA_STATUS +MemMFlowKB ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + MEM_TECH_BLOCK *TechPtr; + MEM_DATA_STRUCT *MemPtr; + ID_INFO CallOutIdInfo; + + NBPtr = MemMainPtr->NBPtr; + TechPtr = MemMainPtr->TechPtr; + MemPtr = MemMainPtr->MemPtr; + + GetLogicalIdOfSocket (MemPtr->DiesPerSystem[BSP_DIE].SocketId, &(MemPtr->DiesPerSystem[BSP_DIE].LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemNIsIdSupportedKB (&(MemPtr->DiesPerSystem[BSP_DIE].LogicalCpuid))) { + MemPtr->IsFlowControlSupported = FALSE; + return AGESA_FATAL; + } else { + MemPtr->IsFlowControlSupported = TRUE; + } + + //---------------------------------------------------------------- + // Memory Context Restore + //---------------------------------------------------------------- + if (MemFeatMain.MemRestore (MemMainPtr)) { + + // Memory DMI support + if (!MemFeatMain.MemDmi (MemMainPtr)) { + return AGESA_CRITICAL; + } + + // Memory CRAT support + if (!MemFeatMain.MemCrat (MemMainPtr)) { + return AGESA_CRITICAL; + } + + return AGESA_SUCCESS; + } + + MemFInitTableDrive (&NBPtr[BSP_DIE], MTBeforeInitializeMCT); + + //---------------------------------------------------------------- + // Initialize MCT + //---------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemInitializeMCT, &(MemMainPtr->MemPtr->StdHeader)); + if (!NBPtr[BSP_DIE].InitializeMCT (&NBPtr[BSP_DIE])) { + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // Low voltage DDR3 + //---------------------------------------------------------------- + // Levelize DDR3 voltage based on socket, as each socket has its own voltage for dimms. + AGESA_TESTPOINT (TpProcMemLvDdr3, &(MemMainPtr->MemPtr->StdHeader)); + if (!MemFeatMain.LvDDR3 (MemMainPtr)) { + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // Initialize DRAM and DCTs + //---------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemInitMCT, &(MemMainPtr->MemPtr->StdHeader)); + // Initialize Memory Controller and Dram + if (!NBPtr[BSP_DIE].InitMCT (&NBPtr[BSP_DIE])) { + return AGESA_FATAL; //fatalexit + } + + MemFInitTableDrive (&NBPtr[BSP_DIE], MTBeforeDInit); + + // Finalize target frequency + //------------------------------------------------ + if (!MemMLvDdr3PerformanceEnhFinalize (MemMainPtr)) { + return AGESA_FATAL; + } + + //------------------------------------------------ + //------------------------------------------------ + // Callout before Dram Init + //------------------------------------------------ + AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDramInit, &(MemMainPtr->MemPtr->StdHeader)); + CallOutIdInfo.IdField.SocketId = NBPtr[BSP_DIE].MCTPtr->SocketId; + CallOutIdInfo.IdField.ModuleId = NBPtr[BSP_DIE].MCTPtr->DieId; + IDS_HDT_CONSOLE (MEM_FLOW, "\nCalling out to Platform BIOS on Socket %d, Module %d...\n", CallOutIdInfo.IdField.SocketId, CallOutIdInfo.IdField.ModuleId); + AgesaHookBeforeDramInit ((UINTN) CallOutIdInfo.IdInformation, MemMainPtr->MemPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "\nVDDIO = 1.%dV\n", (NBPtr[BSP_DIE].RefPtr->DDR3Voltage == VOLT1_5) ? 5 : + (NBPtr[BSP_DIE].RefPtr->DDR3Voltage == VOLT1_35) ? 35 : + (NBPtr[BSP_DIE].RefPtr->DDR3Voltage == VOLT1_25) ? 25 : 999); + AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); + + //------------------------------------------------- + // Do dram init and create memory map + //------------------------------------------------- + IDS_OPTION_HOOK (IDS_BEFORE_DRAM_INIT, &NBPtr[BSP_DIE], &(MemMainPtr->MemPtr->StdHeader)); + NBPtr[BSP_DIE].StartupDCT (&NBPtr[BSP_DIE]); + + // Create memory map + AGESA_TESTPOINT (TpProcMemSystemMemoryMapping, &(MemMainPtr->MemPtr->StdHeader)); + if (!NBPtr[BSP_DIE].HtMemMapInit (&NBPtr[BSP_DIE])) { + return AGESA_FATAL; + } + + //---------------------------------------------------- + // If there is no dimm on the system, do fatal exit + //---------------------------------------------------- + if (NBPtr[BSP_DIE].RefPtr->SysLimit == 0) { + PutEventLog (AGESA_FATAL, MEM_ERROR_NO_DIMM_FOUND_ON_SYSTEM, 0, 0, 0, 0, &(MemMainPtr->MemPtr->StdHeader)); + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // CpuMemTyping + //---------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemMtrrConfiguration, &(MemMainPtr->MemPtr->StdHeader)); + if (!NBPtr[BSP_DIE].CpuMemTyping (&NBPtr[BSP_DIE])) { + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // Before Training Table values + //---------------------------------------------------------------- + MemFInitTableDrive (&NBPtr[BSP_DIE], MTBeforeTrn); + + //---------------------------------------------------------------- + // Training + //---------------------------------------------------------------- + MemMainPtr->mmSharedPtr->DimmExcludeFlag = TRAINING; + AGESA_TESTPOINT (TpProcMemDramTraining, &(MemMainPtr->MemPtr->StdHeader)); + IDS_SKIP_HOOK (IDS_BEFORE_DQS_TRAINING, MemMainPtr, &(MemMainPtr->MemPtr->StdHeader)) { + if (!MemFeatMain.Training (MemMainPtr)) { + return AGESA_FATAL; + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\nEnd DQS training\n\n"); + + //---------------------------------------------------------------- + // Configure DCT for normal operation + //---------------------------------------------------------------- + MemNConfigureDctNormalKB (&NBPtr[BSP_DIE]); + + //---------------------------------------------------------------- + // Disable chipselects that fail training + //---------------------------------------------------------------- + MemMainPtr->mmSharedPtr->DimmExcludeFlag = END_TRAINING; + MemFeatMain.ExcludeDIMM (MemMainPtr); + MemMainPtr->mmSharedPtr->DimmExcludeFlag = NORMAL; + + //---------------------------------------------------------------- + // OtherTiming + //---------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemOtherTiming, &(MemMainPtr->MemPtr->StdHeader)); + if (!NBPtr[BSP_DIE].OtherTiming (&NBPtr[BSP_DIE])) { + return AGESA_FATAL; + } + + IEM_INSERT_CODE (IEM_LATE_DCT_CONFIG, IemLateDctConfigKB, (NBPtr)); + + //---------------------------------------------------------------- + // After Training Table values + //---------------------------------------------------------------- + MemFInitTableDrive (&NBPtr[BSP_DIE], MTAfterTrn); + + //---------------------------------------------------------------- + // Memory Clear + //---------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemMemClr, &(MemMainPtr->MemPtr->StdHeader)); + if (!MemFeatMain.MemClr (MemMainPtr)) { + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // Interleave banks + //---------------------------------------------------------------- + if (NBPtr[BSP_DIE].FeatPtr->InterleaveBanks (&NBPtr[BSP_DIE])) { + if (NBPtr[BSP_DIE].MCTPtr->ErrCode == AGESA_FATAL) { + return AGESA_FATAL; + } + } + + //---------------------------------------------------------------- + // After Programming Interleave registers + //---------------------------------------------------------------- + MemFInitTableDrive (&NBPtr[BSP_DIE], MTAfterInterleave); + + //---------------------------------------------------------------- + // Power Saving + //---------------------------------------------------------------- + if (!MemNPowerSavingKB (&NBPtr[BSP_DIE])) { + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // ECC + //---------------------------------------------------------------- + if (!MemFeatMain.InitEcc (MemMainPtr)) { + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // C6 Storage Allocation + //---------------------------------------------------------------- + NBPtr[BSP_DIE].AllocateC6Storage (&NBPtr[BSP_DIE]); + + //---------------------------------------------------------------- + // UMA Allocation & UMAMemTyping + //---------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemUMAMemTyping, &(MemMainPtr->MemPtr->StdHeader)); + if (!MemFeatMain.UmaAllocation (MemMainPtr)) { + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // OnDimm Thermal + //---------------------------------------------------------------- + if (NBPtr[BSP_DIE].FeatPtr->OnDimmThermal (&NBPtr[BSP_DIE])) { + if (NBPtr[BSP_DIE].MCTPtr->ErrCode == AGESA_FATAL) { + return AGESA_FATAL; + } + } + + //---------------------------------------------------------------- + // Finalize MCT + //---------------------------------------------------------------- + if (!NBPtr[BSP_DIE].FinalizeMCT (&NBPtr[BSP_DIE])) { + return AGESA_FATAL; + } + + //---------------------------------------------------------------- + // After Finalize MCT + //---------------------------------------------------------------- + MemFInitTableDrive (&NBPtr[BSP_DIE], MTAfterFinalizeMCT); + + //---------------------------------------------------------------- + // Memory Context Save + //---------------------------------------------------------------- + MemFeatMain.MemSave (MemMainPtr); + + //---------------------------------------------------------------- + // Memory DMI support + //---------------------------------------------------------------- + if (!MemFeatMain.MemDmi (MemMainPtr)) { + return AGESA_CRITICAL; + } + + //---------------------------------------------------------------- + // Memory CRAT support + //---------------------------------------------------------------- + if (!MemFeatMain.MemCrat (MemMainPtr)) { + return AGESA_CRITICAL; + } + + //---------------------------------------------------------------- + // Save memory S3 data + //---------------------------------------------------------------- + if (!MemFeatMain.MemS3Save (MemMainPtr)) { + return AGESA_CRITICAL; + } + + //---------------------------------------------------------------- + // Switch back to DCT 0 before sending control back + //---------------------------------------------------------------- + NBPtr[BSP_DIE].SwitchDCT (&NBPtr[BSP_DIE], 0); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mdef.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mdef.c new file mode 100644 index 0000000000..9d62c887f4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mdef.c @@ -0,0 +1,155 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mdef.c + * + * Memory Controller header file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "Filecode.h" +#include "mm.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MDEF_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +MemMFlowDef ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +VOID +memDefRet ( VOID ); + +BOOLEAN +memDefTrue ( VOID ); + +BOOLEAN +memDefFalse ( VOID ); + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This is the default return function + */ + +VOID +memDefRet ( VOID ) +{ +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is the default return function that returns TRUE + * + */ +BOOLEAN +memDefTrue ( VOID ) +{ + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is used in place of an un-supported function that returns FALSE. + * + */ +BOOLEAN +memDefFalse ( VOID ) +{ + return FALSE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This is the default return function for flow control + */ +AGESA_STATUS +MemMFlowDef ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + MemMainPtr->MemPtr->IsFlowControlSupported = FALSE; + return AGESA_SUCCESS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is used in place of an un-supported function that returns AGESA_SUCCESS. + * + */ +AGESA_STATUS +memDefRetSuccess ( VOID ) +{ + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/merrhdl.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/merrhdl.c new file mode 100644 index 0000000000..426ce58fef --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/merrhdl.c @@ -0,0 +1,187 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * merrhdl.c + * + * Memory error handling + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "heapManager.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MERRHDL_FILECODE + +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function handle errors occur in memory code. + * + * + * @param[in,out] *MCTPtr - pointer to DIE_STRUCT. + * @param[in,out] DCT - DCT that needs to be handled. + * @param[in,out] ChipSelMask - Chip select mask that needs to be handled + * @param[in,out] *StdHeader - pointer to AMD_CONFIG_PARAMS + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemErrHandle ( + IN DIE_STRUCT *MCTPtr, + IN UINT8 DCT, + IN UINT16 ChipSelMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN ErrorRecovery; + BOOLEAN IgnoreErr; + DCT_STRUCT *DCTPtr; + UINT8 CurrentDCT; + LOCATE_HEAP_PTR LocHeap; + MEM_NB_BLOCK *NBPtr; + MEM_MAIN_DATA_BLOCK mmData; + + DCTPtr = MCTPtr->DctData; + ErrorRecovery = TRUE; + IgnoreErr = FALSE; + IDS_OPTION_HOOK (IDS_MEM_ERROR_RECOVERY, &ErrorRecovery, StdHeader); + + if (ErrorRecovery) { + if (DCT == EXCLUDE_ALL_DCT) { + // Exclude all DCTs on a node + for (CurrentDCT = 0; CurrentDCT < MCTPtr->DctCount; CurrentDCT++) { + DCTPtr[CurrentDCT].Timings.CsTestFail = DCTPtr[CurrentDCT].Timings.CsPresent; + } + } else if (ChipSelMask == EXCLUDE_ALL_CHIPSEL) { + // Exclude the specified DCT + DCTPtr[DCT].Timings.CsTestFail = DCTPtr[DCT].Timings.CsPresent; + } else { + // Exclude the chip select that has been marked out + DCTPtr[DCT].Timings.CsTestFail |= ChipSelMask & DCTPtr[DCT].Timings.CsPresent; + IDS_OPTION_HOOK (IDS_LOADCARD_ERROR_RECOVERY, &DCTPtr[DCT], StdHeader); + } + + // Exclude the failed dimm to recovery from error + if (MCTPtr->NodeMemSize != 0) { + LocHeap.BufferHandle = AMD_MEM_AUTO_HANDLE; + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + // NB block has already been constructed by main block. + // No need to construct it here. + NBPtr = (MEM_NB_BLOCK *)LocHeap.BufferPtr; + if (!NBPtr->SharedPtr->NodeMap[MCTPtr->NodeId].IsValid) { + // Memory map has not been calculated, no need to remap memory across node here. + // Only need to remap memory within the node. + NBPtr = &NBPtr[MCTPtr->NodeId]; + NBPtr->FeatPtr->ExcludeDIMM (NBPtr); + } else { + // Need to remap memory across the whole system. + mmData.MemPtr = NBPtr->MemPtr; + mmData.mmSharedPtr = NBPtr->SharedPtr; + mmData.NBPtr = NBPtr; + mmData.TechPtr = (MEM_TECH_BLOCK *) (&NBPtr[NBPtr->MemPtr->DieCount]); + mmData.DieCount = NBPtr->MemPtr->DieCount; + if (!MemFeatMain.ExcludeDIMM (&mmData)) { + return FALSE; + } + } + } + // If allocation fails, that means the code is not running at BSP. + // Parallel training is in process. + // Remap for parallel training will be done when control returns to BSP. + } + return TRUE; + } else { + IDS_OPTION_HOOK (IDS_MEM_IGNORE_ERROR, &IgnoreErr, StdHeader); + if (IgnoreErr) { + return TRUE; + } + SetMemError (AGESA_FATAL, MCTPtr); + // ErrorRecovery is FALSE + return FALSE; + } +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/minit.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/minit.c new file mode 100644 index 0000000000..318165ade8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/minit.c @@ -0,0 +1,149 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * minit.c + * + * Initializer support function + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "amdlib.h" +#include "AdvancedApi.h" +#include "mport.h" +#include "mu.h" +#include "OptionMemory.h" +#include "Ids.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MINIT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +extern MEM_NB_SUPPORT memNBInstalled[]; +extern MEM_PLATFORM_CFG* memPlatformTypeInstalled[]; +extern UINT8 SizeOfNBInstalledTable; + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the default parameter, function pointers, build options + * and SPD data for memory configuration + * + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * @param[in,out] *PlatFormConfig - Platform profile/build option config structure + * + */ +VOID +AmdMemInitDataStructDef ( + IN OUT MEM_DATA_STRUCT *MemPtr, + IN OUT PLATFORM_CONFIGURATION *PlatFormConfig + ) +{ + UINT8 p; + UINT8 i; + // We need a way of specifying default values for each particular northbridge + // family. We also need to make sure that the IBV knows which parameter struct + // is for which northbridge. + //---------------------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemBeforeMemDataInit, &MemPtr->StdHeader); + IDS_PERF_TIMESTAMP (TP_BEGINMEMBEFOREMEMDATAINIT, &MemPtr->StdHeader); + + MemPtr->PlatFormConfig = PlatFormConfig; + + // + // Initialize Default Parameters + // + MemNCmnInitDefaultsNb (MemPtr); + for ( i = 0; i < SizeOfNBInstalledTable; i++) { + if (memNBInstalled[i].MemNInitDefaults != NULL) { + memNBInstalled[i].MemNInitDefaults (MemPtr); + } + } + + //---------------------------------------------------------------------------- + // INITIALIZE PLATFORM SPECIFIC CONFIGURATION STRUCT + //---------------------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemPlatformSpecificConfig, &MemPtr->StdHeader); + i = 0; + for (p = 0; p < MAX_PLATFORM_TYPES; p++) { + if (memPlatformTypeInstalled[i] != NULL) { + MemPtr->GetPlatformCfg[p] = memPlatformTypeInstalled[i]; + i++; + } else { + MemPtr->GetPlatformCfg[p] = MemAGetPsCfgDef; + } + } + + AGESA_TESTPOINT (TpProcMemAfterMemDataInit, &MemPtr->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDMEMBEFOREMEMDATAINIT, &MemPtr->StdHeader); + + MemPtr->ErrorHandling = MemErrHandle; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mm.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mm.c new file mode 100644 index 0000000000..a355741a11 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mm.c @@ -0,0 +1,253 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mm.c + * + * Main Memory Entrypoint file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MM_FILECODE +/* features */ + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function deallocates heap buffers that were allocated in AmdMemAuto + * + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +MemAmdFinalize ( + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + UINT8 Die; + + for (Die = 0; Die < MemPtr->DieCount; Die++ ) { + HeapDeallocateBuffer (GENERATE_MEM_HANDLE (ALLOC_TRN_DATA_HANDLE, Die, 0, 0), &MemPtr->StdHeader); + HeapDeallocateBuffer (GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, Die, 0, 0), &MemPtr->StdHeader); + } + + HeapDeallocateBuffer (GENERATE_MEM_HANDLE (ALLOC_DIE_STRUCT_HANDLE, 0, 0, 0), &MemPtr->StdHeader); + HeapDeallocateBuffer (AMD_S3_SAVE_HANDLE, &MemPtr->StdHeader); + HeapDeallocateBuffer (AMD_MEM_SPD_HANDLE, &MemPtr->StdHeader); + HeapDeallocateBuffer (AMD_MEM_AUTO_HANDLE, &MemPtr->StdHeader); + + return AGESA_SUCCESS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * MemSocketScan - Scan all nodes, recording the physical Socket number, + * Die Number (relative to the socket), and PCI Device address of each + * populated socket. + * + * This information is used by the northbridge block to map a dram + * channel on a particular DCT, on a particular CPU Die, in a particular + * socket to a the DRAM SPD Data for the DIMMS physically connected to + * that channel. + * + * Also, the customer socket map is populated with pointers to the + * appropriate channel structures, so that the customer can locate the + * appropriate channel configuration data. + * + * This socket scan will always result in Die 0 as the BSP. + * + * @param[in,out] *mmPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + */ +AGESA_STATUS +MemSocketScan ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ) +{ + MEM_DATA_STRUCT *MemPtr; + UINT8 DieIndex; + UINT8 DieCount; + UINT32 SocketId; + UINT32 DieId; + UINT8 Die; + PCI_ADDR Address; + AGESA_STATUS AgesaStatus; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + ASSERT (mmPtr != NULL); + ASSERT (mmPtr->MemPtr != NULL); + MemPtr = mmPtr->MemPtr; + + // + // Count the number of dies in the system + // + DieCount = 0; + for (Die = 0; Die < MAX_NODES_SUPPORTED; Die++) { + if (GetSocketModuleOfNode ((UINT32)Die, &SocketId, &DieId, (VOID *)MemPtr)) { + DieCount++; + } + } + MemPtr->DieCount = DieCount; + mmPtr->DieCount = DieCount; + + if (DieCount > 0) { + // + // Allocate buffer for DIE_STRUCTs + // + AllocHeapParams.RequestedBufferSize = ((UINT16)DieCount * sizeof (DIE_STRUCT)); + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DIE_STRUCT_HANDLE, 0, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) == AGESA_SUCCESS) { + MemPtr->DiesPerSystem = (DIE_STRUCT *)AllocHeapParams.BufferPtr; + // + // Find SocketId, DieId, and PCI address of each node + // + DieIndex = 0; + for (Die = 0; Die < MAX_NODES_SUPPORTED; Die++) { + if (GetSocketModuleOfNode ((UINT32)Die, &SocketId, &DieId, (VOID *)MemPtr)) { + if (GetPciAddress ((VOID *)MemPtr, (UINT8)SocketId, (UINT8)DieId, &Address, &AgesaStatus)) { + MemPtr->DiesPerSystem[DieIndex].SocketId = (UINT8)SocketId; + MemPtr->DiesPerSystem[DieIndex].DieId = (UINT8)DieId; + MemPtr->DiesPerSystem[DieIndex].PciAddr.AddressValue = Address.AddressValue; + + DieIndex++; + } + } + } + AgesaStatus = AGESA_SUCCESS; + } else { + ASSERT(FALSE); // Heap allocation failed for DIE_STRUCTs + AgesaStatus = AGESA_FATAL; + } + } else { + ASSERT(FALSE); // No die in the system + AgesaStatus = AGESA_FATAL; + } + return AgesaStatus; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets memory errors into MemDataStruct + * + * + * @param[in,out] *MCTPtr - Pointer to the DIE_STRUCT + * @param[in] Errorval - Error value to update + */ + +VOID +SetMemError ( + IN AGESA_STATUS Errorval, + IN OUT DIE_STRUCT *MCTPtr + ) +{ + if (MCTPtr->ErrCode < Errorval) { + MCTPtr->ErrCode = Errorval; + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function is default function for the fultion list + * + * @param[in,out] *pMemData - Pointer to the MEM_DATA_STRUCT + */ +VOID +AmdMemFunctionListDef ( + IN OUT VOID *pMemData + ) +{ +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmConditionalPso.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmConditionalPso.c new file mode 100644 index 0000000000..56a769fe6e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmConditionalPso.c @@ -0,0 +1,695 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmConditionalPso.c + * + * Functions to support conditional entries in the Platform Specific Override Table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "Ids.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MMCONDITIONALPSO_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +#define PSO_TYPE 0 +#define PSO_LENGTH 1 +#define PSO_DATA 2 + +typedef enum _PSO_STATE { + PSO_FIND_CONDITION = 100, // Searching for initial Condition statement + PSO_FIND_ACTION, // Searching for initial Action Statement + PSO_MATCH_ACTION, // Trying to find an action that matches the caller's request + PSO_CHECK_CONDITION, // Checking the condition that preceded the found action + PSO_DO_ACTION, // Performing Action + PSO_COMPLETE // Completed processing of this request +} PSO_STATE; + +typedef struct _D3_CMP_CAL { + UINT32 D3Cmp0NCal :3; + UINT32 Reserved34 :2; + UINT32 D3Cmp0PCal :3; + UINT32 Reserved89 :2; + UINT32 D3Cmp1NCal :3; + UINT32 Reserved1314 :2; + UINT32 D3Cmp1PCal :3; + UINT32 Reserved1819 :2; + UINT32 D3Cmp2NCal :3; + UINT32 Reserved2324 :2; + UINT32 D3Cmp2PCal :3; + UINT32 Reserved2831 :2; +} D3_CMP_CAL; + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN + STATIC + MemPSODoActionODT ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + + BOOLEAN + STATIC + MemPSODoActionAddrTmg ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + + BOOLEAN + STATIC + MemPSODoActionODCControl ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + + BOOLEAN + STATIC + MemPSODoActionSlewRate ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +BOOLEAN +STATIC +MemPSODoActionGetFreqLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +BOOLEAN +STATIC +MemCheckRankType ( + IN CH_DEF_STRUCT *CurrentChannel, + IN UINT16 RankType + ); +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * Process Conditional Platform Specific Overrides + * + * @param[in] PlatformMemoryConfiguration - Pointer to Platform config table + * @param[in] NBPtr - Pointer to Current NBBlock + * @param[in] PsoAction - Action type + * @param[in] Dimm - Dimm Number + * + * @return BOOLEAN - TRUE : Action was performed + * FALSE: Action was not performed + * + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemProcessConditionalOverrides ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 PsoAction, + IN UINT8 Dimm + ) +{ + BOOLEAN Result; + MEM_TECH_BLOCK *TechPtr; + UINT8 *Buffer; + UINT8 *ConditionStartPtr; + UINT8 *ActionStartPtr; + UINT8 *SpdBufferPtr; + UINT8 i; + UINT8 DimmMask; + UINT8 CurDimmMask; + BOOLEAN Condition; + BOOLEAN TmpCond; + PSO_STATE State; + ASSERT (PlatformMemoryConfiguration != NULL); + ASSERT (NBPtr != NULL); + ASSERT ((PsoAction >= PSO_ACTION_MIN) && (PsoAction <= PSO_ACTION_MAX)); + // + // Set up local data + // + TechPtr = NBPtr->TechPtr; + Buffer = PlatformMemoryConfiguration; + State = PSO_FIND_CONDITION; + ConditionStartPtr = NULL; + ActionStartPtr = NULL; + Condition = FALSE; + DimmMask = 0xFF; + CurDimmMask = 0xFF; + Result = FALSE; + + if (Dimm != 0xFF) { + DimmMask = ( 1 << Dimm); + } + DimmMask &= (UINT8) (NBPtr->ChannelPtr->ChDimmValid & 0xFF); + if (DimmMask == 0) { + return Result; + } + + // + // Search for Condition Entry + // + while (State != PSO_COMPLETE) { + switch (State) { + // + // Searching for initial Condition statement + // + case PSO_FIND_CONDITION: + ASSERT (Buffer != NULL); + while (Buffer[PSO_TYPE] != PSO_CONDITION_AND) { + // + // If end of table is reached, Change state to complete and break. + // + if (Buffer[PSO_TYPE] == PSO_END) { + State = PSO_COMPLETE; + break; + } + // + // Otherwise, increment Buffer Pointer to the next PSO entry. + // + Buffer += (Buffer[PSO_LENGTH] + 2); + } + // + // If Condition statement has been found, save the Condition Start Pointer, + // and change to next state + // + if (State != PSO_COMPLETE) { + ASSERT (Buffer != NULL); + State = PSO_FIND_ACTION; + ConditionStartPtr = Buffer; + Buffer += (Buffer[PSO_LENGTH] + 2); + } + break; + // + // Searching for an action that matches the caller's request + // + case PSO_FIND_ACTION: + ASSERT (Buffer != NULL); + while (Buffer[PSO_TYPE] != PsoAction) { + // + // If non-conditional entry, change state to complete and break. + // + if ((Buffer[PSO_TYPE] < CONDITIONAL_PSO_MIN) || (Buffer[PSO_TYPE] > CONDITIONAL_PSO_MAX)) { + State = PSO_COMPLETE; + break; + } + // + // Check for the Start of a new condition block + // + if (Buffer[PSO_TYPE] == PSO_CONDITION_AND) { + ConditionStartPtr = Buffer; + } + // + // Otherwise, increment buffer pointer to the next PSO entry. + // + Buffer += (Buffer[PSO_LENGTH] + 2); + } + // + // If Action statement has been found, Save the Action Start Pointer, Reset Buffer to Condition Start + // and Change to next state. + // + if (State != PSO_COMPLETE) { + State = PSO_CHECK_CONDITION; + ASSERT (Buffer != NULL); + ActionStartPtr = Buffer; + Buffer = ConditionStartPtr; + Condition = TRUE; + } + break; + // + // Checking the condition that preceded the found action + // + case PSO_CHECK_CONDITION: + ASSERT (Buffer != NULL); + // + // Point to the next Condition + // + Buffer += (Buffer[PSO_LENGTH] + 2); + ASSERT ((Buffer[PSO_TYPE] >= CONDITIONAL_PSO_MIN) && (Buffer[PSO_TYPE] <= CONDITIONAL_PSO_MAX)); + // + // This section has already been checked for invalid statements so just exit on ACTION_xx + // + if ((Buffer[PSO_TYPE] >= PSO_ACTION_MIN) && (Buffer[PSO_TYPE] <= PSO_ACTION_MAX)) { + if (Condition) { + ASSERT (Buffer != NULL); + State = PSO_DO_ACTION; // Perform the Action + } else { + State = PSO_FIND_CONDITION; // Go back and look for another condition/action + } + Buffer = ActionStartPtr; // Restore Action Pointer + break; + } + switch (Buffer[PSO_TYPE]) { + + case PSO_CONDITION_AND: + // + // Additional CONDITION_AND is ORed with Previous ones, so if Previous result is TRUE + // just restore action pointer and perform the action. + // + if (Condition) { + State = PSO_DO_ACTION; + Buffer = ActionStartPtr; + } else { + // + // If its false, Start over and evaluate next cond. + // reset the Current Dimm Mask + // + Condition = TRUE; + CurDimmMask = 0xFF; + } + break; + + case PSO_CONDITION_LOC: + // + // Condition location + // + CurDimmMask = Buffer[4]; + Condition &= ( ((Buffer[2] & (1 << (NBPtr->MCTPtr->SocketId))) != 0) && + ((Buffer[3] & (1 << (NBPtr->ChannelPtr->ChannelID))) != 0) && + ((CurDimmMask & DimmMask) != 0) ); + break; + + case PSO_CONDITION_SPD: + // + // Condition SPD + // + TmpCond = FALSE; + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i ++) { + if ( ((DimmMask & CurDimmMask) & ((UINT16) (1 << i))) != 0) { + if (TechPtr->GetDimmSpdBuffer (TechPtr, &SpdBufferPtr, i)) { + TmpCond |= ( (SpdBufferPtr[Buffer[2]] & Buffer[3]) == Buffer[4]); + } + } + } + Condition &= TmpCond; + break; + + case PSO_CONDITION_REG: + // + // Condition Register - unsupported at this time + // + break; + + default: + ASSERT (FALSE); + } // End Condition Switch + break; + + case PSO_DO_ACTION: + ASSERT (Buffer != NULL); + // + // Performing Action + // + if ((Buffer[PSO_TYPE] < PSO_ACTION_MIN) || (Buffer[PSO_TYPE] > PSO_ACTION_MAX)) { + State = PSO_COMPLETE; + } + if (Buffer[PSO_TYPE] == PsoAction) { + switch (Buffer[PSO_TYPE]) { + case PSO_ACTION_ODT: + Result = MemPSODoActionODT (NBPtr, &Buffer[PSO_DATA]); + break; + case PSO_ACTION_ADDRTMG: + Result = MemPSODoActionAddrTmg (NBPtr, &Buffer[PSO_DATA]); + break; + case PSO_ACTION_ODCCONTROL: + Result = MemPSODoActionODCControl (NBPtr, &Buffer[PSO_DATA]); + break; + case PSO_ACTION_SLEWRATE: + Result = MemPSODoActionSlewRate (NBPtr, &Buffer[PSO_DATA]); + break; + case PSO_ACTION_SPEEDLIMIT: + Result = MemPSODoActionGetFreqLimit (NBPtr, &Buffer[PSO_DATA]); + break; + case PSO_ACTION_REG: + break; + default: + ASSERT (FALSE); + } // End Action Switch + // + // If Action was performed, mark complete. + // + if (Result) { + State = PSO_COMPLETE; + } + }// End Action + + // + // Point to the next PSO Entry + // + Buffer += (Buffer[PSO_LENGTH] + 2); + break; + + case PSO_COMPLETE: + // + // Completed processing of this request + // + break; + + default: + ASSERT (FALSE); + } // End State Switch + + } // End While + + return Result; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * Perform ODT Platform Override + * + * @param[in] NBPtr - Pointer to Current NBBlock + * @param[in] Buffer - Pointer to the Action Command Data (w/o Type and Len) + * + * @return BOOLEAN - TRUE : Action was performed + * FALSE: Action was not performed + * + * ---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemPSODoActionODT ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + BOOLEAN Result; + UINT32 Speed; + UINT8 Dimms; + UINT8 i; + UINT8 QR_Dimms; + Result = FALSE; + Speed = ((UINT32) 1 << (NBPtr->DCTPtr->Timings.Speed / 66)); + Dimms = NBPtr->ChannelPtr->Dimms; + QR_Dimms = 0; + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) { + if (((NBPtr->ChannelPtr->DimmQrPresent & (UINT16) (1 << i)) != 0) && (i < 2)) { + QR_Dimms ++; + } + } + if ((Speed & ((UINT32 *) Buffer)[0]) != 0) { + if ((((UINT8) (1 << (Dimms - 1)) & Buffer[4]) != 0) || (Buffer[4] == ANY_NUM)) { + if (((QR_Dimms == 0) && (Buffer[5] == NO_DIMM)) || + ((QR_Dimms > 0) && (((UINT8) (1 << (QR_Dimms - 1)) & Buffer[5]) != 0)) || + (Buffer[5] == ANY_NUM)) { + NBPtr->PsPtr->DramTerm = Buffer[6]; + NBPtr->PsPtr->QR_DramTerm = Buffer[7]; + NBPtr->PsPtr->DynamicDramTerm = Buffer[8]; + Result = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, " Platform Override: DramTerm:%02x, QRDramTerm:%02x, DynDramTerm:%02x\n", Buffer[6], Buffer[7], Buffer[8]); + } + } + } + return Result; + } + + /* -----------------------------------------------------------------------------*/ +/** + * Perform Address Timing Platform Override + * + * @param[in] NBPtr - Pointer to Current NBBlock + * @param[in] Buffer - Pointer to the Action Command Data (w/o Type and Len) + * + * @return BOOLEAN - TRUE : Action was performed + * FALSE: Action was not performed + * + * ---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemPSODoActionAddrTmg ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + BOOLEAN Result; + CH_DEF_STRUCT *ChannelPtr; + UINT32 Speed; + UINT16 DimmConfig; + + Result = FALSE; + ChannelPtr = NBPtr->ChannelPtr; + Speed = ((UINT32) 1 << (NBPtr->DCTPtr->Timings.Speed / 66)); + DimmConfig = *(UINT16 *) &(Buffer[4]); + + if ((Speed & ((UINT32 *) Buffer)[0]) != 0) { + if (MemCheckRankType (ChannelPtr, DimmConfig)) { + ChannelPtr->DctAddrTmg = *(UINT32*) &(Buffer[6]); + Result = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, " Platform Override: Address Timing:%08x\n", *(UINT32*) &(Buffer[6])); + } + } + return Result; + } + + /* -----------------------------------------------------------------------------*/ +/** + * Perform Drive Strength Platform Override + * + * @param[in] NBPtr - Pointer to Current NBBlock + * @param[in] Buffer - Pointer to the Action Command Data (w/o Type and Len) + * + * @return BOOLEAN - TRUE : Action was performed + * FALSE: Action was not performed + * + * ---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemPSODoActionODCControl ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + BOOLEAN Result; + CH_DEF_STRUCT *ChannelPtr; + UINT32 Speed; + UINT16 DimmConfig; + + Result = FALSE; + ChannelPtr = NBPtr->ChannelPtr; + Speed = ((UINT32) 1 << (NBPtr->DCTPtr->Timings.Speed / 66)); + DimmConfig = *(UINT16 *) &(Buffer[4]); + + if ((Speed & ((UINT32 *) Buffer)[0]) != 0) { + if (MemCheckRankType (ChannelPtr, DimmConfig)) { + ChannelPtr->DctOdcCtl = *(UINT32*) &(Buffer[6]); + Result = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, " Platform Override: ODC Control:%08x\n", *(UINT32*)&(Buffer[6])); + } + } + return Result; + } + + /* -----------------------------------------------------------------------------*/ +/** + * Perform Slew Rate Platform Override + * + * @param[in] NBPtr - Pointer to Current NBBlock + * @param[in] Buffer - Pointer to the Action Command Data (w/o Type and Len) + * + * @return BOOLEAN - TRUE : Action was performed + * FALSE: Action was not performed + * + * ---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemPSODoActionSlewRate ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + BOOLEAN Result; + CH_DEF_STRUCT *ChannelPtr; + UINT32 Speed; + UINT16 DimmConfig; + + Result = FALSE; + ChannelPtr = NBPtr->ChannelPtr; + Speed = ((UINT32) 1 << (NBPtr->DCTPtr->Timings.Speed / 66)); + DimmConfig = *(UINT16 *) &(Buffer[4]); + + if ((Speed & ((UINT32 *) Buffer)[0]) != 0) { + if (MemCheckRankType (ChannelPtr, DimmConfig)) { + MemNSetBitFieldNb (NBPtr, BFD3Cmp0NCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp0NCal ); + MemNSetBitFieldNb (NBPtr, BFD3Cmp0PCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp0PCal ); + MemNSetBitFieldNb (NBPtr, BFD3Cmp1NCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp1NCal ); + MemNSetBitFieldNb (NBPtr, BFD3Cmp1PCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp1PCal ); + MemNSetBitFieldNb (NBPtr, BFD3Cmp2NCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp2NCal ); + MemNSetBitFieldNb (NBPtr, BFD3Cmp2PCal, ((D3_CMP_CAL *) &(Buffer[6]))->D3Cmp2PCal ); + Result = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, " Platform Override: Slew Rate:%08x\n", *(UINT32 *) &(Buffer[6])); + } + } + return Result; + } + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides the POR supported speed for a specific config + * + * @param[in] NBPtr - Pointer to Current NBBlock + * @param[in] Buffer - Pointer to the Action Command Data (w/o Type and Len) + * + * @return BOOLEAN - TRUE : Action was performed + * FALSE: Action was not performed + * + */ +BOOLEAN +STATIC +MemPSODoActionGetFreqLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + BOOLEAN Result; + CH_DEF_STRUCT *ChannelPtr; + DCT_STRUCT *DCTPtr; + UINT16 DimmConfig; + UINT16 SpeedLimit; + + Result = FALSE; + ChannelPtr = NBPtr->ChannelPtr; + DCTPtr = NBPtr->DCTPtr; + DimmConfig = *(UINT16*) &(Buffer[0]); + SpeedLimit = 0; + // + // Match number of dimms, then Rank Type + // + if (ChannelPtr->Dimms == Buffer[2]) { + if (MemCheckRankType (ChannelPtr, DimmConfig)) { + // + // Select speed based on current voltage + // + if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) { + SpeedLimit = *(UINT16*) &(Buffer[3]); + } else if (NBPtr->RefPtr->DDR3Voltage == VOLT1_25) { + SpeedLimit = *(UINT16*) &(Buffer[7]); + } else { + SpeedLimit = *(UINT16*) &(Buffer[5]); + } + // + // Set the Speed limit + // + if (DCTPtr->Timings.TargetSpeed > SpeedLimit) { + DCTPtr->Timings.TargetSpeed = SpeedLimit; + } + Result = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, " Platform Override: Max Memory Speed for Channel %d: %d\n", NBPtr->Channel, SpeedLimit); + } + } + return Result; +} + + /* -----------------------------------------------------------------------------*/ +/** + * + * This function matches a particular Rank Type Mask to the installed + * DIMM configuration on the provided channel. + * + * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT + * @param[in] RankType Mask of rank type to match + * + * @return BOOLEAN - TRUE : Rank types match + * FALSE: Rank types do not match + * + */ +BOOLEAN +STATIC +MemCheckRankType ( + IN CH_DEF_STRUCT *CurrentChannel, + IN UINT16 RankType + ) +{ + BOOLEAN Result; + UINT8 i; + UINT16 DIMMRankType; + + DIMMRankType = MemAGetPsRankType (CurrentChannel); + Result = TRUE; + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) { + if ( ((DIMMRankType & (0x0F << (i << 2))) + (RankType & (0x0F << (i << 2)))) != 0) { + Result &= (((DIMMRankType & (0x0F << (i << 2))) & ( RankType & ( 0x0F << ( i << 2)))) != 0); + } + if (!Result) { + break; + } + } + return Result; +} \ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmEcc.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmEcc.c new file mode 100644 index 0000000000..acff7196fd --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmEcc.c @@ -0,0 +1,186 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmEcc.c + * + * Main Memory Feature implementation file for ECC Initialization + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 87201 $ @e \$Date: 2013-01-30 11:25:53 -0600 (Wed, 30 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "Porting.h" +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "ma.h" +#include "mfmemclr.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MMECC_FILECODE +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemMEcc ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ); + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * + * + * @param[in,out] *mmPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMEcc ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ) +{ + UINT8 Die; + MEM_SHARED_DATA *SharedPtr; + MEM_PARAMETER_STRUCT *RefPtr; + BOOLEAN RetVal; + + RetVal = TRUE; + RefPtr = mmPtr->MemPtr->ParameterListPtr; + SharedPtr = mmPtr->mmSharedPtr; + + // + // Run Northbridge-specific ECC initialization feature for each die. + // + SharedPtr->AllECC = FALSE; + if (RefPtr->EnableEccFeature) { + SharedPtr->AllECC = TRUE; + AGESA_TESTPOINT (TpProcMemEccInitialization, &(mmPtr->MemPtr->StdHeader)); + + for (Die = 0 ; Die < mmPtr->DieCount ; Die ++ ) { + mmPtr->NBPtr[Die].FeatPtr->CheckEcc (&(mmPtr->NBPtr[Die])); + RetVal &= (BOOLEAN) (mmPtr->NBPtr[Die].MCTPtr->ErrCode < AGESA_FATAL); + } + if (SharedPtr->AllECC == TRUE) { + RefPtr->GStatus[GsbAllECCDimms] = TRUE; + // Sync mem clear before setting scrub rate. + for (Die = 0; Die < mmPtr->DieCount; Die++) { + MemFMctMemClr_Sync (&(mmPtr->NBPtr[Die])); + } + } + } + // Scrubber control + for (Die = 0 ; Die < mmPtr->DieCount ; Die ++ ) { + mmPtr->NBPtr[Die].FeatPtr->InitEcc (&(mmPtr->NBPtr[Die])); + } + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function disable DRAM scrubber + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + */ +VOID +MemMDisableScrubber ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + MEM_SHARED_DATA *SharedPtr; + MEM_NB_BLOCK *NBArray; + + SharedPtr = MemMainPtr->mmSharedPtr; + NBArray = MemMainPtr->NBPtr; + if (SharedPtr->AllECC == TRUE) { + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + NBArray[Node].MemNDisableScrubber (&NBArray[Node]); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function restore the settings of DRAM scrubber + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + */ +VOID +MemMRestoreScrubber ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + MEM_SHARED_DATA *SharedPtr; + MEM_NB_BLOCK *NBArray; + + SharedPtr = MemMainPtr->mmSharedPtr; + NBArray = MemMainPtr->NBPtr; + if (SharedPtr->AllECC == TRUE) { + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + NBArray[Node].MemNRestoreScrubber (&NBArray[Node]); + } + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmExcludeDimm.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmExcludeDimm.c new file mode 100644 index 0000000000..ca599bd6e5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmExcludeDimm.c @@ -0,0 +1,244 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmExcludeDimm.c + * + * Main Memory Feature implementation file for RAS DIMM Exclude Feature + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "Ids.h" +#include "mport.h" +#include "amdlib.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MMEXCLUDEDIMM_FILECODE + +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemMRASExcludeDIMM ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ + +/* -----------------------------------------------------------------------------*/ +/** + * + * Check and disable Chip selects that fail training on all nodes. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMRASExcludeDIMM ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + BOOLEAN IsEnabled; + BOOLEAN RetVal; + BOOLEAN IsChannelIntlvEnabled[MAX_NODES_SUPPORTED]; + UINT8 FirstEnabledNode; + UINT32 BottomIO; + MEM_NB_BLOCK *NBPtr; + MEM_PARAMETER_STRUCT *RefPtr; + S_UINT64 SMsr; + + FirstEnabledNode = 0; + IsEnabled = FALSE; + RetVal = TRUE; + NBPtr = MemMainPtr->NBPtr; + RefPtr = NBPtr[BSP_DIE].RefPtr; + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + if (NBPtr[Node].FeatPtr->ExcludeDIMM (&NBPtr[Node])) { + if (!IsEnabled) { + // Record the first node that has exclude dimm enabled + FirstEnabledNode = Node; + IsEnabled = TRUE; + } + } + } + + // Force memory address remap when we want to undo 1TB hoisting + if (NBPtr->SharedPtr->UndoHoistingAbove1TB) { + IsEnabled = TRUE; + } + + if (IsEnabled) { + // Check if all nodes have all dimms excluded. If yes, fatal exit + NBPtr[BSP_DIE].SharedPtr->CurrentNodeSysBase = 0; + BottomIO = (NBPtr[BSP_DIE].RefPtr->BottomIo & 0xF8) << 8; + // If the first node that has excluded dimms does not have a system base smaller + // than bottomIO, then we don't need to reset the GStatus, as we don't need to + // remap memory hole. + if (NBPtr[FirstEnabledNode].MCTPtr->NodeSysBase < BottomIO) { + RefPtr->GStatus[GsbHWHole] = FALSE; + RefPtr->GStatus[GsbSpIntRemapHole] = FALSE; + RefPtr->GStatus[GsbSoftHole] = FALSE; + RefPtr->HoleBase = 0; + RefPtr->SysLimit = 0; + } + // If Node Interleaving has been executed before the remapping then we need to + // start from the first node. + // There may be a few senarios: + // 1. Node interleaving is not enabled before the remap, and still cannot be enabled after + // remap + // 2. Node interleaving cannot be enabled before the remap, but it can be enabled after + // remap + // 3. Node interleaving is enabled before the remap, but it cannot be enabled after the remap + if (NBPtr->SharedPtr->NodeIntlv.IsValid) { + FirstEnabledNode = 0; + } + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + IsChannelIntlvEnabled [Node] = FALSE; + // Check if node interleaving has been enabled on this node + // if yes, disable it. + if (NBPtr[Node].GetBitField (&NBPtr[Node], BFDramIntlvEn) != 0) { + NBPtr[Node].SetBitField (&NBPtr[Node], BFDramIntlvEn, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDramIntlvSel, 0); + } + if (Node >= FirstEnabledNode) { + // Remap memory on nodes with node number larger than the first node that has excluded dimms. + // If channel interleaving has already been enabled, need to disable it before remapping memory. + if (NBPtr[Node].GetBitField (&NBPtr[Node], BFDctSelIntLvEn) != 0) { + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelIntLvEn, 0); + IsChannelIntlvEnabled [Node] = TRUE; + } + NBPtr[Node].MCTPtr->Status[SbHWHole] = FALSE; + NBPtr[Node].MCTPtr->Status[SbSWNodeHole] = FALSE; + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelBaseAddr, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelHiRngEn, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelHi, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelBaseOffset, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDramHoleAddrReg, 0); + NBPtr[Node].HtMemMapInit (&NBPtr[Node]); + } else if (NBPtr[Node].MCTPtr->NodeMemSize != 0) { + // No change is needed in the memory map of this node. + // Need to adjust the current system base for other nodes processed later. + NBPtr[Node].SharedPtr->CurrentNodeSysBase = (NBPtr[Node].MCTPtr->NodeSysLimit + 1) & 0xFFFFFFF0; + RefPtr->SysLimit = NBPtr[Node].MCTPtr->NodeSysLimit; + // If the current node does not have the memory hole, then set DramHoleAddrReg to be 0. + // If memory hoisting is enabled later by other node, SyncAddrMapToAllNodes will set the base + // and DramMemHoistValid. + // Otherwise, do not change the register value, as we need to keep DramHoleOffset unchanged, as well + // DramHoleValid. + if (!NBPtr[Node].MCTPtr->Status[SbHWHole]) { + NBPtr[Node].SetBitField (&NBPtr[Node], BFDramHoleAddrReg, 0); + } + } + } + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + NBPtr[Node].SyncAddrMapToAllNodes (&NBPtr[Node]); + } + + LibAmdMsrRead (TOP_MEM, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + // Only when TOM is set can CpuMemTyping be re-run + if ((SMsr.hi != 0) || (SMsr.lo != 0)) { + if (RefPtr->SysLimit != 0) { + NBPtr[BSP_DIE].CpuMemTyping (&NBPtr[BSP_DIE]); + + // When 1TB hoisting is not supported, TOP_MEM2 cannot exceed HT reserved region base. + if ((RefPtr->SysLimit >= HT_REGION_BASE_RJ16) && (NBPtr->SharedPtr->UndoHoistingAbove1TB)) { + SMsr.hi = HT_REGION_BASE_RJ16 >> (32 - 16); + SMsr.lo = HT_REGION_BASE_RJ16 << 16; + LibAmdMsrWrite (TOP_MEM2, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + IDS_HDT_CONSOLE (MEM_FLOW, "TOP_MEM2: %08x0000\n", HT_REGION_BASE_RJ16); + RefPtr->Sub1THoleBase = HT_REGION_BASE_RJ16; + RefPtr->SysLimit = HT_REGION_BASE_RJ16 - 1; + } + } + } + + // Re-run node interleaving if it has been exeucuted before the remap + if (NBPtr->SharedPtr->NodeIntlv.IsValid) { + MemFeatMain.InterleaveNodes (MemMainPtr); + } + + // Re-enable channel interleaving if it was enabled before remapping memory + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + if (IsChannelIntlvEnabled [Node]) { + NBPtr[Node].FeatPtr->InterleaveChannels (&NBPtr[Node]); + } + } + + // Reset UndoHoistingAbove1TB if it was previously set + NBPtr->SharedPtr->UndoHoistingAbove1TB = FALSE; + } + + // if all dimms on all nodes are excluded, do fatal exit + if (RefPtr->SysLimit == 0) { + PutEventLog (AGESA_FATAL, MEM_ERROR_NO_DIMM_FOUND_ON_SYSTEM, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_FATAL, NBPtr[BSP_DIE].MCTPtr); + ASSERT (FALSE); + } + + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + RetVal &= (BOOLEAN) (NBPtr[Node].MCTPtr->ErrCode < AGESA_FATAL); + } + + return RetVal; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmLvDdr3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmLvDdr3.c new file mode 100644 index 0000000000..ee3eec7903 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmLvDdr3.c @@ -0,0 +1,300 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmLvDdr3.c + * + * Main Memory Feature implementation file for low voltage DDR3 support + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mmlvddr3.h" +#include "GeneralServices.h" +#include "PlatformMemoryConfiguration.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MMLVDDR3_FILECODE + +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ + +/* -----------------------------------------------------------------------------*/ +/** + * + * Find the common supported voltage on all nodes. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +STATIC BOOLEAN +MemMLvDdr3 ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + BOOLEAN RetVal; + BOOLEAN SecondLoop; + MEM_NB_BLOCK *NBPtr; + MEM_PARAMETER_STRUCT *ParameterPtr; + MEM_SHARED_DATA *mmSharedPtr; + + NBPtr = MemMainPtr->NBPtr; + mmSharedPtr = MemMainPtr->mmSharedPtr; + ParameterPtr = MemMainPtr->MemPtr->ParameterListPtr; + mmSharedPtr->VoltageMap = 0xFF; + SecondLoop = FALSE; + RetVal = TRUE; + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + NBPtr[Node].FeatPtr->LvDdr3 (&NBPtr[Node]); + // Check if there is no common supported voltage + if ((mmSharedPtr->VoltageMap == 0) && !SecondLoop) { + // restart node loop by setting node to 0xFF + Node = 0xFF; + SecondLoop = TRUE; + } + } + + if (mmSharedPtr->VoltageMap == 0) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo commonly supported VDDIO is found.\n"); + PutEventLog (AGESA_WARNING, MEM_WARNING_NO_COMMONLY_SUPPORTED_VDDIO, 0, 0, 0, 0, &(NBPtr[BSP_DIE].MemPtr->StdHeader)); + SetMemError (AGESA_WARNING, NBPtr[BSP_DIE].MCTPtr); + // When there is no commonly supported VDDIO, use 1.35V as the temporal VDDIO + ParameterPtr->DDR3Voltage = VOLT1_35; + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "\nCommonly supported VDDIO is: %s%s%s.\n", ((mmSharedPtr->VoltageMap & 1) != 0) ? "1.5V, " : "", ((mmSharedPtr->VoltageMap & 2) != 0) ? "1.35V, " : "", ((mmSharedPtr->VoltageMap & 4) != 0) ? "1.25V" : ""); + ParameterPtr->DDR3Voltage = CONVERT_ENCODED_TO_VDDIO (LibAmdBitScanReverse (mmSharedPtr->VoltageMap)); + } + + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + // Check if the voltage needs force to 1.5V + NBPtr[Node].FamilySpecificHook[ForceLvDimmVoltage] (&NBPtr[Node], MemMainPtr); + + RetVal &= (BOOLEAN) (NBPtr[Node].MCTPtr->ErrCode < AGESA_FATAL); + } + + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Find the common supported voltage on all nodes, taken into account of the + * user option for performance and power saving. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMLvDdr3PerformanceEnhPre ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + BOOLEAN RetVal; + DIMM_VOLTAGE VDDIO; + MEM_NB_BLOCK *NBPtr; + MEM_PARAMETER_STRUCT *ParameterPtr; + MEM_SHARED_DATA *mmSharedPtr; + PLATFORM_POWER_POLICY PowerPolicy; + UINT8 *PowerPolicyPtr; + + NBPtr = MemMainPtr->NBPtr; + mmSharedPtr = MemMainPtr->mmSharedPtr; + ParameterPtr = MemMainPtr->MemPtr->ParameterListPtr; + PowerPolicyPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MEMORY_POWER_POLICY, 0, 0, 0, NULL, NULL); + if (PowerPolicyPtr != NULL) { + PowerPolicy = (PLATFORM_POWER_POLICY) *PowerPolicyPtr; + IDS_HDT_CONSOLE (MEM_FLOW, "\nPlatform overrides memory power policy"); + } else { + PowerPolicy = MemMainPtr->MemPtr->PlatFormConfig->PlatformProfile.PlatformPowerPolicy; + } + + IDS_OPTION_HOOK (IDS_MEMORY_POWER_POLICY, &PowerPolicy, &NBPtr->MemPtr->StdHeader); + IDS_HDT_CONSOLE (MEM_FLOW, (PowerPolicy == Performance) ? "\nMaximize Performance\n" : "\nMaximize Battery Life\n"); + + if (ParameterPtr->DDR3Voltage != VOLT_INITIAL) { + mmSharedPtr->VoltageMap = VDDIO_DETERMINED; + PutEventLog (AGESA_WARNING, MEM_WARNING_INITIAL_DDR3VOLT_NONZERO, 0, 0, 0, 0, &(NBPtr[BSP_DIE].MemPtr->StdHeader)); + SetMemError (AGESA_WARNING, NBPtr[BSP_DIE].MCTPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "Warning: Initial Value for VDDIO has been changed.\n"); + RetVal = TRUE; + } else { + RetVal = MemMLvDdr3 (MemMainPtr); + + VDDIO = ParameterPtr->DDR3Voltage; + if (NBPtr->IsSupported[PerformanceOnly] || ((PowerPolicy == Performance) && (mmSharedPtr->VoltageMap != 0))) { + // When there is no commonly supported voltage, do not optimize performance + // For cases where we can maximize performance, do the following + // When VDDIO is enforced, DDR3Voltage will be overriden by specific VDDIO + // So cases with DDR3Voltage left to be VOLT_UNSUPPORTED will be open to maximizing performance. + ParameterPtr->DDR3Voltage = VOLT_UNSUPPORTED; + } + + IDS_OPTION_HOOK (IDS_ENFORCE_VDDIO, &(ParameterPtr->DDR3Voltage), &NBPtr->MemPtr->StdHeader); + + if (ParameterPtr->DDR3Voltage != VOLT_UNSUPPORTED) { + // When Voltage is already determined, do not have further process to choose maximum frequency to optimize performance + mmSharedPtr->VoltageMap = VDDIO_DETERMINED; + IDS_HDT_CONSOLE (MEM_FLOW, "VDDIO is determined. No further optimization will be done.\n"); + } else { + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + NBPtr[Node].MaxFreqVDDIO[VOLT1_5_ENCODED_VAL] = UNSUPPORTED_DDR_FREQUENCY; + NBPtr[Node].MaxFreqVDDIO[VOLT1_35_ENCODED_VAL] = UNSUPPORTED_DDR_FREQUENCY; + NBPtr[Node].MaxFreqVDDIO[VOLT1_25_ENCODED_VAL] = UNSUPPORTED_DDR_FREQUENCY; + } + // Reprogram the leveling result as temporal candidate + ParameterPtr->DDR3Voltage = VDDIO; + } + } + + ASSERT (ParameterPtr->DDR3Voltage != VOLT_UNSUPPORTED); + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Finalize the VDDIO for the board for performance enhancement. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMLvDdr3PerformanceEnhFinalize ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Dct; + UINT8 Node; + UINT8 NodeCnt[VOLT1_25 + 1]; + UINT8 MaxCnt; + MEM_NB_BLOCK *NBPtr; + MEM_PARAMETER_STRUCT *ParameterPtr; + MEM_SHARED_DATA *mmSharedPtr; + UINT8 CurrentVoltage; + DIMM_VOLTAGE Voltage; + UINT32 HighestFreq; + + ParameterPtr = MemMainPtr->MemPtr->ParameterListPtr; + mmSharedPtr = MemMainPtr->mmSharedPtr; + NBPtr = MemMainPtr->NBPtr; + + LibAmdMemFill (NodeCnt, 0, VOLT1_25_ENCODED_VAL + 1, &NBPtr->MemPtr->StdHeader); + if (mmSharedPtr->VoltageMap != VDDIO_DETERMINED) { + Voltage = ParameterPtr->DDR3Voltage; + IDS_HDT_CONSOLE (MEM_FLOW, "\nSearching for VDDIO that can maximize frequency: \n"); + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + HighestFreq = 0; + // Find out what the highest frequency that can be reached is on this node across different voltage. + for (CurrentVoltage = VOLT1_5_ENCODED_VAL; CurrentVoltage <= VOLT1_25_ENCODED_VAL; CurrentVoltage ++) { + if (HighestFreq < NBPtr[Node].MaxFreqVDDIO[CurrentVoltage]) { + HighestFreq = NBPtr[Node].MaxFreqVDDIO[CurrentVoltage]; + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "Node%d: 1.5V -> %dMHz, 1.35V -> %dMHz, 1.25V -> %dMHz\n", Node, NBPtr[Node].MaxFreqVDDIO[VOLT1_5_ENCODED_VAL], NBPtr[Node].MaxFreqVDDIO[VOLT1_35_ENCODED_VAL], NBPtr[Node].MaxFreqVDDIO[VOLT1_25_ENCODED_VAL]); + // Figure out what voltage we can have when attaining the highest frequency. + for (CurrentVoltage = VOLT1_5_ENCODED_VAL; CurrentVoltage <= VOLT1_25_ENCODED_VAL; CurrentVoltage ++) { + if (NBPtr[Node].MaxFreqVDDIO[CurrentVoltage] == HighestFreq) { + NodeCnt[CurrentVoltage] ++; + } + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "Number of nodes that can run at maximize performance: 1.5V -> %d Nodes 1.35V -> %d Nodes 1.25V -> %d Nodes.\n", NodeCnt[VOLT1_5_ENCODED_VAL], NodeCnt[VOLT1_35_ENCODED_VAL], NodeCnt[VOLT1_25_ENCODED_VAL]); + MaxCnt = 0; + // Use the VDDIO at which most nodes can run at higher frequency + for (CurrentVoltage = VOLT1_5_ENCODED_VAL; CurrentVoltage <= VOLT1_25_ENCODED_VAL; CurrentVoltage ++) { + if (MaxCnt <= NodeCnt[CurrentVoltage]) { + MaxCnt = NodeCnt[CurrentVoltage]; + ParameterPtr->DDR3Voltage = CONVERT_ENCODED_TO_VDDIO (CurrentVoltage); + } + } + + ASSERT (ParameterPtr->DDR3Voltage != VOLT_UNSUPPORTED); + + mmSharedPtr->VoltageMap = VDDIO_DETERMINED; + if (Voltage != ParameterPtr->DDR3Voltage) { + // Finalize frequency with updated finalized VDDIO + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + // Need to re-sync target speed and different VDDIO may cause different settings + NBPtr[Node].TechPtr->SpdGetTargetSpeed (NBPtr[Node].TechPtr); + for (Dct = 0; Dct < NBPtr[Node].DctCount; Dct++) { + NBPtr[Node].SwitchDCT (&(NBPtr[Node]), Dct); + if (NBPtr[Node].DCTPtr->Timings.CsEnabled != 0) { + if (!NBPtr[Node].PlatformSpec (&(NBPtr[Node]))) { + return FALSE; + } + } + } + } + } + } + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmMemClr.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmMemClr.c new file mode 100644 index 0000000000..bd04ed2e77 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmMemClr.c @@ -0,0 +1,126 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmMemclr.c + * + * Main Memory Feature implementation file for Memory Clear. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "mfmemclr.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_MAIN_MMMEMCLR_FILECODE +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemMMctMemClr ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Initiates/synchronizes memory clear on all nodes with Dram on it. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMMctMemClr ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + UINT8 NodeCnt; + BOOLEAN RetVal; + MEM_NB_BLOCK *NBPtr; + + NBPtr = MemMainPtr->NBPtr; + NodeCnt = MemMainPtr->DieCount; + RetVal = TRUE; + + IDS_OPTION_HOOK (IDS_BEFORE_MEMCLR, NULL, &NBPtr->MemPtr->StdHeader); + + for (Node = 0; Node < NodeCnt; Node++) { + NBPtr->FamilySpecificHook[DisableMemHoleMapping] (&NBPtr[Node], NULL); + } + + for (Node = 0; Node < NodeCnt; Node++) { + MemFMctMemClr_Init (&NBPtr[Node]); + } + + for (Node = 0; Node < NodeCnt; Node++) { + MemFMctMemClr_Sync (&NBPtr[Node]); + RetVal &= (BOOLEAN) (NBPtr[Node].MCTPtr->ErrCode < AGESA_FATAL); + } + + for (Node = 0; Node < NodeCnt; Node++) { + NBPtr->FamilySpecificHook[RestoreMemHoleMapping] (&NBPtr[Node], NULL); + } + + return RetVal; +} \ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmMemRestore.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmMemRestore.c new file mode 100644 index 0000000000..2cba133a66 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmMemRestore.c @@ -0,0 +1,750 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmMemRestore.c + * + * Main Memory Feature implementation file for Node Interleaving + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 86704 $ @e \$Date: 2013-01-24 17:29:29 -0600 (Thu, 24 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "OptionMemory.h" +#include "GeneralServices.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "S3.h" +#include "mfs3.h" +#include "heapManager.h" +#include "cpuRegisters.h" +#include "cpuPostInit.h" +#include "cpuApicUtilities.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MMMEMRESTORE_FILECODE + +#define ST_PRE_ESR 0 +#define ST_POST_ESR 1 +#define ST_DONE 2 + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemMCreateS3NbBlock ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr, + OUT S3_MEM_NB_BLOCK **S3NBPtr + ); + +VOID +MemMContextSave ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +BOOLEAN +MemMContextRestore ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +BOOLEAN +STATIC +MemMDramInit ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +UINT32 +GetReducedMemBlockSize ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +VOID +MemMReducedMemBlockSave ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr, + IN VOID *Storage, + OUT UINT32 *ActualBufferSize + ); + +VOID +MemMReducedMemBlockRestore ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr, + IN VOID *Storage + ); + +BOOLEAN +MemMS3Save ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ +extern MEM_NB_SUPPORT memNBInstalled[]; +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; + +/* -----------------------------------------------------------------------------*/ +/** + * + * Determines the maximum amount of space required to store all reduced NB block + * and DCT block. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + */ +UINT32 +GetReducedMemBlockSize ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + UINT8 Dct; + UINT32 MemBlockSize; + MEM_NB_BLOCK *NBPtr; + + MemBlockSize = sizeof (REDUCED_MEM_BLOCK_HEAP_HEADER); + + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + // Increase the size if the node is present + MemBlockSize += sizeof (REDUCED_NB_BLOCK); + NBPtr = &MemMainPtr->NBPtr[Node]; + + // Sync DCT Select bit with main NB block status + NBPtr->Dct = 0; + NBPtr->SetBitField (NBPtr, BFDctCfgSel, 0); + for (Dct = 0; Dct < NBPtr->DctCount; Dct ++) { + NBPtr->SwitchDCT (NBPtr, Dct); + // Increase the size if memory is present on the DCT + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + MemBlockSize += sizeof (REDUCED_DCT_BLOCK); + } + // Switch back to DCT 0 + NBPtr->SwitchDCT (NBPtr, 0); + } + } + + return MemBlockSize; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Save all the required reduced NB blocks and DCT blocks. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * @param[in] Storage - Beginning of the context buffer. + * @param[out] ActualBufferSize - Actual size used in saving the device list. + * + */ +VOID +MemMReducedMemBlockSave ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr, + IN VOID *Storage, + OUT UINT32 *ActualBufferSize + ) +{ + UINT8 Node; + UINT8 Dct; + MEM_NB_BLOCK *NBPtr; + REDUCED_MEM_BLOCK_HEAP_HEADER *MemBlockHeader; + REDUCED_NB_BLOCK *ReducedNBPtr; + REDUCED_DCT_BLOCK *ReducedDCTPtr; + + // Initialzie the block pointers + MemBlockHeader = (REDUCED_MEM_BLOCK_HEAP_HEADER *)Storage; + MemBlockHeader->NumNodes = MemMainPtr->DieCount; + ReducedNBPtr = (REDUCED_NB_BLOCK *)&MemBlockHeader[1]; + ReducedDCTPtr = (REDUCED_DCT_BLOCK *)&ReducedNBPtr[MemBlockHeader->NumNodes]; + + // Construct the reduced NB/DCT blocks + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + NBPtr = &MemMainPtr->NBPtr[Node]; + ReducedNBPtr->NodeMemSize = NBPtr->MCTPtr->NodeMemSize; + ReducedNBPtr->NodeSysBase = NBPtr->MCTPtr->NodeSysBase; + ReducedNBPtr->NumDcts = 0; + + for (Dct = 0; Dct < NBPtr->DctCount; Dct ++) { + // Sync DCT Select bit with main NB block status + NBPtr->SetBitField (NBPtr, BFDctCfgSel, NBPtr->Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + // Create a reduced block only if memory is present on the DCT + ReducedNBPtr->NumDcts ++; + ReducedDCTPtr->Dct = NBPtr->Dct; + ReducedDCTPtr->DctMemSize = NBPtr->DCTPtr->Timings.DctMemSize; + ReducedDCTPtr->EnabledChipSels = NBPtr->DCTPtr->EnabledChipSels; + ReducedDCTPtr->BankAddrMap = NBPtr->DCTPtr->BankAddrMap; + ReducedDCTPtr->BkIntDis = NBPtr->DCTPtr->BkIntDis; + ReducedDCTPtr ++; + } + // Switch back to DCT 0 + NBPtr->SwitchDCT (NBPtr, 0); + } + ReducedNBPtr ++; + } + + ASSERT ((UINT32) ((UINT8 *)ReducedDCTPtr - (UINT8 *)Storage) == GetReducedMemBlockSize (MemMainPtr)); + *ActualBufferSize += (UINT32) ((UINT8 *)ReducedDCTPtr - (UINT8 *)Storage); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Restore all the required reduced NB blocks and DCT blocks. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * @param[in] Storage - Beginning of the context buffer. + * + */ +VOID +MemMReducedMemBlockRestore ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr, + IN VOID *Storage + ) +{ + UINT8 Node; + UINT8 Dct; + UINT8 NumDcts; + MEM_NB_BLOCK *NBPtr; + DEVICE_BLOCK_HEADER *DeviceList; + REDUCED_MEM_BLOCK_HEAP_HEADER *MemBlockHeader; + REDUCED_NB_BLOCK *ReducedNBPtr; + REDUCED_DCT_BLOCK *ReducedDCTPtr; + + // Initialzie the block pointers + DeviceList = (DEVICE_BLOCK_HEADER *) Storage; + MemBlockHeader = (REDUCED_MEM_BLOCK_HEAP_HEADER *) ((UINT8 *) DeviceList + DeviceList->NextBlockOffset); + ReducedNBPtr = (REDUCED_NB_BLOCK *)&MemBlockHeader[1]; + ReducedDCTPtr = (REDUCED_DCT_BLOCK *)&ReducedNBPtr[MemBlockHeader->NumNodes]; + + // Restore the memory data from the reduced NB/DCT blocks + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + NBPtr = &MemMainPtr->NBPtr[Node]; + NBPtr->MCTPtr->NodeMemSize = ReducedNBPtr->NodeMemSize; + NBPtr->MCTPtr->NodeSysBase = ReducedNBPtr->NodeSysBase; + NumDcts = ReducedNBPtr->NumDcts; + ASSERT (NumDcts <= NBPtr->DctCount); + + for (Dct = 0; Dct < NBPtr->DctCount; Dct ++) { + // Sync DCT Select bit with main NB block status + NBPtr->SetBitField (NBPtr, BFDctCfgSel, NBPtr->Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + + if (NumDcts > 0 && NBPtr->Dct == ReducedDCTPtr->Dct) { + NBPtr->DCTPtr->Timings.DctMemSize = ReducedDCTPtr->DctMemSize; + NBPtr->DCTPtr->EnabledChipSels = ReducedDCTPtr->EnabledChipSels; + NBPtr->DCTPtr->BankAddrMap = ReducedDCTPtr->BankAddrMap; + NBPtr->DCTPtr->BkIntDis = ReducedDCTPtr->BkIntDis; + ReducedDCTPtr ++; + NumDcts --; + } else { + NBPtr->DCTPtr->Timings.DctMemSize = 0; + NBPtr->DCTPtr->EnabledChipSels = 0; + NBPtr->DCTPtr->BankAddrMap = 0; + NBPtr->DCTPtr->BkIntDis = FALSE; + } + // Switch back to DCT 0 + NBPtr->SwitchDCT (NBPtr, 0); + } + ReducedNBPtr ++; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Check and save memory context if possible. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + */ +VOID +MemMContextSave ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + UINT8 i; + MEM_PARAMETER_STRUCT *RefPtr; + LOCATE_HEAP_PTR LocHeap; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + DEVICE_BLOCK_HEADER *DeviceList; + AMD_CONFIG_PARAMS *StdHeader; + UINT32 BufferSize; + VOID *BufferOffset; + MEM_NB_BLOCK *NBArray; + S3_MEM_NB_BLOCK *S3NBPtr; + DESCRIPTOR_GROUP DeviceDescript[MAX_NODES_SUPPORTED]; + + NBArray = MemMainPtr->NBPtr; + RefPtr = NBArray[BSP_DIE].RefPtr; + + if (RefPtr->SaveMemContextCtl) { + MemMDisableScrubber (MemMainPtr); + + RefPtr->MemContext.NvStorage = NULL; + RefPtr->MemContext.NvStorageSize = 0; + + // Make sure DQS training has occurred before saving memory context + if (!RefPtr->MemRestoreCtl) { + StdHeader = &MemMainPtr->MemPtr->StdHeader; + + MemMCreateS3NbBlock (MemMainPtr, &S3NBPtr); + if (S3NBPtr != NULL) { + // Get the mask bit and the register list for node that presents + BufferSize = 0; + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + S3NBPtr->MemS3GetConPCIMask (S3NBPtr[Node].NBPtr, (VOID *)&DeviceDescript[Node]); + S3NBPtr->MemS3GetConMSRMask (S3NBPtr[Node].NBPtr, (VOID *)&DeviceDescript[Node]); + BufferSize += S3NBPtr->MemS3GetRegLstPtr (S3NBPtr[Node].NBPtr, (VOID *)&DeviceDescript[Node]); + } + + // Base on the size of the device list, apply for a buffer for it. + AllocHeapParams.RequestedBufferSize = (UINT32) (BufferSize + sizeof (DEVICE_BLOCK_HEADER)); + AllocHeapParams.BufferHandle = AMD_MEM_S3_DATA_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + DeviceList = (DEVICE_BLOCK_HEADER *) AllocHeapParams.BufferPtr; + DeviceList->RelativeOrMaskOffset = (UINT16) AllocHeapParams.RequestedBufferSize; + + // Copy device list on the stack to the heap. + BufferOffset = sizeof (DEVICE_BLOCK_HEADER) + AllocHeapParams.BufferPtr; + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + for (i = PRESELFREF; i <= POSTSELFREF; i ++) { + // Copy PCI device descriptor to the heap if it exists. + if (DeviceDescript[Node].PCIDevice[i].RegisterListID != 0xFFFFFFFF) { + LibAmdMemCopy (BufferOffset, &(DeviceDescript[Node].PCIDevice[i]), sizeof (PCI_DEVICE_DESCRIPTOR), StdHeader); + DeviceList->NumDevices ++; + BufferOffset = sizeof (PCI_DEVICE_DESCRIPTOR) + (UINT8 *)BufferOffset; + } + // Copy conditional PCI device descriptor to the heap if it exists. + if (DeviceDescript[Node].CPCIDevice[i].RegisterListID != 0xFFFFFFFF) { + LibAmdMemCopy (BufferOffset, &(DeviceDescript[Node].CPCIDevice[i]), sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR), StdHeader); + DeviceList->NumDevices ++; + BufferOffset = sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR) + (UINT8 *)BufferOffset; + } + // Copy MSR device descriptor to the heap if it exists. + if (DeviceDescript[Node].MSRDevice[i].RegisterListID != 0xFFFFFFFF) { + LibAmdMemCopy (BufferOffset, &(DeviceDescript[Node].MSRDevice[i]), sizeof (MSR_DEVICE_DESCRIPTOR), StdHeader); + DeviceList->NumDevices ++; + BufferOffset = sizeof (MSR_DEVICE_DESCRIPTOR) + (UINT8 *)BufferOffset; + } + // Copy conditional MSR device descriptor to the heap if it exists. + if (DeviceDescript[Node].CMSRDevice[i].RegisterListID != 0xFFFFFFFF) { + LibAmdMemCopy (BufferOffset, &(DeviceDescript[Node].PCIDevice[i]), sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR), StdHeader); + DeviceList->NumDevices ++; + BufferOffset = sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR) + (UINT8 *)BufferOffset; + } + } + } + + // Determine size needed + BufferSize = GetWorstCaseContextSize (DeviceList, INIT_RESUME, StdHeader); + BufferSize += GetReducedMemBlockSize (MemMainPtr); + AllocHeapParams.RequestedBufferSize = BufferSize; + AllocHeapParams.BufferHandle = AMD_S3_SAVE_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + // Save memory context + SaveDeviceListContext (DeviceList, AllocHeapParams.BufferPtr, INIT_RESUME, &BufferSize, StdHeader); + // Save pointer to the next block, namely the reduced memory block + DeviceList = (DEVICE_BLOCK_HEADER *)AllocHeapParams.BufferPtr; + DeviceList->NextBlockOffset = BufferSize; + // Save reduced memory block + MemMReducedMemBlockSave (MemMainPtr, AllocHeapParams.BufferPtr + BufferSize, &BufferSize); + RefPtr->MemContext.NvStorageSize = BufferSize; + } + + HeapDeallocateBuffer (AMD_MEM_S3_DATA_HANDLE, StdHeader); + } + } + HeapDeallocateBuffer (AMD_MEM_S3_NB_HANDLE, StdHeader); + + // Locate MemContext since it might have been shifted after deallocating + LocHeap.BufferHandle = AMD_S3_SAVE_HANDLE; + if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) { + RefPtr->MemContext.NvStorage = LocHeap.BufferPtr; + } + } + MemMRestoreScrubber (MemMainPtr); + } + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + NBArray[Node].FamilySpecificHook[AfterSaveRestore] (&NBArray[Node], &NBArray[Node]); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Check and restore memory context if possible. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - DQS timing restore succeeds. + * @return FALSE - DQS timing restore fails. + */ +BOOLEAN +MemMContextRestore ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + UINT8 Mode; + MEM_NB_BLOCK *NBArray; + MEM_PARAMETER_STRUCT *RefPtr; + MEM_DATA_STRUCT *MemPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + VOID *OrMaskPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + NBArray = MemMainPtr->NBPtr; + RefPtr = NBArray[BSP_DIE].RefPtr; + MemPtr = MemMainPtr->MemPtr; + Mode = 0; + + IDS_HDT_CONSOLE (MEM_FLOW, "\nMemRestoreCtl: %d\n", RefPtr->MemRestoreCtl); + IDS_HDT_CONSOLE (MEM_FLOW, "\nSaveMemContextCtl : %d\n", RefPtr->SaveMemContextCtl); + + if (RefPtr->MemRestoreCtl) { + if (RefPtr->MemContext.NvStorage != NULL) { + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart Mem Restore\n"); + MemMCreateS3NbBlock (MemMainPtr, &S3NBPtr); + if (S3NBPtr != NULL) { + // Restore registers before exiting self refresh + RestorePreESRContext (&OrMaskPtr, + RefPtr->MemContext.NvStorage, + INIT_RESUME, + &(MemPtr->StdHeader)); + MemMReducedMemBlockRestore (MemMainPtr, RefPtr->MemContext.NvStorage); + // Exit self refresh + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + // Call this function to sync DctSelCfg and NBPtr->Dct to avoid assert. + NBArray[Node].FamilySpecificHook[AfterSaveRestore] (&NBArray[Node], &NBArray[Node]); + } + if ((RefPtr->IsCapsuleMode && (AmdMemS3Resume (&(MemPtr->StdHeader)) == AGESA_SUCCESS)) || + (!RefPtr->IsCapsuleMode && (MemMDramInit (MemMainPtr) == TRUE))) { + // Restore registers after exiting self refresh + RestorePostESRContext (OrMaskPtr, + RefPtr->MemContext.NvStorage, + INIT_RESUME, + &(MemPtr->StdHeader)); + + // If context restore is enabled, do memclr if ECC is enabled + if (!RefPtr->IsCapsuleMode && RefPtr->EnableEccFeature) { + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + if ((NBArray[Node].MCTPtr->NodeMemSize != 0) && (NBArray[Node].GetBitField (&NBArray[Node], BFDramEccEn) == 0)) { + break; + } + } + if (Node == MemMainPtr->DieCount) { + AGESA_TESTPOINT (TpProcMemMemClr, &(MemMainPtr->MemPtr->StdHeader)); + MemFeatMain.MemClr (MemMainPtr); + } + } + } else { + RefPtr->MemRestoreCtl = FALSE; + } + } else { + RefPtr->MemRestoreCtl = FALSE; + } + HeapDeallocateBuffer (AMD_MEM_S3_NB_HANDLE, &(MemPtr->StdHeader)); + } else { + IEM_SKIP_CODE (IEM_MEM_RESTORE) { + RefPtr->MemRestoreCtl = FALSE; + } + } + } + + // Set the flag to skip memory S3 save when memory data is being restored + if (RefPtr->MemRestoreCtl) { + AllocHeapParams.RequestedBufferSize = 1; + AllocHeapParams.BufferHandle = AMD_SKIP_MEM_S3_SAVE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + + if (HeapAllocateBuffer (&AllocHeapParams, &(MemPtr->StdHeader)) != AGESA_SUCCESS) { + ASSERT (FALSE); + } + + if (RefPtr->IsCapsuleMode) { + PutEventLog (AGESA_SUCCESS, MEM_EVENT_CAPSULE_IN_EFFECT, 0, 0, 0, 0, &(MemPtr->StdHeader)); + } else { + PutEventLog (AGESA_SUCCESS, MEM_EVENT_CONTEXT_RESTORE_IN_EFFECT, 0, 0, 0, 0, &(MemPtr->StdHeader)); + } + } + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + NBArray[Node].FamilySpecificHook[AfterSaveRestore] (&NBArray[Node], &NBArray[Node]); + } + IDS_HDT_CONSOLE (MEM_FLOW, RefPtr->MemRestoreCtl ? "Mem Restore Succeeds!\n" : "Mem Restore Fails!\n"); + return RefPtr->MemRestoreCtl; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Save all memory related data for S3. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMS3Save ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + ALLOCATE_HEAP_PARAMS AllocHeapParams; + MEM_PARAMETER_STRUCT *RefPtr; + BOOLEAN SaveMemContextCtl; + BOOLEAN MemRestoreCtl; + + RefPtr = MemMainPtr->NBPtr[BSP_DIE].RefPtr; + + // If memory context has not been saved + if (RefPtr->MemContext.NvStorage == NULL) { + // Change memory context save and restore control to allow memory context to happen + SaveMemContextCtl = RefPtr->SaveMemContextCtl; + MemRestoreCtl = RefPtr->MemRestoreCtl; + RefPtr->SaveMemContextCtl = TRUE; + RefPtr->MemRestoreCtl = FALSE; + + MemMContextSave (MemMainPtr); + + // Restore the original control + RefPtr->SaveMemContextCtl = SaveMemContextCtl; + RefPtr->MemRestoreCtl = MemRestoreCtl; + + if (RefPtr->MemContext.NvStorage == NULL) { + // Memory context cannot be saved succesfully + ASSERT (FALSE); + return FALSE; + } + } + + // Allocate heap for memory S3 data to pass to main AMDS3Save + // Apply for 4 bytes more than the size of the data buffer to store the size of data buffer + IDS_HDT_CONSOLE (MEM_FLOW, "\nSave memory S3 data in heap\n"); + AllocHeapParams.RequestedBufferSize = RefPtr->MemContext.NvStorageSize + 4; + AllocHeapParams.BufferHandle = AMD_MEM_S3_SAVE_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + + if (HeapAllocateBuffer (&AllocHeapParams, &(MemMainPtr->MemPtr->StdHeader)) == AGESA_SUCCESS) { + LibAmdMemCopy (AllocHeapParams.BufferPtr + 4, RefPtr->MemContext.NvStorage, RefPtr->MemContext.NvStorageSize, &(MemMainPtr->MemPtr->StdHeader)); + *(UINT32 *) AllocHeapParams.BufferPtr = RefPtr->MemContext.NvStorageSize; + return TRUE; + } else { + ASSERT (FALSE); + return FALSE; + } +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * This function does dram init based on register value + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + * + */ +BOOLEAN +STATIC +MemMDramInit ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + UINT8 Dct; + MEM_NB_BLOCK *NBArray; + MEM_NB_BLOCK *NBPtr; + MEM_PARAMETER_STRUCT *RefPtr; + BIT_FIELD_NAME CsBitField; + ID_INFO CallOutIdInfo; + BOOLEAN RetVal; + + RefPtr = MemMainPtr->NBPtr[BSP_DIE].RefPtr; + NBArray = MemMainPtr->NBPtr; + RetVal = TRUE; + + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + NBPtr = &NBArray[Node]; + + // When memory pstate is enabled, change MemPstateStage flag so registers won't be programmed twice + if (NBPtr->MemPstateStage == MEMORY_PSTATE_1ST_STAGE) { + NBPtr->MemPstateStage = MEMORY_PSTATE_S3_STAGE; + } + + // Get dimm population info + NBPtr->TechPtr->DimmPresence (NBPtr->TechPtr); + NBPtr->MemNPlatformSpecificFormFactorInitNb (NBPtr); + + for (Dct = 0; Dct < NBPtr->DctCount; Dct ++) { + NBPtr->SwitchDCT (NBPtr, Dct); + for (CsBitField = BFCSBaseAddr0Reg; CsBitField <= BFCSBaseAddr7Reg; CsBitField ++) { + if ((NBPtr->GetBitField (NBPtr, CsBitField) & 5) != 0) { + // Need this variable for Dram init + NBPtr->DCTPtr->Timings.CsPresent |= (UINT16)1 << (CsBitField - BFCSBaseAddr0Reg); + } + } + + // Enable memory clock + if (NBPtr->GetBitField (NBPtr, BFDisDramInterface) == 0) { + NBPtr->SetBitField (NBPtr, BFMemClkFreqVal, 1); + while (NBPtr->GetBitField (NBPtr, BFFreqChgInProg) != 0) {} + } + + // Get memory clock speed + NBPtr->DCTPtr->Timings.Speed = MemNGetMemClkFreqUnb (NBPtr, (UINT8) NBPtr->GetBitField (NBPtr, BFMemClkFreq)); + NBPtr->DCTPtr->Timings.TargetSpeed = NBPtr->DCTPtr->Timings.Speed; + + // Call platform specific parameter processing function as lots of variable populated here + // will be used during dram init + if (NBPtr->GetBitField (NBPtr, BFDisDramInterface) == 0) { + if (!NBPtr->PsPtr->MemPDoPs (NBPtr)) { + IDS_ERROR_TRAP; + } + } + } + + // Callout before Dram Init + AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDramInit, &(MemMainPtr->MemPtr->StdHeader)); + CallOutIdInfo.IdField.SocketId = NBPtr->MCTPtr->SocketId; + CallOutIdInfo.IdField.ModuleId = NBPtr->MCTPtr->DieId; + IDS_HDT_CONSOLE (MEM_FLOW, "\nCalling out to Platform BIOS on Socket %d, Module %d...\n", CallOutIdInfo.IdField.SocketId, CallOutIdInfo.IdField.ModuleId); + AgesaHookBeforeDramInit ((UINTN) CallOutIdInfo.IdInformation, MemMainPtr->MemPtr); + NBPtr->FamilySpecificHook[AmpVoltageDisp] (NBPtr, NULL); + IDS_HDT_CONSOLE (MEM_FLOW, "\nVDDIO = 1.%dV\n", (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) ? 5 : + (NBPtr->RefPtr->DDR3Voltage == VOLT1_35) ? 35 : + (NBPtr->RefPtr->DDR3Voltage == VOLT1_25) ? 25 : 999); + AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); + + // Do Dram init + AGESA_TESTPOINT (TpProcMemDramInit, &(NBPtr->MemPtr->StdHeader)); + IDS_HDT_CONSOLE (MEM_FLOW, "\nMemClkFreq: %d MHz\n", NBPtr->DCTPtr->Timings.Speed); + NBPtr->FeatPtr->DramInit (NBPtr->TechPtr); + + // Print out hob info + IDS_HDT_CONSOLE (MEM_FLOW, "UmaSize: %x\n", NBPtr->RefPtr->UmaSize); + IDS_HDT_CONSOLE (MEM_FLOW, "UmaBase: %x\n", NBPtr->RefPtr->UmaBase); + IDS_HDT_CONSOLE (MEM_FLOW, "UmaMode: %x\n", NBPtr->RefPtr->UmaMode); + IDS_HDT_CONSOLE (MEM_FLOW, "Sub4GCacheTop: %x\n", NBPtr->RefPtr->Sub4GCacheTop); + IDS_HDT_CONSOLE (MEM_FLOW, "SysLimit: %x\n\n", NBPtr->RefPtr->SysLimit); + + if (NBPtr->MCTPtr->ErrCode == AGESA_FATAL) { + RetVal = FALSE; + } + } + + return RetVal; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * Create S3 NB Block. + * + * @param[in,out] MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * @param[out] S3NBPtr - Pointer to the S3 NB Block pointer + * + */ +VOID +STATIC +MemMCreateS3NbBlock ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr, + OUT S3_MEM_NB_BLOCK **S3NBPtr + ) +{ + UINT8 Node; + UINT8 i; + MEM_NB_BLOCK *NBArray; + MEM_NB_BLOCK *DummyNBs; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + NBArray = MemMainPtr->NBPtr; + + *S3NBPtr = NULL; + + // Allocate heap for S3 NB Blocks + AllocHeapParams.RequestedBufferSize = (MemMainPtr->DieCount * (sizeof (S3_MEM_NB_BLOCK) + sizeof (MEM_NB_BLOCK))); + AllocHeapParams.BufferHandle = AMD_MEM_S3_NB_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &(MemMainPtr->MemPtr->StdHeader)) == AGESA_SUCCESS) { + *S3NBPtr = (S3_MEM_NB_BLOCK *) AllocHeapParams.BufferPtr; + DummyNBs = (MEM_NB_BLOCK *) (AllocHeapParams.BufferPtr + MemMainPtr->DieCount * sizeof (S3_MEM_NB_BLOCK)); + + // Initialize S3 NB Blocks + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + (*S3NBPtr)[Node].NBPtr = &DummyNBs[Node]; + + for (i = 0; memNBInstalled[i].MemS3ResumeConstructNBBlock != 0; i++) { + if (memNBInstalled[i].MemS3ResumeConstructNBBlock (&(*S3NBPtr)[Node], NBArray[BSP_DIE].MemPtr, Node)) { + (*S3NBPtr)[Node].NBPtr->RefPtr = NBArray[Node].RefPtr; + break; + } + }; + if (memNBInstalled[i].MemS3ResumeConstructNBBlock == 0) { + *S3NBPtr = NULL; + break; + } + } + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmNodeInterleave.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmNodeInterleave.c new file mode 100644 index 0000000000..b474d64494 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmNodeInterleave.c @@ -0,0 +1,146 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmNodeInterleave.c + * + * Main Memory Feature implementation file for Node Interleaving + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_MAIN_MMNODEINTERLEAVE_FILECODE + +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemMInterleaveNodes ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ + +/* -----------------------------------------------------------------------------*/ +/** + * + * Check and enable node interleaving on all nodes. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMInterleaveNodes ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + UINT8 NodeCnt; + BOOLEAN RetVal; + MEM_NB_BLOCK *NBPtr; + + NBPtr = MemMainPtr->NBPtr; + NodeCnt = 0; + RetVal = TRUE; + + if (NBPtr->RefPtr->EnableNodeIntlv) { + if (!MemFeatMain.MemClr (MemMainPtr)) { + PutEventLog (AGESA_WARNING, MEM_WARNING_NODE_INTERLEAVING_NOT_ENABLED, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_WARNING, NBPtr->MCTPtr); + return FALSE; + } + + MemMainPtr->mmSharedPtr->NodeIntlv.IsValid = FALSE; + MemMainPtr->mmSharedPtr->NodeIntlv.NodeIntlvSel = 0; + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + if (!NBPtr[Node].FeatPtr->CheckInterleaveNodes (&NBPtr[Node])) { + break; + } + if (NBPtr[Node].MCTPtr->NodeMemSize != 0) { + NodeCnt ++; + } + } + + if ((Node == MemMainPtr->DieCount) && (NodeCnt != 0) && ((NodeCnt & (NodeCnt - 1)) == 0)) { + MemMainPtr->mmSharedPtr->NodeIntlv.NodeCnt = NodeCnt; + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + if (NBPtr[Node].MCTPtr->NodeMemSize != 0) { + NBPtr[Node].FeatPtr->InterleaveNodes (&NBPtr[Node]); + } + } + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + NBPtr[Node].SyncAddrMapToAllNodes (&NBPtr[Node]); + RetVal &= (BOOLEAN) (NBPtr[Node].MCTPtr->ErrCode < AGESA_FATAL); + } + } else { + // + // If all nodes cannot be interleaved + // + PutEventLog (AGESA_WARNING, MEM_WARNING_NODE_INTERLEAVING_NOT_ENABLED, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_WARNING, NBPtr->MCTPtr); + } + } + + return RetVal; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmOnlineSpare.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmOnlineSpare.c new file mode 100644 index 0000000000..91b38b4aa2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmOnlineSpare.c @@ -0,0 +1,165 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmOnlineSpare.c + * + * Main Memory Feature implementation file for Node Interleaving + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_MAIN_MMONLINESPARE_FILECODE +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemMOnlineSpare ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ + +/* -----------------------------------------------------------------------------*/ +/** + * + * Check and enable online spare on all nodes. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMOnlineSpare ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT8 Node; + BOOLEAN IsEnabled; + UINT8 FirstEnabledNode; + UINT32 BottomIO; + BOOLEAN RetVal; + MEM_NB_BLOCK *NBPtr; + MEM_PARAMETER_STRUCT *RefPtr; + + AGESA_TESTPOINT (TpProcMemOnlineSpareInit, &(MemMainPtr->MemPtr->StdHeader)); + FirstEnabledNode = 0; + IsEnabled = FALSE; + RetVal = TRUE; + NBPtr = MemMainPtr->NBPtr; + RefPtr = NBPtr[BSP_DIE].RefPtr; + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + if (NBPtr[Node].FeatPtr->OnlineSpare (&NBPtr[Node])) { + if (!IsEnabled) { + // Record the first node that has spared dimm enabled + FirstEnabledNode = Node; + IsEnabled = TRUE; + } + } + } + + if (IsEnabled) { + NBPtr[BSP_DIE].SharedPtr->CurrentNodeSysBase = 0; + BottomIO = (NBPtr[BSP_DIE].RefPtr->BottomIo & 0xF8) << 8; + // If the first node that has spared dimms does not have a system base smaller + // than bottomIO, then we don't need to reset the GStatus, as we don't need to + // remap memory hole. + if (NBPtr[FirstEnabledNode].MCTPtr->NodeSysBase < BottomIO) { + RefPtr->GStatus[GsbHWHole] = FALSE; + RefPtr->GStatus[GsbSpIntRemapHole] = FALSE; + RefPtr->GStatus[GsbSoftHole] = FALSE; + RefPtr->HoleBase = 0; + } + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + if (Node >= FirstEnabledNode) { + // Remap memory on nodes with node number larger than the first node that has spared dimms. + NBPtr[Node].MCTPtr->Status[SbHWHole] = FALSE; + NBPtr[Node].MCTPtr->Status[SbSWNodeHole] = FALSE; + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelBaseAddr, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelHiRngEn, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelHi, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDctSelBaseOffset, 0); + NBPtr[Node].SetBitField (&NBPtr[Node], BFDramHoleAddrReg, 0); + NBPtr[Node].HtMemMapInit (&NBPtr[Node]); + } else { + // No change is needed in the memory map of this node. + // Need to adjust the current system base for other nodes processed later. + NBPtr[Node].SharedPtr->CurrentNodeSysBase = (NBPtr[Node].MCTPtr->NodeSysLimit + 1) & 0xFFFFFFF0; + // If the current node does not have the memory hole, then set DramHoleAddrReg to be 0. + // If memory hoisting is enabled later by other node, SyncAddrMapToAllNodes will set the base + // and DramMemHoistValid. + // Otherwise, do not change the register value, as we need to keep DramHoleOffset unchanged, as well + // DramHoleValid. + if (!NBPtr[Node].MCTPtr->Status[SbHWHole]) { + NBPtr[Node].SetBitField (&NBPtr[Node], BFDramHoleAddrReg, 0); + } + } + } + + for (Node = 0; Node < MemMainPtr->DieCount; Node++) { + NBPtr[Node].SyncAddrMapToAllNodes (&NBPtr[Node]); + RetVal &= (BOOLEAN) (NBPtr[Node].MCTPtr->ErrCode < AGESA_FATAL); + } + NBPtr[BSP_DIE].CpuMemTyping (&NBPtr[BSP_DIE]); + } + return RetVal; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmParallelTraining.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmParallelTraining.c new file mode 100644 index 0000000000..375344e9ac --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmParallelTraining.c @@ -0,0 +1,288 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmNodeInterleave.c + * + * Main Memory Feature implementation file for Node Interleaving + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "Porting.h" +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuApicUtilities.h" +#include "GeneralServices.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "ma.h" +#include "mu.h" +#include "mfParallelTraining.h" +#include "GeneralServices.h" +#include "heapManager.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_MAIN_MMPARALLELTRAINING_FILECODE + +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemMParallelTraining ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ); + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * + * + * @param[in,out] *mmPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMParallelTraining ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ) +{ + AMD_CONFIG_PARAMS *StdHeader; + MEM_DATA_STRUCT *MemPtr; + MEM_NB_BLOCK *NBPtr; + DIE_INFO TrainInfo[MAX_NODES_SUPPORTED]; + AP_DATA_TRANSFER ReturnData; + AGESA_STATUS Status; + UINT8 ApSts; + UINT8 Die; + UINT8 Socket; + UINT32 Module; + UINT32 LowCore; + UINT32 HighCore; + UINT32 Time; + UINT32 TimeOut; + UINT32 TargetApicId; + BOOLEAN StillTraining; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + UINT8 *BufferPtr; + BOOLEAN TimeoutEn; + + NBPtr = mmPtr->NBPtr; + MemPtr = mmPtr->MemPtr; + StdHeader = &(mmPtr->MemPtr->StdHeader); + Time = 0; + TimeOut = PARALLEL_TRAINING_TIMEOUT; + TimeoutEn = TRUE; + IDS_TIMEOUT_CTL (&TimeoutEn); + + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart parallel training\n"); + AGESA_TESTPOINT (TpProcMemBeforeAnyTraining, StdHeader); + // + // Initialize Training Info Array + // + for (Die = 0; Die < mmPtr->DieCount; Die ++) { + Socket = TrainInfo[Die].Socket = NBPtr[Die].MCTPtr->SocketId; + Module = NBPtr[Die].MCTPtr->DieId; + GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader); + TrainInfo[Die].Core = (UINT8) (LowCore & 0x000000FF); + IDS_HDT_CONSOLE (MEM_FLOW, "\tLaunch core %d of socket %d\n", LowCore, Socket); + TrainInfo[Die].Training = FALSE; + } + // + // Start Training on Each remote die. + // + for (Die = 0; Die < mmPtr->DieCount; Die ++ ) { + if (Die != BSP_DIE) { + NBPtr[Die].BeforeDqsTraining (&(mmPtr->NBPtr[Die])); + if (NBPtr[Die].MCTPtr->NodeMemSize != 0) { + if (!NBPtr[Die].FeatPtr->Training (&(mmPtr->NBPtr[Die]))) { + // Fail to launch code on AP + PutEventLog (AGESA_ERROR, MEM_ERROR_PARALLEL_TRAINING_LAUNCH_FAIL, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, NBPtr[Die].MCTPtr); + if (!MemPtr->ErrorHandling (NBPtr[Die].MCTPtr, EXCLUDE_ALL_DCT, EXCLUDE_ALL_CHIPSEL, &MemPtr->StdHeader)) { + ASSERT (FALSE); + } + } else { + TrainInfo[Die].Training = TRUE; + } + } + } + } + // + // Call training on BSP + // + IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", NBPtr[BSP_DIE].Node); + NBPtr[BSP_DIE].BeforeDqsTraining (&(mmPtr->NBPtr[BSP_DIE])); + NBPtr[BSP_DIE].TrainingFlow (&(mmPtr->NBPtr[BSP_DIE])); + NBPtr[BSP_DIE].AfterDqsTraining (&(mmPtr->NBPtr[BSP_DIE])); + + // + // Get Results from remote processors training + // + do { + StillTraining = FALSE; + for (Die = 0; Die < mmPtr->DieCount; Die ++ ) { + // + // For each Die that is training, read the status + // + if (TrainInfo[Die].Training == TRUE) { + GetLocalApicIdForCore (TrainInfo[Die].Socket, TrainInfo[Die].Core, &TargetApicId, StdHeader); + ApSts = ApUtilReadRemoteControlByte (TargetApicId, StdHeader); + if ((ApSts & 0x80) == 0) { + // + // Allocate buffer for received data + // + AllocHeapParams.RequestedBufferSize = ( + sizeof (DIE_STRUCT) + + NBPtr[Die].DctCount * ( + sizeof (DCT_STRUCT) + ( + NBPtr[Die].ChannelCount * ( + sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK) + ( + (NBPtr[Die].MCTPtr->DctData[0].ChData[0].RowCount * + NBPtr[Die].MCTPtr->DctData[0].ChData[0].ColumnCount * + NUMBER_OF_DELAY_TABLES) + + (MAX_BYTELANES_PER_CHANNEL * MAX_CS_PER_CHANNEL * NUMBER_OF_FAILURE_MASK_TABLES) + + (MAX_DIMMS_PER_CHANNEL * MAX_NUMBER_LANES) + ) + ) + ) + ) + ) + 3; + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_PAR_TRN_HANDLE, Die, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + // + // Receive Training Results + // + + ReturnData.DataPtr = AllocHeapParams.BufferPtr; + ReturnData.DataSizeInDwords = (UINT16) AllocHeapParams.RequestedBufferSize / 4; + ReturnData.DataTransferFlags = 0; + Status = ApUtilReceiveBuffer (TrainInfo[Die].Socket, TrainInfo[Die].Core, &ReturnData, StdHeader); + if (Status != AGESA_SUCCESS) { + SetMemError (Status, NBPtr[Die].MCTPtr); + } + + BufferPtr = AllocHeapParams.BufferPtr; + LibAmdMemCopy (NBPtr[Die].MCTPtr, BufferPtr, sizeof (DIE_STRUCT), StdHeader); + BufferPtr += sizeof (DIE_STRUCT); + LibAmdMemCopy ( NBPtr[Die].MCTPtr->DctData, + BufferPtr, + NBPtr[Die].DctCount * (sizeof (DCT_STRUCT) + NBPtr[Die].ChannelCount * sizeof (CH_DEF_STRUCT)), + StdHeader); + BufferPtr += NBPtr[Die].DctCount * (sizeof (DCT_STRUCT) + NBPtr[Die].ChannelCount * sizeof (CH_DEF_STRUCT)); + LibAmdMemCopy ( NBPtr[Die].PSBlock, + BufferPtr, + NBPtr[Die].DctCount * NBPtr[Die].ChannelCount * sizeof (MEM_PS_BLOCK), + StdHeader); + BufferPtr += NBPtr[Die].DctCount * NBPtr[Die].ChannelCount * sizeof (MEM_PS_BLOCK); + LibAmdMemCopy ( NBPtr[Die].MCTPtr->DctData[0].ChData[0].RcvEnDlys, + BufferPtr, + (NBPtr[Die].DctCount * NBPtr[Die].ChannelCount) * + ((NBPtr[Die].MCTPtr->DctData[0].ChData[0].RowCount * + NBPtr[Die].MCTPtr->DctData[0].ChData[0].ColumnCount * + NUMBER_OF_DELAY_TABLES) + + (MAX_BYTELANES_PER_CHANNEL * MAX_CS_PER_CHANNEL * NUMBER_OF_FAILURE_MASK_TABLES) + + (MAX_DIMMS_PER_CHANNEL * MAX_NUMBER_LANES) + ), + StdHeader); + + HeapDeallocateBuffer (AllocHeapParams.BufferHandle, StdHeader); + + NBPtr[Die].AfterDqsTraining (&(mmPtr->NBPtr[Die])); + TrainInfo[Die].Training = FALSE; + } else { + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_RECEIVED_DATA, NBPtr[Die].Node, 0, 0, 0, StdHeader); + SetMemError (AGESA_FATAL, NBPtr[Die].MCTPtr); + ASSERT(FALSE); // Insufficient Heap Space allocation for parallel training buffer + } + } else if (ApSts == CORE_IDLE) { + // AP does not have buffer to transmit to BSP + // AP fails to locate a buffer for data transfer + TrainInfo[Die].Training = FALSE; + } else { + // Signal to loop through again + StillTraining = TRUE; + } + } + } + // Wait for 1 us + MemUWait10ns (100, NBPtr->MemPtr); + Time ++; + } while ((StillTraining) && ((Time < TimeOut) || !TimeoutEn)); // Continue until all Dies are finished + // if cannot finish in 1 s, do fatal exit + + if (StillTraining && TimeoutEn) { + // Parallel training time out, do fatal exit, as there is at least one AP hangs. + PutEventLog (AGESA_FATAL, MEM_ERROR_PARALLEL_TRAINING_TIME_OUT, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_FATAL, NBPtr[BSP_DIE].MCTPtr); + ASSERT(FALSE); // Timeout occurred while still training + } + + for (Die = 0; Die < mmPtr->DieCount; Die ++ ) { + if (NBPtr[Die].MCTPtr->ErrCode == AGESA_FATAL) { + return FALSE; + } + } + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmStandardTraining.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmStandardTraining.c new file mode 100644 index 0000000000..bb8bccb53a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmStandardTraining.c @@ -0,0 +1,344 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmStandardTraining.c + * + * Main Memory Feature implementation file for Standard Training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "Porting.h" +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "ma.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MMSTANDARDTRAINING_FILECODE +/* features */ +#include "mftds.h" + +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemMStandardTraining ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ); + +BOOLEAN +MemM2DTrainingWithAggressor ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ); + +BOOLEAN +MemMStandardTrainingUsingAdjacentDies ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ); +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ +extern BUILD_OPT_CFG UserOptions; +extern MEM_FEAT_TRAIN_SEQ memTrainSequenceDDR3[]; +/* -----------------------------------------------------------------------------*/ +/** + * + * MemMStandardTraining + * + * This function implements standard memory training whereby training functions + * for all nodes are run by the BSP. + * + * + * @param[in,out] *mmPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMStandardTraining ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ) +{ + UINT8 Die; + // + // If training is disabled, return success. + // + if (!UserOptions.CfgDqsTrainingControl) { + return TRUE; + } + // + // Run Northbridge-specific Standard Training feature for each die. + // + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart serial training\n"); + for (Die = 0 ; Die < mmPtr->DieCount ; Die ++ ) { + IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", Die); + AGESA_TESTPOINT (TpProcMemBeforeAnyTraining, &(mmPtr->MemPtr->StdHeader)); + mmPtr->NBPtr[Die].BeforeDqsTraining (&mmPtr->NBPtr[Die]); + mmPtr->NBPtr[Die].Execute1dMaxRdLatTraining = TRUE; + mmPtr->NBPtr[Die].FeatPtr->Training (&mmPtr->NBPtr[Die]); + mmPtr->NBPtr[Die].TechPtr->TechnologySpecificHook[LrdimmSyncTrainedDlys] (mmPtr->NBPtr[Die].TechPtr, NULL); + mmPtr->NBPtr[Die].AfterDqsTraining (&mmPtr->NBPtr[Die]); + if (mmPtr->NBPtr[Die].MCTPtr->ErrCode == AGESA_FATAL) { + break; + } + } + return (BOOLEAN) (Die == mmPtr->DieCount); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * MemMStandardTrainingUsingAdjacentDies + * + * This function implements standard memory training whereby training functions + * for all nodes are run by the BSP while enabling other dies to eable argressor channel + * + * + * @param[in,out] *mmPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemMStandardTrainingUsingAdjacentDies ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ) +{ + UINT8 Die; + UINT8 AdjacentDie; + UINT32 AdjacentSocketNum; + UINT32 TargetSocketNum; + UINT32 ModuleNum; + UINT8 i; + UINT8 Dct; + UINT8 ChipSel; + BOOLEAN FirstCsFound; + // + // If training is disabled, return success. + // + if (!UserOptions.CfgDqsTrainingControl) { + return TRUE; + } + mmPtr->mmSharedPtr->CommonSmallestMaxNegVref = 0x7F; + mmPtr->mmSharedPtr->CommonSmallestMaxPosVref = 0x7F; + // + // Run Northbridge-specific Standard Training feature for each die. + // + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart standard serial training\n"); + for (Die = 0 ; Die < mmPtr->DieCount ; Die ++ ) { + IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", Die); + AGESA_TESTPOINT (TpProcMemBeforeAnyTraining, &(mmPtr->MemPtr->StdHeader)); + mmPtr->NBPtr[Die].BeforeDqsTraining (&mmPtr->NBPtr[Die]); + mmPtr->NBPtr[Die].Execute1dMaxRdLatTraining = FALSE; + mmPtr->NBPtr[Die].FeatPtr->Training (&mmPtr->NBPtr[Die]); + if (mmPtr->NBPtr[Die].MCTPtr->ErrCode == AGESA_FATAL) { + break; + } + } + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart 2D training with agressors\n"); + for (Die = 0 ; Die < mmPtr->DieCount ; Die ++ ) { + IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", Die); + AGESA_TESTPOINT (TpProcMemBeforeAnyTraining, &(mmPtr->MemPtr->StdHeader)); + GetSocketModuleOfNode (Die, &TargetSocketNum, &ModuleNum, &(mmPtr->MemPtr->StdHeader)); + for (AdjacentDie = 0; AdjacentDie < mmPtr->DieCount; AdjacentDie++) { + mmPtr->NBPtr[Die].DieEnabled[AdjacentDie] = FALSE; + GetSocketModuleOfNode (AdjacentDie, &AdjacentSocketNum, &ModuleNum, &(mmPtr->MemPtr->StdHeader)); + if (TargetSocketNum == AdjacentSocketNum) { + if (AdjacentDie != Die) { + if (mmPtr->NBPtr[AdjacentDie].MCTPtr->NodeMemSize != 0) { + mmPtr->NBPtr[Die].AdjacentDieNBPtr = &mmPtr->NBPtr[AdjacentDie]; + mmPtr->NBPtr[Die].DieEnabled[AdjacentDie] = TRUE; + } + } else { + if (mmPtr->NBPtr[Die].MCTPtr->NodeMemSize != 0) { + mmPtr->NBPtr[Die].DieEnabled[Die] = TRUE; + } + } + // Determine the initial target CS, Max Dimms and max CS number for all DCTs (potential aggressors) + if (mmPtr->NBPtr[AdjacentDie].MCTPtr->NodeMemSize != 0) { + for (Dct = 0; Dct < mmPtr->NBPtr[AdjacentDie].DctCount; Dct++) { + FirstCsFound = FALSE; + mmPtr->NBPtr[AdjacentDie].SwitchDCT (&mmPtr->NBPtr[AdjacentDie], Dct); + for (ChipSel = 0; ChipSel < mmPtr->NBPtr[AdjacentDie].CsPerChannel; ChipSel = ChipSel + (mmPtr->NBPtr[Die].IsSupported[PerDimmAggressors2D] ? 2 : mmPtr->NBPtr[AdjacentDie].CsPerDelay) ) { + if ((mmPtr->NBPtr[AdjacentDie].DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) != 0) { + if (FirstCsFound == FALSE) { + // Set Initial CS value for Current Aggressor CS + mmPtr->NBPtr[AdjacentDie].InitialAggressorCSTarget[Dct] = ChipSel; + mmPtr->NBPtr[AdjacentDie].CurrentAggressorCSTarget[Dct] = mmPtr->NBPtr[AdjacentDie].InitialAggressorCSTarget[Dct]; + FirstCsFound = TRUE; + } + mmPtr->NBPtr[AdjacentDie].MaxAggressorCSEnabled[Dct] = ChipSel; + mmPtr->NBPtr[AdjacentDie].MaxAggressorDimms[Dct]++; + } + } + } + } + } + } + if (mmPtr->NBPtr[Die].MCTPtr->NodeMemSize != 0) { + //Execute Technology specific 2D training features + i = 0; + while (memTrainSequenceDDR3[i].TrainingSequenceEnabled != 0) { + if (memTrainSequenceDDR3[i].TrainingSequenceEnabled (&mmPtr->NBPtr[Die])) { + mmPtr->NBPtr[Die].TrainingSequenceIndex = i; + // Execute 2D RdDqs Training + memTrainSequenceDDR3[i].MemTechFeatBlock->RdDqs2DTraining (mmPtr->NBPtr[Die].TechPtr); + // Execute MaxRdLat Training After 2D training + do { + if (memTrainSequenceDDR3[i].MemTechFeatBlock->MaxRdLatencyTraining (mmPtr->NBPtr[Die].TechPtr)) { + MemFInitTableDrive (&mmPtr->NBPtr[Die], MTAfterMaxRdLatTrn); + } + } while (mmPtr->NBPtr->ChangeNbFrequency (&mmPtr->NBPtr[Die])); + break; + } + i++; + } + } + mmPtr->NBPtr[Die].TechPtr->TechnologySpecificHook[LrdimmSyncTrainedDlys] (mmPtr->NBPtr[Die].TechPtr, NULL); + mmPtr->NBPtr[Die].AfterDqsTraining (&mmPtr->NBPtr[Die]); + if (mmPtr->NBPtr[Die].MCTPtr->ErrCode == AGESA_FATAL) { + break; + } + } + return (BOOLEAN) (Die == mmPtr->DieCount); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * MemM2DTrainingWithAggressor + * + * This function implements standard memory training whereby training functions + * for all nodes are run by the BSP while enabling other dies to eable argressor channel + * + * + * @param[in,out] *mmPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemM2DTrainingWithAggressor ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ) +{ + UINT8 Die; + UINT8 Index; + // + // If training is disabled, return success. + // + if (!UserOptions.CfgDqsTrainingControl) { + return TRUE; + } + mmPtr->mmSharedPtr->CommonSmallestMaxNegVref = 0x7F; + mmPtr->mmSharedPtr->CommonSmallestMaxPosVref = 0x7F; + // + // Run Northbridge-specific Standard Training feature for each die. + // + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart standard serial training\n"); + for (Die = 0 ; Die < mmPtr->DieCount ; Die ++ ) { + IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", Die); + AGESA_TESTPOINT (TpProcMemBeforeAnyTraining, &(mmPtr->MemPtr->StdHeader)); + mmPtr->NBPtr[Die].BeforeDqsTraining (&mmPtr->NBPtr[Die]); + mmPtr->NBPtr[Die].Execute1dMaxRdLatTraining = FALSE; + mmPtr->NBPtr[Die].FeatPtr->Training (&mmPtr->NBPtr[Die]); + if (mmPtr->NBPtr[Die].MCTPtr->ErrCode == AGESA_FATAL) { + break; + } + } + + //---------------------------------------------------------------- + // Determine Aggressor Chipselects for all DCTs on all nodes. + //---------------------------------------------------------------- + MemFeatMain.AggressorDetermination (mmPtr); + + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart 2D training with agressors run independently\n"); + for (Die = 0 ; Die < mmPtr->DieCount ; Die ++ ) { + IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", Die); + AGESA_TESTPOINT (TpProcMemBeforeAnyTraining, &(mmPtr->MemPtr->StdHeader)); + + if (mmPtr->NBPtr[Die].MCTPtr->NodeMemSize != 0) { + //Execute Technology specific 2D training features + Index = 0; + while (memTrainSequenceDDR3[Index].TrainingSequenceEnabled != 0) { + if (memTrainSequenceDDR3[Index].TrainingSequenceEnabled (&mmPtr->NBPtr[Die])) { + mmPtr->NBPtr[Die].TrainingSequenceIndex = Index; + // Execute 2D RdDqs Training + memTrainSequenceDDR3[Index].MemTechFeatBlock->RdDqs2DTraining (mmPtr->NBPtr[Die].TechPtr); + // Execute MaxRdLat Training After 2D training + do { + if (memTrainSequenceDDR3[Index].MemTechFeatBlock->MaxRdLatencyTraining (mmPtr->NBPtr[Die].TechPtr)) { + MemFInitTableDrive (&mmPtr->NBPtr[Die], MTAfterMaxRdLatTrn); + } + } while (mmPtr->NBPtr->ChangeNbFrequency (&mmPtr->NBPtr[Die])); + break; + } + Index++; + } + } + mmPtr->NBPtr[Die].TechPtr->TechnologySpecificHook[LrdimmSyncTrainedDlys] (mmPtr->NBPtr[Die].TechPtr, NULL); + mmPtr->NBPtr[Die].AfterDqsTraining (&mmPtr->NBPtr[Die]); + if (mmPtr->NBPtr[Die].MCTPtr->ErrCode == AGESA_FATAL) { + break; + } + } // End Die For Loop + + return (BOOLEAN) (Die == mmPtr->DieCount); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmUmaAlloc.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmUmaAlloc.c new file mode 100644 index 0000000000..163fecdaec --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmUmaAlloc.c @@ -0,0 +1,262 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmUmaAlloc.c + * + * Main Memory Feature implementation file for UMA allocation. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 86704 $ @e \$Date: 2013-01-24 17:29:29 -0600 (Thu, 24 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "amdlib.h" +#include "heapManager.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "Ids.h" +#include "mport.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MMUMAALLOC_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemMUmaAlloc ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +/*----------------------------------------------------------------------------- +* EXPORTED FUNCTIONS +* +*----------------------------------------------------------------------------- +*/ +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * UMA allocation mechanism. + * + * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK + * + */ +BOOLEAN +MemMUmaAlloc ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ) +{ + UINT32 TOM; + UINT32 TOM2; + UINT32 UmaSize; + UINT32 TopOfChIntlv; + UINT32 DctSelHi; + UINT32 UmaAlignment; + UINT32 UmaAbove4GBase; + UINT32 UmaBelow4GBase; + BOOLEAN DctSelIntLvEn; + BOOLEAN UmaAbove4GEn; + S_UINT64 SMsr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + UMA_INFO *UmaInfoPtr; + UINT8 Node; + + MEM_DATA_STRUCT *MemPtr; + MEM_NB_BLOCK *NBPtr; + MEM_PARAMETER_STRUCT *RefPtr; + + MemPtr = MemMainPtr->MemPtr; + NBPtr = &(MemMainPtr->NBPtr[BSP_DIE]); + RefPtr = NBPtr->RefPtr; + + TOM2 = 0; + SMsr.lo = SMsr.hi = 0; + UmaAbove4GBase = 0; + RefPtr->UmaBase = 0; + UmaAlignment = (UINT32) UserOptions.CfgUmaAlignment; + UmaAbove4GEn = UserOptions.CfgUmaAbove4G; + DctSelIntLvEn = (NBPtr->GetBitField (NBPtr, BFDctSelIntLvEn) != 0) ? TRUE : FALSE; + TopOfChIntlv = NBPtr->GetBitField (NBPtr, BFDctSelBaseAddr) << (27 - 16); + DctSelHi = NBPtr->GetBitField (NBPtr, BFDctSelHi); + + // Allocate heap for UMA_INFO + AllocHeapParams.RequestedBufferSize = sizeof (UMA_INFO); + AllocHeapParams.BufferHandle = AMD_UMA_INFO_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (AGESA_SUCCESS != HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader)) { + ASSERT(FALSE); // Could not allocate heap for Uma information. + return FALSE; + } + UmaInfoPtr = (UMA_INFO *) AllocHeapParams.BufferPtr; + // Default all the fields of UMA_INFO + UmaInfoPtr->UmaMode = (UINT8) UMA_NONE; + UmaInfoPtr->UmaSize = 0; + UmaInfoPtr->UmaBase = 0; + UmaInfoPtr->UmaAttributes = 0; + UmaInfoPtr->MemClock = NBPtr->DCTPtr->Timings.TargetSpeed; + + switch (RefPtr->UmaMode) { + case UMA_NONE: + UmaSize = 0; + break; + case UMA_SPECIFIED: + UmaSize = RefPtr->UmaSize; + break; + case UMA_AUTO: + UmaSize = NBPtr->GetUmaSize (NBPtr); + break; + default: + UmaSize = 0; + IDS_ERROR_TRAP; + } + + if (UmaSize != 0) { + //TOM scaled from [47:0] to [47:16] + LibAmdMsrRead (TOP_MEM, (UINT64 *)&SMsr, &(NBPtr->MemPtr->StdHeader)); + TOM = (SMsr.lo >> 16) | (SMsr.hi << (32 - 16)); + + UmaBelow4GBase = (TOM - UmaSize) & UmaAlignment; + // Initialize Ref->UmaBase to UmaBelow4GBase + RefPtr->UmaBase = UmaBelow4GBase; + + // Uma Above 4G support + if (UmaAbove4GEn) { + //TOM2 scaled from [47:0] to [47:16] + LibAmdMsrRead (TOP_MEM2, (UINT64 *)&SMsr, &(NBPtr->MemPtr->StdHeader)); + TOM2 = (SMsr.lo >> 16) | (SMsr.hi << (32 - 16)); + if (TOM2 != 0) { + UmaAbove4GBase = (TOM2 - UmaSize) & UmaAlignment; + //Set UmaAbove4GBase to 0 if UmaAbove4GBase is below 4GB + if (UmaAbove4GBase < _4GB_RJ16) { + UmaAbove4GBase = 0; + } + if (UmaAbove4GBase != 0) { + RefPtr->UmaBase = UmaAbove4GBase; + // 1. TopOfChIntlv == 0 indicates that whole DCT0 and DCT1 memory are interleaved. + // 2. TopOfChIntlv >= TOM tells us : + // -All or portion of Uma region that above 4G is NOT interleaved. + // -Whole Uma region that below 4G is interleaved. + if (DctSelIntLvEn && (TopOfChIntlv >= TOM)) { + RefPtr->UmaBase = UmaBelow4GBase; + } + } + } + } + + UmaInfoPtr->UmaMode = (UINT8) (RefPtr->UmaMode); + UmaInfoPtr->UmaBase = (UINT64) ((UINT64) RefPtr->UmaBase << 16); + + if (RefPtr->UmaBase >= _4GB_RJ16) { + // UmaSize might be extended if it is 128MB or 256MB .. aligned, so update it. + RefPtr->UmaSize = TOM2 - UmaAbove4GBase; + // Uma Typing + MemNSetMTRRUmaRegionUCNb (NBPtr, &UmaAbove4GBase, &TOM2); + if (DctSelIntLvEn && (TopOfChIntlv == 0)) { + UmaInfoPtr->UmaAttributes = UMA_ATTRIBUTE_INTERLEAVE | UMA_ATTRIBUTE_ON_DCT0 | UMA_ATTRIBUTE_ON_DCT1; + } else { + // Entire UMA region is in the high DCT + UmaInfoPtr->UmaAttributes = (DctSelHi == 0) ? UMA_ATTRIBUTE_ON_DCT0 : UMA_ATTRIBUTE_ON_DCT1; + } + } else { + // UmaSize might be extended if it is 128MB or 256MB .. aligned, so update it. + RefPtr->UmaSize = TOM - UmaBelow4GBase; + // Uma Typing + NBPtr->UMAMemTyping (NBPtr); + if (DctSelIntLvEn && ((TopOfChIntlv == 0) || (TopOfChIntlv >= TOM))) { + UmaInfoPtr->UmaAttributes = UMA_ATTRIBUTE_INTERLEAVE | UMA_ATTRIBUTE_ON_DCT0 | UMA_ATTRIBUTE_ON_DCT1; + } else { + if (UmaBelow4GBase >= TopOfChIntlv) { + // Entire UMA region is in the high DCT + UmaInfoPtr->UmaAttributes = (DctSelHi == 0) ? UMA_ATTRIBUTE_ON_DCT0 : UMA_ATTRIBUTE_ON_DCT1; + } else if (TopOfChIntlv >= TOM) { + // Entire UMA region is in the low DCT + UmaInfoPtr->UmaAttributes = (DctSelHi == 1) ? UMA_ATTRIBUTE_ON_DCT0 : UMA_ATTRIBUTE_ON_DCT1; + } else { + // UMA region is in both DCT0 and DCT1 + UmaInfoPtr->UmaAttributes = UMA_ATTRIBUTE_ON_DCT0 | UMA_ATTRIBUTE_ON_DCT1; + } + } + } + UmaInfoPtr->UmaSize = (RefPtr->UmaSize) << 16; + IDS_HDT_CONSOLE (MEM_FLOW, "UMA is allocated:\n\tBase: %x0000\n\tSize: %x0000\n", RefPtr->UmaBase, RefPtr->UmaSize); + NBPtr->FamilySpecificHook[FixupUmaInfo] (NBPtr, UmaInfoPtr); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "No UMA region is allocated !"); + // Update the results + RefPtr->UmaSize = 0; + RefPtr->UmaBase = 0; + } + + // Wrap UMA with ECC exclusion range so that MCT recognizes the data written by GMC + if (MemMainPtr->mmSharedPtr->AllECC == TRUE) { + MemMDisableScrubber (MemMainPtr); + for (Node = 0; Node < MemMainPtr->DieCount; Node ++) { + NBPtr = &(MemMainPtr->NBPtr[Node]); + NBPtr->MemNSetEccExclusionRange (NBPtr); + } + MemMRestoreScrubber (MemMainPtr); + } + + return TRUE; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmflow.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmflow.c new file mode 100644 index 0000000000..d497aec68d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmflow.c @@ -0,0 +1,406 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmflow.c + * + * Main Memory Flow Entrypoint file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "amdlib.h" +#include "AdvancedApi.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mu.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MMFLOW_FILECODE +/* features */ + +extern MEM_NB_SUPPORT memNBInstalled[]; +extern MEM_TECH_CONSTRUCTOR* memTechInstalled[]; +extern MEM_FEAT_BLOCK_MAIN MemFeatMain; +extern MEM_FLOW_CFG* memFlowControlInstalled[]; + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +VOID +STATIC +MemSPDDataProcess ( + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function is the main memory configuration function for DR DDR3 + * + * Requirements: + * + * Run-Time Requirements: + * 1. Complete Hypertransport Bus Configuration + * 2. AmdMemInitDataStructDef must be run to set default values + * 3. MSR bit to allow access to high PCI regs set on all nodes + * 4. BSP in Big Real Mode + * 5. Stack available + * 6. MCG_CTL=-1, MC4_EN=0 for all CPUs + * 7. MCi_STS from shutdown/warm reset recorded (if desired) prior to entry + * 8. All var MTRRs reset to zero + * 9. State of NB_CFG.DisDatMsk set properly on all CPUs + * + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ +AGESA_STATUS +AmdMemAuto ( + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + MEM_SHARED_DATA mmSharedData; + MEM_MAIN_DATA_BLOCK mmData; + MEM_NB_BLOCK *NBPtr; + MEM_TECH_BLOCK *TechPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + AGESA_STATUS Retval; + UINT8 i; + UINT8 Die; + UINT8 DieCount; + UINT8 Tab; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + ASSERT (MemPtr != NULL); + + AGESA_TESTPOINT (TpProcMemAmdMemAuto, &MemPtr->StdHeader); + IDS_PERF_TIMESTAMP (TP_BEGINPROCAMDMEMAUTO, &MemPtr->StdHeader); + + IDS_HDT_CONSOLE (MEM_FLOW, "MEM PARAMS:\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\tBottomIo : %04x\n", MemPtr->ParameterListPtr->BottomIo); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemHoleRemap : %d\n", MemPtr->ParameterListPtr->MemHoleRemapping); + IDS_HDT_CONSOLE (MEM_FLOW, "\tLimitBelow1TB : %d\n", MemPtr->ParameterListPtr->LimitMemoryToBelow1Tb); + IDS_HDT_CONSOLE (MEM_FLOW, "\tUserTimingMode : %d\n", MemPtr->ParameterListPtr->UserTimingMode); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClockValue : %d\n", MemPtr->ParameterListPtr->MemClockValue); + IDS_HDT_CONSOLE (MEM_FLOW, "\tBankIntlv : %d\n", MemPtr->ParameterListPtr->EnableBankIntlv); + IDS_HDT_CONSOLE (MEM_FLOW, "\tNodeIntlv : %d\n", MemPtr->ParameterListPtr->EnableNodeIntlv); + IDS_HDT_CONSOLE (MEM_FLOW, "\tChannelIntlv : %d\n", MemPtr->ParameterListPtr->EnableChannelIntlv); + IDS_HDT_CONSOLE (MEM_FLOW, "\tEccFeature : %d\n", MemPtr->ParameterListPtr->EnableEccFeature); + IDS_HDT_CONSOLE (MEM_FLOW, "\tPowerDown : %d\n", MemPtr->ParameterListPtr->EnablePowerDown); + IDS_HDT_CONSOLE (MEM_FLOW, "\tOnLineSpare : %d\n", MemPtr->ParameterListPtr->EnableOnLineSpareCtl); + IDS_HDT_CONSOLE (MEM_FLOW, "\tParity : %d\n", MemPtr->ParameterListPtr->EnableParity); + IDS_HDT_CONSOLE (MEM_FLOW, "\tBankSwizzle : %d\n", MemPtr->ParameterListPtr->EnableBankSwizzle); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClr : %d\n", MemPtr->ParameterListPtr->EnableMemClr); + IDS_HDT_CONSOLE (MEM_FLOW, "\tUmaMode : %d\n", MemPtr->ParameterListPtr->UmaMode); + IDS_HDT_CONSOLE (MEM_FLOW, "\tUmaSize : %d\n", MemPtr->ParameterListPtr->UmaSize); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemRestoreCtl : %d\n", MemPtr->ParameterListPtr->MemRestoreCtl); + IDS_HDT_CONSOLE (MEM_FLOW, "\tSaveMemContextCtl : %d\n", MemPtr->ParameterListPtr->SaveMemContextCtl); + IDS_HDT_CONSOLE (MEM_FLOW, "\tExternalVrefCtl : %d\n", MemPtr->ParameterListPtr->ExternalVrefCtl ); + IDS_HDT_CONSOLE (MEM_FLOW, "\tForceTrainMode : %d\n", MemPtr->ParameterListPtr->ForceTrainMode ); + IDS_HDT_CONSOLE (MEM_FLOW, "\tAMP : %d\n\n", MemPtr->ParameterListPtr->AmpEnable); + + //---------------------------------------------------------------------------- + // Get TSC rate, which will be used later in Wait10ns routine + //---------------------------------------------------------------------------- + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &MemPtr->StdHeader); + FamilySpecificServices->GetTscRate (FamilySpecificServices, &MemPtr->TscRate, &MemPtr->StdHeader); + + //---------------------------------------------------------------------------- + // Read In SPD Data + //---------------------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemBeforeSpdProcessing, &MemPtr->StdHeader); + MemSPDDataProcess (MemPtr); + + //---------------------------------------------------------------- + // Initialize Main Data Block + //---------------------------------------------------------------- + mmData.MemPtr = MemPtr; + mmData.mmSharedPtr = &mmSharedData; + LibAmdMemFill (&mmSharedData, 0, sizeof (mmSharedData), &MemPtr->StdHeader); + mmSharedData.DimmExcludeFlag = NORMAL; + mmSharedData.NodeIntlv.IsValid = FALSE; + //---------------------------------------------------------------- + // Discover populated CPUs + // + //---------------------------------------------------------------- + Retval = MemSocketScan (&mmData); + if (Retval == AGESA_FATAL) { + return Retval; + } + DieCount = mmData.DieCount; + //---------------------------------------------------------------- + // + // Allocate Memory for NB and Tech Blocks + // + // NBPtr[Die]----+ + // | + // V + // +---+---+---+---+---+---+---+---+ + // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | NB Blocks + // +---+---+---+---+---+---+---+---+ + // | | | | | | | | + // | | | | | | | | + // v v v v v v v v + // +---+---+---+---+---+---+---+---+ + // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | Tech Blocks + // +---+---+---+---+---+---+---+---+ + // + // + //---------------------------------------------------------------- + AllocHeapParams.RequestedBufferSize = (DieCount * (sizeof (MEM_NB_BLOCK) + sizeof (MEM_TECH_BLOCK))); + AllocHeapParams.BufferHandle = AMD_MEM_AUTO_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (AGESA_SUCCESS != HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader)) { + ASSERT(FALSE); // NB and Tech Block Heap allocate error + return AGESA_FATAL; + } + NBPtr = (MEM_NB_BLOCK *)AllocHeapParams.BufferPtr; + TechPtr = (MEM_TECH_BLOCK *) (&NBPtr[DieCount]); + mmData.NBPtr = NBPtr; + mmData.TechPtr = TechPtr; + + //---------------------------------------------------------------- + // Create NB Blocks + // + //---------------------------------------------------------------- + for (Die = 0 ; Die < DieCount ; Die++ ) { + i = 0; + while (memNBInstalled[i].MemConstructNBBlock != 0) { + if (memNBInstalled[i].MemConstructNBBlock (&NBPtr[Die], MemPtr, memNBInstalled[i].MemFeatBlock, &mmSharedData, Die) == TRUE) { + break; + } + i++; + } + // Couldn't find a NB which supported this family + if (memNBInstalled[i].MemConstructNBBlock == 0) { + return AGESA_FATAL; + } + } + //---------------------------------------------------------------- + // Create Technology Blocks + // + //---------------------------------------------------------------- + for (Die = 0 ; Die < DieCount ; Die++ ) { + i = 0; + while (memTechInstalled[i] != NULL) { + if (memTechInstalled[i] (&TechPtr[Die], &NBPtr[Die])) { + NBPtr[Die].TechPtr = &TechPtr[Die]; + break; + } + i++; + } + // Couldn't find a Tech block which supported this family + if (memTechInstalled[i] == NULL) { + return AGESA_FATAL; + } + } + + //---------------------------------------------------------------- + // AMP initialization + // + //---------------------------------------------------------------- + for (Die = 0 ; Die < DieCount ; Die++ ) { + NBPtr[Die].FeatPtr->InitAMP (&NBPtr[Die]); + } + + //---------------------------------------------------------------- + // + // MEMORY INITIALIZATION TASKS + // + //---------------------------------------------------------------- + i = 0; + while (memFlowControlInstalled[i] != NULL) { + Retval = memFlowControlInstalled[i] (&mmData); + if (MemPtr->IsFlowControlSupported == TRUE) { + break; + } + i++; + } + + //---------------------------------------------------------------- + // Deallocate NB register tables + //---------------------------------------------------------------- + for (Tab = 0; Tab < NumberOfNbRegTables; Tab++) { + HeapDeallocateBuffer (GENERATE_MEM_HANDLE (ALLOC_NB_REG_TABLE, Tab, 0, 0), &MemPtr->StdHeader); + } + + //---------------------------------------------------------------- + // Check for errors and return + //---------------------------------------------------------------- + AGESA_TESTPOINT (TpProcMemEnd, &MemPtr->StdHeader); + IDS_PERF_TIMESTAMP (TP_ENDPROCAMDMEMAUTO, &MemPtr->StdHeader); + for (Die = 0; Die < DieCount; Die++) { + if (NBPtr[Die].MCTPtr->ErrCode > Retval) { + Retval = NBPtr[Die].MCTPtr->ErrCode; + } + } + return Retval; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function fills a default SPD buffer with SPD values for all DIMMs installed in the system + * + * The SPD Buffer is populated with a Socket-Channel-Dimm centric view of the Dimms. At this + * point, the Memory controller type is not known, and the platform BIOS does not know the anything + * about which DIMM is on which DCT. So the DCT relationship is abstracted from the arrangement + * of SPD information here. We use the utility functions GetSpdSocketIndex(), GetMaxChannelsPerSocket(), + * and GetMaxDimmsPerChannel() to Map the SPD data according to which Socket-relative channel the DIMMs + * are connected to. The functions rely on either the maximum values in the + * PlatformSpecificOverridingTable or if unspecified, the absolute maximums in AGESA.H. + * + * This mapping is translated in the Northbridge object Constructor and the Technology block constructor. + * + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * + */ + +VOID +STATIC +MemSPDDataProcess ( + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + UINT8 Socket; + UINT8 Channel; + UINT8 Dimm; + UINT8 DimmIndex; + UINT32 AgesaStatus; + UINT8 MaxSockets; + UINT8 MaxChannelsPerSocket; + UINT8 MaxDimmsPerChannel; + SPD_DEF_STRUCT *DimmSPDPtr; + PSO_TABLE *PsoTable; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + AGESA_READ_SPD_PARAMS SpdParam; + + ASSERT (MemPtr != NULL); + MaxSockets = (UINT8) (0x000000FF & GetPlatformNumberOfSockets ()); + PsoTable = MemPtr->ParameterListPtr->PlatformMemoryConfiguration; + // + // Allocate heap for the table + // + AllocHeapParams.RequestedBufferSize = (GetSpdSocketIndex (PsoTable, MaxSockets, &MemPtr->StdHeader) * sizeof (SPD_DEF_STRUCT)); + AllocHeapParams.BufferHandle = AMD_MEM_SPD_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) == AGESA_SUCCESS) { + MemPtr->SpdDataStructure = (SPD_DEF_STRUCT *) AllocHeapParams.BufferPtr; + // + // Initialize SpdParam Structure + // + LibAmdMemCopy ((VOID *)&SpdParam, (VOID *)MemPtr, (UINTN)sizeof (SpdParam.StdHeader), &MemPtr->StdHeader); + // + // Populate SPDDataBuffer + // + SpdParam.MemData = MemPtr; + DimmIndex = 0; + for (Socket = 0; Socket < (UINT16)MaxSockets; Socket++) { + MaxChannelsPerSocket = GetMaxChannelsPerSocket (PsoTable, Socket, &MemPtr->StdHeader); + SpdParam.SocketId = Socket; + for (Channel = 0; Channel < MaxChannelsPerSocket; Channel++) { + SpdParam.MemChannelId = Channel; + MaxDimmsPerChannel = GetMaxDimmsPerChannel (PsoTable, Socket, Channel); + for (Dimm = 0; Dimm < MaxDimmsPerChannel; Dimm++) { + SpdParam.DimmId = Dimm; + DimmSPDPtr = &(MemPtr->SpdDataStructure[DimmIndex++]); + SpdParam.Buffer = DimmSPDPtr->Data; + AGESA_TESTPOINT (TpProcMemBeforeAgesaReadSpd, &MemPtr->StdHeader); + AgesaStatus = AgesaReadSpd (0, &SpdParam); + AGESA_TESTPOINT (TpProcMemAfterAgesaReadSpd, &MemPtr->StdHeader); + if (AgesaStatus == AGESA_SUCCESS) { + DimmSPDPtr->DimmPresent = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, "SPD Socket %d Channel %d Dimm %d: %08x\n", Socket, Channel, Dimm, SpdParam.Buffer); + } else { + DimmSPDPtr->DimmPresent = FALSE; + } + } + } + } + } else { + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_SPD, 0, 0, 0, 0, &MemPtr->StdHeader); + // + // Assert here if unable to allocate heap for SPDs + // + IDS_ERROR_TRAP; + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmlvddr3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmlvddr3.h new file mode 100644 index 0000000000..bbbf5f6ed5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mmlvddr3.h @@ -0,0 +1,80 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmLvDdr3.h + * + * Main low voltage DDR3 support common header + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MMLVDDR3_H_ +#define _MMLVDDR3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemMLvDdr3PerformanceEnhPre ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +BOOLEAN +MemMLvDdr3PerformanceEnhFinalize ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); +#endif /* _MMLVDDR3_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.asm b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.asm new file mode 100644 index 0000000000..8f14379b42 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.asm @@ -0,0 +1,496 @@ +;***************************************************************************** +; AMD Generic Encapsulated Software Architecture +; +; $Workfile:: mu.asm $ $Revision:: 841#$ $Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ +; Description: Main memory controller system configuration for AGESA +; +; +;***************************************************************************** +; + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** +;============================================================================ + + + .XLIST + .LIST + + .686p + .MODEL FLAT + .CODE + ASSUME FS: NOTHING + +; Define the calling convention used for the C library modules +;@attention - This should be in a central include file +CALLCONV EQU NEAR C + + +;=============================================================================== +;memUOutPort: +; +; Do a 32 Bit IO Out operation using edx. +; NOTE: This function will be obsolete in the future. +; +; In: Port - port number +; Value - value to be written +; +; Out: +; +; All registers preserved. +;=============================================================================== +MemUOutPort PROC CALLCONV PUBLIC Port:DWORD, Value:DWORD + pushad + mov edx,Port + mov eax,Value + out dx,al + popad + ret +MemUOutPort ENDP + + +;---------------------------------------------------------------------------- +; _SFENCE(); +; +_SFENCE macro + db 0Fh,0AEh,0F8h + endm + +;---------------------------------------------------------------------------- +; _MFENCE(); +; +_MFENCE macro + db 0Fh,0AEh,0F0h + endm + +;---------------------------------------------------------------------------- +; _EXECFENCE(); +; +_EXECFENCE macro + out 0EDh,al ;prevent speculative execution of following instructions + endm + +;=============================================================================== +;MemUWriteCachelines: +; Write a test pattern to DRAM +; +; In: Pattern - pointer to the write pattern +; Address - Physical address to be read +; ClCount - number of cachelines to be read +; Out: +; +;All registers preserved. +;=============================================================================== +MemUWriteCachelines PROC CALLCONV PUBLIC Address:DWORD, Pattern:NEAR PTR DWORD, ClCount:WORD + pushad + push ds + + mov eax,Address + push ss + pop ds + xor edx,edx + mov edx, DWORD PTR Pattern + mov esi,edx + mov edx,16 + _EXECFENCE + xor ecx, ecx + mov cx,ClCount + shl ecx,2 + @@: + db 66h, 0Fh,6Fh,06 ;MOVDQA xmm0,[esi] + db 64h, 66h, 0Fh,0E7h,00 ;MOVNTDQ fs:[eax],xmm0 (xmm0 is 128 bits) + add eax,edx + add esi,edx + loop @B + + pop ds + popad + ret +MemUWriteCachelines ENDP + +;=============================================================================== +;MemUReadCachelines: +; +; Read a pattern of 72 bit times (per DQ), to test dram functionality. The +;pattern is a stress pattern which exercises both ISI and crosstalk. The number +;of cache lines to fill is dependent on DCT width mode and burstlength. +; +; In: Buffer - pointer to a buffer where read data will be stored +; Address - Physical address to be read +; ClCount - number of cachelines to be read +; Out: +; +;All registers preserved. +;=============================================================================== +MemUReadCachelines PROC CALLCONV PUBLIC Buffer:NEAR PTR DWORD, Address:DWORD, ClCount:WORD +LOCAL Count:BYTE + pushad + ; First, issue continuous dummy reads to fill up the cache + mov eax,Address + .if (ClCount > 18) + mov cx,ClCount + shr cx,4 + mov Count,cl + .while (Count != 0) + push eax + mov edi,eax + add edi,128 ;bias value (to account for signed displacement) + ;clflush opcode=0F AE /7 + mov esi,edi + mov ebx,esi + mov ecx,esi + mov edx,esi + add edi,4*64 ;TestAddr+4 cache lines + add ebx,8*64 ;TestAddr+8 cache lines + add ecx,12*64 ;TestAddr+12 cache lines + add edx,16*64 ;TestAddr+16 cache lines + sub edx,128 + _EXECFENCE + mov eax,fs:[esi-128] ;TestAddr + _MFENCE + mov eax,fs:[esi-64] ;TestAddr+1 cache line + _MFENCE + mov eax,fs:[esi] ;TestAddr+2 cache lines + _MFENCE + mov eax,fs:[esi+64] ;TestAddr+3 cache lines + _MFENCE + mov eax,fs:[edi-128] ;TestAddr+4 cache lines + _MFENCE + mov eax,fs:[edi-64] ;TestAddr+5 cache lines + _MFENCE + mov eax,fs:[edi] ;TestAddr+6 cache lines + _MFENCE + mov eax,fs:[edi+64] ;TestAddr+7 cache lines + _MFENCE + mov eax,fs:[ebx-128] ;TestAddr+8 cache lines + _MFENCE + mov eax,fs:[ebx-64] ;TestAddr+9 cache lines + _MFENCE + mov eax,fs:[ebx] ;TestAddr+10 cache lines + _MFENCE + mov eax,fs:[ebx+64] ;TestAddr+11 cache lines + _MFENCE + mov eax,fs:[ecx-128] ;TestAddr+12 cache lines + _MFENCE + mov eax,fs:[ecx-64] ;TestAddr+13 cache lines + _MFENCE + mov eax,fs:[ecx] ;TestAddr+14 cache lines + _MFENCE + mov eax,fs:[ecx+64] ;TestAddr+15 cache lines + _MFENCE + pop eax + add eax,(16*64) ;Next 16CL + dec Count + .endw + .else + mov edi,eax + add edi,128 ;bias value (to account for signed displacement) + ;clflush opcode=0F AE /7 + mov esi,edi + mov ebx,esi + mov ecx,esi + mov edx,esi + add edi,4*64 ;TestAddr+4 cache lines + add ebx,8*64 ;TestAddr+8 cache lines + add ecx,12*64 ;TestAddr+12 cache lines + add edx,16*64 ;TestAddr+16 cache lines + sub edx,128 + .if(ClCount == 1) + _MFENCE + mov eax,fs:[esi-128] ;TestAddr + _MFENCE + .elseif(ClCount == 3) + _EXECFENCE + mov eax,fs:[esi-128] ;TestAddr + _MFENCE + mov eax,fs:[esi-64] ;TestAddr+1 cache line + _MFENCE + mov eax,fs:[esi] ;TestAddr+2 cache lines + _MFENCE + .elseif(ClCount == 6) + _EXECFENCE + mov eax,fs:[esi-128] ;TestAddr + _MFENCE + mov eax,fs:[esi-64] ;TestAddr+1 cache line + _MFENCE + mov eax,fs:[esi] ;TestAddr+2 cache lines + _MFENCE + mov eax,fs:[esi+64] ;TestAddr+3 cache lines + _MFENCE + mov eax,fs:[edi-128] ;TestAddr+4 cache lines + _MFENCE + mov eax,fs:[edi-64] ;TestAddr+5 cache lines + _MFENCE + .elseif(ClCount == 9) + _EXECFENCE + mov eax,fs:[esi-128] ;TestAddr + _MFENCE + mov eax,fs:[esi-64] ;TestAddr+1 cache line + _MFENCE + mov eax,fs:[esi] ;TestAddr+2 cache lines + _MFENCE + mov eax,fs:[esi+64] ;TestAddr+3 cache lines + _MFENCE + mov eax,fs:[edi-128] ;TestAddr+4 cache lines + _MFENCE + mov eax,fs:[edi-64] ;TestAddr+5 cache lines + _MFENCE + mov eax,fs:[edi] ;TestAddr+6 cache lines + _MFENCE + mov eax,fs:[edi+64] ;TestAddr+7 cache lines + _MFENCE + mov eax,fs:[ebx-128] ;TestAddr+8 cache lines + _MFENCE + .elseif(ClCount == 18) + _EXECFENCE + mov eax,fs:[esi-128] ;TestAddr + _MFENCE + mov eax,fs:[esi-64] ;TestAddr+1 cache line + _MFENCE + mov eax,fs:[esi] ;TestAddr+2 cache lines + _MFENCE + mov eax,fs:[esi+64] ;TestAddr+3 cache lines + _MFENCE + mov eax,fs:[edi-128] ;TestAddr+4 cache lines + _MFENCE + mov eax,fs:[edi-64] ;TestAddr+5 cache lines + _MFENCE + mov eax,fs:[edi] ;TestAddr+6 cache lines + _MFENCE + mov eax,fs:[edi+64] ;TestAddr+7 cache lines + _MFENCE + mov eax,fs:[ebx-128] ;TestAddr+8 cache lines + _MFENCE + mov eax,fs:[ebx-64] ;TestAddr+9 cache lines + _MFENCE + mov eax,fs:[ebx] ;TestAddr+10 cache lines + _MFENCE + mov eax,fs:[ebx+64] ;TestAddr+11 cache lines + _MFENCE + mov eax,fs:[ecx-128] ;TestAddr+12 cache lines + _MFENCE + mov eax,fs:[ecx-64] ;TestAddr+13 cache lines + _MFENCE + mov eax,fs:[ecx] ;TestAddr+14 cache lines + _MFENCE + mov eax,fs:[ecx+64] ;TestAddr+15 cache lines + _MFENCE + mov eax,fs:[edx] ;TestAddr+16 cache lines + _MFENCE + mov eax,fs:[edx+64] ;TestAddr+17 cache lines + _MFENCE + .endif + .endif + _MFENCE + + ; Then, copy data to buffer + mov esi,Address + xor edx,edx + mov edx,DWORD PTR Buffer + mov edi,edx + xor ecx, ecx + mov cx,ClCount + shl ecx,6 + @@: + mov al,fs:[esi] + mov ss:[edi],al + inc esi + inc edi + loop @B + + popad + ret +MemUReadCachelines ENDP + +;=============================================================================== +;MemUDummyCLRead: +; +; Perform a single cache line read from a given physical address. +; +; In: Address - Physical address to be read +; ClCount - number of cachelines to be read +; Out: +; +;All registers preserved. +;=============================================================================== +MemUDummyCLRead PROC CALLCONV PUBLIC Address:DWORD + _SFENCE + pushad + mov eax,Address + mov dl,fs:[eax] + popad + ret +MemUDummyCLRead ENDP + +;=============================================================================== +;MemUFlushPattern: +; +; Flush a pattern of 72 bit times (per DQ) from cache. This procedure is used +;to ensure cache miss on the next read training. +; +; In: Address - Physical address to be flushed +; ClCount - number of cachelines to be flushed +; Out: +; +;All registers preserved. +;=============================================================================== +MemUFlushPattern PROC CALLCONV PUBLIC Address:DWORD, ClCount:WORD + pushad + mov edi,Address + movzx ecx,ClCount + @@: + _MFENCE ; Force strong ordering of clflush + db 64h,0Fh,0AEh,3Fh ; MemUClFlush fs:[edi] + _MFENCE + add edi,64 + loop @B + popad + ret +MemUFlushPattern ENDP + + +;=============================================================================== +;MemUGetWrLvNblErr: +; Read ClCount number of cachelines then return the bitmap that indicates +; the write leveling result of each byte lane. +; +; IN: ErrBitmap - pointer to a DWORD that will be assigned with WL result +; Address - Physical address to be sampled +; ClCount - number of cachelines to be read +; +; OUT: ErrBitmap - WL result +; +;All registers preserved +;=============================================================================== +MemUGetWrLvNblErr PROC CALLCONV PUBLIC ErrBitmap:NEAR PTR DWORD, Address:DWORD, ClCount:WORD +LOCAL ZeroCount[32]:WORD + + pushad + mov esi,Address + _EXECFENCE + ;Cache fill + movzx ecx,ClCount + @@: + mov eax,fs:[esi] + add esi,64 + loop @B + _MFENCE + + ; Then, count the number of 0's + ;push es + ;push ss + ;pop es + lea edi,ZeroCount + mov cx,SIZEOF ZeroCount + mov al,0 + rep stosb + ;pop es + + mov esi,Address + lea edi,ZeroCount + mov cx,ClCount + shl cx,6 + .while(cx > 0) + mov al,fs:[esi] + test al,00Fh ;check lower nibble + .if(ZERO?) + inc WORD PTR [edi] + .endif + add edi,2 + test al,0F0h ;check upper nibble + .if(ZERO?) + inc WORD PTR [edi] + .endif + add edi,2 + inc esi + dec cx + test cx,07h + .if(ZERO?) + sub edi,(16*2) + sub cx,8 + add esi,8 + .endif + .endw + + ; Then, average and compress data to error bits + lea esi,ZeroCount + mov dx,ClCount + shl dx,1 + xor eax,eax + xor ecx,ecx + mov cl,0 + .while(cl<16) + .if(WORD PTR [esi] < dx) + bts eax,ecx + .endif + add esi,2 + inc cl + .endw + xor edx,edx + mov dx,WORD PTR ErrBitmap + mov [edx], ax + + popad + ret +MemUGetWrLvNblErr ENDP + +;=============================================================================== +;AlignPointerTo16Byte: +; Modifies BufferPtr to be 16 byte aligned +; +; In: BufferPtrPtr - Pointer to buffer pointer +; Out: BufferPtrPtr - Pointer to buffer pointer that has been 16 byte aligned +; +;All registers preserved. +;=============================================================================== +AlignPointerTo16Byte PROC CALLCONV PUBLIC BufferPtrPtr:NEAR PTR DWORD + push edx + push eax + mov edx, BufferPtrPtr + mov eax, [edx] + add eax, 16 + and ax, 0FFF0h + mov [edx], eax + pop eax + pop edx + ret +AlignPointerTo16Byte ENDP + +;=============================================================================== +;MemUMFenceInstr: +; Serialize instruction +; +; In: +; Out: +; +;All registers preserved. +;=============================================================================== +MemUMFenceInstr PROC CALLCONV PUBLIC + _MFENCE + ret +MemUMFenceInstr ENDP + + END + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.c new file mode 100644 index 0000000000..a4e5716fad --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/mu.c @@ -0,0 +1,250 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * HyperTransport features and sequence implementation. + * + * Implements the external AmdHtInitialize entry point. + * Contains routines for directing the sequence of available features. + * Mostly, but not exclusively, AGESA_TESTPOINT invocations should be + * contained in this file, and not in the feature code. + * + * From a build option perspective, it may be that a few lines could be removed + * from compilation in this file for certain options. It is considered that + * the code savings from this are too small to be of concern and this file + * should not have any explicit build option implementation. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: HyperTransport + * @e \$Revision: 35978 $ @e \$Date: 2010-08-07 02:18:50 +0800 (Sat, 07 Aug 2010) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2011, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * *************************************************************************** + * + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Filecode.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +MemUWriteCachelines ( + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ); + +VOID +MemUReadCachelines ( + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ); + +VOID +MemUDummyCLRead ( + IN UINT32 Address + ); + +VOID +MemUMFenceInstr ( + VOID + ); + +VOID +MemUFlushPattern ( + IN UINT32 Address, + IN UINT16 ClCount + ); + +VOID +AlignPointerTo16Byte ( + IN OUT UINT8 **BufferPtrPtr + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +//---------------------------------------------------------------------------- + +VOID +MemUWriteCachelines ( + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ) +{ + UINTN Index; + CHAR8 *Position; + __m128i *Src = (void *) Pattern; + __m128i *Dest = (void *) (size_t)Address; + + Position = (void *) Pattern; + + // ssd - important: without this, the src data may get evicted from cache + _mm_mfence (); + + for (Index = 0; Index < ClCount * 4; Index++){ + _mm_stream_si128_fs (Dest, Src); + Src++; + Dest++; + } + + // ssd - might not be required, but no measurable boot time impact + _mm_mfence (); +} + +//---------------------------------------------------------------------------- +// MemUReadCachelines: +// +// Read a pattern of 72 bit times (per DQ), to test dram functionality. The +// pattern is a stress pattern which exercises both ISI and crosstalk. The number +// of cache lines to fill is dependent on DCT width mode and burstlength. +// +// In: Buffer - pointer to a buffer where read data will be stored +// Address - Physical address to be read +// ClCount - number of cachelines to be read + +VOID +MemUReadCachelines ( + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ) +{ + UINTN Index; + UINT32 *Dest; + + for (Index = 0; Index < ClCount * 16; Index++) { + Dest = (void *) &Buffer [Index * 4]; + *Dest = __readfsdword (Address + Index * 4); + _mm_mfence (); + } +} + +//---------------------------------------------------------------------------- +// MemUDummyCLRead: +// +// Perform a single cache line read from a given physical address. +// +// In: Address - Physical address to be read +// ClCount - number of cachelines to be read + +//FUNC_ATTRIBUTE (noinline) +VOID +MemUDummyCLRead ( + IN UINT32 Address + ) +{ + _mm_sfence (); + __readfsbyte (Address); +} + +//---------------------------------------------------------------------------- + +VOID +MemUMFenceInstr ( + VOID + ) +{ + _mm_mfence (); +} + +//---------------------------------------------------------------------------- +// MemUFlushPattern: +// +// Flush a pattern of 72 bit times (per DQ) from cache. This procedure is used +// to ensure cache miss on the next read training. +// +// In: Address - Physical address to be flushed +// ClCount - number of cachelines to be flushed +//FUNC_ATTRIBUTE(noinline) +VOID +MemUFlushPattern ( + IN UINT32 Address, + IN UINT16 ClCount + ) +{ + UINTN Index; + + // ssd - theory: a tlb flush is needed to avoid problems with clflush + __writemsr (0x20F, __readmsr (0x20F)); + + for (Index = 0; Index < ClCount; Index++) { + // mfence prevents speculative execution of the clflush + _mm_mfence (); + _mm_clflush_fs ((void *) (size_t) (Address + Index * 64)); + } +} + +//---------------------------------------------------------------------------- + +//FUNC_ATTRIBUTE(noinline) +VOID +AlignPointerTo16Byte ( + IN OUT UINT8 **BufferPtrPtr + ) +{ + size_t Address = (size_t) *BufferPtrPtr; + Address += 15; + Address -= Address % 16; + *BufferPtrPtr = (void *) Address; +} + +//---------------------------------------------------------------------------- diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/muc.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/muc.c new file mode 100644 index 0000000000..8d8177325e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/muc.c @@ -0,0 +1,760 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * muc.c + * + * Utility functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Main) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "cpuServices.h" +#include "amdlib.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "Ids.h" +#include "mport.h" +#include "mu.h" +#include "cpuFamilyTranslation.h" +#include "cpuCacheInit.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_MAIN_MUC_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +CONST UINT32 Pattern2[16] = { + 0x12345678, 0x87654321, 0x23456789, 0x98765432, + 0x59385824, 0x30496724, 0x24490795, 0x99938733, + 0x40385642, 0x38465245, 0x29432163, 0x05067894, + 0x12349045, 0x98723467, 0x12387634, 0x34587623 +}; + +CONST UINT32 MaxLatPat[48] = { + 0x6E0E3FAC, 0x0C3CFF52, + 0x4A688181, 0x49C5B613, + 0x7C780BA6, 0x5C1650E3, + 0x0C4F9D76, 0x0C6753E6, + 0x205535A5, 0xBABFB6CA, + 0x610E6E5F, 0x0C5F1C87, + 0x488493CE, 0x14C9C383, + 0xF5B9A5CD, 0x9CE8F615, + + 0xAAD714B5, 0xC38F1B4C, + 0x72ED647C, 0x669F7562, + 0x5233F802, 0x4A898B30, + 0x10A40617, 0x3326B465, + 0x55386E04, 0xC807E3D3, + 0xAB49E193, 0x14B4E63A, + 0x67DF2495, 0xEA517C45, + 0x7624CE51, 0xF8140C51, + + 0x4824BD23, 0xB61DD0C9, + 0x072BCFBE, 0xE8F3807D, + 0x919EA373, 0x25E30C47, + 0xFEB12958, 0x4DA80A5A, + 0xE9A0DDF8, 0x792B0076, + 0xE81C73DC, 0xF025B496, + 0x1DB7E627, 0x808594FE, + 0x82668268, 0x655C7783 +}; + +CONST UINT8 PatternJD[9] = {0x44, 0xA6, 0x38, 0x4F, 0x4B, 0x2E, 0xEF, 0xD5, 0x54}; + +CONST UINT8 PatternJD_256[256] = { + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xF7, 0x08, 0xF7, 0x00, 0xFF, + 0x00, 0xF7, 0x00, 0xFF, 0x00, 0xF7, 0x00, 0xF7, + 0x08, 0xF7, 0x08, 0xFF, 0x00, 0xFF, 0x08, 0xFF, + 0x00, 0xFF, 0x08, 0xFF, 0x08, 0xF7, 0xFB, 0x04, + 0xFB, 0xFB, 0x04, 0xFB, 0xFB, 0xFB, 0x04, 0xFB, + 0xFB, 0xFB, 0xFB, 0x04, 0xFB, 0x04, 0x04, 0xFB, + 0x04, 0x04, 0x04, 0xFB, 0x04, 0x04, 0x04, 0x04, + 0xFB, 0x7F, 0x80, 0x7F, 0x00, 0xFF, 0x00, 0x7F, + 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x7F, 0x80, 0x7F, + 0x80, 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0x00, 0xFF, + 0x80, 0xFF, 0x80, 0x7F, 0xBF, 0x40, 0xBF, 0xBF, + 0x40, 0xBF, 0xBF, 0xBF, 0x40, 0xBF, 0xBF, 0xBF, + 0xBF, 0x40, 0xBF, 0x40, 0x40, 0xBF, 0x40, 0x40, + 0x40, 0xBF, 0x40, 0x40, 0x40, 0x40, 0xBF, 0xFD, + 0x02, 0xFD, 0x00, 0xFF, 0x00, 0xFD, 0x00, 0xFF, + 0x00, 0xFD, 0x00, 0xFD, 0x02, 0xFD, 0x02, 0xFF, + 0x00, 0xFF, 0x02, 0xFF, 0x00, 0xFF, 0x02, 0xFF, + 0x02, 0xFD, 0xFE, 0x01, 0xFE, 0xFE, 0x01, 0xFE, + 0xFE, 0xFE, 0x01, 0xFE, 0xFE, 0xFE, 0xFE, 0x01, + 0xFE, 0x01, 0x01, 0xFE, 0x01, 0x01, 0x01, 0xFE, + 0x01, 0x01, 0x01, 0x01, 0xFE, 0xDF, 0x20, 0xDF, + 0x00, 0xFF, 0x00, 0xDF, 0x00, 0xFF, 0x00, 0xDF, + 0x00, 0xDF, 0x20, 0xDF, 0x20, 0xFF, 0x00, 0xFF, + 0x20, 0xFF, 0x00, 0xFF, 0x20, 0xFF, 0x20, 0xDF, + 0xEF, 0x10, 0xEF, 0xEF, 0x10, 0xEF, 0xEF, 0xEF, + 0x10, 0xEF, 0xEF, 0xEF, 0xEF, 0x10, 0xEF, 0x10, + 0x10, 0xEF, 0x10, 0x10, 0x10, 0xEF, 0x10, 0x10, + 0x10, 0x10, 0xEF, 0xF7, 0x00, 0xFF, 0x04, 0x7F, + 0x00, 0xFF, 0x40, 0xFD, 0x00, 0xFF, 0x01, 0xDF +}; + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns the (index)th UINT8 + * from an indicated test pattern. + * + * @param[in] Pattern - encoding of test pattern type + * @param[in] Buffer[] - buffer to be filled + * @param[in] Size - Size of the buffer + * + * ---------------------------------------------------------------------------- + */ + +VOID +MemUFillTrainPattern ( + IN TRAIN_PATTERN Pattern, + IN UINT8 Buffer[], + IN UINT16 Size + ) +{ + UINT8 Result; + UINT8 i; + UINT8 Mask; + UINT16 Index; + UINT16 k; + + for (Index = 0; Index < Size; Index++) { + k = Index; + // get one byte from Pattern + switch (Pattern) { + case TestPattern0: + Result = 0xAA; + break; + case TestPattern1: + Result = 0x55; + break; + case TestPattern2: + ASSERT (Index < sizeof (Pattern2)); + Result = ((UINT8 *)Pattern2)[Index]; + break; + case TestPatternML: + if (Size != 6 * 64) { + Result = ((UINT8 *)MaxLatPat)[Index]; + } else { + Result = ((UINT8 *)MaxLatPat)[Index & 0xF7]; + } + break; + case TestPatternJD256B: + k >>= 1; + // break is not being used here because TestPatternJD256B also need + // to run TestPatternJD256A sequence. + case TestPatternJD256A: + k >>= 3; + ASSERT (k < sizeof (PatternJD_256)); + Result = PatternJD_256[k]; + break; + case TestPatternJD1B: + k >>= 1; + // break is not being used here because TestPatternJD1B also need + // to run TestPatternJD1A sequence. + case TestPatternJD1A: + k >>= 3; + i = (UINT8) (k >> 3); + Mask = (UINT8) (0x80 >> (k & 7)); + + if (i == 0) { + Result = 0; + } else { + Result = (UINT16)1 << (i - 1); + } + + ASSERT (i < sizeof (PatternJD)); + if (PatternJD[i] & Mask) { + Result = ~Result; + } + break; + case TestPattern3: + Result = 0x36; + break; + case TestPattern4: + Result = 0xC9; + break; + default: + Result = 0; + IDS_ERROR_TRAP; + } + + // fill in the Pattern buffer + Buffer[Index] = Result; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function flushes cache lines + * + * @param[in,out] MemPtr - pointer to MEM_DATA_STRUCTURE + * @param[in] ClCount - Number of cache lines + * @param[in] Address - System Address [47:16] + * + * ---------------------------------------------------------------------------- + */ + +VOID +MemUProcIOClFlush ( + IN UINT32 Address, + IN UINT16 ClCount, + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + MemUSetTargetWTIO (Address, MemPtr); + MemUFlushPattern (MemUSetUpperFSbase (Address, MemPtr), ClCount); + MemUResetTargetWTIO (MemPtr); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the upper 32-bits of the Base address, 4GB aligned) for the FS selector. + * @param[in,out] MemPtr - pointer to MEM_DATA_STRUCTURE + * @param[in] Address - System Address [47:16] + * + * @return Address - Lowest 32-bit of physical address + * ---------------------------------------------------------------------------- + */ + +UINT32 +MemUSetUpperFSbase ( + IN UINT32 Address, + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + S_UINT64 SMsr; + + SMsr.lo = 0; + SMsr.hi = Address >> 16; + LibAmdMsrWrite (FS_BASE, (UINT64 *)&SMsr, &MemPtr->StdHeader); + return Address << 16; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function resets the target address space to Write Through IO by disabling IORRs + * + * @param[in,out] MemPtr - pointer to MEM_DATA_STRUCTURE + * + * ---------------------------------------------------------------------------- + */ + +VOID +MemUResetTargetWTIO ( + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + S_UINT64 SMsr; + SMsr.hi = 0; + SMsr.lo = 0; + LibAmdMsrWrite (IORR0_MASK, (UINT64 *)&SMsr, &MemPtr->StdHeader); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the target range to WT IO (using an IORR overlapping + * the already existing + * + * @param[in,out] MemPtr - pointer to MEM_DATA_STRUCTURE + * @param[in] Address - System Address [47:16] + * + * ---------------------------------------------------------------------------- + */ + +VOID +MemUSetTargetWTIO ( + IN UINT32 Address, + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + S_UINT64 SMsr; + + SMsr.lo = Address << 16; + SMsr.hi = Address >> 16; + LibAmdMsrWrite (IORR0_BASE,(UINT64 *)&SMsr, &MemPtr->StdHeader); // IORR0 Base + SMsr.hi = 0xFFFF; + SMsr.lo = 0xFC000800; + LibAmdMsrWrite (IORR0_MASK, (UINT64 *)&SMsr, &MemPtr->StdHeader); // 64MB Mask +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Waits specified number of 10ns cycles + * @param[in,out] MemPtr - pointer to MEM_DATA_STRUCTURE + * @param[in] Count - Number of 10ns cycles to wait; Note that Count must not exceed 1000000 + * + * ---------------------------------------------------------------------------- + */ + +VOID +MemUWait10ns ( + IN UINT32 Count, + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + UINT64 TargetTsc; + UINT64 CurrentTsc; + + ASSERT (Count <= 1000000); + + MemUMFenceInstr (); + + LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader); + TargetTsc = CurrentTsc + ((Count * MemPtr->TscRate + 99) / 100); + IEM_SKIP_CODE (IEM_WAIT) { + do { + LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader); + } while (CurrentTsc < TargetTsc); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Find the entry of platform specific overriding table. + * + * @param[in] PlatformMemoryConfiguration - Platform config table + * @param[in] EntryType - Entry type + * @param[in] SocketID - Physical socket ID + * @param[in] ChannelID - Physical channel ID + * @param[in] DimmID - Physical Dimm ID + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * @param[in,out] *StdHeader - Pointer of AMD_CONFIG_PARAMS + * - If both *LogicalIdPtr and *StdHeader are "NULL" input, + * that means, the "EntryType" are not CPU family dependent, + * ex. PSO_MAX_DIMMS for NUMBER_OF_DIMMS_SUPPORTED macro. + * + * + * @return NULL - entry could not be found. + * @return Pointer - points to the entry's data. + * + * ---------------------------------------------------------------------------- + */ + +VOID * +FindPSOverrideEntry ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN PSO_ENTRY EntryType, + IN UINT8 SocketID, + IN UINT8 ChannelID, + IN UINT8 DimmID, + IN CPU_LOGICAL_ID *LogicalIdPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *Buffer; + CPU_LOGICAL_ID LogicalCpuId; + UINT32 RawCpuId; + + LogicalCpuId.Family = AMD_FAMILY_UNKNOWN; + LogicalCpuId.Revision = 0; + RawCpuId = 0; + + Buffer = PlatformMemoryConfiguration; + // + // Do not need to look for CPU family specific PSO if LogicalIdPtr and StdHeader are NULL. + // + if ((LogicalIdPtr != NULL) && (StdHeader != NULL)) { + // + // Looking for the CPU family signature followed by CPUID value. + // And check to see if the CPUID value is matched with current CPU's : + // - If matched, Buffer points to following PSO macros' start address. + // - If not matched, Buffer points to PlatformMemoryConfiguration for global PSO parsing. + // + while (Buffer[0] != PSO_END) { + if (Buffer[0] == PSO_CPU_FAMILY_TO_OVERRIDE) { + RawCpuId = *(UINT32 *)&Buffer[2]; + GetLogicalIdFromCpuid (RawCpuId, &LogicalCpuId, StdHeader); + if ((LogicalCpuId.Family & LogicalIdPtr->Family) != 0) { + if ((LogicalCpuId.Revision & LogicalIdPtr->Revision) != 0) { + Buffer += Buffer[1] + 2; + break; + } + } + } + Buffer += Buffer[1] + 2; + } + // + // If no CPU family specific PSO macros exist, Buffer points to PlatformMemoryConfiguration again + // + if (Buffer[0] == PSO_END) { + Buffer = PlatformMemoryConfiguration; + } + } + + while ((Buffer[0] != PSO_END) && (Buffer[0] != PSO_CPU_FAMILY_TO_OVERRIDE)) { + if (Buffer[0] == EntryType) { + if ((Buffer[2] & ((UINT8) 1 << SocketID)) != 0 ) { + if ((Buffer[3] & ((UINT8) 1 << ChannelID)) != 0 ) { + if ((Buffer[4] & ((UINT8) 1 << DimmID)) != 0 ) { + return &Buffer[5]; + } + } + } + } + Buffer += Buffer[1] + 2; + } + + return NULL; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the max dimms for a given memory channel on a given + * processor. It first searches the platform override table for the max dimms + * value. If it is not provided, the AGESA default value is returned. The target + * socket must be a valid present socket. + * + * @param[in] PlatformMemoryConfiguration - Platform config table + * @param[in] SocketID - ID of the processor that owns the channel + * @param[in] ChannelID - Channel to get max dimms for + * + * + * @return UINT8 - Max Number of Dimms for that channel + */ +UINT8 +GetMaxDimmsPerChannel ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN UINT8 ChannelID + ) +{ + UINT8 *DimmsPerChPtr; + UINT8 MaxDimmPerCH; + + DimmsPerChPtr = FindPSOverrideEntry (PlatformMemoryConfiguration, PSO_MAX_DIMMS, SocketID, ChannelID, 0, NULL, NULL); + if (DimmsPerChPtr != NULL) { + MaxDimmPerCH = *DimmsPerChPtr; + } else { + MaxDimmPerCH = MAX_DIMMS_PER_CHANNEL; + } + // Maximum number of dimms per channel cannot be larger than its default value. + ASSERT (MaxDimmPerCH <= MAX_DIMMS_PER_CHANNEL); + + return MaxDimmPerCH; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the max soldered-down dimms for a given memory channel on a given + * processor. It first searches the platform override table for the soldered-down dimms + * value. If it is not provided, the AGESA default value is returned. The target + * socket must be a valid present socket. + * + * @param[in] PlatformMemoryConfiguration - Platform config table + * @param[in] SocketID - ID of the processor that owns the channel + * @param[in] ChannelID - Channel to get max dimms for + * + * + * @return UINT8 - Max Number of soldered-down dimms for that channel + */ +UINT8 +GetMaxSolderedDownDimmsPerChannel ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN UINT8 ChannelID + ) +{ + UINT8 *DimmsPerChPtr; + UINT8 MaxSolderedDownDimmPerCH; + + DimmsPerChPtr = FindPSOverrideEntry (PlatformMemoryConfiguration, PSO_MAX_SOLDERED_DOWN_DIMMS, SocketID, ChannelID, 0, NULL, NULL); + if (DimmsPerChPtr != NULL) { + MaxSolderedDownDimmPerCH = *DimmsPerChPtr; + } else { + MaxSolderedDownDimmPerCH = 0; + } + // Maximum number of dimms per channel cannot be larger than its default value. + ASSERT (MaxSolderedDownDimmPerCH <= MAX_DIMMS_PER_CHANNEL); + + return MaxSolderedDownDimmPerCH; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the max memory channels on a given processor. + * It first searches the platform override table for the max channels value. + * If it is not provided, the AGESA default value is returned. + * + * @param[in] PlatformMemoryConfiguration - Platform config table + * @param[in] SocketID - ID of the processor + * @param[in] StdHeader - Header for library and services + * + * + * @return UINT8 - Max Number of Channels on that Processor + */ +UINT8 +GetMaxChannelsPerSocket ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *ChannelsPerSocketPtr; + UINT8 MaxChannelsPerSocket; + + if (IsProcessorPresent (SocketID, StdHeader)) { + ChannelsPerSocketPtr = FindPSOverrideEntry (PlatformMemoryConfiguration, PSO_MAX_CHNLS, SocketID, 0, 0, NULL, NULL); + if (ChannelsPerSocketPtr != NULL) { + MaxChannelsPerSocket = *ChannelsPerSocketPtr; + } else { + MaxChannelsPerSocket = MAX_CHANNELS_PER_SOCKET; + } + // Maximum number of channels per socket cannot be larger than its default value. + ASSERT (MaxChannelsPerSocket <= MAX_CHANNELS_PER_SOCKET); + } else { + MaxChannelsPerSocket = 0; + } + + return MaxChannelsPerSocket; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the max number of chip select on a given channel of + * a given processor. It first searches the platform override table for the max + * chip select value. If it is not provided, the AGESA default value is returned. + * The target socket must be a valid present socket. + * + * @param[in] PlatformMemoryConfiguration - Platform config table + * @param[in] SocketID - ID of the processor + * @param[in] ChannelID - ID of a channel + * + * + * @return UINT8 - Max Number of chip selects on the channel of the Processor + */ +UINT8 +GetMaxCSPerChannel ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN UINT8 ChannelID + ) +{ + UINT8 *CSPerSocketPtr; + UINT8 MaxCSPerChannel; + + CSPerSocketPtr = FindPSOverrideEntry (PlatformMemoryConfiguration, PSO_MAX_CHIPSELS, SocketID, ChannelID, 0, NULL, NULL); + if (CSPerSocketPtr != NULL) { + MaxCSPerChannel = *CSPerSocketPtr; + } else { + MaxCSPerChannel = MAX_CS_PER_CHANNEL; + } + // Max chip select per channel cannot be larger than its default value + ASSERT (MaxCSPerChannel <= MAX_CS_PER_CHANNEL); + + return MaxCSPerChannel; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the index of the first Dimm SPD structure for a + * given processor socket. It checks the Max Dimms per channel for every memory + * channel on every processor up to the current one, and adds them together. + * + * This function may also be used to calculate the maximum dimms per system + * by passing the total number of dimm sockets + * + * @param[in] PlatformMemoryConfiguration - Platform config table + * @param[in] SocketID - ID of the processor + * @param[in] StdHeader - Header for library and services + * + * @return UINT8 - SPD Index + */ +UINT8 +GetSpdSocketIndex ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 SpdSocketIndex; + UINT8 Socket; + UINT8 Channel; + UINT8 MaxChannelsPerSocket; + + SpdSocketIndex = 0; + for (Socket = 0; Socket < SocketID; Socket++) { + MaxChannelsPerSocket = GetMaxChannelsPerSocket (PlatformMemoryConfiguration, Socket, StdHeader); + for (Channel = 0; Channel < MaxChannelsPerSocket; Channel++) { + SpdSocketIndex = SpdSocketIndex + GetMaxDimmsPerChannel (PlatformMemoryConfiguration, Socket, Channel); + } + } + return SpdSocketIndex; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the index of the first Dimm SPD structure for a + * given channel relative to the processor socket. It checks the Max Dimms per + * channel for every memory channel on that processor up to the current one, + * and adds them together. + * + * This function may also be used to calculate the maximum dimms per system + * by passing the total number of DIMM sockets + * + * @param[in] PlatformMemoryConfiguration - Platform config table + * @param[in] SocketID - ID of the processor + * @param[in] ChannelID - ID of the Channel + * @param[in] StdHeader - Header for library and services + * + * @return UINT8 - SPD Index + */ +UINT8 +GetSpdChannelIndex ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN UINT8 ChannelID, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 SpdChannelIndex; + UINT8 Channel; + + SpdChannelIndex = 0; + ASSERT (ChannelID < GetMaxChannelsPerSocket (PlatformMemoryConfiguration, SocketID, StdHeader)) + for (Channel = 0; Channel < ChannelID; Channel++) { + SpdChannelIndex = SpdChannelIndex + GetMaxDimmsPerChannel (PlatformMemoryConfiguration, SocketID, Channel); + } + return SpdChannelIndex; +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function returns the upper 32 bits mask for variable MTRR based on + * the CPU_LOGICAL_ID. + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * @param[in] StdHeader - Header for library and services + * + * @return UINT32 - MTRR mask for upper 32 bits + * + */ +UINT32 +GetVarMtrrHiMsk ( + IN CPU_LOGICAL_ID *LogicalIdPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 TempNotCare; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + CONST CACHE_INFO *CacheInfoPtr; + + GetCpuServicesFromLogicalId (LogicalIdPtr, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **) &CacheInfoPtr, &TempNotCare, StdHeader); + return (UINT32) (CacheInfoPtr->VariableMtrrMask >> 32); +} + + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function returns number of memclk converted from ns + * @param[in] Speed - memclk frequency + * @param[in] NumberOfns - number of ns to be converted + * + * @return UINT32 - number of memclk + * + */ +UINT32 +MemUnsToMemClk ( + IN UINT32 Speed, + IN UINT32 NumberOfns + ) +{ + return (UINT32) ((NumberOfns * Speed + 999) / 1000); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnS3kb.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnS3kb.h new file mode 100644 index 0000000000..ac11e67bf7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnS3kb.h @@ -0,0 +1,84 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnS3kb.h + * + * S3 resume memory related function for KB. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _MNS3KB_H_ +#define _MNS3KB_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ +/// ID for register list of KB +typedef enum { + PCI_LST_ESR_KB, ///< Assign 0x0000 for PCI register list for pre exit self refresh. + PCI_LST_KB, ///< Assign 0x0001 for PCI register list for post exist self refresh. + CPCI_LST_ESR_KB, ///< Assign 0x0002 for conditional PCI register list for pre exit self refresh. + CPCI_LST_KB, ///< Assign 0x0003 for conditional PCI register list for post exit self refresh. + MSR_LST_ESR_KB, ///< Assign 0x0004 for MSR register list for pre exit self refresh. + MSR_LST_KB, ///< Assign 0x0005 for MSR register list for post exit self refresh. + CMSR_LST_ESR_KB, ///< Assign 0x0006 for conditional MSR register list for pre exit self refresh. + CMSR_LST_KB ///< Assign 0x0007 for conditional MSR register list for post exit self refresh. +} RegisterListIDKB; + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define SET_S3_NB_PSTATE_OFFSET(Offset, NBPstate) ((NBPstate << 10) | Offset) + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +#endif //_MNS3KB_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mndctkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mndctkb.c new file mode 100644 index 0000000000..819fb20a50 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mndctkb.c @@ -0,0 +1,1217 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mndctkb.c + * + * Northbridge DCT support for KB + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 86880 $ @e \$Date: 2013-01-28 11:15:07 -0600 (Mon, 28 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mport.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mu.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mnkb.h" +#include "mftds.h" +#include "merrhdl.h" +#include "cpuFamRegisters.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuF16Utilities.h" +#include "IdsF16KbAllService.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + +#define FILECODE PROC_MEM_NB_KB_MNDCTKB_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define UNUSED_CLK 4 + +CONST BIT_FIELD_NAME MemPstateBF[4] = {BFMemPstate0, BFMemPstate1, BFMemPstate2, BFMemPstate3}; +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +UINT32 +STATIC +MemNTotalSyncComponentsKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function programs the memory controller with configuration parameters + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - An Error value lower than AGESA_FATAL may have occurred + * @return FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred + * @return NBPtr->MCTPtr->ErrCode - Contains detailed AGESA_STATUS value + */ + +BOOLEAN +MemNAutoConfigKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 i; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + MEM_PARAMETER_STRUCT *RefPtr; + UINT32 PowerDownMode; + UINT32 Tstag; + + RefPtr = NBPtr->RefPtr; + MCTPtr = NBPtr->MCTPtr; + DCTPtr = NBPtr->DCTPtr; + + // + //====================================================================== + // Build Dram Config Lo Register Value + //====================================================================== + MemNSetBitFieldNb (NBPtr, BFUnBuffDimm, 1); + MemNSetBitFieldNb (NBPtr, BFPendRefPaybackS3En, 1); + MemNSetBitFieldNb (NBPtr, BFStagRefEn, 1); + // + // DimmEccEn + // + if (MCTPtr->Status[SbEccDimms]) { + MemNSetBitFieldNb (NBPtr, BFDimmEccEn, 1); + } + // + //====================================================================== + // Build Dram Config Hi Register Value + //====================================================================== + // + // + // MemClkFreq + // + MemNSetBitFieldNb (NBPtr, BFMemClkFreq, MemNGetMemClkFreqIdUnb (NBPtr, DCTPtr->Timings.Speed)); + + PowerDownMode = 1; + IDS_OPTION_HOOK (IDS_POWERDOWN_MODE, &PowerDownMode, &(NBPtr->MemPtr->StdHeader)); + MemNSetBitFieldNb (NBPtr, BFPowerDownMode, PowerDownMode); + + if (NBPtr->MemPstateStage == MEMORY_PSTATE_1ST_STAGE) { + MemNBrdcstSetNb (NBPtr, BFM1MemClkFreq, MemNGetMemClkFreqIdUnb (NBPtr, DDR667_FREQUENCY)); + MemNSetBitFieldNb (NBPtr, BFDphyMemPsSelEn, 0); + MemNBrdcstSetNb (NBPtr, BFRate, MemNGetMemClkFreqIdUnb (NBPtr, DDR667_FREQUENCY) | 0x8); + MemNBrdcstSetNb (NBPtr, BFMxMrsEn, 7); + } + + MemNSetBitFieldNb (NBPtr, BFDphyMemPsSelEn, 1); + // + //====================================================================== + // Build Dram MRS Register Value + //====================================================================== + // + MemNSetBitFieldNb (NBPtr, BFPchgPDModeSel, 1); + MemNSetBitFieldNb (NBPtr, BFBurstCtrl, 1); + + //====================================================================== + // DRAM Controller Miscellaneous 2 + //====================================================================== + MemNSetBitFieldNb (NBPtr, BFPerRankTimingEn, 1); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\nEnable Per Rank Training....\n\n"); + MemNSetBitFieldNb (NBPtr, BFPrtlChPDEnhEn, 0); + MemNSetBitFieldNb (NBPtr, BFAggrPDEn, 1); + MemNSetBitFieldNb (NBPtr, BFDctSelBankSwap, 1); + + //====================================================================== + // Trace Buffer Extended Address Initialization + //====================================================================== + MemNSetBitFieldNb (NBPtr, BFTrcBufAdrPtrHi, 0); + MemNSetBitFieldNb (NBPtr, BFTrcBufDramLimitHi, 0); + MemNSetBitFieldNb (NBPtr, BFTrcBufDramBaseHi, 0); + + //====================================================================== + // GMC to DCT control + //====================================================================== + MemNSetBitFieldNb (NBPtr, BFGmcTokenLimit, 4); + MemNSetBitFieldNb (NBPtr, BFMctTokenLimit, 4); + MemNSetBitFieldNb (NBPtr, BFGmcToDctControl1, 0x04040404); + MemNSetBitFieldNb (NBPtr, BFCpuElevPrioPeriod, 0xC); + MemNSetBitFieldNb (NBPtr, BFCpuElevPrioDis, 0); + + //====================================================================== + // Other Registers + //====================================================================== + // + // + // Non-SPD Timings + // + MemNSetBitFieldNb (NBPtr, BFTrwtWB, 0x17); + MemNSetBitFieldNb (NBPtr, BFTrwtTO, 0x16); + MemNSetBitFieldNb (NBPtr, BFTwrrd, 0xB ); + + MemNSetBitFieldNb (NBPtr, BFTrdrdSdSc, 0xB); + MemNSetBitFieldNb (NBPtr, BFTrdrdSdDc, 0xB); + MemNSetBitFieldNb (NBPtr, BFTrdrdDd, 0xB); + + MemNSetBitFieldNb (NBPtr, BFTwrwrSdSc, 0xB); + MemNSetBitFieldNb (NBPtr, BFTwrwrSdDc, 0xB); + MemNSetBitFieldNb (NBPtr, BFTwrwrDd, 0xB); + + MemNSetBitFieldNb (NBPtr, BFWrOdtOnDuration, DEFAULT_WR_ODT_KB); + MemNSetBitFieldNb (NBPtr, BFRdOdtOnDuration, DEFAULT_RD_ODT_KB); + MemNSetBitFieldNb (NBPtr, BFWrOdtTrnOnDly, DEFAULT_RD_ODT_TRNONDLY_KB); + + // Tstag = BIOS: MAX(D18F2x204_dct[0]_mp[1:0][Trrd], CEIL(D18F2x204_dct[0]_mp[1:0][FourActWindow]/4)) + Tstag = MAX (MemNGetBitFieldNb (NBPtr, BFTrrd), (MemNGetBitFieldNb (NBPtr, BFFourActWindow) + 3) / 4); + for (i = 0; i < 4; i++) { + MemNSetBitFieldNb (NBPtr, BFTstag0 + i, Tstag); + } + + MemNSetBitFieldNb (NBPtr, BFTmrd, 4); + MemNSetBitFieldNb (NBPtr, BFFlushWrOnS3StpGnt, 1); + MemNSetBitFieldNb (NBPtr, BFFastSelfRefEntryDis, 0); + + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function caps speed based on battery life check. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + */ +VOID +MemNCapSpeedBatteryLifeKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + CONST UINT16 SupportedFreq[] = { + DDR2133_FREQUENCY, + DDR1866_FREQUENCY, + DDR1600_FREQUENCY, + DDR1333_FREQUENCY, + DDR1066_FREQUENCY, + DDR800_FREQUENCY, + DDR667_FREQUENCY + }; + + UINT32 FreqNumeratorInMHz; + UINT32 FreqDivisor; + UINT32 VoltageInuV; + UINT32 NBFreq; + UINT16 DdrFreq; + UINT16 j; + UINT8 Dct; + INT8 NbPs; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + FamilySpecificServices = NULL; + GetCpuServicesOfSocket (NBPtr->MCTPtr->SocketId, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &(NBPtr->MemPtr->StdHeader)); + + + // Find the lowest supported NB Pstate + NBFreq = 0; + for (NbPs = 3; NbPs >= 0; NbPs--) { + if (FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices, + NBPtr->MemPtr->PlatFormConfig, + &NBPtr->PciAddr, + (UINT32) NbPs, + &FreqNumeratorInMHz, + &FreqDivisor, + &VoltageInuV, + &(NBPtr->MemPtr->StdHeader))) { + if (MemNGetBitFieldNb (NBPtr, MemPstateBF[NbPs]) == 0) { + NBFreq = FreqNumeratorInMHz / FreqDivisor; + break; + } + } + } + + ASSERT (NBFreq > 0); + + // Pick Max MEMCLK that is less than or equal to NCLK + DdrFreq = DDR800_FREQUENCY; + for (j = 0; j < GET_SIZE_OF (SupportedFreq); j++) { + if (NBFreq >= ((UINT32) SupportedFreq[j]) && NBFreq <= ((UINT32) SupportedFreq[j] * 2)) { + DdrFreq = SupportedFreq[j]; + break; + } + } + ASSERT (j < GET_SIZE_OF (SupportedFreq)); + + // Cap MemClk frequency to lowest NCLK frequency + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.TargetSpeed > DdrFreq) { + NBPtr->DCTPtr->Timings.TargetSpeed = DdrFreq; + } + } + + // Initialize NbPsCtlReg + NBPtr->NbPsCtlReg = 0; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function retrieves the Max latency parameters + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @param[in] *MinDlyPtr - Pointer to variable to store the Minimum Delay value + * @param[in] *MaxDlyPtr - Pointer to variable to store the Maximum Delay value + * @param[in] *DlyBiasPtr - Pointer to variable to store Delay Bias value + * @param[in] MaxRcvEnDly - Maximum receiver enable delay value + */ + +VOID +MemNGetMaxLatParamsKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT16 MaxRcvEnDly, + IN OUT UINT16 *MinDlyPtr, + IN OUT UINT16 *MaxDlyPtr, + IN OUT UINT16 *DlyBiasPtr + ) +{ + UINT32 N; + UINT32 T; + UINT32 P; + UINT32 MemClkPeriod; + + // 1. P = N = T = 0. + P = N = T = 0; + + // Get all sync components BKDG steps 3,4,6 + P = MemNTotalSyncComponentsKB (NBPtr); + + // 8. P = P + CEIL(MAX(D18F2x9C_x0000_00[2A:10]_dct[1:0][DqsRcvEnGrossDelay, DqsRcvEnFineDelay] + + // D18F2x9C_x0000_0[3:0]0[7:5]_dct[1:0][RdDqsTime] PCLKs)) + 1 + P = P + (MaxRcvEnDly + 31) / 32 + 1; + + // 11. N = (P/(MemClkFreq * 2) + T) * NclkFreq; Convert from PCLKs plus time to NCLKs. + MemClkPeriod = 1000000 / ((NBPtr->MemPstate == MEMORY_PSTATE0) ? NBPtr->DCTPtr->Timings.Speed : DDR667_FREQUENCY); + N = ((((P * MemClkPeriod + 1) / 2) + T) * NBPtr->NBClkFreq + 999999) / 1000000; + + // Calculate a starting MaxRdLatency delay value with steps 5, 9, and 12 excluded + *MinDlyPtr = (UINT16) N; + + *MaxDlyPtr = 0x3FF; + + // Program D18F2x210_dct[0]_nbp[3:0][MaxRdLatency] = CEIL(current value + 1 NCLK + 1.5 MEMCLK + + // IF (NclkFreq/MemClkFreq < 2) THEN 1 MEMCLK ELSE 0 ENDIF) + N = 1; + P = 3 + (((NBPtr->NBClkFreq / ((NBPtr->MemPstate == MEMORY_PSTATE0) ? NBPtr->DCTPtr->Timings.Speed : DDR667_FREQUENCY)) < 2) ? 2 : 0); + N += (((P * MemClkPeriod + 1) / 2) * NBPtr->NBClkFreq + 999999) / 1000000; + *DlyBiasPtr = (UINT16) N; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the maximum round-trip latency in the system from the processor to the DRAM + * devices and back. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] MaxRcvEnDly - Maximum receiver enable delay value + * + */ + +VOID +MemNSetMaxLatencyKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT16 MaxRcvEnDly + ) +{ + UINT32 N; + UINT32 T; + UINT32 P; + UINT32 Px2; + UINT32 MemClkPeriod; + + AGESA_TESTPOINT (TpProcMemRcvrCalcLatency, &(NBPtr->MemPtr->StdHeader)); + + // + // Initial value for MaxRdLat used in training + // + N = 0x55; + + if (MaxRcvEnDly != 0xFFFF) { + // 1. P = N = T = 0. + P = N = T = 0; + + // Get all sync components BKDG steps 3,4,6 + P = MemNTotalSyncComponentsKB (NBPtr); + + // 5. P = P + 6 + P += 6; + + // 8. P = P + CEIL(MAX(D18F2x9C_x0000_00[2A:10]_dct[1:0][DqsRcvEnGrossDelay, DqsRcvEnFineDelay] + + // D18F2x9C_x0000_0[3:0]0[6:5]_dct[1:0][RdDqsTime] PCLKs)) + 1 + P = P + (MaxRcvEnDly + 31) / 32 + 1; + + // 9. If (NclkFreq/MemClkFreq < 2) then P = P + 4.5 Else P = P + 2.5 + if ((NBPtr->NBClkFreq / NBPtr->DCTPtr->Timings.Speed) < 2) { + Px2 = P * 2 + 9; + } else { + Px2 = P * 2 + 5; + } + + // 10. T = T + 1050 ps + T += 1050; + + // 11. N = (P/(MemClkFreq * 2) + T) * NclkFreq; Convert from PCLKs plus time to NCLKs. + MemClkPeriod = 1000000 / NBPtr->DCTPtr->Timings.Speed; + N = ((((Px2 * MemClkPeriod + 3) / 4) + T) * NBPtr->NBClkFreq + 999999) / 1000000; + + // 12. D18F2x210_dct[1:0]_nbp[3:0][MaxRdLatency] = CEIL(N) + 1 + N = N + 1; + } + + NBPtr->DCTPtr->Timings.MaxRdLat = (UINT16) N; + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMaxRdLat: %03x\n", N); + MemNSetBitFieldNb (NBPtr, BFMaxLatency, N); +} + +/*----------------------------------------------------------------------------- + * + * + * This function set MaxRdLat after HW receiver enable training is completed + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNExitPhyAssistedTrainingKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 Dct; + UINT8 ChipSel; + MEM_TECH_BLOCK *TechPtr; + + TechPtr = NBPtr->TechPtr; + + // Calculate Max Latency for both channels to prepare for position training + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB ; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + + // Reset DisAutoRefresh and ZqcsInterval for position training. + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 1); + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 0); + MemNSetBitFieldNb (NBPtr, BFRxDqInsDly, 0); + } + + if (TechPtr->FindMaxDlyForMaxRdLat (TechPtr, &ChipSel)) { + NBPtr->SetMaxLatency (NBPtr, TechPtr->MaxDlyForMaxRdLat); + } + } + + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets the total of sync components for Max Read Latency calculation + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return Total in PCLKs + */ +UINT32 +STATIC +MemNTotalSyncComponentsKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 P; + + P = 0; + + // 3. If (D18F2x9C_x0000_0004_dct[1:0][AddrCmdSetup] = 0 & D18F2x9C_x0000_0004_dct[1:0][CsOdt- + // Setup] = 0 & D18F2x9C_x0000_0004_dct[1:0][CkeSetup] = 0) + // then P = P + 1 + // else P = P + 2 + if ((MemNGetBitFieldNb (NBPtr, BFAddrTmgControl) & 0x0202020) == 0) { + P += 1; + } else { + P += 2; + } + + // 4. P = P + (8 - D18F2x210_dct[1:0]_nbp[3:0][RdPtrInit]) + P = P + (8 - (UINT16) MemNGetBitFieldNb (NBPtr, BFRdPtrInit)); + + // 7. P = P + (2 * (D18F2x200_dct[1:0][Tcl] - 1 clocks)) + P = P + (2 * (MemNGetBitFieldNb (NBPtr, BFTcl) - 1)); + + return P; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function obtains the memory frequency in the current context + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +UINT16 +MemNGetMemClkFreqInCurrentContextKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + UINT16 MemClkSpeed; + + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + break; + } + } + + if (MemNGetBitFieldNb (NBPtr, MemPstateBF[MemNGetBitFieldNb (NBPtr, BFNbPsSel)]) == 0) { + MemClkSpeed = NBPtr->DCTPtr->Timings.Speed; + } else { + MemClkSpeed = MemNGetMemClkFreqUnb (NBPtr, (UINT8) MemNGetBitFieldNb (NBPtr, BFM1MemClkFreq)); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMemclk Freq: %d\n", MemClkSpeed); + + return MemClkSpeed; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates and programs NB P-state dependent registers + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNProgramNbPstateDependentRegistersKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 RdPtrInit; + UINT8 Dct; + UINT8 *DimmsPerChPtr; + UINT8 MaxSolderedDownDimmPerCh; + UINT32 MemClkSpeed; + + MemClkSpeed = NBPtr->GetMemClkFreqInCurrentContext (NBPtr); + + // IF (((NBCOF >= DdrRate) == FALSE) THEN + // RdPtrInit = 0010b + // ELSE IF (((NBCOF >= DdrRate) == TRUE) && (DdrRate == 667 || DdrRate == 800 || DdrRate == 1600))THEN + // RdPtrInit = 0110b + // ELSE IF (((NBCOF >= DdrRate) == TRUE) && (DdrRate == 1866 || DdrRate ==2133))THEN + // RdPtrInit = 0101b + // ELSE IF (((NBCOF >= DdrRate) == TRUE) && (DdrRate == 2400))THEN + // RdPtrInit = 0100b + // ENDIF + if (NBPtr->NBClkFreq < (UINT32) (MemClkSpeed * 2)) { + RdPtrInit = 2; + } else { + RdPtrInit = (MemClkSpeed < DDR1600_FREQUENCY) ? 6 : ((MemClkSpeed < DDR2400_FREQUENCY) ? 5 : 4); + } + MemNBrdcstSetNb (NBPtr, BFRdPtrInit, RdPtrInit); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tRdPtr: %d\n", RdPtrInit); + + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + // Set ProcOdtAdv + // BIOS:IF(Solder-down DRAM || SODIMM) && DdrRate <= 1333) THEN 0 ELSE 1 ENDIF. + MaxSolderedDownDimmPerCh = GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID); + DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, + PSO_SOLDERED_DOWN_SODIMM_TYPE, + NBPtr->MCTPtr->SocketId, + NBPtr->ChannelPtr->ChannelID, + 0, NULL, NULL); + if (((DimmsPerChPtr != NULL) || (MaxSolderedDownDimmPerCh != 0) || (NBPtr->ChannelPtr->SODimmPresent != 0)) && + (NBPtr->DCTPtr->Timings.Speed <= DDR1333_FREQUENCY)) { + MemNSetBitFieldNb (NBPtr, BFProcOdtAdv, 0); + } else { + MemNSetBitFieldNb (NBPtr, BFProcOdtAdv, 0x4000); + } + MemNSetBitFieldNb (NBPtr, BFDataTxFifoWrDly, 0); + if (NBPtr->DCTPtr->Timings.Speed >= DDR1600_FREQUENCY) { + MemNSetBitFieldNb (NBPtr, BFReducedLoop, (2 << 13)); + } + } + } + + IDS_OPTION_HOOK (IDS_NBPS_REG_OVERRIDE, NBPtr, &NBPtr->MemPtr->StdHeader); + MemFInitTableDrive (NBPtr, MTAfterNbPstateChange); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This is a general purpose function that executes before DRAM init + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNBeforeDramInitKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + // c. Program DCT training specific configuration. + MemNConfigureDctTrainingKB (NBPtr); + // d. Program the remaining DCT registers not covered by an explicit sequence dependency. + MemNProgramNonSeqDependentRegistersKB (NBPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the memory controller for training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNConfigureDctTrainingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + // + // 2.10.6.7 DCT Training Specific Configuration + // + MemNSetBitFieldNb (NBPtr, BFAddrCmdTriEn, 0); + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 1); + MemNSetBitFieldNb (NBPtr, BFForceAutoPchg, 0); + MemNSetBitFieldNb (NBPtr, BFDynPageCloseEn, 0); + MemNSetBitFieldNb (NBPtr, BFBankSwizzleMode, 0); + MemNSetBitFieldNb (NBPtr, BFDcqBypassMax, 0); + MemNSetBitFieldNb (NBPtr, BFPowerDownEn, 0); + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 0); + MemNSetBitFieldNb (NBPtr, BFRxMaxDurDllNoLock, 0); + MemNSetBitFieldNb (NBPtr, BFTxMaxDurDllNoLock, 0); + MemNSetBitFieldNb (NBPtr, BFEnRxPadStandby, 0); + MemNSetBitFieldNb (NBPtr, BFBankSwap, 0); + MemNSetBitFieldNb (NBPtr, BFODTSEn, 0); + MemNSetBitFieldNb (NBPtr, BFCmdThrottleMode, 0); + MemNSetBitFieldNb (NBPtr, BFBwCapEn, 0); + MemNSetBitFieldNb (NBPtr, BFDramScrub, 0); + MemNSetBitFieldNb (NBPtr, BFScrubReDirEn, 0); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the remaining DCT registers not covered by + * an explicit sequence dependency. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNProgramNonSeqDependentRegistersKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + MemNSetBitFieldNb (NBPtr, BFDllCSRBiasTrim, 0x1000); + + IEM_INSERT_CODE (IEM_BEFORE_DRAM_INIT, IemBeforeDramInitOverrideKB, (NBPtr)); + } + } +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the memory controller for normal operation + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNConfigureDctNormalKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + BOOLEAN DllShutDownEn; + + DllShutDownEn = TRUE; + IDS_OPTION_HOOK (IDS_DLL_SHUT_DOWN, &DllShutDownEn, &(NBPtr->MemPtr->StdHeader)); + + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + // + // 2.10.6.7 DCT Training Specific Configuration + // + MemNSetBitFieldNb (NBPtr, BFAddrCmdTriEn, 1); + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 0); + if (DllShutDownEn && NBPtr->IsSupported[SetDllShutDown]) { + MemNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 0); + } + MemNSetBitFieldNb (NBPtr , BFForceAutoPchg, 0); + MemNSetBitFieldNb (NBPtr , BFDynPageCloseEn, 0); + if (NBPtr->RefPtr->EnableBankSwizzle) { + MemNSetBitFieldNb (NBPtr, BFBankSwizzleMode, 1); + } + MemNSetBitFieldNb (NBPtr, BFDcqBypassMax, 0x01F); + MemNPowerDownCtlKB (NBPtr); + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 2); + MemNSetBitFieldNb (NBPtr, BFBankSwap, 1); + // + // Post Training values for BFRxMaxDurDllNoLock, BFTxMaxDurDllNoLock, + // and BFEnRxPadStandby are handled by Power savings code + // + // BFBwCapEn and BFODTSEn are handled by OnDimmThermal Code + // + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function modifies CS interleaving low address according to several conditions for KB. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *LowBit - Pointer to low bit + * + */ + +BOOLEAN +MemNCSIntLvLowAddrAdjKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *LowBit + ) +{ + UINT8 DctSelBankSwap; + + DctSelBankSwap = (UINT8) MemNGetBitFieldNb (NBPtr, BFDctSelBankSwap); + // + //D18F2x[5C:40]_dct[1:0][15:5] = BaseAddr[21:11] && + //D18F2x[6C:60]_dct[1:0][15:5] = AddrMask[21:11], so *LowBit needs to be added with 2. + // + *(UINT8 *) LowBit += 2; + + if (MemNGetBitFieldNb (NBPtr, BFBankSwap) == 1) { + if (DctSelBankSwap == 1) { + *(UINT8 *) LowBit = 5; + } else { + *(UINT8 *) LowBit = 6; + } + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function releases the NB P-state force. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + */ +BOOLEAN +MemNReleaseNbPstateKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &NBPtr->MemPtr->StdHeader); + + // 6. Restore the initial D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0] values. + MemNSetBitFieldNb (NBPtr, BFNbPstateCtlReg, (MemNGetBitFieldNb (NBPtr, BFNbPstateCtlReg) & 0xFFFF9FFF) | (NBPtr->NbPsCtlReg & 0x6000)); + // 7. Restore the initial D18F5x170[NbPstateThreshold, NbPstateHi] values. + MemNSetBitFieldNb (NBPtr, BFNbPstateCtlReg, (MemNGetBitFieldNb (NBPtr, BFNbPstateCtlReg) & 0xFFFFF13F) | (NBPtr->NbPsCtlReg & 0x0EC0)); + // 8. Restore the initial D18F5x170[NbPstateLo] values. + MemNSetBitFieldNb (NBPtr, BFNbPstateLo, (NBPtr->NbPsCtlReg >> 3) & 3); + + // Clear NbPsSel to 0 + MemNSetBitFieldNb (NBPtr, BFNbPsSel, 0); + // Update TSC rate + FamilySpecificServices->GetTscRate (FamilySpecificServices, &NBPtr->MemPtr->TscRate, &NBPtr->MemPtr->StdHeader); + + if (MemNGetBitFieldNb (NBPtr, BFMemPsSel) != 0) { + MemNChangeMemPStateContextNb (NBPtr, 0); + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function handles multiple stage of training when multiple Mem Pstate is enabled + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * + */ + +BOOLEAN +MemNMemPstateStageChangeKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + BOOLEAN RetVal; + TRN_DLY_TYPE AccessType; + UINT8 Dct; + UINT8 ChipSel; + UINT8 ByteLane; + UINT16 CsEnabled; + UINT16 TrnDly; + UINT8 Tcl; + + RetVal = FALSE; + + if (NBPtr->MemPstateStage == MEMORY_PSTATE_1ST_STAGE) { + MemNChangeMemPStateContextNb (NBPtr, 1); + // Load memory registers in M1 context from data saved in the heap + IDS_HDT_CONSOLE (MEM_FLOW, "\nLoad Training registers for M1 with DDR667 training result\n"); + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + // Save MemPstate 1 data in output data structures + LibAmdMemCopy (NBPtr->ChannelPtr->RcvEnDlysMemPs1, NBPtr->ChannelPtr->RcvEnDlys, (MAX_DIMMS * MAX_DELAYS) * 2, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->RdDqsDlysMemPs1, NBPtr->ChannelPtr->RdDqsDlys, MAX_DIMMS * MAX_DELAYS, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->WrDqsDlysMemPs1, NBPtr->ChannelPtr->WrDqsDlys, MAX_DIMMS * MAX_DELAYS, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->WrDatDlysMemPs1, NBPtr->ChannelPtr->WrDatDlys, MAX_DIMMS * MAX_DELAYS, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->RdDqs2dDlysMemPs1, NBPtr->ChannelPtr->RdDqs2dDlys, MAX_DIMMS * MAX_NUMBER_LANES, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->RdDqsMinDlysMemPs1, NBPtr->ChannelPtr->RdDqsMinDlys, MAX_DIMMS * MAX_DELAYS, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->RdDqsMaxDlysMemPs1, NBPtr->ChannelPtr->RdDqsMaxDlys, MAX_DIMMS * MAX_DELAYS, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->WrDatMinDlysMemPs1, NBPtr->ChannelPtr->WrDatMinDlys, MAX_DIMMS * MAX_DELAYS, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->WrDatMaxDlysMemPs1, NBPtr->ChannelPtr->WrDatMaxDlys, MAX_DIMMS * MAX_DELAYS, &(NBPtr->MemPtr->StdHeader)); + LibAmdMemCopy (NBPtr->ChannelPtr->FailingBitMaskMemPs1, NBPtr->ChannelPtr->FailingBitMask, MAX_CS_PER_CHANNEL * MAX_DELAYS, &(NBPtr->MemPtr->StdHeader)); + + CsEnabled = NBPtr->DCTPtr->Timings.CsEnabled; + // Set Memory Pstate 1 training value into registers + for (AccessType = AccessRcvEnDly; AccessType <= AccessWrDqsDly; AccessType ++) { + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL_KB; ChipSel = ChipSel + NBPtr->CsPerDelay) { + if ((CsEnabled & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSel)) != 0) { + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + TrnDly = (UINT16) GetTrainDlyFromHeapNb (NBPtr, AccessType, DIMM_BYTE_ACCESS (ChipSel / NBPtr->CsPerDelay, ByteLane)); + NBPtr->SetTrainDly (NBPtr, AccessType, DIMM_BYTE_ACCESS (ChipSel / NBPtr->CsPerDelay, ByteLane), TrnDly); + } + } + } + } + + if (NBPtr->RefPtr->EnablePowerDown) { + MemNSetTxpNb (NBPtr); + // + // BFPchgPDEnDelay = + // IF (D18F2xA8_dct[0][AggrPDEn]) THEN + // (D18F2x200_dct[0]_mp[1:0][Tcl] + 5 + + // CEIL((MAX(D18F2x9C_x0000_00[2A:10]_dct[0]_mp[1:0][DqsRcvEnGrossDelay]) + // + 0.5) / 2)) ELSE 00h ENDIF. + // + if (MemNGetBitFieldNb (NBPtr, BFAggrPDEn) == 1) { + Tcl = NBPtr->DCTPtr->Timings.CasL; + MemNSetBitFieldNb (NBPtr, BFPchgPDEnDelay, Tcl + 5 + NBPtr->TechPtr->GetMinMaxGrossDly (NBPtr->TechPtr, AccessRcvEnDly, TRUE) / 2 + 1); + } else { + MemNSetBitFieldNb (NBPtr, BFPchgPDEnDelay, 0); + } + MemNSetBitFieldNb (NBPtr, BFAggrPDDelay, 0x20); + } + MemNSetOtherTimingKB (NBPtr); + // Save timing data structure for memory Pstate 1 + LibAmdMemCopy (NBPtr->DCTPtr->TimingsMemPs1, &(NBPtr->DCTPtr->Timings), sizeof (CH_TIMING_STRUCT), &(NBPtr->MemPtr->StdHeader)); + + MemFInitTableDrive (NBPtr, MTAfterMemPstate1PartialTrn); + } + } + + // Switch back to M0 context + MemNChangeMemPStateContextNb (NBPtr, 0); + + // Load memory registers in M1 context from data saved in the heap + IDS_HDT_CONSOLE (MEM_FLOW, "\nGoing into training stage 2. Complete training at DDR667 is done.\n"); + NBPtr->MemPstateStage = MEMORY_PSTATE_2ND_STAGE; + } else if ((NBPtr->MemPstateStage == MEMORY_PSTATE_2ND_STAGE) && (NBPtr->DCTPtr->Timings.TargetSpeed == NBPtr->DCTPtr->Timings.Speed)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nGoing into training stage 3. Partial training at all frequencies is done.\n"); + NBPtr->MemPstateStage = MEMORY_PSTATE_3RD_STAGE; + RetVal = TRUE; + } else { + // MemPstate is disabled. Do not go through the MemPstate handling flow. + RetVal = TRUE; + } + + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function Sets Power Down options and enables Power Down + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * The following registers are set: + * BFPowerDownMode BFPrtlChPDEnhEn + * BFTxp BFAggrPDDelay + * BFTxpDll BFAggrPDEn + * BFPchgPDEnDelay BFPowerDownEn + * + * NOTE: Delay values must be set before turning on the associated Enable bit + */ +VOID +MemNPowerDownCtlKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 PowerDownMode; + CONST UINT32 PwrMngm1[] = {0, 0, 0x05050403, 0x05050403, 0x06060403, 0x07070504, 0x08080504, 0x0A0A0605, 0x0B0B0706}; + UINT8 i; + UINT16 Speed; + UINT8 Tcl; + + if (NBPtr->RefPtr->EnablePowerDown) { + // + // PowerDownMode + // + PowerDownMode = (UINT8) UserOptions.CfgPowerDownMode; + PowerDownMode = (!NBPtr->IsSupported[ChannelPDMode]) ? PowerDownMode : 0; + IDS_OPTION_HOOK (IDS_POWERDOWN_MODE, &PowerDownMode, &(NBPtr->MemPtr->StdHeader)); + if (PowerDownMode == 1) { + MemNSetBitFieldNb (NBPtr, BFPowerDownMode, 1); + } + // + // Txp + // + MemNSetTxpNb (NBPtr); + // + // PchgPDModeSel is set elswhere. + // + // Partial Channel Power Down + // + MemNSetBitFieldNb (NBPtr, BFPrtlChPDDynDly, 4); + MemNSetBitFieldNb (NBPtr, BFPrtlChPDEnhEn, 0); + // + // Aggressive PowerDown + // + MemNSetBitFieldNb (NBPtr, BFAggrPDDelay, 0x20); + MemNSetBitFieldNb (NBPtr, BFAggrPDEn, 1); + // + // BFPchgPDEnDelay = + // IF (D18F2xA8_dct[0][AggrPDEn]) THEN + // (D18F2x200_dct[0]_mp[1:0][Tcl] + 5 + + // CEIL((MAX(D18F2x9C_x0000_00[2A:10]_dct[0]_mp[1:0][DqsRcvEnGrossDelay]) + // + 0.5) / 2)) ELSE 00h ENDIF. + // + if (MemNGetBitFieldNb (NBPtr, BFAggrPDEn) == 1) { + Tcl = NBPtr->DCTPtr->Timings.CasL; + MemNSetBitFieldNb (NBPtr, BFPchgPDEnDelay, Tcl + 5 + NBPtr->TechPtr->GetMinMaxGrossDly (NBPtr->TechPtr, AccessRcvEnDly, TRUE) / 2 + 1); + } else { + MemNSetBitFieldNb (NBPtr, BFPchgPDEnDelay, 0); + } + + // Program DRAM Power Management 1 register + Speed = NBPtr->DCTPtr->Timings.Speed; + i = (UINT8) ((Speed < DDR800_FREQUENCY) ? ((Speed / 66) - 3) : (Speed / 133)); + ASSERT ((i > 1) && (i < sizeof (PwrMngm1))); + MemNSetBitFieldNb (NBPtr, BFDramPwrMngm1Reg, PwrMngm1[i]); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Always set upper 2 bits of CKETri bitfield + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNBeforePlatformSpecKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MemNSetBitFieldNb (NBPtr, BFCSMapCKE, 0x08040201); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function programs MaxRdLatency based on the seeded value of RxEnDly + * prior to DQS Receiver Enable Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * + */ + +BOOLEAN +MemNSetMaxRdLatBasedOnSeededRxEnDlyKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 ChipSel; + + TechPtr = NBPtr->TechPtr; + + if (TechPtr->FindMaxDlyForMaxRdLat (TechPtr, &ChipSel)) { + NBPtr->SetMaxLatency (NBPtr, TechPtr->MaxDlyForMaxRdLat); + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function uses calculated values from DCT.Timings structure to + * program its registers for KB + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNProgramCycTimingsKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + CONST CTENTRY TmgAdjTab[] = { + // BitField, Min, Max, Bias, Ratio_x2 + {BFTcl, 5, 14, 0, 2}, + {BFTrcd, 2, 19, 0, 2}, + {BFTrp, 2, 19, 0, 2}, + {BFTrtp, 4, 10, 0, 2}, + {BFTras, 8, 40, 0, 2}, + {BFTrc, 10, 56, 0, 2}, + {BFTwrDDR3, 5, 16, 0, 2}, + {BFTrrd, 4, 9, 0, 2}, + {BFTwtr, 4, 9, 0, 2}, + {BFFourActWindow, 6, 42, 0, 2} + }; + + DCT_STRUCT *DCTPtr; + UINT8 *MiniMaxTmg; + UINT8 *MiniMaxTrfc; + UINT8 Value8; + UINT8 ValFAW; + UINT8 ValTrrd; + UINT8 j; + UINT8 Tcwl; + UINT8 RdOdtTrnOnDly; + BIT_FIELD_NAME BitField; + MEM_PARAMETER_STRUCT *RefPtr; + + DCTPtr = NBPtr->DCTPtr; + RefPtr = NBPtr->RefPtr; + + ValFAW = 0; + ValTrrd = 0; + + //====================================================================== + // Program DRAM Timing values + //====================================================================== + // + MiniMaxTmg = &DCTPtr->Timings.CasL; + for (j = 0; j < GET_SIZE_OF (TmgAdjTab); j++) { + BitField = TmgAdjTab[j].BitField; + + if (BitField == BFTrp) { + if (NBPtr->IsSupported[AdjustTrp]) { + MiniMaxTmg[j] ++; + if (MiniMaxTmg[j] < 5) { + MiniMaxTmg[j] = 5; + } + } + } + + if (MiniMaxTmg[j] < TmgAdjTab[j].Min) { + MiniMaxTmg[j] = TmgAdjTab[j].Min; + } else if (MiniMaxTmg[j] > TmgAdjTab[j].Max) { + MiniMaxTmg[j] = TmgAdjTab[j].Max; + } + + Value8 = (UINT8) MiniMaxTmg[j]; + + if (BitField == BFTwrDDR3) { + if ((Value8 > 8) && ((Value8 & 1) != 0)) { + Value8++; + } + } else if (BitField == BFTrrd) { + ValTrrd = Value8; + } else if (BitField == BFFourActWindow) { + ValFAW = Value8; + } + + MemNSetBitFieldNb (NBPtr, BitField, Value8); + } + + MiniMaxTrfc = &DCTPtr->Timings.Trfc0; + for (j = 0; j < 4; j++) { + if ((NBPtr->DCTPtr->Timings.DctDimmValid & (1 << j)) != 0) { + ASSERT (MiniMaxTrfc[j] <= 4); + MemNSetBitFieldNb (NBPtr, BFTrfc0 + j, MiniMaxTrfc[j]); + } + } + + Tcwl = (UINT8) (DCTPtr->Timings.Speed / 133) + 2; + Tcwl = (Tcwl > 5) ? Tcwl : 5; + MemNSetBitFieldNb (NBPtr, BFTcwl, Tcwl); + + if (RefPtr->DramDoubleRefreshRate) { + MemNSetBitFieldNb (NBPtr, BFTref, 3); // 3.9 us + } else { + MemNSetBitFieldNb (NBPtr, BFTref, 2); // 7.8 us + } + + RdOdtTrnOnDly = (DCTPtr->Timings.CasL > Tcwl) ? (DCTPtr->Timings.CasL - Tcwl) : 0; + MemNSetBitFieldNb (NBPtr, BFRdOdtTrnOnDly, RdOdtTrnOnDly); + NBPtr->FamilySpecificHook[ProgOdtControl] (NBPtr, NULL); + + // + // Program Tstag + // + if (NBPtr->MemPstate == 0) { + for (j = 0; j < 4; j++) { + MemNSetBitFieldNb (NBPtr, BFTstag0 + j, MAX (ValTrrd, (ValFAW + 3) / 4)); + } + } + + // + // Program Tmod + // + MemNSetBitFieldNb (NBPtr, BFTmod, (DCTPtr->Timings.Speed < DDR1866_FREQUENCY) ? 0x0C : + (DCTPtr->Timings.Speed > DDR1866_FREQUENCY) ? 0x10 : 0x0E); + // + // Program Tzqcs and Tzqoper + // + // Tzqcs max(64nCK, 80ns) + MemNSetBitFieldNb (NBPtr, BFTzqcs, MIN (6, (MAX (64, MemUnsToMemClk (NBPtr->DCTPtr->Timings.Speed, 80)) + 15) / 16)); + // Tzqoper max(256nCK, 320ns) + MemNSetBitFieldNb (NBPtr, BFTzqoper, MIN (0xC, (MAX (256, MemUnsToMemClk (NBPtr->DCTPtr->Timings.Speed, 320)) + 31) / 32)); + + // Program power management timing + MemNDramPowerMngTimingNb (NBPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnflowkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnflowkb.c new file mode 100644 index 0000000000..29aebe333b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnflowkb.c @@ -0,0 +1,129 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnflowkb.c + * + * KB initializer for MCT and DCT + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mnkb.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + +#define FILECODE PROC_MEM_NB_KB_MNFLOWKB_FILECODE +/* features */ + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function selects appropriate Tech functions for the NB. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNTechBlockSwitchKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + + TechPtr = NBPtr->TechPtr; + + // Specify Dimm-Byte training for Nb + MemTDimmByteTrainInit (TechPtr); + + // Remove the following functions because they are not needed for KB + TechPtr->SetDramMode = (BOOLEAN (*) (MEM_TECH_BLOCK *)) memDefTrue; + TechPtr->SpdCalcWidth = (BOOLEAN (*) (MEM_TECH_BLOCK *)) memDefTrue; + TechPtr->SetDqsEccTmgs = (BOOLEAN (*) (MEM_TECH_BLOCK *)) memDefTrue; + TechPtr->FindMaxDlyForMaxRdLat = MemTFindMaxRcvrEnDlyRdDqsDlyByteUnb; + TechPtr->ResetDCTWrPtr = MemTResetRcvFifoUnb; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnidendimmkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnidendimmkb.c new file mode 100644 index 0000000000..aa240d03cc --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnidendimmkb.c @@ -0,0 +1,147 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnidendimmkb.c + * + * TN northbridge constructor for dimm identification translator. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 84482 $ @e \$Date: 2012-12-16 22:48:10 -0600 (Sun, 16 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "mm.h" +#include "mn.h" +#include "OptionMemory.h" +#include "mnkb.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuFamRegisters.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + +#define FILECODE PROC_MEM_NB_KB_MNIDENDIMMKB_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemNIdentifyDimmConstructorKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ); + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the northbridge block for dimm identification translator + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * @param[in,out] NodeID - ID of current node to construct + * @return TRUE - This is the correct constructor for the targeted node. + * @return FALSE - This isn't the correct constructor for the targeted node. + */ + +BOOLEAN +MemNIdentifyDimmConstructorKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ) +{ + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemNIsIdSupportedKB (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { + return FALSE; + } + + NBPtr->NodeCount = 1; + NBPtr->DctCount = MAX_DCTS_PER_NODE_KB; + NBPtr->CsRegMsk = 0x7FF8FFE0; + NBPtr->MemPtr = MemPtr; + NBPtr->MCTPtr = &(MemPtr->DiesPerSystem[NodeID]); + NBPtr->PciAddr.AddressValue = MemPtr->DiesPerSystem[NodeID].PciAddr.AddressValue; + NBPtr->Node = ((UINT8) NBPtr->PciAddr.Address.Device) - 24; + NBPtr->Ganged = FALSE; + MemNInitNBRegTableKB (NBPtr, NBPtr->NBRegTable); + NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldKB; + NBPtr->GetBitField = MemNGetBitFieldNb; + NBPtr->SetBitField = MemNSetBitFieldNb; + NBPtr->GetSocketRelativeChannel = MemNGetSocketRelativeChannelNb; + NBPtr->FamilySpecificHook[DCTSelectSwitch] = MemNDctCfgSelectUnb; + NBPtr->FamilySpecificHook[FixupSysAddr] = MemNDefaultFamilyHookNb; + + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.c new file mode 100644 index 0000000000..dbc2de3ce6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.c @@ -0,0 +1,628 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnkb.c + * + * Common Northbridge functions for KB + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 87494 $ @e \$Date: 2013-02-04 12:06:47 -0600 (Mon, 04 Feb 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mm.h" +#include "mn.h" +#include "mnkb.h" +#include "mu.h" +#include "S3.h" +#include "cpuRegisters.h" +#include "cpuFamRegisters.h" +#include "cpuFamilyTranslation.h" +#include "heapManager.h" +#include "GeneralServices.h" +#include "IdsF16KbAllService.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_MEM_NB_KB_MNKB_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemNRegAccessFenceKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +/** + * Array for frequency change related parameters. + */ +CONST MEM_FREQ_CHANGE_PARAM FreqChangeParamKB = {0x0190, 0, 0, 0, 0, 0, 0, 0}; + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +extern PSO_ENTRY DefaultPlatformMemoryConfiguration[]; +extern OPTION_MEM_FEATURE_NB* memNTrainFlowControl[]; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the northbridge block + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * @param[in] *FeatPtr - Pointer to the MEM_FEAT_BLOCK_NB + * @param[in] *SharedPtr - Pointer to the MEM_SHARED_DATA + * @param[in] NodeID - UINT8 indicating node ID of the NB object. + * + * @return Boolean indicating that this is the correct memory + * controller type for the node number that was passed in. + */ + +BOOLEAN +MemConstructNBBlockKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN MEM_FEAT_BLOCK_NB *FeatPtr, + IN MEM_SHARED_DATA *SharedPtr, + IN UINT8 NodeID + ) +{ + UINT8 Dct; + UINT8 Channel; + UINT8 SpdSocketIndex; + UINT8 SpdChannelIndex; + DIE_STRUCT *MCTPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfSocket (MemPtr->DiesPerSystem->SocketId, &(MemPtr->DiesPerSystem->LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemNIsIdSupportedKB (&(MemPtr->DiesPerSystem->LogicalCpuid))) { + return FALSE; + } + + NBPtr->MemPtr = MemPtr; + NBPtr->RefPtr = MemPtr->ParameterListPtr; + NBPtr->SharedPtr = SharedPtr; + + MCTPtr = MemPtr->DiesPerSystem; + NBPtr->MCTPtr = MCTPtr; + NBPtr->MCTPtr->NodeId = NodeID; + NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue; + NBPtr->VarMtrrHiMsk = GetVarMtrrHiMsk (&(MemPtr->DiesPerSystem->LogicalCpuid), &(MemPtr->StdHeader)); + + // + // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs + // + AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_KB * ( + sizeof (DCT_STRUCT) + ( + MAX_CHANNELS_PER_DCT_KB * (sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK) + sizeof (CH_TIMING_STRUCT)) + ) + ); + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_DCT_STRUCT_AND_CH_DEF_STRUCTs, NBPtr->Node, 0, 0, 0, &MemPtr->StdHeader); + SetMemError (AGESA_FATAL, MCTPtr); + ASSERT(FALSE); // Could not allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs + return FALSE; + } + + MCTPtr->DctCount = MAX_DCTS_PER_NODE_KB; + MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_KB * sizeof (DCT_STRUCT); + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MCTPtr->DctData[Dct].Dct = Dct; + MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_KB; + MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[0].Dct = Dct; + AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_KB * sizeof (CH_DEF_STRUCT); + MCTPtr->DctData[Dct].TimingsMemPs1 = (CH_TIMING_STRUCT *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_KB * sizeof (CH_TIMING_STRUCT); + } + NBPtr->PSBlock = (MEM_PS_BLOCK *) AllocHeapParams.BufferPtr; + + // + // Initialize Socket List + // + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemPtr->SocketList[MCTPtr->SocketId].ChannelPtr[(MCTPtr->DieId * 2) + Dct] = &(MCTPtr->DctData[Dct].ChData[0]); + MemPtr->SocketList[MCTPtr->SocketId].TimingsPtr[(MCTPtr->DieId * 2) + Dct] = &(MCTPtr->DctData[Dct].Timings); + MCTPtr->DctData[Dct].ChData[0].ChannelID = (MCTPtr->DieId * 2) + Dct; + } + + MemNInitNBDataKB (NBPtr); + + FeatPtr->InitCPG (NBPtr); + FeatPtr->InitHwRxEn (NBPtr); + FeatPtr->InitEarlySampleSupport (NBPtr); + FeatPtr->InitRdWr2DTraining (NBPtr); + + NBPtr->FeatPtr = FeatPtr; + + // + // Calculate SPD Offsets per channel and assign pointers to the data. At this point, we calculate the Node-Dct-Channel + // centric offsets and store the pointers to the first DIMM of each channel in the Channel Definition struct for that + // channel. This pointer is then used later to calculate the offsets to be used for each logical dimm once the + // dimm types(QR or not) are known. This is done in the Technology block constructor. + // + // Calculate the SpdSocketIndex separately from the SpdChannelIndex. + // This will facilitate modifications due to some processors that might + // map the DCT-CHANNEL differently. + // + SpdSocketIndex = GetSpdSocketIndex (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, &MemPtr->StdHeader); + // + // Traverse the Dct/Channel structures + // + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_KB; Channel++) { + // + // Calculate the number of Dimms on this channel using the + // die/dct/channel to Socket/channel conversion. + // + SpdChannelIndex = GetSpdChannelIndex (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, + MemNGetSocketRelativeChannelNb (NBPtr, Dct, Channel), + &MemPtr->StdHeader); + NBPtr->MCTPtr->DctData[Dct].ChData[Channel].SpdPtr = &(MemPtr->SpdDataStructure[SpdSocketIndex + SpdChannelIndex]); + } + } + + // + // Initialize Dct and DctCfgSel bit + // + MemNSetBitFieldNb (NBPtr, BFDctCfgSel, 0); + MemNSwitchDCTNb (NBPtr, 0); + + if (MemNGetBitFieldNb (NBPtr, BFMemPstateDis) == 1) { + // MemPstate is disabled + NBPtr->MemPstateStage = 0; + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes member functions and variables of NB block. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNInitNBDataKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->DctCachePtr = NBPtr->DctCache; + NBPtr->PsPtr = NBPtr->PSBlock; + + MemNInitNBRegTableKB (NBPtr, NBPtr->NBRegTable); + NBPtr->Node = ((UINT8) NBPtr->PciAddr.Address.Device) - 24; + NBPtr->Dct = 0; + NBPtr->Channel = 0; + NBPtr->DctCount = MAX_DCTS_PER_NODE_KB; + NBPtr->ChannelCount = MAX_CHANNELS_PER_DCT_KB; + NBPtr->NodeCount = MAX_NODES_SUPPORTED_KB; + NBPtr->Ganged = FALSE; + NBPtr->PosTrnPattern = POS_PATTERN_256B; + NBPtr->MemCleared = FALSE; + NBPtr->StartupSpeed = DDR667_FREQUENCY; + NBPtr->RcvrEnDlyLimit = 0x1FF; + NBPtr->DefDctSelIntLvAddr = 4; + NBPtr->NbFreqChgState = 0; + NBPtr->FreqChangeParam = (MEM_FREQ_CHANGE_PARAM *) &FreqChangeParamKB; + NBPtr->MaxRxEnSeedTotal = 0x1FF; + NBPtr->MinRxEnSeedGross = 0; + NBPtr->CsRegMsk = 0x7FF8FFE0; + NBPtr->RdDqsDlyRetrnStat = RDDQSDLY_RTN_NEEDED; + NBPtr->MemPstate = MEMORY_PSTATE0; + NBPtr->MemPstateStage = MEMORY_PSTATE_1ST_STAGE; + NBPtr->CsPerChannel = MAX_CS_PER_CHANNEL_KB; + NBPtr->CsPerDelay = 1; + NBPtr->RdDqsDlyForMaxRdLat = 0x1F; + NBPtr->TotalMaxVrefRange = 0x20; + NBPtr->TotalRdDQSDlyRange = 0x40; + NBPtr->MaxSeedCount = MAX_2D_DQS_SEED_COUNT; + NBPtr->TotalBitTimes2DRdTraining = TOTAL_BIT_TIMES_2D_RD_TRAINING_KB; + NBPtr->TotalBitTimes2DWrTraining = TOTAL_BIT_TIMES_2D_WR_TRAINING_KB; + NBPtr->PhaseLaneMask = 0x3FFFF; + NBPtr->MaxDiamondStep = 3; + NBPtr->DiamondWidthRd = 9; + NBPtr->DiamondWidthWr = 9; + NBPtr->RdRolloverMultiple = 8; + + + LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader); + MemNInitNBDataNb (NBPtr); + + NBPtr->SetMaxLatency = MemNSetMaxLatencyKB; + NBPtr->getMaxLatParams = MemNGetMaxLatParamsKB; + NBPtr->InitializeMCT = MemNInitializeMctKB; + NBPtr->FinalizeMCT = MemNFinalizeMctKB; + NBPtr->SendMrsCmd = MemNSendMrsCmdUnb; + NBPtr->sendZQCmd = MemNSendZQCmdNb; + NBPtr->WritePattern = MemNWritePatternKB; + NBPtr->ReadPattern = MemNReadPatternKB; + NBPtr->GenHwRcvEnReads = (VOID (*) (MEM_NB_BLOCK *, UINT32)) memDefRet; + NBPtr->CompareTestPattern = MemNCompareTestPatternNb; + NBPtr->InsDlyCompareTestPattern = MemNInsDlyCompareTestPatternNb; + NBPtr->StitchMemory = MemNStitchMemoryNb; + NBPtr->AutoConfig = MemNAutoConfigKB; + NBPtr->PlatformSpec = MemNPlatformSpecUnb; + NBPtr->InitMCT = MemNInitMCTNb; + NBPtr->DisableDCT = MemNDisableDCTUnb; + NBPtr->StartupDCT = MemNStartupDCTUnb; + NBPtr->SyncTargetSpeed = MemNSyncTargetSpeedNb; + NBPtr->ChangeFrequency = MemNChangeFrequencyUnb; + NBPtr->RampUpFrequency = MemNRampUpFrequencyUnb; + NBPtr->ChangeNbFrequency = MemNChangeNbFrequencyUnb; + NBPtr->ChangeNbFrequencyWrap = MemNChangeNbFrequencyWrapUnb; + NBPtr->GetMemClkFreqInCurrentContext = MemNGetMemClkFreqInCurrentContextKB; + NBPtr->ProgramNbPsDependentRegs = MemNProgramNbPstateDependentRegistersKB; + NBPtr->ProgramCycTimings = MemNProgramCycTimingsKB; + NBPtr->SyncDctsReady = (BOOLEAN (*) (MEM_NB_BLOCK *)) memDefTrue; + NBPtr->HtMemMapInit = MemNHtMemMapInitKB; + NBPtr->SyncAddrMapToAllNodes = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; + NBPtr->CpuMemTyping = MemNCPUMemTypingNb; + NBPtr->BeforeDqsTraining = MemNBeforeDQSTrainingKB; + NBPtr->AfterDqsTraining = MemNAfterDQSTrainingKB; + NBPtr->OtherTiming = MemNOtherTimingKB; + NBPtr->UMAMemTyping = MemNUMAMemTypingNb; + NBPtr->GetSocketRelativeChannel = MemNGetSocketRelativeChannelNb; + NBPtr->TechBlockSwitch = MemNTechBlockSwitchKB; + NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldKB; + NBPtr->SetEccSymbolSize = MemNSetEccSymbolSizeNb; + NBPtr->TrainingFlow = MemNTrainingFlowUnb; + NBPtr->PollBitField = MemNPollBitFieldNb; + NBPtr->BrdcstCheck = MemNBrdcstCheckNb; + NBPtr->BrdcstSet = MemNBrdcstSetNb; + NBPtr->GetTrainDly = MemNGetTrainDlyNb; + NBPtr->SetTrainDly = MemNSetTrainDlyNb; + NBPtr->PhyFenceTraining = MemNPhyFenceTrainingUnb; + NBPtr->GetSysAddr = MemNGetMCTSysAddrNb; + NBPtr->RankEnabled = MemNRankEnabledNb; + NBPtr->MemNBeforeDramInitNb = MemNBeforeDramInitKB; + NBPtr->MemNcmnGetSetTrainDly = MemNcmnGetSetTrainDlyUnb; + NBPtr->MemPPhyFenceTrainingNb = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; + NBPtr->MemNInitPhyComp = MemNInitPhyCompKB; + NBPtr->MemNBeforePlatformSpecNb = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; + NBPtr->MemNPlatformSpecificFormFactorInitNb = MemNPlatformSpecificFormFactorInitTblDrvNb; + NBPtr->MemNPFenceAdjustNb = MemNPFenceAdjustKB; + NBPtr->GetTrainDlyParms = MemNGetTrainDlyParmsUnb; + NBPtr->TrainingPatternInit = MemNTrainingPatternInitNb; + NBPtr->TrainingPatternFinalize = MemNTrainingPatternFinalizeNb; + NBPtr->GetApproximateWriteDatDelay = MemNGetApproximateWriteDatDelayNb; + NBPtr->FlushPattern = MemNFlushPatternNb; + NBPtr->MinDataEyeWidth = MemNMinDataEyeWidthNb; + NBPtr->MemNCapSpeedBatteryLife = MemNCapSpeedBatteryLifeKB; + NBPtr->GetUmaSize = MemNGetUmaSizeKB; + NBPtr->GetMemClkFreqId = MemNGetMemClkFreqIdUnb; + NBPtr->EnableSwapIntlvRgn = (VOID (*) (MEM_NB_BLOCK *, UINT32, UINT32)) memDefRet; + NBPtr->WaitXMemClks = MemNWaitXMemClksNb; + NBPtr->MemNGetDramTerm = MemNGetDramTermTblDrvNb; + NBPtr->MemNGetDynDramTerm = MemNGetDynDramTermTblDrvNb; + NBPtr->MemNGetMR0CL = MemNGetMR0CLTblDrvNb; + NBPtr->MemNGetMR0WR = MemNGetMR0WRTblDrvNb; + NBPtr->MemNSaveMR0 = (VOID (*) (MEM_NB_BLOCK *, UINT32)) memDefRet; + NBPtr->MemNGetMR2CWL = MemNGetMR2CWLUnb; + NBPtr->AllocateC6Storage = MemNAllocateC6StorageKB; + NBPtr->MemNBeforePlatformSpecNb = MemNBeforePlatformSpecKB; + NBPtr->AgressorContinuousWrites = MemNAgressorContinuousWritesUnb; + NBPtr->GetPrbs2dRdDqsSeed = (UINT32 (*) (struct _MEM_NB_BLOCK *NBPtr , UINT8 SeedCount)) memDefRet; + NBPtr->InPhaseCompareRdDqs2DPattern = (UINT32 (*) (struct _MEM_NB_BLOCK *NBPtr, UINT8 Buffer[], UINT8 Pattern[], UINT16 ByteCount)) memDefRet; + NBPtr->Phase180CompareRdDqs2DPattern = (UINT32 (*) (struct _MEM_NB_BLOCK *NBPtr, UINT8 Buffer[], UINT8 Pattern[], UINT16 ByteCount)) memDefRet; + NBPtr->InitializeRdDqs2dVictimContinuousWrites = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; + NBPtr->FinalizeRdDqs2dVictimContinuousWrites = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; + NBPtr->InitializeRdDqs2dVictimChipSelContinuousWrites = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; + NBPtr->StartRdDqs2dVictimContinuousWrites = (VOID (*) (struct _MEM_NB_BLOCK *NBPtr , UINT8 SeedCount)) memDefRet; + NBPtr->MemN2DRdDQSDataCollection = (BOOLEAN (*) (MEM_NB_BLOCK *)) memDefRet; + NBPtr->MemNGetMemoryWidth = MemNGetMemoryWidthUnb; + NBPtr->MemNDisableScrubber = MemNDisableScrubberKB; + NBPtr->MemNRestoreScrubber = MemNRestoreScrubberKB; + NBPtr->MemNSetEccExclusionRange = MemNSetEccExclusionRangeUnb; + + NBPtr->IsSupported[SetDllShutDown] = TRUE; + NBPtr->IsSupported[CheckEccDLLPwrDnConfig] = TRUE; + NBPtr->IsSupported[CheckMaxDramRate] = TRUE; + NBPtr->IsSupported[CheckPhyFenceTraining] = TRUE; + NBPtr->IsSupported[CheckSendAllMRCmds] = TRUE; + NBPtr->IsSupported[CheckFindPSOverideWithSocket] = TRUE; + NBPtr->IsSupported[FenceTrnBeforeDramInit] = TRUE; + NBPtr->IsSupported[UnifiedNbFence] = TRUE; + NBPtr->IsSupported[CheckODTControls] = TRUE; + NBPtr->IsSupported[EccByteTraining] = TRUE; + NBPtr->IsSupported[CheckDramTerm] = TRUE; + NBPtr->IsSupported[CheckDramTermDyn] = TRUE; + NBPtr->IsSupported[CheckQoff] = TRUE; + NBPtr->IsSupported[CheckDrvImpCtrl] = TRUE; + NBPtr->IsSupported[CheckSetSameDctODTsEn] = TRUE; + NBPtr->IsSupported[WLSeedAdjust] = TRUE; + NBPtr->IsSupported[WLNegativeDelay] = TRUE; + NBPtr->IsSupported[TwoStageDramInit] = TRUE; + NBPtr->IsSupported[ForceEnMemHoleRemapping] = TRUE; + NBPtr->IsSupported[ProgramCsrComparator] = TRUE; + NBPtr->IsSupported[AdjustTrp] = TRUE; // erratum 638 + NBPtr->IsSupported[ForcePhyToM0] = TRUE; + NBPtr->IsSupported[SwitchRdDqsDlyForMaxRdLatency] = TRUE; + NBPtr->IsSupported[OptimizedPatternWrite2D] = TRUE; + + NBPtr->FamilySpecificHook[ExitPhyAssistedTraining] = MemNExitPhyAssistedTrainingKB; + NBPtr->FamilySpecificHook[DCTSelectSwitch] = MemNDctCfgSelectUnb; + NBPtr->FamilySpecificHook[AfterSaveRestore] = MemNAfterSaveRestoreUnb; + NBPtr->FamilySpecificHook[OverrideRcvEnSeed] = MemNOverrideRcvEnSeedKB; + NBPtr->FamilySpecificHook[OverrideWLSeed] = MemNOverrideWLSeedKB; + NBPtr->FamilySpecificHook[CalcWrDqDqsEarly] = MemNCalcWrDqDqsEarlyKB; + NBPtr->FamilySpecificHook[AdjustRdDqsDlyOffset] = MemNAdjustRdDqsDlyOffsetUnb; + NBPtr->FamilySpecificHook[GetDdrMaxRate] = MemNGetMaxDdrRateUnb; + NBPtr->FamilySpecificHook[AfterMemClkFreqVal] = MemNAdjustPllLockTimeKB; + NBPtr->FamilySpecificHook[AdjustCSIntLvLowAddr] = MemNCSIntLvLowAddrAdjKB; + NBPtr->FamilySpecificHook[ReleaseNbPstate] = MemNReleaseNbPstateKB; + NBPtr->FamilySpecificHook[InitializeRxEnSeedlessTraining] = MemNInitializeRxEnSeedlessTrainingUnb; + NBPtr->FamilySpecificHook[TrackRxEnSeedlessRdWrNoWindBLError] = MemNTrackRxEnSeedlessRdWrNoWindBLErrorUnb; + NBPtr->FamilySpecificHook[TrackRxEnSeedlessRdWrSmallWindBLError] = MemNTrackRxEnSeedlessRdWrSmallWindBLErrorUnb; + NBPtr->FamilySpecificHook[InitialzeRxEnSeedlessByteLaneError] = MemNInitialzeRxEnSeedlessByteLaneErrorUnb; + NBPtr->FamilySpecificHook[MemPstateStageChange] = MemNMemPstateStageChangeKB; + NBPtr->FamilySpecificHook[ProgramFence2RxDll] = MemNProgramFence2RxDllKB; + NBPtr->FamilySpecificHook[RdDqsDlyRestartChk] = MemNRdDqsDlyRestartChkKB; + NBPtr->FamilySpecificHook[BeforeWrDatTrn] = MemNHookBfWrDatTrnKB; + NBPtr->FamilySpecificHook[RegAccessFence] = MemNRegAccessFenceKB; + NBPtr->FamilySpecificHook[AdjustWrDqsBeforeSeedScaling] = MemNAdjustWrDqsBeforeSeedScalingUnb; + NBPtr->FamilySpecificHook[WLMR1] = MemNWLMR1KB; + NBPtr->FamilySpecificHook[Adjust2DPhaseMaskBasedOnEcc] = MemNAdjust2DPhaseMaskBasedOnEccUnb; + NBPtr->FamilySpecificHook[ProgramPOdtOff] = MemNProgramPOdtOffKB; + NBPtr->FamilySpecificHook[RelocatePscTblEntryByMotherBoardLayer] = memNRelocatePscTableEntryByMotherBoardLayerKB; + NBPtr->FamilySpecificHook[AdjustHwRcvEnSeedGross] = MemNAdjustHwRcvEnSeedGrossKB; + NBPtr->FamilySpecificHook[ForceEccSymbolSize] = MemNForceEccSymbolSizeKB; + NBPtr->FamilySpecificHook[AdjustRdDqsDlyForMaxRdLat] = MemNAdjustRdDqsDlyForMaxRdLatUnb; + NBPtr->FamilySpecificHook[SetMaxRdLatBasedOnSeededRxEnDly] = MemNSetMaxRdLatBasedOnSeededRxEnDlyKB; + NBPtr->FamilySpecificHook[DisableMemHoleMapping] = MemNDisableMemHoleMappingKB; + NBPtr->FamilySpecificHook[RestoreMemHoleMapping] = MemNRestoreMemHoleMappingKB; + NBPtr->FamilySpecificHook[PhyInitVref] = MemNPhyInitVrefKB; + + IEM_INSERT_CODE (IEM_NBBLOCK_INIT, IemInitNBDataOverrideKB, (NBPtr)); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the default values in the MEM_DATA_STRUCT + * + * NOTE: This function must first verify the NB Family. + * + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * + */ +VOID +MemNInitDefaultsKB ( + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + MEM_PARAMETER_STRUCT *RefPtr; + CPU_LOGICAL_ID LogicalCpuid; + ASSERT (MemPtr != NULL); + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfCurrentCore (&LogicalCpuid, &(MemPtr->StdHeader)); + if (MemNIsIdSupportedKB (&LogicalCpuid)) { + RefPtr = MemPtr->ParameterListPtr; + RefPtr->EnableNodeIntlv = FALSE; + RefPtr->EnableChannelIntlv = FALSE; + RefPtr->EnableParity = FALSE; + RefPtr->EnableOnLineSpareCtl = FALSE; + } +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function writes training pattern + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Pattern[] - Pattern to write + * @param[in] Address - System Address [47:16] + * @param[in] ClCount - Number of cache lines + * + */ + +VOID +MemNWritePatternKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ) +{ + Address = MemUSetUpperFSbase (Address, NBPtr->MemPtr); + MemUWriteCachelines (Address, Pattern, ClCount); +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function reads training pattern + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Buffer to fill + * @param[in] Address - System Address [47:16] + * @param[in] ClCount - Number of cache lines + * + */ + +VOID +MemNReadPatternKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ) +{ + Address = MemUSetUpperFSbase (Address, NBPtr->MemPtr); + MemUReadCachelines (Buffer, Address, ClCount); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initiates DQS training for KB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +BOOLEAN +memNEnableTrainSequenceKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + BOOLEAN Retval; + Retval = TRUE; + if (!MemNIsIdSupportedKB (&(NBPtr->MemPtr->DiesPerSystem[NBPtr->MCTPtr->NodeId].LogicalCpuid))) { + Retval = FALSE; + } + return Retval; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function obtains PSC table entry pointer by mother board layer design for KB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *TblEntryPtr - Pointer to the PSC table entry + * + */ + +BOOLEAN +memNRelocatePscTableEntryByMotherBoardLayerKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *TblEntryPtr + ) +{ + PSC_TBL_ENTRY **TblEntry; + UINT8 *SwitchCountPtr; + UINT8 i; + + SwitchCountPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MOTHER_BOARD_LAYERS, 0, 0, 0, NULL, NULL); + if (SwitchCountPtr != NULL) { + // + // Relocate the table entry pointer to the set for the current mother board design + // + TblEntry = *(PSC_TBL_ENTRY ***) TblEntryPtr; + for (i = 0; i < *SwitchCountPtr; i ++) { + while (*TblEntry != NULL) { + TblEntry ++; + } + TblEntry ++; + } + *(PSC_TBL_ENTRY ***) TblEntryPtr = TblEntry; + } + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function makes sure that previous phy register writes are done. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * + */ + +BOOLEAN +STATIC +MemNRegAccessFenceKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + // If subsequent writes to this array are scheduled, such as when writing several byte lanes during dram + // training, then it is recommended to issue a dummy register read to ensure the last write. + NBPtr->GetTrainDly (NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (0, 0)); + + return TRUE; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.h new file mode 100644 index 0000000000..628df0cc90 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnkb.h @@ -0,0 +1,410 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnkb.h + * + * Northbridge KB + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 87494 $ @e \$Date: 2013-02-04 12:06:47 -0600 (Mon, 04 Feb 2013) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MNKB_H_ +#define _MNKB_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ +#define MAX_DCTS_PER_NODE_KB 1 +#define MAX_CHANNELS_PER_DCT_KB 1 +#define MAX_NODES_SUPPORTED_KB 1 +#define MAX_CS_PER_CHANNEL_KB 4 + +#define DEFAULT_WR_ODT_KB 6 +#define DEFAULT_RD_ODT_KB 6 +#define DEFAULT_RD_ODT_TRNONDLY_KB 0 + +#define TOTAL_BIT_TIMES_2D_RD_TRAINING_KB (64 * 1024) +#define TOTAL_BIT_TIMES_2D_WR_TRAINING_KB (64 * 1024) +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemConstructNBBlockKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN MEM_FEAT_BLOCK_NB *FeatPtr, + IN MEM_SHARED_DATA *SharedPtr, + IN UINT8 NodeID + ); + +VOID +MemNInitNBDataKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNInitDefaultsKB ( + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +BOOLEAN +MemNInitializeMctKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNAutoConfigKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNOtherTimingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNInitPhyCompKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNWritePatternKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ); + +VOID +MemNReadPatternKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ); + +VOID +MemNInitNBRegTableKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT TSEFO NBRegTable[] + ); + +BOOLEAN +MemNIsIdSupportedKB ( + IN CPU_LOGICAL_ID *LogicalIdPtr + ); + +UINT32 +MemNCmnGetSetFieldKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ); + +BOOLEAN +memNEnableTrainSequenceKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNTechBlockSwitchKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNAfterDQSTrainingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNCapSpeedBatteryLifeKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNGetMaxLatParamsKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT16 MaxRcvEnDly, + IN OUT UINT16 *MinDlyPtr, + IN OUT UINT16 *MaxDlyPtr, + IN OUT UINT16 *DlyBiasPtr + ); + +VOID +MemNSetMaxLatencyKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT16 MaxRcvEnDly + ); + +BOOLEAN +MemNExitPhyAssistedTrainingKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemNOverrideRcvEnSeedKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *SeedPtr + ); + +VOID +MemNBeforeDQSTrainingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +UINT16 +MemNGetMemClkFreqInCurrentContextKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNProgramNbPstateDependentRegistersKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNAdjustPllLockTimeKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *PllLockTime + ); + +BOOLEAN +MemNOverrideWLSeedKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *SeedPtr + ); + +BOOLEAN +MemNFinalizeMctKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNHtMemMapInitKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +UINT32 +MemNGetUmaSizeKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNBeforeDramInitKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNCSIntLvLowAddrAdjKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *LowBit + ); + +VOID +MemNAllocateC6StorageKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNPFenceAdjustKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT INT16 *Value16 + ); + +BOOLEAN +MemNReleaseNbPstateKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemNMemPstateStageChangeKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemNProgramFence2RxDllKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Fence2Data + ); + +BOOLEAN +MemNRdDqsDlyRestartChkKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Center + ); + +BOOLEAN +MemNHookBfWrDatTrnKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *ChipSel + ); + +VOID +MemNSetOtherTimingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNPowerDownCtlKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNBeforePlatformSpecKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNWLMR1KB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Value + ); + +BOOLEAN +MemNProgramPOdtOffKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Value + ); + +BOOLEAN +memNRelocatePscTableEntryByMotherBoardLayerKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *TblEntryPtr + ); + +BOOLEAN +MemNAdjustHwRcvEnSeedGrossKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Value + ); + +BOOLEAN +MemNPowerSavingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNForceEccSymbolSizeKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Size + ); + +BOOLEAN +MemNCalcWrDqDqsEarlyKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +VOID +MemNConfigureDctTrainingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNProgramNonSeqDependentRegistersKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNConfigureDctNormalKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNSetMaxRdLatBasedOnSeededRxEnDlyKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +VOID +MemNPhyPowerSavingMPstateKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNDisableScrubberKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNRestoreScrubberKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNProgramCycTimingsKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNDisableMemHoleMappingKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemNRestoreMemHoleMappingKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemNPhyInitVrefKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ); +#endif /* _MNKB_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnmctkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnmctkb.c new file mode 100644 index 0000000000..e1ffb28f9b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnmctkb.c @@ -0,0 +1,551 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnmctkb.c + * + * Northbridge KB MCT supporting functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 87696 $ @e \$Date: 2013-02-07 12:35:03 -0600 (Thu, 07 Feb 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mport.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbHandleLib.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "mm.h" +#include "mn.h" +#include "OptionMemory.h" +#include "mnkb.h" +#include "cpuFeatures.h" +#include "Filecode.h" +#include "mftds.h" +#include "mu.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + +#define FILECODE PROC_MEM_NB_KB_MNMCTKB_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define _16MB_RJ16 0x0100 +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function force memory Pstate to M0 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemNInitializeMctKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MemNSetBitFieldNb (NBPtr, BFMemPsSel, 0); + MemNSetBitFieldNb (NBPtr, BFEnSplitMctDatBuffers, 1); + + MemNBrdcstSetUnConditionalNb (NBPtr, BFPStateToAccess, 0); + + MemNForcePhyToM0Unb (NBPtr); + + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets final values for specific registers. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemNFinalizeMctKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_DATA_STRUCT *MemPtr; + MEM_PARAMETER_STRUCT *RefPtr; + DRAM_PREFETCH_MODE DramPrefetchMode; + UINT16 Speed; + UINT32 Value32; + UINT8 DcqBwThrotWm1; + UINT8 DcqBwThrotWm2; + + MemPtr = NBPtr->MemPtr; + RefPtr = MemPtr->ParameterListPtr; + DramPrefetchMode = MemPtr->PlatFormConfig->PlatformProfile.AdvancedPerformanceProfile.DramPrefetchMode; + Speed = NBPtr->DCTPtr->Timings.Speed; + + // + // F2x11C + // + MemNSetBitFieldNb (NBPtr, BFMctCfgHiReg, 0x0CE00F30); + if (DramPrefetchMode == DISABLE_DRAM_PREFETCH_FOR_IO || DramPrefetchMode == DISABLE_DRAM_PREFETCHER) { + MemNSetBitFieldNb (NBPtr, BFPrefIoDis, 1); + } + + if (DramPrefetchMode == DISABLE_DRAM_PREFETCH_FOR_CPU || DramPrefetchMode == DISABLE_DRAM_PREFETCHER) { + MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 1); + } + + + if (Speed == DDR667_FREQUENCY) { + DcqBwThrotWm1 = 3; + DcqBwThrotWm2 = 4; + } else if (Speed == DDR800_FREQUENCY) { + DcqBwThrotWm1 = 3; + DcqBwThrotWm2 = 5; + } else if (Speed == DDR1066_FREQUENCY) { + DcqBwThrotWm1 = 4; + DcqBwThrotWm2 = 6; + } else if (Speed == DDR1333_FREQUENCY) { + DcqBwThrotWm1 = 5; + DcqBwThrotWm2 = 8; + } else if (Speed == DDR1600_FREQUENCY) { + DcqBwThrotWm1 = 6; + DcqBwThrotWm2 = 9; + } else if (Speed == DDR1866_FREQUENCY) { + DcqBwThrotWm1 = 7; + DcqBwThrotWm2 = 10; + } else { + DcqBwThrotWm1 = 8; + DcqBwThrotWm2 = 12; + } + // + // F2x1B0 + // + Value32 = MemNGetBitFieldNb (NBPtr, BFExtMctCfgLoReg); + Value32 &= 0x003FE8C0; + Value32 |= 0x0FC01001; + MemNSetBitFieldNb (NBPtr, BFExtMctCfgLoReg, Value32); + + // + // F2x1B4 + // + Value32 = MemNGetBitFieldNb (NBPtr, BFExtMctCfgHiReg); + Value32 &= 0xFFFFFC00; + Value32 |= (((UINT32) DcqBwThrotWm2 << 5) | (UINT32) DcqBwThrotWm1); + MemNSetBitFieldNb (NBPtr, BFExtMctCfgHiReg, Value32); + + // Set LockDramCfg + if (IsFeatureEnabled (C6Cstate, NBPtr->MemPtr->PlatFormConfig, &(NBPtr->MemPtr->StdHeader))) { + IDS_SKIP_HOOK (IDS_LOCK_DRAM_CFG, NBPtr, &NBPtr->MemPtr->StdHeader) { + MemNSetBitFieldNb (NBPtr, BFLockDramCfg, 1); + } + } + + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function create the HT memory map for KB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemNHtMemMapInitKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 WeReMask; + UINT8 LgcyMmioHoleEn; + UINT32 BottomIo; + UINT32 HoleOffset; + UINT32 DctLimitAddr; + UINT32 NodeSysBase; + UINT32 NodeSysLimit; + MEM_PARAMETER_STRUCT *RefPtr; + DIE_STRUCT *MCTPtr; + + RefPtr = NBPtr->RefPtr; + MCTPtr = NBPtr->MCTPtr; + // + // Physical addresses in this function are right adjusted by 16 bits ([47:16]) + // They are BottomIO, HoleOffset, DctLimitAddr, NodeSysBase, NodeSysLimit. + // + + // Enforce bottom of IO be be 128MB aligned + BottomIo = (RefPtr->BottomIo & 0xF8) << 8; + + if (MCTPtr->NodeMemSize != 0) { + NodeSysBase = 0; + NodeSysLimit = MCTPtr->NodeMemSize - 1; + DctLimitAddr = MCTPtr->DctData[0].Timings.DctMemSize; + LgcyMmioHoleEn = 0; + + if (NodeSysLimit >= BottomIo) { + // HW Dram Remap + MCTPtr->Status[SbHWHole] = TRUE; + RefPtr->GStatus[GsbHWHole] = TRUE; + MCTPtr->NodeHoleBase = BottomIo; + RefPtr->HoleBase = BottomIo; + + HoleOffset = _4GB_RJ16 - BottomIo; + + NodeSysLimit += HoleOffset; + + if ((DctLimitAddr > 0) && (DctLimitAddr < BottomIo)) { + HoleOffset += DctLimitAddr; + } else { + if (DctLimitAddr >= BottomIo) { + DctLimitAddr += HoleOffset; + } + HoleOffset += NodeSysBase; + LgcyMmioHoleEn = 1; + } + + MemNSetBitFieldNb (NBPtr, BFDramHoleBase, BottomIo >> 8); + MemNSetBitFieldNb (NBPtr, BFDramHoleOffset, HoleOffset >> 7); + MemNSetBitFieldNb (NBPtr, BFDramHoleValid, 1); + MemNSetBitFieldNb (NBPtr, BFDramMemHoistValid, 1); + } else { + // No Remapping. Normal Contiguous mapping + } + MCTPtr->NodeSysBase = NodeSysBase; + MCTPtr->NodeSysLimit = NodeSysLimit; + RefPtr->SysLimit = MCTPtr->NodeSysLimit; + + WeReMask = 3; + // Set the Dram base and set the WE and RE flags in the base. + MemNSetBitFieldNb (NBPtr, BFDramBaseReg0, (NodeSysBase << 8) | WeReMask); + // Set the Dram limit and set DstNode. + MemNSetBitFieldNb (NBPtr, BFDramLimitReg0, ((NodeSysLimit << 8) & 0xFFFF0000)); + + MemNSetBitFieldNb (NBPtr, BFDramBaseAddr, NodeSysBase >> (27 - 16)); + MemNSetBitFieldNb (NBPtr, BFDramLimitAddr, NodeSysLimit >> (27 - 16)); + + MemNSetBitFieldNb (NBPtr, BFDramCtrlBaseReg0, 1); + MemNSetBitFieldNb (NBPtr, BFLgcyMmioHoleEn0, LgcyMmioHoleEn); + MemNSetBitFieldNb (NBPtr, BFDramCtrlLimitReg0, ((DctLimitAddr - 1) >> (27 - 16 - 11)) & 0xFFFFF800); + } + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Report the Uma size that is going to be allocated. + * Total system memory UMASize + * >= 2G 512M + * >=1G 256M + * <1G 64M + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return Uma size [31:0] = Addr [47:16] + */ +UINT32 +MemNGetUmaSizeKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 SysMemSize; + UINT32 SizeOfUma; + + SysMemSize = NBPtr->RefPtr->SysLimit + 1; + SysMemSize = (SysMemSize + 0x100) & 0xFFFFF000; // Ignore 16MB allocated for C6 when finding UMA size + if (SysMemSize >= 0x8000) { + SizeOfUma = 512 << (20 - 16); + } else if (SysMemSize >= 0x4000) { + SizeOfUma = 256 << (20 - 16); + } else { + SizeOfUma = 64 << (20 - 16); + } + + return SizeOfUma; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function allocates 16MB of memory for C6 storage when it is requested to be enabled + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNAllocateC6StorageKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 SysLimit; + UINT32 DramLimitReg; + + if (NBPtr->SharedPtr->C6Enabled || IsFeatureEnabled (C6Cstate, NBPtr->MemPtr->PlatFormConfig, &(NBPtr->MemPtr->StdHeader))) { + + SysLimit = NBPtr->RefPtr->SysLimit; + + // Calculate new SysLimit + if (!NBPtr->SharedPtr->C6Enabled) { + // System memory available is reduced by 16MB + SysLimit -= _16MB_RJ16; + + NBPtr->MCTPtr->NodeSysLimit = SysLimit; + NBPtr->RefPtr->SysLimit = SysLimit; + NBPtr->SharedPtr->C6Enabled = TRUE; + + // Set TOPMEM and MTRRs (only need to be done once for BSC) + MemNC6AdjustMSRs (NBPtr); + } + + // Set Dram Limit + DramLimitReg = MemNGetBitFieldNb (NBPtr, BFDramLimitReg0) & 0x0000FFFF; + MemNSetBitFieldNb (NBPtr, BFDramLimitReg0, ((SysLimit << 8) & 0xFFFF0000) | DramLimitReg); + MemNSetBitFieldNb (NBPtr, BFDramLimitHiReg0, SysLimit >> 24); + + // Set BFCC6SaveEn and LockDramCfg + MemNSetBitFieldNb (NBPtr, BFCC6SaveEn, 1); + IDS_SKIP_HOOK (IDS_LOCK_DRAM_CFG, NBPtr, &NBPtr->MemPtr->StdHeader) { + MemNSetBitFieldNb (NBPtr, BFLockDramCfg, 1); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function programs Powerdown and other power saving features for KB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemNPowerSavingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + // + // Phy Power Saving + // + MemNPhyPowerSavingMPstateKB (NBPtr); + if (NBPtr->MemPstateStage == MEMORY_PSTATE_3RD_STAGE) { + MemNChangeMemPStateContextNb (NBPtr, 1); + MemNPhyPowerSavingMPstateKB (NBPtr); + MemFInitTableDrive (NBPtr, MTAfterSettingMemoryPstate1); + MemNChangeMemPStateContextNb (NBPtr, 0); + } + // + // Power Down Enable + // + if (NBPtr->RefPtr->EnablePowerDown) { + MemNSetBitFieldNb (NBPtr, BFPowerDownEn, 1); + } + } + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function force the ECC symbol size + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Size - ECC symbol size + * + * @return TRUE + */ + +BOOLEAN +MemNForceEccSymbolSizeKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Size + ) +{ + *(BOOLEAN *)Size = FALSE; + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function disables scrubber temporarily for write access to + * DCT additional address space + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNDisableScrubberKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->DisDramScrub = NBPtr->GetBitField (NBPtr, BFDisDramScrub); + NBPtr->SetBitField (NBPtr, BFDisDramScrub, 1); + NBPtr->GetBitField (NBPtr, BFDisDramScrub); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function restores scrubber settings + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNRestoreScrubberKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->SetBitField (NBPtr, BFDisDramScrub, NBPtr->DisDramScrub); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function disable memory hole mappings + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Optional parameter + * + * @return TRUE + */ + +BOOLEAN +MemNDisableMemHoleMappingKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 Range; + CONST BIT_FIELD_NAME LgcyMmioHoleEnBF[] = {BFLgcyMmioHoleEn0}; + + for (Range = 0; Range < sizeof (LgcyMmioHoleEnBF) / sizeof (BIT_FIELD_NAME); Range++) { + NBPtr->LgcyMmioHoleEnMap &= ~(1 << Range); + NBPtr->LgcyMmioHoleEnMap |= (NBPtr->GetBitField (NBPtr, LgcyMmioHoleEnBF[Range]) << Range); + NBPtr->SetBitField (NBPtr, LgcyMmioHoleEnBF[Range], 0); + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function restore memory hole mappings + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Optional parameter + * + * @return TRUE + */ + +BOOLEAN +MemNRestoreMemHoleMappingKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 Range; + CONST BIT_FIELD_NAME LgcyMmioHoleEnBF[] = {BFLgcyMmioHoleEn0}; + + for (Range = 0; Range < sizeof (LgcyMmioHoleEnBF) / sizeof (BIT_FIELD_NAME); Range++) { + NBPtr->SetBitField (NBPtr, LgcyMmioHoleEnBF[Range], (NBPtr->LgcyMmioHoleEnMap >> Range) & 1); + } + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c new file mode 100644 index 0000000000..1b5350ad01 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c @@ -0,0 +1,268 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnotkb.c + * + * Northbridge Non-SPD timings for KB + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "OptionMemory.h" +#include "mnkb.h" +#include "mu.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_MEM_NB_KB_MNOTKB_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the non-SPD timings + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemNOtherTimingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart Programming of Non-SPD Timings.\n"); + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctDimmValid > 0) { + MemNSetOtherTimingKB (NBPtr); + } + } + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the non-SPD timings in PCI registers + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNSetOtherTimingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + INT8 ROD; + INT8 WOD; + INT8 LD; + INT8 WrEarlyx2; + INT8 CDDTrdrdSdDc; + INT8 CDDTrdrdDd; + INT8 CDDTwrwrDd; + INT8 CDDTwrwrSdDc; + INT8 CDDTrwtTO; + INT8 CDDTwrrd; + UINT8 TrdrdSdDc; + UINT8 TrdrdDd; + UINT8 TwrwrSdDc; + UINT8 TwrwrDd; + UINT8 TrdrdSdSc; + UINT8 TwrwrSdSc; + UINT8 Twrrd; + UINT8 TrwtTO; + BOOLEAN PerRankTimingEn; + + CH_DEF_STRUCT *ChannelPtr; + ChannelPtr = NBPtr->ChannelPtr; + + PerRankTimingEn = (BOOLEAN) (MemNGetBitFieldNb (NBPtr, BFPerRankTimingEn)); + // + // Latency Difference (LD) = Tcl - Tcwl + // + LD = (INT8) (MemNGetBitFieldNb (NBPtr, BFTcl)) - (INT8) (MemNGetBitFieldNb (NBPtr, BFTcwl)); + + // + // Read ODT Delay (ROD) = MAX ( 0, (RdOdtOnDuration - 6)) + // + ROD = MAX (0, (INT8) (MemNGetBitFieldNb (NBPtr, BFRdOdtOnDuration) - 6)); + // + // Write ODT Delay (WOD) = MAX (0, (WrOdtOnDuration - 6)) + // + WOD = MAX (0, (INT8) (MemNGetBitFieldNb (NBPtr, BFWrOdtOnDuration) - 6)); + // + // WrEarly = ABS (WrDqDqsEarly) / 2 + // + WrEarlyx2 = (INT8) MemNGetBitFieldNb (NBPtr, BFWrDqDqsEarly); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tLD: %d ROD: %d WOD: %d WrEarlyx2: %d\n\n", LD, ROD, WOD, WrEarlyx2); + // + // Read to Read Timing (TrdrdSdSc, TrdrdScDc, TrdrdDd) + // + // TrdrdSdSc = 1. + // TrdrdSdDc (in MEMCLKs) = MAX(TrdrdSdSc, 3 + (IF (D18F2xA8_dct[0][PerRankTimingEn]) + // THEN CEIL(CDDTrdrdSdDc / 2 + 0.5) ELSE 0 ENDIF)). + // TrdrdDd (in MEMCLKs) = MAX(TrdrdSdDc, ROD + 3, CEIL(CDDTrdrdDd/2 + 3.5)). + // + TrdrdSdSc = 1; + + CDDTrdrdSdDc = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessRcvEnDly, TRUE, FALSE); + TrdrdSdDc = MAX (TrdrdSdSc, PerRankTimingEn ? (3 + (CDDTrdrdSdDc + 1 + 1) / 2) : 3); + + CDDTrdrdDd = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessRcvEnDly, FALSE, TRUE); + TrdrdDd = MAX (ROD + 3, (CDDTrdrdDd + 7 + 1) / 2); + TrdrdDd = MAX (TrdrdSdDc, TrdrdDd); + + MemNSetBitFieldNb (NBPtr, BFTrdrdDd, (UINT32) TrdrdDd); + MemNSetBitFieldNb (NBPtr, BFTrdrdSdDc, (UINT32) TrdrdSdDc); + MemNSetBitFieldNb (NBPtr, BFTrdrdSdSc, (UINT32) TrdrdSdSc); + // + // Write to Write Timing (TwrwrSdSc, TwrwrScDc, TwrwrDd) + // + // TwrwrSdSc (in MEMCLKs) = 1. + // TwrwrSdDc (in MEMCLKs) = MAX(TwrwrSdSc, WOD + 3, 3 + (IF (D18F2xA8_dct[0][PerRank-TimingEn]) + // THEN CEIL(CDDTwrwrSdDc / 2 + 0.5) ELSE 0 ENDIF)). + // + // TwrwrDd (in MEMCLKs) = MAX(TwrwrSdDc, WOD + 3, CEIL(CDDTwrwrDd / 2 + 3.5)). + // + TwrwrSdSc = 1; + + CDDTwrwrSdDc = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessWrDqsDly, TRUE, FALSE); + TwrwrSdDc = (UINT8) MAX ((UINT8) (WOD + 3), (3 + (PerRankTimingEn ? ((CDDTwrwrSdDc + 1 + 1) / 2) : 0))); + TwrwrSdDc = MAX (TwrwrSdSc, TwrwrSdDc); + + CDDTwrwrDd = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessWrDqsDly, FALSE, TRUE); + TwrwrDd = (UINT8) MAX ((UINT8) (WOD + 3), (CDDTwrwrDd + 7 + 1) / 2); + TwrwrDd = MAX (TwrwrSdDc, TwrwrDd); + + MemNSetBitFieldNb (NBPtr, BFTwrwrDd, (UINT32) TwrwrDd); + MemNSetBitFieldNb (NBPtr, BFTwrwrSdDc, (UINT32) TwrwrSdDc); + MemNSetBitFieldNb (NBPtr, BFTwrwrSdSc, (UINT32) TwrwrSdSc); + // + // Write to Read DIMM Termination Turn-around + // + // Twrrd (in MEMCLKs) = MAX(1, MAX(WOD, CEIL(CDDTwrrd / 2 + 2 - WrEarly)) - LD + 3). + // + CDDTwrrd = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessRcvEnDly, FALSE, TRUE); + Twrrd = MAX (1, MAX (WOD, (CDDTwrrd + 1 + 4 - WrEarlyx2) / 2) - LD + 3); + + MemNSetBitFieldNb (NBPtr, BFTwrrd, (UINT32) Twrrd); + // + // Read to Write Turnaround for Data, DQS Contention + // + // TrwtTO (in MEMCLKs) = MAX(ROD, CEIL(CDDTrwtTO / 2 + WrEarly)) + LD + 3 + // If 1 DIMM/ch, substitute ROD = 0 in the above equation. + // + CDDTrwtTO = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessWrDqsDly, TRUE, TRUE); + + TrwtTO = MAX ((ChannelPtr->Dimms == 1 ? 0 : ROD) , (CDDTrwtTO + WrEarlyx2 + 1) / 2) + LD + 3; + + MemNSetBitFieldNb (NBPtr, BFTrwtTO, (UINT32) TrwtTO); + // + // Read to Write Turnaround for opportunistic Write Bursting + // + // TrwtWB = TrwtTO + 1 + // + MemNSetBitFieldNb (NBPtr, BFTrwtWB, (UINT32) TrwtTO + 1); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t TrdrdSdSc : %02x\n", TrdrdSdSc); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrdrdSdDc : %02x TrdrdSdDc : %02x\n", CDDTrdrdSdDc, TrdrdSdDc); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrdrdDd : %02x TrdrdDd : %02x\n\n", CDDTrdrdDd, TrdrdDd); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t TwrwrSdSc : %02x\n", TwrwrSdSc); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrwrSdDc : %02x TwrwrSdDc : %02x\n", CDDTwrwrSdDc, TwrwrSdDc ); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrwrDd : %02x TwrwrDd : %02x\n\n", CDDTwrwrDd, TwrwrDd); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t TrwtWB : %02x\n", TrwtTO + 1); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrrd : %02x Twrrd : %02x\n", (UINT8) CDDTwrrd, (UINT8) Twrrd ); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrwtTO : %02x TrwtTO : %02x\n\n", (UINT8) CDDTrwtTO, (UINT8) TrwtTO ); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnphykb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnphykb.c new file mode 100644 index 0000000000..17a3779878 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnphykb.c @@ -0,0 +1,1078 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnphykb.c + * + * Northbridge Phy support for KB + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 87494 $ @e \$Date: 2013-02-04 12:06:47 -0600 (Mon, 04 Feb 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mport.h" +#include "ma.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mu.h" +#include "OptionMemory.h" // need def for MEM_FEAT_BLOCK_NB +#include "mnkb.h" +#include "PlatformMemoryConfiguration.h" +#include "cpuFamRegisters.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + +#define FILECODE PROC_MEM_NB_KB_MNPHYKB_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define UNUSED_CLK 4 + +/// The structure of TxPrePN tables +typedef struct { + UINT32 Speed; ///< Applied memory speed + UINT16 TxPrePNVal[6]; ///< Table values +} TXPREPN_STRUCT; + +/// The entry of individual TxPrePN tables +typedef struct { + UINT8 TxPrePNTblSize; ///< Total Table size + CONST TXPREPN_STRUCT *TxPrePNTblPtr; ///< Pointer to the table +} TXPREPN_ENTRY; + +/// Type of an entry for processing phy init compensation for KB +typedef struct { + BIT_FIELD_NAME IndexBitField; ///< Bit field on which the value is decided + BIT_FIELD_NAME StartTargetBitField; ///< First bit field to be modified + BIT_FIELD_NAME EndTargetBitField; ///< Last bit field to be modified + UINT16 ExtraValue; ///< Extra value needed to be written to bit field + CONST TXPREPN_ENTRY *TxPrePN; ///< Pointer to slew rate table +} PHY_COMP_INIT_NB; +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemNRdPosTrnKB ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern MEM_FEAT_TRAIN_SEQ memTrainSequenceDDR3[]; +/* -----------------------------------------------------------------------------*/ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the DDR phy compensation logic + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNInitPhyCompKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + // + // Phy Predriver Calibration Codes for Data/DQS + // + CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV15KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.5V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0xFFF, 0x410, 0x208, 0x104}} + }; + CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV135KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.35V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0xFFF, 0xFFF, 0x820, 0x410}} + }; + CONST STATIC TXPREPN_STRUCT TxPrePNDataDqsV125KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.25V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0xFFF, 0xFFF, 0xFFF, 0xFFF}} + }; + CONST STATIC TXPREPN_ENTRY TxPrePNDataDqsKB[] = { + {GET_SIZE_OF (TxPrePNDataDqsV15KB), (TXPREPN_STRUCT *)&TxPrePNDataDqsV15KB}, + {GET_SIZE_OF (TxPrePNDataDqsV135KB), (TXPREPN_STRUCT *)&TxPrePNDataDqsV135KB}, + {GET_SIZE_OF (TxPrePNDataDqsV125KB), (TXPREPN_STRUCT *)&TxPrePNDataDqsV125KB} + }; + + // + // Phy Predriver Calibration Codes for Cmd/Addr + // + CONST STATIC TXPREPN_STRUCT TxPrePNCmdAddrV15KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.5V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0x082, 0x041, 0x041, 0x041, 0x000, 0x0C3}} + }; + CONST STATIC TXPREPN_STRUCT TxPrePNCmdAddrV135KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.35V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0x186, 0x104, 0x0C3, 0x082, 0x000, 0x208}} + }; + CONST STATIC TXPREPN_STRUCT TxPrePNCmdAddrV125KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.25V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0x30C, 0x28A, 0x208, 0x186, 0x000, 0x410}} + }; + CONST STATIC TXPREPN_ENTRY TxPrePNCmdAddrKB[] = { + {GET_SIZE_OF (TxPrePNCmdAddrV15KB), (TXPREPN_STRUCT *)&TxPrePNCmdAddrV15KB}, + {GET_SIZE_OF (TxPrePNCmdAddrV135KB), (TXPREPN_STRUCT *)&TxPrePNCmdAddrV135KB}, + {GET_SIZE_OF (TxPrePNCmdAddrV125KB), (TXPREPN_STRUCT *)&TxPrePNCmdAddrV125KB} + }; + + // + // Phy Predriver Calibration Codes for Clock + // + CONST STATIC TXPREPN_STRUCT TxPrePNClockV15KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.5V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0xFFF, 0xFFF, 0xFFF, 0x820, 0x000, 0xFFF}} + }; + CONST STATIC TXPREPN_STRUCT TxPrePNClockV135KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.35V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFFF}} + }; + CONST STATIC TXPREPN_STRUCT TxPrePNClockV125KB[] = { + //{TxPreP, TxPreN}[Speed][Drive Strength] at 1.25V + {DDR667 + DDR800 + DDR1066 + DDR1333 + DDR1600 + DDR1866 + DDR2133, {0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFFF}} + }; + CONST STATIC TXPREPN_ENTRY TxPrePNClockKB[] = { + {GET_SIZE_OF (TxPrePNClockV15KB), (TXPREPN_STRUCT *)&TxPrePNClockV15KB}, + {GET_SIZE_OF (TxPrePNClockV135KB), (TXPREPN_STRUCT *)&TxPrePNClockV135KB}, + {GET_SIZE_OF (TxPrePNClockV125KB), (TXPREPN_STRUCT *)&TxPrePNClockV125KB} + }; + + // + // Tables to describe the relationship between drive strength bit fields, PreDriver Calibration bit fields and also + // the extra value that needs to be written to specific PreDriver bit fields + // + CONST PHY_COMP_INIT_NB PhyCompInitBitFieldKB[] = { + // 3. Program TxPreP/TxPreN for Data and DQS according toTable 25 if VDDIO is 1.5V or Table 26 if 1.35V. + // A. Program D18F2x9C_x0D0F_0[F,7:0]0[A,6]_dct[1:0]={0000b, TxPreP, TxPreN}. + // B. Program D18F2x9C_x0D0F_0[F,7:0]02_dct[1:0]={0000b, TxPreP, TxPreN}. + {BFDqsDrvStren, BFDataByteTxPreDriverCal2Pad1, BFDataByteTxPreDriverCal2Pad1, 0, TxPrePNDataDqsKB}, + {BFDataDrvStren, BFDataByteTxPreDriverCal2Pad2, BFDataByteTxPreDriverCal2Pad2, 0, TxPrePNDataDqsKB}, + {BFDataDrvStren, BFDataByteTxPreDriverCal, BFDataByteTxPreDriverCal, 8, TxPrePNDataDqsKB}, + // 4. Program TxPreP/TxPreN for Cmd/Addr according to Table 28 if VDDIO is 1.5V or Table 29 if 1.35V. + // A. Program D18F2x9C_x0D0F_[C,8][1:0][12,0E,0A,06]_dct[1:0]={0000b, TxPreP, TxPreN}. + // B. Program D18F2x9C_x0D0F_[C,8][1:0]02_dct[1:0]={1000b, TxPreP, TxPreN}. + {BFCsOdtDrvStren, BFCmdAddr0TxPreDriverCal2Pad1, BFCmdAddr0TxPreDriverCal2Pad2, 0, TxPrePNCmdAddrKB}, + {BFAddrCmdDrvStren, BFCmdAddr1TxPreDriverCal2Pad1, BFAddrTxPreDriverCal2Pad4, 0, TxPrePNCmdAddrKB}, + {BFCsOdtDrvStren, BFCmdAddr0TxPreDriverCalPad0, BFCmdAddr0TxPreDriverCalPad0, 8, TxPrePNCmdAddrKB}, + {BFCkeDrvStren, BFAddrTxPreDriverCalPad0, BFAddrTxPreDriverCalPad0, 8, TxPrePNCmdAddrKB}, + {BFAddrCmdDrvStren, BFCmdAddr1TxPreDriverCalPad0, BFCmdAddr1TxPreDriverCalPad0, 8, TxPrePNCmdAddrKB}, + // 5. Program TxPreP/TxPreN for Clock according to Table 31 if VDDIO is 1.5V or Table 32 if 1.35V. + // A. Program D18F2x9C_x0D0F_2[2:0]02_dct[1:0]={1000b, TxPreP, TxPreN}. + {BFClkDrvStren, BFClock0TxPreDriverCalPad0, BFClock1TxPreDriverCalPad0, 8, TxPrePNClockKB} + }; + + CONST PHY_COMP_INIT_NB PhyCompInitBitFieldUpdateKB[] = { + // 3. Program TxPreP/TxPreN for Data and DQS according toTable 25 if VDDIO is 1.5V or Table 26 if 1.35V. + // B. Program D18F2x9C_x0D0F_0[F,7:0]02_dct[1:0]={0000b, TxPreP, TxPreN}. + {BFDataDrvStren, BFDataByteTxPreDriverCal, BFDataByteTxPreDriverCal, 8, TxPrePNDataDqsKB}, + }; + + BIT_FIELD_NAME CurrentBitField; + UINT32 SpeedMask; + UINT8 SizeOfTable; + UINT8 Voltage; + UINT8 i; + UINT8 j; + UINT8 k; + UINT8 Dct; + CONST TXPREPN_STRUCT *TblPtr; + UINT8 TxP; + UINT8 TxN; + UINT32 POdt; + UINT32 NOdt; + + Dct = NBPtr->Dct; + NBPtr->SwitchDCT (NBPtr, 0); + // 1. Program D18F2x[1,0]9C_x0000_0008[DisAutoComp, DisablePreDriverCal] = {1b, 1b}. + MemNSetBitFieldNb (NBPtr, BFDisablePredriverCal, 3); + NBPtr->SwitchDCT (NBPtr, Dct); + + SpeedMask = (UINT32) 1 << (NBPtr->DCTPtr->Timings.Speed / 66); + Voltage = (UINT8) CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage); + + for (j = 0; j < GET_SIZE_OF (PhyCompInitBitFieldKB); j ++) { + i = (UINT8) MemNGetBitFieldNb (NBPtr, PhyCompInitBitFieldKB[j].IndexBitField); + ASSERT (i < 4 || i == 5); + TblPtr = (PhyCompInitBitFieldKB[j].TxPrePN[Voltage]).TxPrePNTblPtr; + SizeOfTable = (PhyCompInitBitFieldKB[j].TxPrePN[Voltage]).TxPrePNTblSize; + for (k = 0; k < SizeOfTable; k++, TblPtr++) { + if ((TblPtr->Speed & SpeedMask) != 0) { + for (CurrentBitField = PhyCompInitBitFieldKB[j].StartTargetBitField; CurrentBitField <= PhyCompInitBitFieldKB[j].EndTargetBitField; CurrentBitField ++) { + ASSERT (TblPtr->TxPrePNVal[i] != 0); + MemNSetBitFieldNb (NBPtr, CurrentBitField, ((PhyCompInitBitFieldKB[j].ExtraValue << 12) | TblPtr->TxPrePNVal[i])); + } + break; + } + } + // Asserting if no table is found corresponding to current memory speed. + ASSERT (k < SizeOfTable); + } + NBPtr->SwitchDCT (NBPtr, 0); + // 6. Program D18F2x9C_x0000_0008_dct[1:0]_mp[1:0][DisAutoComp] = 0. + MemNSetBitFieldNb (NBPtr, BFDisablePredriverCal, 1); + NBPtr->SwitchDCT (NBPtr, Dct); + + // ODT Calibration Codes Saturation Workaround + if ((NBPtr->MCTPtr->LogicalCpuid.Revision & AMD_F16_KB_A0) != 0) { + // 7. Wait 20us. + MemUWait10ns (20000, NBPtr->MemPtr); + // 8. Program D18F2x9C_x0000_0008_dct[#NUM_DCTS#]_mp[1:0][DisAutoComp] = 1. Wait 20us. + MemNSetBitFieldNb (NBPtr, BFDisablePredriverCal, 3); + MemUWait10ns (20000, NBPtr->MemPtr); + // 9. Compute POdt and NOdt for VDDIO as follows based on Table 44: + // POdt = (SlopeP * D18F2x9C_x0D0F_4001_dct[#NUM_DCTS#][TxP] + InterceptP) / 10000 + // POdt = POdt > 63 ? 63 : POdt + // NOdt = (SlopeN * D18F2x9C_x0D0F_4001_dct[#NUM_DCTS#][TxN] + InterceptN) / 10000 + // NOdt = NOdt > 63 ? 63 : NOdt + TxP = (UINT8) ((MemNGetBitFieldNb (NBPtr, BFTxP) >> 8) & 0xFF); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\tTxP: %08X\n", TxP); + TxN = (UINT8)MemNGetBitFieldNb (NBPtr, BFTxN); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\tTxN: %08X\n", TxN); + POdt = 0; + NOdt = 0; + if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) { + POdt = (3497 * TxP + 115010 + 9999) / 10000; + NOdt = (3725 * TxN + 119020 + 9999) / 10000; + } else if (NBPtr->RefPtr->DDR3Voltage == VOLT1_35) { + POdt = (3403 * TxP + 99205 + 9999) / 10000; + NOdt = (3514 * TxN + 112930 + 9999) / 10000; + } else if (NBPtr->RefPtr->DDR3Voltage == VOLT1_25) { + POdt = (2400 * TxP + 119620 + 9999) / 10000; + NOdt = (2971 * TxN + 120050 + 9999) / 10000; + } else { + ASSERT (FALSE); + } + + POdt = (POdt > 63) ? 63 : POdt; + IDS_HDT_CONSOLE (MEM_FLOW, "\nOBS357142 POdt: %02X\n", POdt); + NOdt = (NOdt > 63) ? 63 : NOdt; + IDS_HDT_CONSOLE (MEM_FLOW, "\nOBS357142 NOdt: %02X\n", NOdt); + + // 10. Broadcast write the computed POdt and NOdt: + // D18F2x9C_x0D0F_1C00_dct[0] = {00b, POdt, 00b, NOdt}. + // D18F2x9C_x0D0F_1C00_dct[0] is the broadcast write address for D18F2x9C_x0D0F_0[F,8:0]0[B,7,3]_dct[0] + MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0F0B, ((POdt << 8) & 0x3F00) + NOdt); + MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0F07, ((POdt << 8) & 0x3F00) + NOdt); + MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0F03, ((POdt << 8) & 0x3F00) + NOdt); + + // 11. Set Calibration Valid bit for calibration update according to Table 45, Table 46, or Table 47: + // Program D18F2x9C_x0D0F_0[F,8:0]02_dct[#NUM_DCTS#]={1000b, TxPreP, TxPreN}. + for (j = 0; j < GET_SIZE_OF (PhyCompInitBitFieldUpdateKB); j ++) { + i = (UINT8) MemNGetBitFieldNb (NBPtr, PhyCompInitBitFieldUpdateKB[j].IndexBitField); + ASSERT (i < 4 || i == 5); + TblPtr = (PhyCompInitBitFieldUpdateKB[j].TxPrePN[Voltage]).TxPrePNTblPtr; + SizeOfTable = (PhyCompInitBitFieldUpdateKB[j].TxPrePN[Voltage]).TxPrePNTblSize; + for (k = 0; k < SizeOfTable; k++, TblPtr++) { + if ((TblPtr->Speed & SpeedMask) != 0) { + for (CurrentBitField = PhyCompInitBitFieldUpdateKB[j].StartTargetBitField; CurrentBitField <= PhyCompInitBitFieldUpdateKB[j].EndTargetBitField; CurrentBitField ++) { + ASSERT (TblPtr->TxPrePNVal[i] != 0); + MemNSetBitFieldNb (NBPtr, CurrentBitField, ((PhyCompInitBitFieldUpdateKB[j].ExtraValue << 12) | TblPtr->TxPrePNVal[i])); + } + break; + } + } + // Asserting if no table is found corresponding to current memory speed. + ASSERT (k < SizeOfTable); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This is a general purpose function that executes before DRAM training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNBeforeDQSTrainingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + MemNSetBitFieldNb (NBPtr, BFTrNibbleSel, 0); + // + // 2.10.6.9.2 - BIOS should program D18F2x210_dct[1:0]_nbp[3:0][MaxRdLatency] to 55h. + // + MemNSetBitFieldNb (NBPtr, BFMaxLatency, 0x55); + NBPtr->CsPerDelay = MemNCSPerDelayNb (NBPtr); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This is a function that executes after DRAM training for KB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNAfterDQSTrainingKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + UINT8 Dimm; + UINT8 Byte; + UINT16 Dly; + + MemNBrdcstSetNb (NBPtr, BFMemPhyPllPdMode, 2); + MemNBrdcstSetNb (NBPtr, BFPllLockTime, 0x190); + + // + // Synch RdDqs2dDly to RdDqsDly for S3 Save/Restore + // + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + if (!(NBPtr->DctCachePtr->Is2Dx4)) { + // Only synch when 1D training has been performed or 2D training with x8 DIMMs + for (Dimm = 0; Dimm < 4; Dimm++) { + for (Byte = 0; Byte < 9; Byte++) { + Dly = (UINT16) MemNGetTrainDlyNb (NBPtr, AccessRdDqsDly, DIMM_BYTE_ACCESS (Dimm, Byte)); + MemNSetTrainDlyNb (NBPtr, AccessRdDqs2dDly, DIMM_NBBL_ACCESS (Dimm, Byte * 2), Dly); + MemNSetTrainDlyNb (NBPtr, AccessRdDqs2dDly, DIMM_NBBL_ACCESS (Dimm, (Byte * 2) + 1), Dly); + NBPtr->ChannelPtr->RdDqs2dDlys[(Dimm * MAX_NUMBER_LANES) + (Byte * 2)] = (UINT8) Dly; + NBPtr->ChannelPtr->RdDqs2dDlys[(Dimm * MAX_NUMBER_LANES) + (Byte * 2) + 1] = (UINT8) Dly; + } + } + } + } + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides the seed for hardware based RcvEn training of KB. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *SeedPtr - Pointer to the seed value. + * + * @return TRUE + */ + +BOOLEAN +MemNOverrideRcvEnSeedKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *SeedPtr + ) +{ + UINT16 SeedVal; + UINT8 MaxSolderedDownDimmPerCh; + UINT8 *DimmsPerChPtr; + + MaxSolderedDownDimmPerCh = GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID); + DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, + PSO_SOLDERED_DOWN_SODIMM_TYPE, + NBPtr->MCTPtr->SocketId, + NBPtr->ChannelPtr->ChannelID, + 0, NULL, NULL); + if (MaxSolderedDownDimmPerCh != 0 || DimmsPerChPtr != NULL) { + // Solder-down DRAM + SeedVal = 0x20; + } else if (NBPtr->ChannelPtr->SODimmPresent != 0) { + // SODIMM + SeedVal = 0x32; + } else { + // Unbuffered dimm + SeedVal = 0x32; + } + + *(UINT16 *)SeedPtr = SeedVal - (0x20 * (UINT16) MemNGetBitFieldNb (NBPtr, BFWrDqDqsEarly)); + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function choose the correct PllLockTime for KB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *PllLockTime - Bit offset of the field to be programmed + * + * @return TRUE + */ +BOOLEAN +MemNAdjustPllLockTimeKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *PllLockTime + ) +{ + if (MemNGetBitFieldNb (NBPtr, BFMemPhyPllPdMode) == 2) { + *(UINT16*) PllLockTime = 0x190; + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides the seed for hardware based WL for KB. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *SeedPtr - Pointer to the seed value. + * + * @return TRUE + */ + +BOOLEAN +MemNOverrideWLSeedKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *SeedPtr + ) +{ + UINT8 MaxSolderedDownDimmPerCh; + UINT8 *DimmsPerChPtr; + + MaxSolderedDownDimmPerCh = GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID); + DimmsPerChPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, + PSO_SOLDERED_DOWN_SODIMM_TYPE, + NBPtr->MCTPtr->SocketId, + NBPtr->ChannelPtr->ChannelID, + 0, NULL, NULL); + if (MaxSolderedDownDimmPerCh != 0 || DimmsPerChPtr != NULL) { + // Solder-down DRAM + *(UINT8*) SeedPtr = 0xE; + } else if (NBPtr->ChannelPtr->SODimmPresent != 0) { + // SODIMM + *(UINT8*) SeedPtr = 0xE; + } else { + // Unbuffered dimm + *(UINT8*) SeedPtr = 0x15; + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function adjusts Avg PRE value of Phy fence training for KB. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Value16 - Pointer to the value that we want to adjust + * + */ +VOID +MemNPFenceAdjustKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT INT16 *Value16 + ) +{ + // If FenceTrSel != 00b subtract Char.Temp:8 + if (MemNGetBitFieldNb (NBPtr, BFFenceTrSel) != 0) { + *Value16 -= 8; + } + + if (*Value16 < 0) { + *Value16 = 0; + } + + // This makes sure the phy fence value will be written to M1 context as well. + MULTI_MPSTATE_COPY_TSEFO (NBPtr->NBRegTable, BFPhyFence); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function programs Fence2RxDll for KB. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Fence2Data - Pointer to the value of fence2 data + * + */ +BOOLEAN +MemNProgramFence2RxDllKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Fence2Data + ) +{ + UINT16 Fence2RxDllTxPad; + UINT16 Fence2Value; + UINT16 Fence1; + + Fence2Value = (UINT16) MemNGetBitFieldNb (NBPtr, BFFence2); + Fence2RxDllTxPad = (*(UINT16*) Fence2Data & 0x1F) | (((*(UINT16*) Fence2Data >> 5) & 0x1F) << 10); + + Fence2Value &= ~(UINT16) ((0x1F << 10) | 0x1F); + Fence2Value |= Fence2RxDllTxPad; + MemNSetBitFieldNb (NBPtr, BFFence2, Fence2Value); + + if (NBPtr->MemPstateStage == MEMORY_PSTATE_1ST_STAGE) { + MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 30, 16, BFPhyFence); + + Fence1 = (UINT16) MemNGetBitFieldNb (NBPtr, BFPhyFence); + MemNSetBitFieldNb (NBPtr, BFChAM1FenceSave, Fence1); + } + + return TRUE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function checks if RdDqsDly needs to be restarted for Kabini + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Center - Center of the data eye + * + * @return TRUE + */ + +BOOLEAN +MemNRdDqsDlyRestartChkKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Center + ) +{ + INT8 EyeCenter; + UINT8 ByteLane; + BOOLEAN RetVal; + MEM_TECH_BLOCK *TechPtr; + CH_DEF_STRUCT *ChanPtr; + + TechPtr = NBPtr->TechPtr; + ChanPtr = NBPtr->ChannelPtr; + ByteLane = NBPtr->TechPtr->Bytelane; + RetVal = TRUE; + + // If the average value of passing read DQS delay for the lane is negative, then adjust the input receiver + // DQ delay in D18F2x9C_x0D0F_0[F,7:0][5F,1F]_dct[1:0] for the lane as follows: + + EyeCenter = ((INT8) ChanPtr->RdDqsMinDlys[ByteLane] + (INT8) ChanPtr->RdDqsMaxDlys[ByteLane] + 1) / 2; + + if ((EyeCenter < 0) && (NBPtr->RdDqsDlyRetrnStat != RDDQSDLY_RTN_SUSPEND)) { + IDS_HDT_CONSOLE (MEM_FLOW, " Negative data eye center.\n"); + + if (MemNGetBitFieldNb (NBPtr, BFRxDqInsDly) < 3) { + // IF (RxDqInsDly < 3) THEN increment RxDqInsDly and repeat step 3 above for all ranks and lanes + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tRxDqInsDly < 3, increment it and restart RdDqsDly training on current Dct.\n"); + + MemNSetBitFieldNb (NBPtr, BFRxDqInsDly, MemNGetBitFieldNb (NBPtr, BFRxDqInsDly) + 1); + NBPtr->RdDqsDlyRetrnStat = RDDQSDLY_RTN_ONGOING; + + // When Retrain condition is detected, record the current chipsel at which the retrain starts + // so we don't need to retrain RcvEnDly and WrDatDly on the chipsels that are already done with these steps. + if (TechPtr->RestartChipSel < ((INT8) TechPtr->ChipSel)) { + TechPtr->RestartChipSel = (INT8) TechPtr->ChipSel; + } + + RetVal = FALSE; + } else { + // ELSE program the read DQS delay for the lane with a value of zero + IDS_HDT_CONSOLE (MEM_FLOW, " "); + IDS_HDT_CONSOLE (MEM_FLOW, "Center of data eye is still negative after 2 retires. Do not restart training, just use 0\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t "); + *(UINT8 *) Center = 0; + } + } + + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - All bytelanes pass + * @return FALSE - Some bytelanes fail +*/ +BOOLEAN +MemNRdPosTrnKB ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + BOOLEAN RetVal; + + if (((INT8) TechPtr->ChipSel) > TechPtr->RestartChipSel) { + RetVal = MemTRdPosWithRxEnDlySeeds3 (TechPtr); + } else { + // Skip RcvEnDly cycle training when current chip select has already gone through that step. + // Because a retrain condition can only be detected on a chip select after RcvEnDly cycle training + // So when current chip select is equal to RestartChipSel, we don't need to redo RcvEnDly cycle training. + // Only redo DQS position training. + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\tSkip RcvEnDly Cycle Training on Current Chip Select.\n\n"); + RetVal = MemTTrainDQSEdgeDetect (TechPtr); + } + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function skips WrDatDly training when a retrain condition is just detected + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *ChipSel - Pointer to ChipSel + * + * @return TRUE + */ + +BOOLEAN +MemNHookBfWrDatTrnKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *ChipSel + ) +{ + BOOLEAN RetVal; + + RetVal = TRUE; + if (NBPtr->RdDqsDlyRetrnStat == RDDQSDLY_RTN_ONGOING) { + NBPtr->RdDqsDlyRetrnStat = RDDQSDLY_RTN_NEEDED; + // Clear chipsel value to force a restart of Rd Dqs Training + if (NBPtr->CsPerDelay == 1) { + *(UINT8 *) ChipSel = 0xFF; + } else { + *(UINT8 *) ChipSel = 0xFE; + } + + RetVal = FALSE; + } else if (((INT8) NBPtr->TechPtr->ChipSel) < NBPtr->TechPtr->RestartChipSel) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSkip WrDatDly Training on Current Chip Select.\n\n"); + // Skip WrDatDly training when current chip select has gone through WrDatDly procedure + // A retrain is detected during RdDqsDly training, so if RestartChipSel is equal to current + // chip select, then WrDatDly has not been started for current chip select in the previous cycle. + // However, RcvEnDly cycle training has been done for current chip select. + // So we don't need to do RcvEnDly cycle training when current chip select is equal to RestartChipSel + // but we need to do WrDatDly training for current chip select. + RetVal = FALSE; + } + + // when return is FALSE, WrDatDly training will be skipped + + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets up output driver and write leveling mode in MR1 during WL + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Value - MR1 value + * + * @return TRUE + */ + +BOOLEAN +MemNWLMR1KB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Value + ) +{ + BOOLEAN Target; + + // For the target rank of the target DIMM, enable write leveling mode and enable the output driver. + // For all other ranks of the target DIMM, enable write leveling mode and disable the output driver. + Target = (BOOLEAN) (*(UINT16 *) Value >> 7) & 1; + + if (NBPtr->CsPerDelay == 1) { + // Clear Qoff and reset it based on KB requirement + *(UINT16 *) Value &= ~((UINT16) 1 << 12); + + if (!Target) { + *(UINT16 *) Value |= (((UINT16) 1 << 7) | ((UINT16) 1 << 12)); + } + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs POdtOff to disable/enable receiver pad termination + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Value - POdtOff value + * + * @return TRUE + */ + +BOOLEAN +MemNProgramPOdtOffKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Value + ) +{ + MemNSetBitFieldNb (NBPtr, BFPOdtOff, (*(BOOLEAN *) Value) ? 0x1000 : 0); + + return TRUE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function adjust the SeedGross value for hardware Receiver Enable Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Value - POdtOff value + * + * @return TRUE + */ + +BOOLEAN +MemNAdjustHwRcvEnSeedGrossKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Value + ) +{ + UINT16 SeedGross; + UINT32 MemClkSpeed; + + // Program D18F2x9C_x0000_00[2A:10]_dct[0]_mp[1:0][DqsRcvEnGrossDelay] = IF ((NBCOF / DdrRate + // < 1) && (D18F2x200_dct[0]_mp[1:0][Tcl]=5) && (SeedGross<1) THEN 1 ELSE SeedGross ENDIF. + MemClkSpeed = NBPtr->DCTPtr->Timings.Speed; + SeedGross = *(UINT16 *)Value; + if (NBPtr->NBClkFreq < (UINT32) (MemClkSpeed * 2) && MemNGetBitFieldNb (NBPtr, BFTcl) == 5 && SeedGross < 1) { + SeedGross = 1; + } + *(UINT16 *)Value = SeedGross; + + return TRUE; +} + +/*----------------------------------------------------------------------------- + * + * + * This function calculates the value of WrDqDqsEarly and programs it into + * the DCT and adds it to the WrDqsGrossDelay of each byte lane on each + * DIMM of the channel. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNCalcWrDqDqsEarlyKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + MEM_TECH_BLOCK *TechPtr; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + UINT8 Dimm; + UINT8 ByteLane; + UINT8 *WrDqsDlysPtr; + UINT8 WrDqDqsEarly; + UINT8 ChipSel; + + ASSERT ((NBPtr->IsSupported[WLSeedAdjust]) && (NBPtr->IsSupported[WLNegativeDelay])); + + TechPtr = NBPtr->TechPtr; + ChannelPtr = NBPtr->ChannelPtr; + DCTPtr = NBPtr->DCTPtr; + + ASSERT (NBPtr != NULL); + ASSERT (ChannelPtr != NULL); + ASSERT (DCTPtr != NULL); + // + // For each DIMM: + // - The Critical Gross Delay (CGD) is the minimum GrossDly of all byte lanes and all DIMMs. + // - If (CGD < 0) Then + // - D18F2xA8_dct[1:0][WrDqDqsEarly] = ABS(CGD) + // - WrDqsGrossDly = GrossDly + WrDqDqsEarly + // - Else + // - D18F2xA8_dct[1:0][WrDqDqsEarly] = 1. + // - WrDqsGrossDly = GrossDly + 1 + // + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCalculating WrDqDqsEarly, adjusting WrDqs.\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMin. Critical Delay: %x\n", TechPtr->WLCriticalDelay); + + if (TechPtr->WLCriticalDelay < 0) { + // We've saved the entire negative delay value, so take the ABS and convert to GrossDly. + WrDqDqsEarly = (UINT8) (0x00FF &((((ABS (TechPtr->WLCriticalDelay)) + 0x1F) / 0x20))); + } else { + WrDqDqsEarly = 1; + } + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tWrDqDqsEarly : %02x\n\n", WrDqDqsEarly); + // + // Loop through All WrDqsDlys on all DIMMs + // + for (ChipSel = 0; ChipSel < NBPtr->CsPerChannel; ChipSel = ChipSel + NBPtr->CsPerDelay) { + if ((NBPtr->MCTPtr->Status[SbLrdimms]) ? ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0) : + ((DCTPtr->Timings.CsEnabled & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSel)) != 0)) { + // + // If LRDIMMs, only include the physical dimms, not logical Dimms + // + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS %x:", ChipSel); + Dimm = ChipSel / NBPtr->CsPerDelay; + + WrDqsDlysPtr = &(ChannelPtr->WrDqsDlys[(Dimm * TechPtr->DlyTableWidth ())]); + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + WrDqsDlysPtr[ByteLane] += (WrDqDqsEarly << 5); + NBPtr->SetTrainDly (NBPtr, AccessWrDqsDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), WrDqsDlysPtr[ByteLane]); + IDS_HDT_CONSOLE (MEM_FLOW, " %02x", WrDqsDlysPtr[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + } + + MemNSetBitFieldNb (NBPtr, BFWrDqDqsEarly, WrDqDqsEarly); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets phy power saving related settings in different MPstate context. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return none + * ---------------------------------------------------------------------------- + */ +VOID +MemNPhyPowerSavingMPstateKB ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + STATIC UINT8 RxSequence[] = {8, 4, 3, 5, 2, 6, 1, 7, 0}; + STATIC UINT8 TxSequence[] = {0, 7, 1, 6, 2, 5, 3, 4, 8}; + UINT16 DllPower[9]; + UINT8 NumLanes; + UINT8 DllWakeTime; + UINT8 MaxRxStggrDly; + UINT8 MinRcvEnGrossDly; + UINT8 MinWrDqsGrossDly; + UINT8 dRxStggrDly; + UINT8 dTxStggrDly; + UINT8 TempStggrDly; + UINT8 MaxTxStggrDly; + UINT8 Tcl; + UINT8 Tcwl; + UINT8 WrDqDqsEarly; + UINT8 i; + UINT8 j; + + // 3. Program D18F2x9C_x0D0F_0[F,8:0]30_dct[0][PwrDn] to disable the ECC lane if + // D18F2x90_dct[0][DimmEccEn]==0. + if (NBPtr->IsSupported[CheckEccDLLPwrDnConfig]) { + if (!NBPtr->MCTPtr->Status[SbEccDimms]) { + MemNSetBitFieldNb (NBPtr, BFEccDLLPwrDnConf, 0x0010); + } + } + + IDS_HDT_CONSOLE (MEM_FLOW, "Start Phy power saving setting for memory Pstate %d\n", NBPtr->MemPstate); + // 4. Program D18F2x9C_x0D0F_0[F,8:0]13_dct[1:0][DllDisEarlyU] = 1b. + // 5. Program D18F2x9C_x0D0F_0[F,8:0]13_dct[1:0][DllDisEarlyL] = 1b. + // 6. D18F2x9C_x0D0F_0[F,7:0][53,13]_dct[1:0][RxDqsUDllPowerDown] = 1. + MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0F13, MemNGetBitFieldNb (NBPtr, BFPhy0x0D0F0F13) | 0x83); + // 7. D18F2x9C_x0D0F_812F_dct[1:0][PARTri] = ~D18F2x90_dct[1:0][ParEn]. + // 8. D18F2x9C_x0D0F_812F_dct[1:0][Add17Tri, Add16Tri] = {1b, 1b} + if (NBPtr->MemPstate == MEMORY_PSTATE0) { + MemNSetBitFieldNb (NBPtr, BFAddrCmdTri, MemNGetBitFieldNb (NBPtr, BFAddrCmdTri) | 0xA1); + } + // 9. IF (DimmsPopulated == 1)&& ((D18F2x9C_x0000_0000_dct[1:0]_mp[1:0][CkeDrvStren]==010b) || + // (D18F2x9C_x0000_0000_dct[1:0]_mp[1:0][CkeDrvStren]==011b)) THEN THEN + // program D18F2x9C_x0D0F_C0[40,00]_dct[1:0][LowPowerDrvStrengthEn] = 1 + // ELSE program D18F2x9C_x0D0F_C0[40,00]_dct[1:0][LowPowerDrvStrengthEn] = 0 ENDIF. + if ((NBPtr->ChannelPtr->Dimms == 1) && ((MemNGetBitFieldNb (NBPtr, BFCkeDrvStren) == 2) || (MemNGetBitFieldNb (NBPtr, BFCkeDrvStren) == 3))) { + MemNSetBitFieldNb (NBPtr, BFLowPowerDrvStrengthEn, 0x100); + } + // 11. Program D18F2x9C_x0D0F_0[F,7:0][50,10]_dct[1:0][EnRxPadStandby] = IF + // (D18F2x94_dct[1:0][MemClkFreq] <= 800 MHz) THEN 1 ELSE 0 ENDIF. + MemNSetBitFieldNb (NBPtr, BFEnRxPadStandby, (NBPtr->DCTPtr->Timings.Speed <= DDR1600_FREQUENCY) ? 0x1000 : 0); + // 12. Program D18F2x9C_x0000_000D_dct[1:0]_mp[1:0] as follows: + // If (DDR rate < = 1600) TxMaxDurDllNoLock = RxMaxDurDllNoLock = 8h + // else TxMaxDurDllNoLock = RxMaxDurDllNoLock = 7h. + if (NBPtr->DCTPtr->Timings.Speed <= DDR1600_FREQUENCY) { + MemNSetBitFieldNb (NBPtr, BFRxMaxDurDllNoLock, 8); + MemNSetBitFieldNb (NBPtr, BFTxMaxDurDllNoLock, 8); + } else { + MemNSetBitFieldNb (NBPtr, BFRxMaxDurDllNoLock, 7); + MemNSetBitFieldNb (NBPtr, BFTxMaxDurDllNoLock, 7); + } + + // TxCPUpdPeriod = RxCPUpdPeriod = 011b. + MemNSetBitFieldNb (NBPtr, BFRxCPUpdPeriod, 3); + MemNSetBitFieldNb (NBPtr, BFTxCPUpdPeriod, 3); + // TxDLLWakeupTime = RxDLLWakeupTime = 11b. + MemNSetBitFieldNb (NBPtr, BFRxDLLWakeupTime, 3); + MemNSetBitFieldNb (NBPtr, BFTxDLLWakeupTime, 3); + + IDS_SKIP_HOOK (IDS_DLLSTAGGERDLY_OVERRIDE, NULL, &(NBPtr->MemPtr->StdHeader)) { + // 12. Program D18F2x9C_x0D0F_0[F,7:0][5C,1C]_dct[1:0] as follows. + // Let Numlanes = 8. = 9 with ECC. + NumLanes = (NBPtr->MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8; + // RxDllStggrEn = TxDllStggrEn = 1. + for (i = 0; i < 9; i ++) { + DllPower[i] = 0x8080; + } + // 13. If (DDR rate > = 1866) DllWakeTime = 1, Else DllWakeTime = 0. + DllWakeTime = (NBPtr->DCTPtr->Timings.Speed >= DDR1866_FREQUENCY) ? 1 : 0; + // Let MaxRxStggrDly = ((Tcl-1)*2) + MIN(DqsRcvEnGrossDelay for all byte lanes (see D18F2x9C_x0000_00[2A:10]_dct[1:0]_mp[1:0])) - 6. + MinRcvEnGrossDly = NBPtr->TechPtr->GetMinMaxGrossDly (NBPtr->TechPtr, AccessRcvEnDly, FALSE); + Tcl = (UINT8) MemNGetBitFieldNb (NBPtr, BFTcl); + ASSERT (Tcl >= 1); + ASSERT (((Tcl - 1) * 2 + MinRcvEnGrossDly) >= 6); + MaxRxStggrDly = (Tcl - 1) * 2 + MinRcvEnGrossDly - 6; + // Let (real) dRxStggrDly = (MaxRxStggrDly - DllWakeTime) / (Numlanes - 1). + ASSERT (MaxRxStggrDly >= DllWakeTime); + dRxStggrDly = (MaxRxStggrDly - DllWakeTime) / (NumLanes - 1); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMinimum RcvEnGrossDly: 0x%02x MaxRxStggrDly: 0x%02x dRxStggrDly: 0x%02x\n", MinRcvEnGrossDly, MaxRxStggrDly, dRxStggrDly); + // For each byte lane in the ordered sequence {8, 4, 3, 5, 2, 6, 1, 7, 0}, program RxDllStggrDly[5:0] = an + // increasing value, starting with 0 for the first byte lane in the sequence and increasing at a rate of dRxStggrDly + // for each subsequent byte lane. Convert the real to integer by rounding down or using C (int) typecast after linearization. + + for (i = 9 - NumLanes, j = 0; i < 9; i ++, j ++) { + TempStggrDly = ((MaxRxStggrDly - DllWakeTime) * j + NumLanes - 2) / (NumLanes - 1); + DllPower[RxSequence[i]] |= ((TempStggrDly & 0x3F) << 8); + } + + // Let MaxTxStggrDly = MIN(((Tcwl-1)*2) + MIN(WrDqsGrossDly for all byte lanes) - WrDqDqsEarly - + // 4, MaxRxStggrDly) + Tcwl = (UINT8) MemNGetBitFieldNb (NBPtr, BFTcwl); + WrDqDqsEarly = (UINT8) MemNGetBitFieldNb (NBPtr, BFWrDqDqsEarly); + MinWrDqsGrossDly = NBPtr->TechPtr->GetMinMaxGrossDly (NBPtr->TechPtr, AccessWrDqsDly, FALSE); + ASSERT (Tcwl >= 1); + ASSERT ((Tcwl - 1) * 2 + MinWrDqsGrossDly - WrDqDqsEarly >= 4); + MaxTxStggrDly = MIN ((Tcwl - 1) * 2 + MinWrDqsGrossDly - WrDqDqsEarly - 4, MaxRxStggrDly); + // Let dTxStggrDly = (MaxTxStggrDly - DllWakeTime) / (Numlanes - 1). + ASSERT (MaxTxStggrDly >= DllWakeTime); + dTxStggrDly = (MaxTxStggrDly - DllWakeTime) / (NumLanes - 1); + // For each byte lane in the ordered sequence {8, 4, 3, 5, 2, 6, 1, 7, 0}, program TxDllStggrDly[5:0] = an + // increasing integer value, starting with 0 for the first byte lane in the sequence and increasing at a rate of + // dTxStggrDly for each subsequent byte lane. + IDS_HDT_CONSOLE (MEM_FLOW, "\tMinimum WrDqsGrossDly: 0x%02x MaxTxStggrDly: 0x%02x dTxStggrDly: 0x%02x\n", MinWrDqsGrossDly, MaxTxStggrDly, dTxStggrDly); + + for (i = 0, j = 0; i < NumLanes; i ++, j ++) { + TempStggrDly = ((MaxTxStggrDly - DllWakeTime) * j + NumLanes - 2) / (NumLanes - 1); + DllPower[TxSequence[i]] |= (TempStggrDly & 0x3F); + } + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tByte Lane : ECC 07 06 05 04 03 02 01 00\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tDll Power : %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", + DllPower[8], DllPower[7], DllPower[6], DllPower[5], DllPower[4], DllPower[3], DllPower[2], DllPower[1], DllPower[0]); + + for (i = 0; i < NumLanes; i ++) { + MemNSetBitFieldNb (NBPtr, BFDataByteDllPowerMgnByte0 + i, (MemNGetBitFieldNb (NBPtr, BFDataByteDllPowerMgnByte0 + i) & 0x4040) | DllPower[i]); + } + } + + // 14. For M0 & M1 context program RxChMntClkEn=RxSsbMntClkEn=0. + MemNSetBitFieldNb (NBPtr, BFRxChMntClkEn, 0); + MemNSetBitFieldNb (NBPtr, BFRxSsbMntClkEn, 0); + + // 15. Program D18F2x9C_x0D0F_0[F,8:0]30_dct[0][TxPclkGateEn,PchgPdPClkGateEn,DataCtlPipePclkGateEn] = {1, 1, 1} + MemNSetBitFieldNb (NBPtr, BFTxPclkGateEn, 1 << 9); + MemNSetBitFieldNb (NBPtr, BFPchgPdPclkGateEn, 1 << 7); + MemNSetBitFieldNb (NBPtr, BFDataCtlPipePclkGateEn, 1 << 6); + + IDS_OPTION_HOOK (IDS_PHY_DLL_STANDBY_CTRL, NBPtr, &NBPtr->MemPtr->StdHeader); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs Vref according to platform requirements + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + */ +BOOLEAN +MemNPhyInitVrefKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + MemNBrdcstSetNb (NBPtr, BFVrefSel, (NBPtr->RefPtr->ExternalVrefCtl ? 0x0002 : 0x0001)); + + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnregkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnregkb.c new file mode 100644 index 0000000000..724af40213 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnregkb.c @@ -0,0 +1,847 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnregkb.c + * + * Common Northbridge register related functions for KB + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 87696 $ @e \$Date: 2013-02-07 12:35:03 -0600 (Thu, 07 Feb 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbCommonLib.h" +#include "GnbRegistersKB.h" +#include "GnbRegisterAccKB.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mnkb.h" +#include "merrhdl.h" +#include "cpuRegisters.h" +#include "cpuFamRegisters.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + +#define FILECODE PROC_MEM_NB_KB_MNREGKB_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define PHY_DIRECT_ADDRESS_MASK 0x0D000000ul + +STATIC CONST UINT8 InstancesPerTypeKB[8] = {9, 3, 1, 2, 2, 0, 1, 1}; + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/*-----------------------------------------------------------------------------*/ +/** + * MemNIsIdSupportedKB + * This function matches the CPU_LOGICAL_ID with certain criteria to + * determine if it is supported by this NBBlock. + * + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * + * @return TRUE - This node is a KB. + * @return FALSE - This node is not a KB. + * + */ +BOOLEAN +MemNIsIdSupportedKB ( + IN CPU_LOGICAL_ID *LogicalIdPtr + ) +{ + if (((LogicalIdPtr->Family & AMD_FAMILY_16_KB) != 0) + && ((LogicalIdPtr->Revision & AMD_F16_ALL) != 0)) { + return TRUE; + } else { + return FALSE; + } +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *----------------------------------------------------------------------------*/ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets or sets a value to a bit field in a PCI register. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Bit Field to be programmed + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +MemNCmnGetSetFieldKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + TSEFO Address; + PCI_ADDR PciAddr; + UINT8 Type; + UINT8 IsLinked; + UINT32 Value; + UINT32 Highbit; + UINT32 Lowbit; + UINT32 Mask; + UINT8 IsPhyDirectAccess; + UINT8 IsWholeRegAccess; + UINT8 NumOfInstances; + UINT8 Instance; + UINT8 IsMultipleMPstate; + + Value = 0; + if (FieldName == BFDctAccessDone) { + // No need to poll DctAccessDone for KB due to enhancement in phy + Value = 1; + } else if ((FieldName < BFEndOfList) && (FieldName >= 0)) { + Address = NBPtr->NBRegTable[FieldName]; + if (Address) { + Lowbit = TSEFO_END (Address); + Highbit = TSEFO_START (Address); + Type = (UINT8) TSEFO_TYPE (Address); + IsLinked = (UINT8) TSEFO_LINKED (Address); + IsPhyDirectAccess = (UINT8) TSEFO_DIRECT_EN (Address); + IsWholeRegAccess = (UINT8) TSEFO_WHOLE_REG_ACCESS (Address); + if (NBPtr->MemPstate == MEMORY_PSTATE0) { + IsMultipleMPstate = TSEFO_MULTI_MPSTATE_COPY (Address); + } else { + // Do not write in both instances when context is already in MP1 + IsMultipleMPstate = 0; + } + + Address = TSEFO_OFFSET (Address); + + // By default, a bit field has only one instance + NumOfInstances = 1; + + if ((Type == DCT_PHY_ACCESS) && IsPhyDirectAccess) { + Address |= PHY_DIRECT_ADDRESS_MASK; + if (IsWholeRegAccess) { + // In the case of whole register access (bit 0 to 15), + // HW broadcast and nibble mask will be used. + Address |= Lowbit << 16; + Lowbit = 0; + Highbit = 15; + } else { + // In the case only some bits on a register is accessed, + // BIOS will do read-mod-write to all chiplets manually. + // And nibble mask will be 1111b always. + if ((Address & 0xFFFF) == 0xE008) { + // Special case for PStateToAccess, which use nibble mask + Address |= 0x00040000; + } else { + Address |= 0x000F0000; + } + Field >>= Lowbit; + if ((Address & 0x0F00) == 0x0F00) { + // Broadcast mode + // Find out how many instances to write to + NumOfInstances = InstancesPerTypeKB[(Address >> 13) & 0x7]; + if (!IsSet) { + // For read, only read from instance 0 in broadcast mode + NumOfInstances = 1; + } + } + } + } + + ASSERT (NumOfInstances > 0); + + for (Instance = 0; Instance < NumOfInstances; Instance++) { + if (Type == NB_ACCESS) { + PciAddr.AddressValue = Address; + PciAddr.Address.Device = NBPtr->PciAddr.Address.Device; + PciAddr.Address.Bus = NBPtr->PciAddr.Address.Bus; + PciAddr.Address.Segment = NBPtr->PciAddr.Address.Segment; + Address = PciAddr.AddressValue; + LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader); + if ((FieldName != BFDctAddlDataReg) && (FieldName != BFDctAddlOffsetReg) && (FieldName != BFDctCfgSel)) { + IDS_HDT_CONSOLE (MEM_GETREG, "~Dev%x Dct%d Fn%d_%03x = %x\n", + NBPtr->PciAddr.Address.Device, NBPtr->Dct, + (Address >> 12) & 0xF, Address & 0xFFF, Value); + } + } else if (Type == DCT_PHY_ACCESS) { + if (IsPhyDirectAccess && (NumOfInstances > 1)) { + Address = (Address & 0x0FFFF0FF) | (((UINT32) Instance) << 8); + } + MemNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + Value = MemNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + IDS_HDT_CONSOLE (MEM_GETREG, "~Dev%x Dct%d Fn2_9C_%x = %x\n", NBPtr->PciAddr.Address.Device, NBPtr->Dct, Address & 0x0FFFFFFF, Value); + } else { + // DCT_EXTRA_ACCESS is not supported on KB + ASSERT (FALSE); + } + + if (IsSet) { + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT32)0xFFFFFFFF; + } + Value &= ~(Mask << Lowbit); + Value |= (Field & Mask) << Lowbit; + + do { + if (Type == NB_ACCESS) { + PciAddr.AddressValue = Address; + LibAmdPciWrite (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader); + if ((FieldName != BFDctAddlDataReg) && (FieldName != BFDctAddlOffsetReg) && (FieldName != BFDctCfgSel)) { + IDS_HDT_CONSOLE (MEM_SETREG, "~Dev%x Dct%d Fn%d_%03x [%d:%d] = %x\n", + NBPtr->PciAddr.Address.Device, NBPtr->Dct, + (Address >> 12) & 0xF, Address & 0xFFF, Highbit, Lowbit, Field); + } + } else if (Type == DCT_PHY_ACCESS) { + ASSERT (!NBPtr->IsSupported[ScrubberEn]); // Phy CSR write is not allowed after scrubber is enabled + MemNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + MemNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + IDS_HDT_CONSOLE (MEM_SETREG, "~Dev%x Dct%d Fn2_9C_%x [%d:%d] = %x\n", + NBPtr->PciAddr.Address.Device, NBPtr->Dct, + Address & 0x0FFFFFFF, Highbit, Lowbit, Field); + } else { + // DCT_EXTRA_ACCESS is not supported on KB + ASSERT (FALSE); + } + if (IsLinked) { + MemNCmnGetSetFieldKB (NBPtr, 1, FieldName + 1, Field >> (Highbit - Lowbit + 1)); + } + if (IsMultipleMPstate && (NBPtr->MemPstateStage == MEMORY_PSTATE_1ST_STAGE)) { + // if there are multiple Pstate register copies, program register in M1 context when the frequency is DDR667 + if (NBPtr->MemPstate == MEMORY_PSTATE0) { + MemNChangeMemPStateContextNb (NBPtr, 1); + } else { + // Switch back to M0 context + MemNChangeMemPStateContextNb (NBPtr, 0); + } + } + } while ((NBPtr->MemPstate == MEMORY_PSTATE1) && IsMultipleMPstate && (NBPtr->MemPstateStage == MEMORY_PSTATE_1ST_STAGE)); + } else { + Value = Value >> Lowbit; // Shift + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } + if (IsLinked) { + Value |= MemNCmnGetSetFieldKB (NBPtr, 0, FieldName + 1, 0) << (Highbit - Lowbit + 1); + } + // For direct phy access, shift the bit back for compatibility reason. + if ((Type == DCT_PHY_ACCESS) && IsPhyDirectAccess) { + Value <<= Lowbit; + } + } + } + } else { + IDS_HDT_CONSOLE (MEM_UNDEF_BF, "\t\tUndefined BF enum: %x\n", FieldName); + } + } else { + ASSERT (FALSE); // Invalid bit field index + } + return Value; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes bit field translation table + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] NBRegTable[] - Pointer to the bit field data structure + * + */ + +VOID +MemNInitNBRegTableKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT TSEFO NBRegTable[] + ) +{ + UINT16 i; + + // Allocate heap for NB register table + if (!MemNAllocateNBRegTableNb (NBPtr, NbRegTabKB)) { + return; // escape if fails + } + NBRegTable = NBPtr->NBRegTable; + + for (i = 0; i < BFEndOfList; i++) { + NBRegTable[i] = 0; + } + + // --------------------------------------------------------------------------- + // + // FUNCTION 1 + // + // --------------------------------------------------------------------------- + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0xF0), 31, 0, BFDramHoleAddrReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0xF0), 31, 24, BFDramHoleBase); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0xF0), 15, 7, BFDramHoleOffset); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0xF0), 1, 1, BFDramMemHoistValid); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0xF0), 0, 0, BFDramHoleValid); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x10C), 5, 4, BFNbPsSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x10C), 3, 3, BFMemPsSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x10C), 2, 0, BFDctCfgSel); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x120), 20, 0, BFDramBaseAddr); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x124), 20, 0, BFDramLimitAddr); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x200), 31, 0, BFDramCtrlBaseReg0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x200), 1, 1, BFLgcyMmioHoleEn0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x204), 31, 0, BFDramCtrlLimitReg0); + // --------------------------------------------------------------------------- + // + // FUNCTION 2 + // + // --------------------------------------------------------------------------- + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 17, 17, BFAddrCmdTriEn); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 23, 21, BFMrsChipSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 20, 18, BFMrsBank); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 17, 0, BFMrsAddress); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 7, 0, BFDramBankAddrReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 23, 23, BFPchgPDModeSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 1, 0, BFBurstCtrl); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 29, 24, BFMemClkDis); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 17, 16, BFTref); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 27, 27, BFDisDllShutdownSR); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 25, 25, BFPendRefPaybackS3En); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 24, 24, BFStagRefEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 23, 23, BFForceAutoPchg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 20, 20, BFDynPageCloseEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 19, 19, BFDimmEccEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 17, 17, BFEnterSelfRef); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 1, 1, BFExitSelfRef); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 31, BFDphyMemPsSelEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 28, 24, BFDcqBypassMax); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 22, 22, BFBankSwizzleMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 21, 21, BFFreqChgInProg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 20, 20, BFSlowAccessMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 16, 16, BFPowerDownMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 15, 15, BFPowerDownEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 7, 7, BFMemClkFreqVal); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 4, 0, BFMemClkFreq); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA4), 14, 12, BFCmdThrottleMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA4), 11, 11, BFBwCapEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA4), 8, 8, BFODTSEn); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 31, 31, BFPerRankTimingEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 28, 28, BFFastSelfRefEntryDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 22, 22, BFPrtlChPDEnhEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 21, 21, BFAggrPDEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 20, 20, BFBankSwap); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 17, 16, BFMemPhyPllPdMode); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 10, 10, BFMemCleared); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 9, 9, BFMemClrBusy); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 5, 5, BFDctDatIntLv); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 3, 3, BFMemClrInit); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 9, 9, BFDctSelBankSwap); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x118), 19, 19, BFLockDramCfg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x118), 18, 18, BFCC6SaveEn); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 31, 0, BFMctCfgHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x120), 23, 16, BFTrcBufAdrPtrHi); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x120), 15, 8, BFTrcBufDramLimitHi); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x120), 7, 0, BFTrcBufDramBaseHi); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1B0), 31, 0, BFExtMctCfgLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1B4), 31, 0, BFExtMctCfgHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1B4), 27, 27, BFFlushWrOnS3StpGnt); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1B4), 26, 26, BFEnSplitMctDatBuffers); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x1BC), 31, 0, BFCSMapCKE); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x200), 29, 24, BFTras); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x200), 20, 16, BFTrp); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x200), 12, 8, BFTrcd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x200), 4, 0, BFTcl); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x204), 27, 24, BFTrtp); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x204), 21, 16, BFFourActWindow); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x204), 11, 8, BFTrrd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x204), 5, 0, BFTrc); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x208), 26, 24, BFTrfc3); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x208), 18, 16, BFTrfc2); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x208), 10, 8, BFTrfc1); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x208), 2, 0, BFTrfc0); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x20C), 17, 16, BFWrDqDqsEarly); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x20C), 11, 8, BFTwtr); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x20C), 4, 0, BFTcwl); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x210), 31, 22, BFMaxLatency); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x210), 18, 16, BFDataTxFifoWrDly); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x210), 3, 0, BFRdPtrInit); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x214), 19, 16, BFTwrwrSdSc); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x214), 11, 8, BFTwrwrSdDc); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x214), 3, 0, BFTwrwrDd); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x218), 27, 24, BFTrdrdSdSc); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x218), 19, 16, BFTrdrdSdDc); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x218), 11, 8, BFTwrrd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x218), 3, 0, BFTrdrdDd); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x21C), 20, 16, BFTrwtWB); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x21C), 12, 8, BFTrwtTO); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x220), 12, 8, BFTmod); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x220), 3, 0, BFTmrd); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x224), 10, 8, BFTzqcs); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x224), 3, 0, BFTzqoper); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x228), 31, 24, BFTstag3); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x228), 23, 16, BFTstag2); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x228), 15, 8, BFTstag1); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x228), 7, 0, BFTstag0); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x22C), 4, 0, BFTwrDDR3); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x230), 31, 0, BFPhyRODTCSLow); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x234), 31, 0, BFPhyRODTCSHigh); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x238), 31, 0, BFPhyWODTCSLow); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x23C), 31, 0, BFPhyWODTCSHigh); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x240), 14, 12, BFWrOdtOnDuration); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x240), 10, 8, BFWrOdtTrnOnDly); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x240), 7, 4, BFRdOdtOnDuration); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x240), 3, 0, BFRdOdtTrnOnDly); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x244), 3, 0, BFPrtlChPDDynDly); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x248), 31, 31, BFRxChMntClkEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x248), 29, 24, BFAggrPDDelay); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x248), 21, 16, BFPchgPDEnDelay); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x248), 12, 8, BFTxpdll); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x248), 3, 0, BFTxp); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x24C), 29, 24, BFTcksrx); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x24C), 21, 16, BFTcksre); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x24C), 13, 8, BFTckesr); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x24C), 3, 0, BFTpd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x24C), 31, 0, BFDramPwrMngm1Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 20, 18, BFDataPatGenSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 12, 12, BFCmdSendInProg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 11, 11, BFSendCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 10, 10, BFTestStatus); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 9, 8, BFCmdTgt); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 7, 5, BFCmdType); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 4, 4, BFStopOnErr); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 3, 3, BFResetAllErr); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 2, 2, BFCmdTestEnable); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 13, 13, BFLfsrRollOver ); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x254), 26, 24, BFTgtChipSelectA); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x254), 23, 21, BFTgtBankA); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x254), 9, 0, BFTgtAddressA); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x258), 26, 24, BFTgtChipSelectB); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x258), 23, 21, BFTgtBankB); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x258), 9, 0, BFTgtAddressB); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x25C), 31, 22, BFBubbleCnt2); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x25C), 21, 12, BFBubbleCnt); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x25C), 7, 0, BFCmdStreamLen); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x260), 20, 0, BFCmdCount); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x268), 17, 0, BFNibbleErrSts); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x26C), 17, 0, BFNibbleErr180Sts); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x270), 18, 0, BFDataPrbsSeed); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x274), 31, 0, BFDramDqMaskLow ); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x278), 31, 0, BFDramDqMaskHigh); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x27C), 7, 0, BFDramEccMask ); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x288), 31, 24, BFXorPatOvr); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x28C), 31, 31, BFSendActCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x28C), 30, 30, BFSendPchgCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x28C), 29, 22, BFCmdChipSelect); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x28C), 21, 19, BFCmdBank); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x28C), 17, 0, BFCmdAddress); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x294), 31, 0, BFDQErrLow); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x298), 31, 0, BFDQErrHigh); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x29C), 7, 0, BFEccErr ); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2A8), 31, 0, BFDramUserDataPattern0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2AC), 31, 0, BFDramUserDataPattern1); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2B0), 31, 0, BFDramUserDataPattern2); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2B4), 31, 0, BFDramUserDataPattern3); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2E0), 30, 30, BFFastMstateDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2E0), 28, 24, BFM1MemClkFreq); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2E0), 22, 20, BFMxMrsEn); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2E8), 31, 16, BFMxMr1); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2E8), 15, 0, BFMxMr0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2EC), 15, 0, BFMxMr2); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x2F0), 0, 0, BFEffArbDis); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x400), 11, 8, BFGmcTokenLimit); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x400), 3, 0, BFMctTokenLimit); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x404), 31, 0, BFGmcToDctControl1); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x408), 28, 24, BFCpuElevPrioPeriod); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x408), 0, 0, BFCpuElevPrioDis); + + // --------------------------------------------------------------------------- + // + // DCT PHY REGISTERS + // + // --------------------------------------------------------------------------- + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 22, 20, BFDqsDrvStren); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 18, 16, BFDataDrvStren); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 14, 12, BFClkDrvStren); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 10, 8, BFAddrCmdDrvStren); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 6, 4, BFCsOdtDrvStren); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 2, 0, BFCkeDrvStren); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 29, BFDisablePredriverCal); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 13, 13, BFDqsRcvTrEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 7, 6, BFFenceTrSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 3, 3, BFPhyFenceTrEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 2, 2, BFTrNibbleSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0B, 31, 0, BFDramPhyStatusReg); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0C, 20, 16, BFPhyFence); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0C, 15, 12, BFCKETri); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0C, 11, 8, BFODTTri); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0C, 7, 0, BFChipSelTri); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D, 25, 24, BFRxDLLWakeupTime); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D, 22, 20, BFRxCPUpdPeriod); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D, 19, 16, BFRxMaxDurDllNoLock); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D, 9, 8, BFTxDLLWakeupTime); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D, 6, 4, BFTxCPUpdPeriod); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D, 3, 0, BFTxMaxDurDllNoLock); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x50, 31, 0, BFRstRcvFifo); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F13, 8, 8, BFRxSsbMntClkEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F13, 14, 14, BFProcOdtAdv); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F13, 7, 0, BFPhy0x0D0F0F13); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0830, 4, 4, BFEccDLLPwrDnConf); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F30, 6, 6, BFDataCtlPipePclkGateEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F30, 7, 7, BFPchgPdPclkGateEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F30, 9, 9, BFTxPclkGateEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FE013, 15, 0, BFPllRegWaitTime); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FE006, 15, 0, BFPllLockTime); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F02, 15, 0, BFDataByteTxPreDriverCal); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F04, 12, 12, BFPOdtOff); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F06, 15, 0, BFDataByteTxPreDriverCal2Pad1); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F0A, 15, 0, BFDataByteTxPreDriverCal2Pad2); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8006, 15, 0, BFCmdAddr0TxPreDriverCal2Pad1); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F800A, 15, 0, BFCmdAddr0TxPreDriverCal2Pad2); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8106, 15, 0, BFCmdAddr1TxPreDriverCal2Pad1); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F810A, 15, 0, BFCmdAddr1TxPreDriverCal2Pad2); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC006, 15, 0, BFAddrTxPreDriverCal2Pad1); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC00A, 15, 0, BFAddrTxPreDriverCal2Pad2); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC00E, 15, 0, BFAddrTxPreDriverCal2Pad3); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC012, 15, 0, BFAddrTxPreDriverCal2Pad4); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8002, 15, 0, BFCmdAddr0TxPreDriverCalPad0); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8102, 15, 0, BFCmdAddr1TxPreDriverCalPad0); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC002, 15, 0, BFAddrTxPreDriverCalPad0); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2002, 15, 0, BFClock0TxPreDriverCalPad0); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2102, 15, 0, BFClock1TxPreDriverCalPad0); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F4001, 15, 8, BFTxP); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F4001, 7, 0, BFTxN); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F0B, 31, 0, BFPhy0x0D0F0F0B); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F07, 31, 0, BFPhy0x0D0F0F07); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F03, 31, 0, BFPhy0x0D0F0F03); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F812F, 15, 0, BFAddrCmdTri); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F10, 12, 12, BFEnRxPadStandby); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D04E008, 8, 8, BFPStateToAccess); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2030, 4, 4, BFPhyClkConfig0); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2130, 4, 4, BFPhyClkConfig1); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FE040, 3, 0, BFRate); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F1E, 14, 12, BFDllCSRBiasTrim); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F1F, 4, 3, BFDataRxVioLvl); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F1F, 7, 5, BFRxDqInsDly); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F2F1F, 4, 3, BFClkRxVioLvl); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F4009, 3, 2, BFCsrComparator); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F4009, 15, 14, BFCmpVioLvl); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F8F1F, 4, 3, BFCmdRxVioLvl); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FC01F, 4, 3, BFAddrRxVioLvl); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F31, 9, 0, BFDataFence2); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FE019, 14, 0, BFFence2); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0FE01A, 15, 0, BFChAM1FenceSave); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F30, 8, 8, BFBlockRxDqsLock); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F001C, 15, 0, BFDataByteDllPowerMgnByte0); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F011C, 15, 0, BFDataByteDllPowerMgnByte1); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F021C, 15, 0, BFDataByteDllPowerMgnByte2); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F031C, 15, 0, BFDataByteDllPowerMgnByte3); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F041C, 15, 0, BFDataByteDllPowerMgnByte4); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F051C, 15, 0, BFDataByteDllPowerMgnByte5); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F061C, 15, 0, BFDataByteDllPowerMgnByte6); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F071C, 15, 0, BFDataByteDllPowerMgnByte7); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F081C, 15, 0, BFDataByteDllPowerMgnByte8); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F1C, 15, 0, BFDataByteDllPowerMgnByteAll); + + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F4006, 2, 0, BFObsrvVrefSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F4007, 2, 0, BFVrefSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F4007, 8, 3, BFVrefDAC); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F20, 15, 0, BFDataByteRxDqsDLLDimm0Broadcast); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F21, 15, 0, BFDataByteRxDqsDLLDimm1Broadcast); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F22, 15, 0, BFDataByteRxDqsDLLDimm2Broadcast); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F23, 15, 0, BFDataByteRxDqsDLLDimm3Broadcast); + MAKE_TSEFO (NBRegTable, DCT_PHY_DIRECT, 0x0D0F0F38, 14, 13, BFReducedLoop); + + // --------------------------------------------------------------------------- + // + // FUNCTION 3 + // + // --------------------------------------------------------------------------- + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x40), 31, 0, BFMcaNbCtlReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x44), 22, 22, BFDramEccEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x44), 2, 2, BFSyncOnUcEccEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x180), 25, 25, BFEccSymbolSize); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x58), 4, 0, BFDramScrub); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x5C), 0, 0, BFScrubReDirEn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x5C), 31, 0, BFScrubAddrLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x60), 31, 0, BFScrubAddrHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0x88), 27, 27, BFDisDramScrub); + + // --------------------------------------------------------------------------- + // + // FUNCTION 4 + // + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // + // FUNCTION 5 + // + // --------------------------------------------------------------------------- + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x84), 20, 16, BFDdrMaxRate); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x160), 18, 18, BFMemPstate0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x164), 18, 18, BFMemPstate1); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x168), 18, 18, BFMemPstate2); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x16C), 18, 18, BFMemPstate3); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x160), 16, 10, BFNbVid0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x164), 16, 10, BFNbVid1); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x168), 16, 10, BFNbVid2); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x16C), 16, 10, BFNbVid3); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x160), 21, 21, BFNbVid0Hi); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x164), 21, 21, BFNbVid1Hi); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x168), 21, 21, BFNbVid2Hi); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x16C), 21, 21, BFNbVid3Hi); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x170), 31, 0, BFNbPstateCtlReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x170), 31, 31, BFMemPstateDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x170), 14, 14, BFSwNbPstateLoDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x170), 7, 6, BFNbPstateHi); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x170), 4, 3, BFNbPstateLo); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x170), 1, 0, BFNbPstateMaxVal); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x174), 24, 24, BFCurMemPstate); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x174), 20, 19, BFCurNbPstate); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x174), 0, 0, BFNbPstateDis); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x188), 1, 0, BFNbOffsetTrim); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x240), 31, 0, BFECCExclusionBaseLow); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x244), 15, 0, BFECCExclusionBaseHigh); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x248), 31, 0, BFECCExclusionLimitLow); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x24C), 15, 0, BFECCExclusionLimitHigh); + + // --------------------------------------------------------------------------- + // + // LINK BITFIELD + // + // --------------------------------------------------------------------------- + LINK_TSEFO (NBRegTable, BFNbVid0, BFNbVid0Hi); + LINK_TSEFO (NBRegTable, BFNbVid1, BFNbVid1Hi); + LINK_TSEFO (NBRegTable, BFNbVid2, BFNbVid2Hi); + LINK_TSEFO (NBRegTable, BFNbVid3, BFNbVid3Hi); + + // --------------------------------------------------------------------------- + // + // REGISTERS WITH MULTIPLE MEMORY PSTATE COPIES + // + // --------------------------------------------------------------------------- + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFODCControl); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFDqsDrvStren); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFDataDrvStren); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFClkDrvStren); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFAddrCmdDrvStren); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFCsOdtDrvStren); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFCkeDrvStren); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFAddrTmgControl); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFDisablePredriverCal); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFProcOdtAdv); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFPOdtOff); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFDllCSRBiasTrim); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFDataRxVioLvl); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFRxDqInsDly); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTras); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTrp); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTrcd); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTcl); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTrtp); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFFourActWindow); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTrrd); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTrc); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFWrDqDqsEarly); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTwtr); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTcwl); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFTwrDDR3); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFWrOdtOnDuration); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFWrOdtTrnOnDly); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFRdOdtOnDuration); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFRdOdtTrnOnDly); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFMxMr0); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFMxMr1); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFMxMr2); + // These Phy fence registers don't have mutiple memory Pstate copies + // But they need to be written again in M1 context + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFDataFence2); + MULTI_MPSTATE_COPY_TSEFO (NBRegTable, BFFence2); + + IDS_OPTION_HOOK (IDS_INIT_MEM_REG_TABLE, NBPtr, &NBPtr->MemPtr->StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mns3kb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mns3kb.c new file mode 100644 index 0000000000..7c433ad033 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mns3kb.c @@ -0,0 +1,1258 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mns3kb.c + * + * KB memory specific function to support S3 resume + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/KB) + * @e \$Revision: 87696 $ @e \$Date: 2013-02-07 12:35:03 -0600 (Thu, 07 Feb 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "S3.h" +#include "mfs3.h" +#include "mnkb.h" +#include "cpuRegisters.h" +#include "cpuFamRegisters.h" +#include "cpuFamilyTranslation.h" +#include "mnS3kb.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_MEM_NB_KB_MNS3KB_FILECODE +#define DCT0_MEMPSTATE_MASK 0x10 +#define DCT1_MEMPSTATE_MASK 0x20 +#define DO_NOT_CARE 0 +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +UINT16 +STATIC +MemNS3GetRegLstPtrKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT DESCRIPTOR_GROUP *DescriptPtr + ); + +AGESA_STATUS +STATIC +MemNS3GetDeviceRegLstKB ( + IN UINT32 RegisterLstID, + OUT VOID **RegisterHeader + ); + +VOID +STATIC +MemNS3SetDfltPhyRegKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +STATIC +MemNS3SetDynModeChangeKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +STATIC +MemNS3SetPhyStatusRegKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +STATIC +MemNS3DisableChannelKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +STATIC +MemNS3GetConPCIMaskKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT DESCRIPTOR_GROUP *DescriptPtr + ); + +VOID +STATIC +MemNS3ChangeMemPStateContextAndFlowNb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +STATIC +MemNS3GetCSRKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +STATIC +MemNS3SetCSRKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +STATIC +MemNS3SetPhyFenceKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN VOID *Value, + IN OUT VOID *ConfigPtr + ); + +BOOLEAN +MemS3ResumeConstructNBBlockKB ( + IN OUT VOID *S3NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ); + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +PCI_SPECIAL_CASE PciSpecialCaseFuncKB[] = { + {MemNS3GetCSRKB, MemNS3SetCSRKB}, + {MemNS3GetBitFieldNb, MemNS3SetBitFieldNb}, + {MemNS3GetNBPStateDepRegUnb, MemNS3SetNBPStateDepRegUnb}, + { (VOID (*) (ACCESS_WIDTH, PCI_ADDR, VOID *, VOID *)) memDefRet, MemNS3SetDfltPhyRegKB}, + {MemNS3ChangeMemPStateContextAndFlowNb, MemNS3ChangeMemPStateContextAndFlowNb}, + { (VOID (*) (ACCESS_WIDTH, PCI_ADDR, VOID *, VOID *)) memDefRet, MemNS3SetDynModeChangeKB}, + { (VOID (*) (ACCESS_WIDTH, PCI_ADDR, VOID *, VOID *)) memDefRet, MemNS3DisableChannelKB}, + {MemNS3SaveNBRegisterUnb, MemNS3RestoreNBRegisterUnb}, + {MemNS3GetBitFieldNb, MemNS3SetPreDriverCalUnb}, + { (VOID (*) (ACCESS_WIDTH, PCI_ADDR, VOID *, VOID *)) memDefRet, MemNS3SetPhyStatusRegKB}, + { (VOID (*) (ACCESS_WIDTH, PCI_ADDR, VOID *, VOID *)) memDefRet, MemNS3SetMemClkFreqValUnb}, + {MemNS3ChangeMemPStateContextNb, MemNS3ChangeMemPStateContextNb}, + {MemNS3GetBitFieldNb, MemNS3SetPhyFenceKB}, + { (VOID (*) (ACCESS_WIDTH, PCI_ADDR, VOID *, VOID *)) memDefRet, MemNS3ReleaseNBPSUnb}, + { (VOID (*) (ACCESS_WIDTH, PCI_ADDR, VOID *, VOID *)) memDefRet, MemNS3ForceNBP0Unb}, + {MemNSaveHobDataUnb, MemNRestoreHobDataUnb} +}; + +MSR_SPECIAL_CASE MsrSpecialCaseFuncKB[] = { + { MemNModdifyMtrrFixDramModEn, MemNModdifyMtrrFixDramModEn} +}; +PCI_REG_DESCRIPTOR ROMDATA S3PciPreSelfRefDescriptorKB[] = { + {{14,3, 1}, DO_NOT_CARE, 0, 0}, + {{0, 0, 0}, FUNC_2, 0x110, 0x00000020}, + {{0, 0, 0}, FUNC_1, 0x40, 0xFFFF0703}, + {{0, 0, 0}, FUNC_1, 0x44, 0xFFFF0707}, + {{0, 0, 0}, FUNC_1, 0xF0, 0xFF00FF83}, + {{0, 0, 0}, FUNC_1, 0x120, 0x00001FFF}, + {{0, 0, 0}, FUNC_1, 0x124, 0x00001FFF}, + {{0, 0, 0}, FUNC_1, 0x200, 0x00FFF87B}, + {{0, 0, 0}, FUNC_1, 0x204, 0x00FFF800}, + {{0, 0, 0}, FUNC_2, 0x114, 0x00000200}, + {{0, 0, 0}, FUNC_2, 0x118, 0xF773FFFF}, + {{0, 0, 0}, FUNC_2, 0x11C, 0xAFFFFFFF}, + {{0, 0, 0}, FUNC_2, 0x120, 0x00FFFFFF}, + {{0, 0, 0}, FUNC_2, 0x1B0, 0xFFD3FF3F}, + {{0, 0, 0}, FUNC_2, 0x1B4, 0xFC7FFFFF}, + {{0, 0, 0}, FUNC_2, 0x1BC, 0xFFFFFFFF}, + {{0, 0, 0}, FUNC_2, 0xA4, 0x00F07900}, + {{0, 0, 0}, FUNC_5, 0x240, 0xFFFFFFC1}, + {{0, 0, 0}, FUNC_5, 0x244, 0x0000FFFF}, + {{0, 0, 0}, FUNC_5, 0x248, 0xFFFFFFC0}, + {{0, 0, 0}, FUNC_5, 0x24C, 0x0000FFFF} +}; + +CONST PCI_REGISTER_BLOCK_HEADER ROMDATA S3PciPreSelfRefKB = { + 0, + (sizeof (S3PciPreSelfRefDescriptorKB) / sizeof (PCI_REG_DESCRIPTOR)), + S3PciPreSelfRefDescriptorKB, + PciSpecialCaseFuncKB +}; + +CONDITIONAL_PCI_REG_DESCRIPTOR ROMDATA S3CPciPreSelfDescriptorKB[] = { + // DCT 0 + {{7, 0, 1}, DCT0, 0x40, 0x7FF8FFED, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x44, 0x7FF8FFED, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x48, 0x7FF8FFED, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x4C, 0x7FF8FFED, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x60, 0x7FF8FFE0, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x64, 0x7FF8FFE0, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x78, 0x00020000, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x80, 0x0000FFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x84, 0x00800003, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x88, 0x3F000000, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x8C, 0x00070000, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x90, 0x0BFF0000, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0xA8, 0x9C730000, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x1BC, 0xFFFFFFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x200, 0x3F1F1F1F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x204, 0x0F3F0F3F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x208, 0x07070707, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x20C, 0x00030F1F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{2, 0, 1}, DCT0, SET_S3_NB_PSTATE_OFFSET (0x210, 0), 0xFFC7000F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{2, 0, 1}, DCT0, SET_S3_NB_PSTATE_OFFSET (0x210, 1), 0xFFC7000F, DCT0_NBPSTATE_SUPPORT_MASK, DCT0_ANY_DIMM_MASK}, + {{2, 0, 1}, DCT0, SET_S3_NB_PSTATE_OFFSET (0x210, 2), 0xFFC7000F, DCT0_NBPSTATE_SUPPORT_MASK, DCT0_ANY_DIMM_MASK}, + {{2, 0, 1}, DCT0, SET_S3_NB_PSTATE_OFFSET (0x210, 3), 0xFFC7000F, DCT0_NBPSTATE_SUPPORT_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x214, 0x000F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x218, 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x21C, 0x001F1F00, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x220, 0x00001F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x224, 0x0000070F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x228, 0xFFFFFFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 1, 1}, DCT0, 0x22C, 0x0000001F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x230, 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x234, 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x238, 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x23C, 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x240, 0x000077FF, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 1, 1}, DCT0, 0x244, 0x0000000F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x248, 0xBF3F1F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x24C, 0x3F3F3F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x2E0, 0x5F700000, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x2E8, 0xFFFFFFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x2EC, 0x0000FFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 1, 1}, DCT0, 0x2F0, 0x00000001, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x400, 0x00000F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x404, 0x8F1F0F1F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x408, 0x1F000007, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x420, 0x00000F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + + // Phy Initialization + // 1. Program D18F2x9C_x0D0F_E013_dct[1:0] = 0118h. + {{1, 2, 1}, DCT0, BFPllRegWaitTime, 0, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + // 2. Force the phy to M0 with the following sequence: + // A. Program D18F2x9C_x0D0F_E006_dct[1:0][PllLockTime] = 190h. + {{3, 3, 1}, DCT0, BFPllLockTime, 0, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + // B. For each DCT: Program D18F2x9C_x0000_000B_dct[1:0] = 80800000h. + {{9, 3, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0B), 0, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + // C. Program D18F2x9C_x0000_000B_dct[0] = 40000000h. + // D. For each DCT: Program D18F2x9C_x0000_000B_dct[1:0] = 80000000h + {{5, 3, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0B), 0, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + + // 3. Phy voltage related + {{1, 1, 1}, DCT0, BFDataRxVioLvl, 0x00000018, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFClkRxVioLvl, 0x00000018, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFCmpVioLvl, 0x0000C000, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFCmdRxVioLvl, 0x00000018, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFCsrComparator, 0x0000000C, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFAddrRxVioLvl, 0x00000018, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFObsrvVrefSel, 0x00000007, DCT0_MASK, ANY_DIMM_MASK}, + + // 4. Frequency Change + // Check if a channel needs to be disabled + {{1, 1, 1}, DCT0, BFCKETri, 0, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + {{6, 3, 1}, DCT0, 0, 0, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFPhyClkConfig0, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFPhyClkConfig1, 0, DCT0_MASK, ANY_DIMM_MASK}, + + {{7, 0, 1}, DCT0, 0x94, 0x9FF1CC1F, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFPOdtOff, 0, DCT0_MASK, ANY_DIMM_MASK}, + + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x04), 0x003F3F3F, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFProcOdtAdv, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFReducedLoop, 0, DCT0_MASK, ANY_DIMM_MASK}, + + // Enable MemClk + {{10, 0, 1}, DCT0, 0x94, 0, DCT0_MASK, DCT0_ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFPllLockTime, 0, DCT0_MASK, ANY_DIMM_MASK}, + // Hardware programs POdtOff for the current M-state (D18F2x9C_x0D0F_E006_dct[0][PhyPS]) with the value in D18F2x94_dct[0] + // [ProcOdtDis] (via D18F2x9C_x0000_000B_dct[0][ProcOdtDis]) when the memory frequency is updated. BIOS must reprogram this + // BIOS must reprogram this field after each frequency change if the target value differs from D18F2x94_dct[0][ProcOdtDis]. + {{1, 2, 1}, DCT0, BFPOdtOff, 0, DCT0_MASK, ANY_DIMM_MASK}, + + // DCT 0 + // 5. Phy Fence + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0C), 0x7FFF3FFF, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataFence2, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFFence2, 0x00007C1F, DCT0_MASK, ANY_DIMM_MASK}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x04), 0x003F3F3F, DCT0_MASK, ANY_DIMM_MASK}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x00), 0x70777777, DCT0_MASK, ANY_DIMM_MASK}, + // 6. Phy Compensation Init + {{3, 3, 1}, DCT0, BFDisablePredriverCal, 0, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + {{1, 0, 1}, DCT0, BFPhy0x0D0F0F0B, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 0, 1}, DCT0, BFPhy0x0D0F0F07, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 0, 1}, DCT0, BFPhy0x0D0F0F03, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteTxPreDriverCal2Pad1, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteTxPreDriverCal2Pad2, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{8, 2, 1}, DCT0, BFDataByteTxPreDriverCal, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFCmdAddr0TxPreDriverCal2Pad1, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFCmdAddr0TxPreDriverCal2Pad2, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFCmdAddr1TxPreDriverCal2Pad1, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFCmdAddr1TxPreDriverCal2Pad2, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFAddrTxPreDriverCal2Pad1, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFAddrTxPreDriverCal2Pad2, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFAddrTxPreDriverCal2Pad3, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFAddrTxPreDriverCal2Pad4, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{8, 2, 1}, DCT0, BFCmdAddr0TxPreDriverCalPad0, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{8, 2, 1}, DCT0, BFCmdAddr1TxPreDriverCalPad0, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{8, 2, 1}, DCT0, BFAddrTxPreDriverCalPad0, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{8, 2, 1}, DCT0, BFClock0TxPreDriverCalPad0, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{8, 2, 1}, DCT0, BFClock1TxPreDriverCalPad0, 0, DCT0_MASK, ANY_DIMM_MASK}, + + {{1, 1, 1}, DCT0, BFDisablePredriverCal, 0, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK}, + // Program MemPstate 1 registers + // Switch to MemPstate context 1 + {{11, 3, 1}, DO_NOT_CARE, 1, DO_NOT_CARE, DCT0_MEMPSTATE_MASK + DCT1_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFRate, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFProcOdtAdv, 0, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFDataRxVioLvl, 0x00000018, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x200, 0x3F1F1F1F, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x204, 0x0F3F0F3F, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x208, 0x07070707, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x20C, 0x00030F1F, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x214, 0x000F0F0F, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x218, 0x0F0F0F0F, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x21C, 0x001F1F00, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 1, 1}, DCT0, 0x22C, 0x0000001F, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x240, 0x000077FF, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x248, 0xBF3F1F0F, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 0, 1}, DCT0, 0x2E8, 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + {{7, 2, 1}, DCT0, 0x2EC, 0x0000FFFF, DCT0_MEMPSTATE_MASK, DCT0_ANY_DIMM_MASK}, + // Compute Phy fence for MemPstate 1 + // DCT 0 + {{12, 2, 1}, DCT0, BFChAM1FenceSave, 0, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x04), 0x003F3F3F, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x00), 0x70777777, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + + {{1, 1, 1}, DCT0, BFDisablePredriverCal, 0, DCT0_MEMPSTATE_MASK + DCT1_MEMPSTATE_MASK, ANY_DIMM_MASK}, + // Switch back to MemPstate context 0 + {{11, 3, 1}, DO_NOT_CARE, 0, DO_NOT_CARE, DCT0_MEMPSTATE_MASK + DCT1_MEMPSTATE_MASK, ANY_DIMM_MASK}, + + // Set Fence back to Fence of M0 to prepare for fine delay restore for M0 + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0C), 0x7FFF3FFF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataFence2, 0, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFFence2, 0x00007C1F, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + + {{15, 0, 1}, S3_UMA_SIZE, 0, 0, ANY_DIMM_MASK, ANY_DIMM_MASK, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{15, 0, 1}, S3_UMA_BASE, 0, 0, ANY_DIMM_MASK, ANY_DIMM_MASK, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{15, 1, 1}, S3_UMA_MODE, 0, 0, ANY_DIMM_MASK, ANY_DIMM_MASK, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{15, 0, 1}, S3_SUB_4G_CACHE_TOP, 0, 0, ANY_DIMM_MASK, ANY_DIMM_MASK, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{15, 0, 1}, S3_SYSLIMIT, 0, 0, ANY_DIMM_MASK, ANY_DIMM_MASK, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + // Always put UMA_ATTRIBUTE after other types for hob data save and restore + {{15, 0, 1}, S3_UMA_ATTRIBUTE, 0, 0, ANY_DIMM_MASK, ANY_DIMM_MASK, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + + {{15, 1, 1}, S3_VDDIO, 0, 0, ANY_DIMM_MASK, ANY_DIMM_MASK, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE} +}; + +CONST CPCI_REGISTER_BLOCK_HEADER ROMDATA S3CPciPreSelfRefKB = { + 0, + (sizeof (S3CPciPreSelfDescriptorKB) / sizeof (CONDITIONAL_PCI_REG_DESCRIPTOR)), + S3CPciPreSelfDescriptorKB, + PciSpecialCaseFuncKB +}; + +CONDITIONAL_PCI_REG_DESCRIPTOR ROMDATA S3CPciPostSelfDescriptorKB[] = { + // DCT0 + {{12, 2, 1}, DCT0, BFChAM1FenceSave, 0, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFRxDqInsDly, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x10), 0x03FF03FF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x11), 0x03FF03FF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x13), 0x03FF03FF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x14), 0x03FF03FF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x16), 0x03FF03FF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x17), 0x03FF03FF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x19), 0x03FF03FF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x1A), 0x03FF03FF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x20), 0x03FF03FF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x21), 0x03FF03FF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x23), 0x03FF03FF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x24), 0x03FF03FF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x26), 0x03FF03FF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x27), 0x03FF03FF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x29), 0x03FF03FF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x2A), 0x03FF03FF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x01), 0xFFFFFFFF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x02), 0xFFFFFFFF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x101), 0xFFFFFFFF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x102), 0xFFFFFFFF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x201), 0xFFFFFFFF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x202), 0xFFFFFFFF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x301), 0xFFFFFFFF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x302), 0xFFFFFFFF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x05), 0x3E3E3E3E, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x06), 0x3E3E3E3E, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x105), 0x3E3E3E3E, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x106), 0x3E3E3E3E, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x205), 0x3E3E3E3E, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x206), 0x3E3E3E3E, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x305), 0x3E3E3E3E, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x306), 0x3E3E3E3E, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x30), 0x00FF00FF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x31), 0x00FF00FF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x33), 0x00FF00FF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x34), 0x00FF00FF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x36), 0x00FF00FF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x37), 0x00FF00FF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x39), 0x00FF00FF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x3A), 0x00FF00FF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x40), 0x00FF00FF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x41), 0x00FF00FF, DCT0_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x43), 0x00FF00FF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x44), 0x00FF00FF, DCT0_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x46), 0x00FF00FF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x47), 0x00FF00FF, DCT0_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x49), 0x00FF00FF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x4A), 0x00FF00FF, DCT0_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0D), 0x037F037F, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFPhy0x0D0F0F13, 0x00000083, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDllCSRBiasTrim, 0x00007000, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFRxSsbMntClkEn, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFEnRxPadStandby, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFEccDLLPwrDnConf, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFTxPclkGateEn, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFPchgPdPclkGateEn, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFDataCtlPipePclkGateEn, 0, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte0, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte1, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte2, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte3, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte4, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte5, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte6, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte7, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte8, 0xBFBF, DCT0_MASK, ANY_DIMM_MASK}, + + {{11, 3, 1}, DO_NOT_CARE, 1, DO_NOT_CARE, DCT0_MEMPSTATE_MASK + DCT1_MEMPSTATE_MASK, ANY_DIMM_MASK}, + + // DCT0 + {{12, 2, 1}, DCT0, BFChAM1FenceSave, 0, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFRxDqInsDly, 0, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x10), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x11), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x13), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x14), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x16), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x17), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x19), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x1A), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x20), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x21), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x23), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x24), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x26), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x27), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x29), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x2A), 0x03FF03FF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x01), 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x02), 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x101), 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x102), 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x201), 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x202), 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x301), 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x302), 0xFFFFFFFF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x05), 0x3E3E3E3E, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x06), 0x3E3E3E3E, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x105), 0x3E3E3E3E, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x106), 0x3E3E3E3E, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x205), 0x3E3E3E3E, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x206), 0x3E3E3E3E, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x305), 0x3E3E3E3E, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x306), 0x3E3E3E3E, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x30), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x31), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x33), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x34), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x36), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x37), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x39), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x3A), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x40), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x41), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x01}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x43), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x44), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x04}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x46), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x47), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x10}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x49), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x4A), 0x00FF00FF, DCT0_MEMPSTATE_MASK, 0x40}, + {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0D), 0x037F037F, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFPhy0x0D0F0F13, 0x00000083, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDllCSRBiasTrim, 0x00007000, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFRxSsbMntClkEn, 0, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFEnRxPadStandby, 0, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte0, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte1, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte2, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte3, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte4, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte5, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte6, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte7, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFDataByteDllPowerMgnByte8, 0xBFBF, DCT0_MEMPSTATE_MASK, ANY_DIMM_MASK}, + + {{11, 3, 1}, DO_NOT_CARE, 0, DO_NOT_CARE, DCT0_MEMPSTATE_MASK + DCT1_MEMPSTATE_MASK, ANY_DIMM_MASK}, + + {{1, 1, 1}, DCT0, BFAddrCmdTri, 0x0000000A1, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 1, 1}, DCT0, BFDisDllShutdownSR, 0, DCT0_MASK, ANY_DIMM_MASK}, + + {{1, 1, 1}, DCT0, BFVrefSel, 0x00000007, DCT0_MASK, ANY_DIMM_MASK}, + {{1, 2, 1}, DCT0, BFVrefDAC, 0x000001F8, DCT0_MASK, ANY_DIMM_MASK}, + + {{0, 0, 0}, FUNC_2, 0x1B4, 0x08000000, ANY_DIMM_MASK, ANY_DIMM_MASK}, + {{0, 0, 0}, FUNC_3, 0x180, 0x02000000, ANY_DIMM_MASK, ANY_DIMM_MASK}, + {{0, 0, 0}, FUNC_3, 0x58, 0x0000001F, ANY_DIMM_MASK, ANY_DIMM_MASK}, + {{0, 0, 0}, FUNC_3, 0x5C, 0x00000001, ANY_DIMM_MASK, ANY_DIMM_MASK}, + {{0, 0, 0}, FUNC_3, 0x44, 0x00400004, ANY_DIMM_MASK, ANY_DIMM_MASK}, + + {{0, 0, 0}, FUNC_2, 0x118, 0x00040000, ANY_DIMM_MASK, ANY_DIMM_MASK}, + {{0, 0, 0}, FUNC_2, 0x118, 0x00080000, ANY_DIMM_MASK, ANY_DIMM_MASK}, + + {{13, 3, 1}, DO_NOT_CARE, 0, DO_NOT_CARE, ANY_DIMM_MASK, ANY_DIMM_MASK} +}; + +CONST CPCI_REGISTER_BLOCK_HEADER ROMDATA S3CPciPostSelfRefKB = { + 0, + (sizeof (S3CPciPostSelfDescriptorKB) / sizeof (CONDITIONAL_PCI_REG_DESCRIPTOR)), + S3CPciPostSelfDescriptorKB, + PciSpecialCaseFuncKB +}; + +MSR_REG_DESCRIPTOR ROMDATA S3MSRPreSelfRefDescriptorKB[] = { + {{0, 0, 0}, 0xC0010010, 0x00000000007F0000}, + {{0, 0, 0}, 0xC001001A, 0x0000FFFFFF800000}, + {{0, 0, 0}, 0xC001001D, 0x0000FFFFFF800000}, + {{0, 0, 0}, 0xC001001F, 0x0044601080000600}, + {{0, 0, 1}, 0, 0, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x250, 0x1F1F1F1F1F1F1F1F, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x258, 0x1F1F1F1F1F1F1F1F, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 1}, 1, 0, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000200, 0x0000FFFFFFFFF007, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000202, 0x0000FFFFFFFFF007, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000204, 0x0000FFFFFFFFF007, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000206, 0x0000FFFFFFFFF007, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000208, 0x0000FFFFFFFFF007, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x0000020A, 0x0000FFFFFFFFF007, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000201, 0x0000FFFFFFFFF800, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000203, 0x0000FFFFFFFFF800, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000205, 0x0000FFFFFFFFF800, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000207, 0x0000FFFFFFFFF800, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x00000209, 0x0000FFFFFFFFF800, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE}, + {{0, 0, 0}, 0x0000020B, 0x0000FFFFFFFFF800, RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE} +}; + +CONST MSR_REGISTER_BLOCK_HEADER ROMDATA S3MSRPreSelfRefKB = { + 0, + (sizeof (S3MSRPreSelfRefDescriptorKB) / sizeof (MSR_REG_DESCRIPTOR)), + S3MSRPreSelfRefDescriptorKB, + MsrSpecialCaseFuncKB +}; + +VOID *MemS3RegListKB[] = { + (VOID *)&S3PciPreSelfRefKB, + NULL, + (VOID *)&S3CPciPreSelfRefKB, + (VOID *)&S3CPciPostSelfRefKB, + (VOID *)&S3MSRPreSelfRefKB, + NULL, + NULL, + NULL +}; + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the northbridge block for S3 resume + * + * @param[in,out] *S3NBPtr - Pointer to MEM_NB_BLOCK. + * @param[in,out] *MemPtr - Pointer to MEM_DATA_STRUCT. + * @param[in] NodeID - Node ID of the target node. + * + * @return BOOLEAN + * TRUE - This is the correct constructor for the targeted node. + * FALSE - This isn't the correct constructor for the targeted node. + */ +BOOLEAN +MemS3ResumeConstructNBBlockKB ( + IN OUT VOID *S3NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ) +{ + INT32 i; + MEM_NB_BLOCK *NBPtr; + + NBPtr = ((S3_MEM_NB_BLOCK *)S3NBPtr)->NBPtr; + + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemNIsIdSupportedKB (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { + return FALSE; + } + + NBPtr->RefPtr = NULL; + NBPtr->MemPtr = MemPtr; + NBPtr->MCTPtr = &(MemPtr->DiesPerSystem[NodeID]); + NBPtr->PciAddr.AddressValue = MemPtr->DiesPerSystem[NodeID].PciAddr.AddressValue; + MemNInitNBRegTableKB (NBPtr, NBPtr->NBRegTable); + NBPtr->Node = ((UINT8) NBPtr->PciAddr.Address.Device) - 24; + NBPtr->Dct = 0; + NBPtr->Channel = 0; + NBPtr->Ganged = FALSE; + NBPtr->NodeCount = MAX_NODES_SUPPORTED_KB; + NBPtr->DctCount = MAX_DCTS_PER_NODE_KB; + NBPtr->MemPstate = MEMORY_PSTATE0; + NBPtr->MemPstateStage = 0; + NBPtr->NbPsCtlReg = 0; + + NBPtr->IsSupported[SetDllShutDown] = TRUE; + + for (i = 0; i < EnumSize; i++) { + NBPtr->IsSupported[i] = FALSE; + } + + for (i = 0; i < NumberOfHooks; i++) { + NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) memDefTrue; + } + + LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &MemPtr->StdHeader); + + NBPtr->SwitchDCT = MemNSwitchDCTNb; + NBPtr->SwitchChannel = MemNSwitchChannelNb; + NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldKB; + NBPtr->GetBitField = MemNGetBitFieldNb; + NBPtr->SetBitField = MemNSetBitFieldNb; + NBPtr->MemNIsIdSupportedNb = MemNIsIdSupportedKB; + ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3ExitSelfRefReg = (VOID (*) (MEM_NB_BLOCK *, AMD_CONFIG_PARAMS *)) memDefRet; + ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetConPCIMask = MemNS3GetConPCIMaskKB; + ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetConMSRMask = (VOID (*) (MEM_NB_BLOCK *, DESCRIPTOR_GROUP *)) memDefRet; + ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3Resume = MemNS3ResumeUNb; + ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3RestoreScrub = MemNS3RestoreScrubNb; + ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetRegLstPtr = MemNS3GetRegLstPtrKB; + ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetDeviceRegLst = MemNS3GetDeviceRegLstKB; + ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3SpecialCaseHeapSize = 0; + NBPtr->FamilySpecificHook[DCTSelectSwitch] = MemNS3DctCfgSelectUnb; + + MemNSetBitFieldNb (NBPtr, BFDctCfgSel, 0); + MemNSwitchDCTNb (NBPtr, 0); + MemNSetBitFieldNb (NBPtr, BFMemPsSel, 0); + + if (MemNGetBitFieldNb (NBPtr, BFMemPstateDis) != 1) { + NBPtr->MemPstateStage = MEMORY_PSTATE_S3_STAGE; + MemNBrdcstSetUnConditionalNb (NBPtr, BFPStateToAccess, 0); + } + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *----------------------------------------------------------------------------*/ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the register list for each device for KB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in, out] *DescriptPtr - Pointer to DESCRIPTOR_GROUP + * @return UINT16 - size of the device descriptor on the target node. + */ +UINT16 +STATIC +MemNS3GetRegLstPtrKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT DESCRIPTOR_GROUP *DescriptPtr + ) +{ + UINT8 i; + UINT16 Size; + Size = 0; + for (i = PRESELFREF; i <= POSTSELFREF; i ++) { + DescriptPtr->PCIDevice[i].Type = (UINT8) (DEV_TYPE_PCI_PRE_ESR + i); + DescriptPtr->PCIDevice[i].Node = NBPtr->Node; + DescriptPtr->PCIDevice[i].RegisterListID = 0xFFFFFFFF; + if ((PCI_REGISTER_BLOCK_HEADER *) MemS3RegListKB[PCI_LST_ESR_KB - PCI_LST_ESR_KB + i] != NULL) { + DescriptPtr->PCIDevice[i].RegisterListID = PCI_LST_ESR_KB + i; + Size += sizeof (PCI_DEVICE_DESCRIPTOR); + } + DescriptPtr->CPCIDevice[i].Type = (UINT8) (DEV_TYPE_CPCI_PRE_ESR + i); + DescriptPtr->CPCIDevice[i].Node = NBPtr->Node; + DescriptPtr->CPCIDevice[i].RegisterListID = 0xFFFFFFFF; + if ((CPCI_REGISTER_BLOCK_HEADER *) MemS3RegListKB[CPCI_LST_ESR_KB - PCI_LST_ESR_KB + i] != NULL) { + DescriptPtr->CPCIDevice[i].RegisterListID = CPCI_LST_ESR_KB + i; + Size += sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR); + } + DescriptPtr->MSRDevice[i].Type = (UINT8) (DEV_TYPE_MSR_PRE_ESR + i); + DescriptPtr->MSRDevice[i].RegisterListID = 0xFFFFFFFF; + if ((MSR_REGISTER_BLOCK_HEADER *) MemS3RegListKB[MSR_LST_ESR_KB - PCI_LST_ESR_KB + i] != NULL) { + DescriptPtr->MSRDevice[i].RegisterListID = MSR_LST_ESR_KB + i; + Size += sizeof (MSR_DEVICE_DESCRIPTOR); + } + DescriptPtr->CMSRDevice[i].Type = (UINT8) (DEV_TYPE_CMSR_PRE_ESR + i); + DescriptPtr->CMSRDevice[i].RegisterListID = 0xFFFFFFFF; + if ((CMSR_REGISTER_BLOCK_HEADER *) MemS3RegListKB[CMSR_LST_ESR_KB - PCI_LST_ESR_KB + i] != NULL) { + DescriptPtr->CMSRDevice[i].RegisterListID = CMSR_LST_ESR_KB + i; + Size += sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR); + } + } + return Size; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function return the register list according to the register ID. + * + * @param[in] RegisterLstID - value of the Register list ID. + * @param[out] **RegisterHeader - pointer to the address of the register list. + * @return AGESA_STATUS + * - AGESA_FATAL + * - AGESA_SUCCESS + */ +AGESA_STATUS +STATIC +MemNS3GetDeviceRegLstKB ( + IN UINT32 RegisterLstID, + OUT VOID **RegisterHeader + ) +{ + if (RegisterLstID >= (sizeof (MemS3RegListKB) / sizeof (VOID *))) { + ASSERT(FALSE); // RegisterListID exceeded size of Register list + return AGESA_FATAL; + } + if (MemS3RegListKB[RegisterLstID] != NULL) { + *RegisterHeader = MemS3RegListKB[RegisterLstID]; + return AGESA_SUCCESS; + } + ASSERT(FALSE); // Device register list error + return AGESA_FATAL; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function that set PllLockTime or disable auto compensation. + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +STATIC +MemNS3SetDfltPhyRegKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT16 RegValue; + BIT_FIELD_NAME BitField; + + IDS_SKIP_HOOK (IDS_BEFORE_S3_SPECIAL, &Address, ConfigPtr) { + BitField = (BIT_FIELD_NAME) Address.Address.Register; + RegValue = 0; + + if (BitField == BFPllLockTime) { + RegValue = 0x190; + } else if (BitField == BFDisablePredriverCal) { + RegValue = 3; + } else { + ASSERT (FALSE); + } + MemNS3SetBitFieldNb (AccessS3SaveWidth16, Address, &RegValue, ConfigPtr); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets bit 31 [DynModeChange] of F2x9C_xB + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +STATIC +MemNS3SetDynModeChangeKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT32 RegValue; + + IDS_SKIP_HOOK (IDS_BEFORE_S3_SPECIAL, &Address, ConfigPtr) { + if ((Address.Address.Register & 0x400) == 0) { + RegValue = 0x40000000; + MemNS3SetCSRKB (AccessS3SaveWidth32, Address, &RegValue, ConfigPtr); + } + RegValue = 0x80000000; + MemNS3SetCSRKB (AccessS3SaveWidth32, Address, &RegValue, ConfigPtr); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets F2x9C_xB to 0x80800000 + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +STATIC +MemNS3SetPhyStatusRegKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT32 RegValue; + + IDS_SKIP_HOOK (IDS_BEFORE_S3_SPECIAL, &Address, ConfigPtr) { + RegValue = 0x80800000; + MemNS3SetCSRKB (AccessS3SaveWidth32, Address, &RegValue, ConfigPtr); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function does the channel disable sequence + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +STATIC +MemNS3DisableChannelKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + UINT32 RegValue; + UINT8 Die; + + // See which Node should be accessed + Die = (UINT8) (Address.Address.Device - 24); + + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[Die].NBPtr; + + // Function field contains the DCT number + NBPtr->SwitchDCT (NBPtr, (UINT8) Address.Address.Function); + RegValue = MemNGetBitFieldNb (NBPtr, BFCKETri); + // if CKETri is 0b1111, this channel is disabled + if (RegValue == 0xF) { + //Wait for 24 MEMCLKs, which is 60ns under 400MHz + MemFS3Wait10ns (6, NBPtr->MemPtr); + MemNSetBitFieldNb (NBPtr, BFMemClkDis, 0xFF); + MemNSetBitFieldNb (NBPtr, BFDisDramInterface, 1); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function changes memory Pstate context + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +VOID +STATIC +MemNS3ChangeMemPStateContextAndFlowNb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + UINT8 Die; + + // See which Node should be accessed + Die = (UINT8) (Address.Address.Device - 24); + + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[Die].NBPtr; + if (NBPtr->MemPstate == MEMORY_PSTATE0) { + // If MemoryPstate is not disabled, switch to MemPState 1 context, and reprocess the register list + MemNChangeMemPStateContextNb (NBPtr, 1); + *(UINT32 *) Value = RESTART_FROM_BEGINNING_LIST; + } else { + // Switch back to MemPstate0 Context + MemNChangeMemPStateContextNb (NBPtr, 0); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns the conditional PCI device mask + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in, out] *DescriptPtr - Pointer to DESCRIPTOR_GROUP + * @return none + */ +VOID +STATIC +MemNS3GetConPCIMaskKB ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT DESCRIPTOR_GROUP *DescriptPtr + ) +{ + BIT_FIELD_NAME bitfield; + UINT32 RegVal; + UINT8 DCT; + UINT8 DimmMask; + UINT8 BadDimmMask; + UINT8 NbPsCapMsk; + UINT8 MemPstateMsk; + UINT8 CsPerDelay; + + NbPsCapMsk = 0; + MemPstateMsk = 0; + DimmMask = 0; + BadDimmMask = 0; + CsPerDelay = 1; + + for (DCT = 0; DCT < NBPtr->DctCount; DCT ++) { + MemNSwitchDCTNb (NBPtr, DCT); + if (MemNGetBitFieldNb (NBPtr, BFMemClkFreqVal)) { + if (MemNGetBitFieldNb (NBPtr, BFPerRankTimingEn) == 0) { + CsPerDelay = 2; + } + for (bitfield = BFCSBaseAddr0Reg; bitfield <= BFCSBaseAddr7Reg; bitfield ++) { + RegVal = MemNGetBitFieldNb (NBPtr, bitfield); + if (RegVal & 0x1) { + DimmMask |= (UINT8) (1 << ((((bitfield - BFCSBaseAddr0Reg) / CsPerDelay) << 1) + DCT)); + } else if (RegVal & 0x4) { + BadDimmMask |= (UINT8) (1 << ((((bitfield - BFCSBaseAddr0Reg) / CsPerDelay) << 1) + DCT)); + } + } + } + } + // Check if the system is capable of doing NB Pstate change + if (MemNGetBitFieldNb (NBPtr, BFNbPstateDis) == 0) { + NbPsCapMsk = DCT0_NBPSTATE_SUPPORT_MASK; + } + if (MemNGetBitFieldNb (NBPtr, BFMemPstateDis) == 0) { + MemPstateMsk = DCT0_MEMPSTATE_MASK; + } + + MemNSwitchDCTNb (NBPtr, 0); + // Set channel mask + DescriptPtr->CPCIDevice[PRESELFREF].Mask1 = 0; + DescriptPtr->CPCIDevice[POSTSELFREF].Mask1 = 0; + for (DCT = 0; DCT < NBPtr->DctCount; DCT ++) { + if (DimmMask & (0x55 << DCT)) { + // Set mask before exit self refresh + DescriptPtr->CPCIDevice[PRESELFREF].Mask1 |= (NbPsCapMsk | MemPstateMsk | 1) << DCT; + // Set mask after exit self refresh + DescriptPtr->CPCIDevice[POSTSELFREF].Mask1 |= (NbPsCapMsk | MemPstateMsk | 1) << DCT; + } else if (BadDimmMask & (0x55 << DCT)) { + // Need to save function 2 registers for bad dimm + DescriptPtr->CPCIDevice[PRESELFREF].Mask1 |= 1 << DCT; + } + } + + // Set dimm mask + DescriptPtr->CPCIDevice[PRESELFREF].Mask2 = DimmMask; + DescriptPtr->CPCIDevice[POSTSELFREF].Mask2 = DimmMask; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function read the value of CSR register. + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in] *Value - Pointer to the value be read. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +STATIC +MemNS3GetCSRKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT8 TempValue; + UINT8 Dct; + UINT32 ExtendOffset; + UINT32 TempFunc; + + ExtendOffset = Address.Address.Register; + TempFunc = Address.Address.Function; + + // Switch Dct + Address.Address.Function = FUNC_1; + Address.Address.Register = 0x10C; + Dct = 0; + if (ExtendOffset & 0x400) { + Dct = 1; + } + LibAmdPciRead (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + TempValue = (TempValue & 0xF8) | Dct; + LibAmdPciWrite (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + Address.Address.Function = TempFunc; + + Address.Address.Register = 0x98; + ExtendOffset &= 0x3FF; + LibAmdPciWrite (AccessS3SaveWidth32, Address, &ExtendOffset, ConfigPtr); + IDS_OPTION_HOOK (IDS_AFTER_DCT_PHY_ACCESS, NULL, ConfigPtr); + Address.Address.Register = 0x9C; + LibAmdPciRead (AccessWidth, Address, Value, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function write to a CSR register + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value be read. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +STATIC +MemNS3SetCSRKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT8 TempValue; + UINT8 Dct; + UINT32 ExtendOffset; + UINT32 ValueWrite; + UINT32 TempFunc; + + ExtendOffset = Address.Address.Register; + + TempFunc = Address.Address.Function; + // Switch Dct + Address.Address.Function = FUNC_1; + Address.Address.Register = 0x10C; + Dct = 0; + if (ExtendOffset & 0x400) { + Dct = 1; + } + LibAmdPciRead (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + TempValue = (TempValue & 0xFE) | Dct; + LibAmdPciWrite (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + + Address.Address.Function = TempFunc; + Address.Address.Register = 0x9C; + + ExtendOffset &= 0x3FF; + ExtendOffset |= 0x40000000; + switch (AccessWidth) { + case AccessS3SaveWidth8: + ValueWrite = *(UINT8 *) Value; + break; + case AccessS3SaveWidth16: + ValueWrite = *(UINT16 *) Value; + break; + case AccessS3SaveWidth32: + ValueWrite = *(UINT32 *) Value; + break; + default: + ASSERT (FALSE); + } + LibAmdPciWrite (AccessS3SaveWidth32, Address, &ValueWrite, ConfigPtr); + Address.Address.Register = 0x98; + LibAmdPciWrite (AccessS3SaveWidth32, Address, &ExtendOffset, ConfigPtr); + IDS_OPTION_HOOK (IDS_AFTER_DCT_PHY_ACCESS, NULL, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function that set Phy Fence + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +STATIC +MemNS3SetPhyFenceKB ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT16 FenceValue; + UINT16 Fence2Data; + UINT16 Fence2Reg; + BIT_FIELD_NAME BitField; + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + + BitField = (BIT_FIELD_NAME) Address.Address.Register; + FenceValue = *(UINT16 *) Value; + // See which Node should be accessed + + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[0].NBPtr; + + // Do nothing if currently in memory pstate 0 context + if (NBPtr->MemPstate == MEMORY_PSTATE0) { + return; + } + + MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 30, 16, BFPhyFence); + MemNSetBitFieldNb (NBPtr, BFPhyFence, FenceValue); + + // Program Fence 2 for MState 1 + Fence2Data = 0; + if ((FenceValue & 0x1F) < 16) { + Fence2Data |= (FenceValue & 0x1F) | 0x10; + } + if (((FenceValue >> 5) & 0x1F) < 16) { + Fence2Data |= (((FenceValue >> 5) & 0x1F) | 0x10) << 10; + } + if (((FenceValue >> 10) & 0x1F) < 16) { + Fence2Data |= (((FenceValue >> 10) & 0x1F) | 0x10) << 5; + } + MemNSetBitFieldNb (NBPtr, BFDataFence2, Fence2Data); + + // Program another Fence 2 register for Mstate 1 + Fence2Reg = (UINT16) MemNGetBitFieldNb (NBPtr, BFFence2); + Fence2Reg = (Fence2Reg &~(UINT16) ((0x1F << 10) | 0x1F)) | (Fence2Data & 0x1F) | (((Fence2Data >> 5) & 0x1F) << 10); + MemNSetBitFieldNb (NBPtr, BFFence2, Fence2Reg); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mn.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mn.c new file mode 100644 index 0000000000..f9e62d0b01 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mn.c @@ -0,0 +1,608 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mn.c + * + * Common Northbridge functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/) + * @e \$Revision: 86704 $ @e \$Date: 2013-01-24 17:29:29 -0600 (Thu, 24 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "mport.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "S3.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_NB_MN_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern OPTION_MEM_FEATURE_NB* memNTrainFlowControl[]; + +extern BUILD_OPT_CFG UserOptions; +extern PSO_ENTRY DefaultPlatformMemoryConfiguration[]; +extern MEM_PLATFORM_CFG* memPlatformTypeInstalled[]; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the default values in the MEM_DATA_STRUCT + * + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * + */ +VOID +MemNCmnInitDefaultsNb ( + IN OUT MEM_DATA_STRUCT *MemPtr + ) +{ + UINT8 Socket; + UINT8 Channel; + MEM_PARAMETER_STRUCT *RefPtr; + ASSERT (MemPtr != NULL); + RefPtr = MemPtr->ParameterListPtr; + // + // Memory Map/Mgt. + // Mask Bottom IO with 0xF8 to force hole size to have granularity of 128MB + RefPtr->BottomIo = 0xE0; + RefPtr->UmaMode = UserOptions.CfgUmaMode; + RefPtr->UmaSize = UserOptions.CfgUmaSize; + RefPtr->MemHoleRemapping = TRUE; + RefPtr->LimitMemoryToBelow1Tb = UserOptions.CfgLimitMemoryToBelow1Tb; + // + // Dram Timing + // + RefPtr->UserTimingMode = UserOptions.CfgTimingModeSelect; + RefPtr->MemClockValue = UserOptions.CfgMemoryClockSelect; + // + // Socket Struct + // + for (Socket = 0; Socket < MAX_SOCKETS_SUPPORTED; Socket++) { + for (Channel = 0; Channel < MAX_CHANNELS_PER_SOCKET; Channel++) { + MemPtr->SocketList[Socket].ChannelPtr[Channel] = NULL; + MemPtr->SocketList[Socket].TimingsPtr[Channel] = NULL; + } + } + // + // Memory Clear + RefPtr->EnableMemClr = TRUE; + // + // TableBasedAlterations + // + RefPtr->TableBasedAlterations = NULL; + // + // Platform config table + // + RefPtr->PlatformMemoryConfiguration = DefaultPlatformMemoryConfiguration; + // + // Memory Restore + // + RefPtr->MemRestoreCtl = FALSE; + RefPtr->SaveMemContextCtl = FALSE; + // + // Capsule support + // + RefPtr->IsCapsuleMode = FALSE; + AmdS3ParamsInitializer (&RefPtr->MemContext); + // + // Dram Configuration + // + RefPtr->EnableBankIntlv = UserOptions.CfgMemoryEnableBankInterleaving; + RefPtr->EnableNodeIntlv = UserOptions.CfgMemoryEnableNodeInterleaving; + RefPtr->EnableChannelIntlv = UserOptions.CfgMemoryChannelInterleaving; + RefPtr->EnableBankSwizzle = UserOptions.CfgBankSwizzle; + RefPtr->EnableParity = UserOptions.CfgMemoryParityEnable; + RefPtr->EnableOnLineSpareCtl = UserOptions.CfgOnlineSpare; + // + // Dram Power + // + RefPtr->EnablePowerDown = UserOptions.CfgMemoryPowerDown; + // + // ECC + // + RefPtr->EnableEccFeature = UserOptions.CfgEnableEccFeature; + // + // Vref + // + RefPtr->ExternalVrefCtl = UserOptions.CfgExternalVrefCtlFeature; + // + //Training Mode + // + RefPtr->ForceTrainMode = UserOptions.CfgForceTrainMode; + // + // AMP + // + RefPtr->AmpEnable = FALSE; + RefPtr->AmpWarningMsgEnable = FALSE; + // + // Preferred technology type that AGESA will enable when it is mixed with other technology types. + // + RefPtr->DimmTypeUsedInMixedConfig = UserOptions.CfgDimmTypeUsedInMixedConfig; + + // 2x DRAM refresh rate. + RefPtr->DramDoubleRefreshRate = UserOptions.CfgDramDoubleRefreshRateEn; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes member functions and variables of NB block. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNInitNBDataNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + INT32 i; + UINT8 *BytePtr; + + NBPtr->DctCachePtr = NBPtr->DctCache; + NBPtr->PsPtr = NBPtr->PSBlock; + + BytePtr = (UINT8 *) (NBPtr->DctCache); + for (i = 0; i < sizeof (NBPtr->DctCache); i++) { + *BytePtr++ = 0; + } + + for (i = 0; i < EnumSize; i++) { + NBPtr->IsSupported[i] = FALSE; + } + + for (i = 0; i < NumberOfHooks; i++) { + NBPtr->FamilySpecificHook[i] = MemNDefaultFamilyHookNb; + } + + for (i = 0; i < NBPtr->DctCount; i++) { + NBPtr->PSBlock[i].MemPGetPass1Seeds = (BOOLEAN (*) (MEM_NB_BLOCK *)) memDefTrue; + } + + NBPtr->SwitchDCT = MemNSwitchDCTNb; + NBPtr->SwitchChannel = MemNSwitchChannelNb; + NBPtr->GetBitField = MemNGetBitFieldNb; + NBPtr->SetBitField = MemNSetBitFieldNb; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Get System address of Chipselect RJ 16 bits (Addr[47:16]) + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Receiver - Chipselect to be targeted [0-7] + * @param[out] AddrPtr - Pointer to System Address [47:16] + * + * @return TRUE - Address is valid + * @return FALSE - Address is not valid + */ + +BOOLEAN +MemNGetMCTSysAddrNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Receiver, + OUT UINT32 *AddrPtr + ) +{ + S_UINT64 SMsr; + UINT32 CSBase; + UINT32 HoleBase; + UINT32 DctSelBaseAddr; + UINT32 BottomUma; + DIE_STRUCT *MCTPtr; + MEM_DATA_STRUCT *MemPtr; + + MCTPtr = NBPtr->MCTPtr; + MemPtr = NBPtr->MemPtr; + + ASSERT (Receiver < 8); + + CSBase = MemNGetBitFieldNb (NBPtr, BFCSBaseAddr0Reg + Receiver); + if (CSBase & 1) { + ASSERT ((CSBase & 0xE0) == 0); // Should not enable CS interleaving before DQS training. + + // Scale base address from [39:8] to [47:16] + CSBase >>= 8; + + HoleBase = MCTPtr->NodeHoleBase ? MCTPtr->NodeHoleBase : 0x7FFFFFFF; + + if ((MemNGetBitFieldNb (NBPtr, BFDctSelHiRngEn) == 1) && (NBPtr->Dct == MemNGetBitFieldNb (NBPtr, BFDctSelHi))) { + DctSelBaseAddr = MemNGetBitFieldNb (NBPtr, BFDctSelBaseAddr) << (27 - 16); + if (DctSelBaseAddr > HoleBase) { + DctSelBaseAddr -= _4GB_RJ16 - HoleBase; + } + CSBase += DctSelBaseAddr; + } else { + CSBase += MCTPtr->NodeSysBase; + } + + if (CSBase >= HoleBase) { + CSBase += _4GB_RJ16 - HoleBase; + } + + CSBase += (UINT32)1 << (21 - 16); // Add 2MB offset to avoid compat area. + if ((CSBase >= (MCT_TRNG_KEEPOUT_START >> 8)) && (CSBase <= (MCT_TRNG_KEEPOUT_END >> 8))) { + CSBase += (((MCT_TRNG_KEEPOUT_END >> 8) - CSBase) + 0x0F) & 0xFFFFFFF0; + } + + if (MCTPtr->Status[SbHWHole]) { + if (MCTPtr->Status[SbSWNodeHole]) { + LibAmdMsrRead (TOP_MEM, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + if ((CSBase >= (SMsr.lo >> 16)) && (CSBase < _4GB_RJ16)) { + return FALSE; + } + } + } + + BottomUma = NBPtr->RefPtr->Sub4GCacheTop >> 16; + if (BottomUma && (CSBase >= BottomUma) && (CSBase < _4GB_RJ16)) { + return FALSE; + } + *AddrPtr = CSBase; + return TRUE; + } + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines if a Rank is enabled. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Receiver - Receiver to check + * @return - FALSE + * + */ + +BOOLEAN +MemNRankEnabledNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Receiver + ) +{ + UINT32 CSBase; + CSBase = MemNGetBitFieldNb (NBPtr, BFCSBaseAddr0Reg + Receiver); + if (CSBase & 1) { + return TRUE; + } else { + return FALSE; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the EccSymbolSize bit depending upon configurations + * and system override. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNSetEccSymbolSizeNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT16 X4DimmsOnly; + BOOLEAN Size; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + + ASSERT (NBPtr != NULL); + + MCTPtr = NBPtr->MCTPtr; + DCTPtr = NBPtr->DCTPtr; + + // Determine if this node has only x4 DRAM parts + X4DimmsOnly = (UINT16) ((!(DCTPtr->Timings.Dimmx8Present | DCTPtr->Timings.Dimmx16Present)) && DCTPtr->Timings.Dimmx4Present); + // + // Check if EccSymbolSize BKDG value is overridden + // + if (UserOptions.CfgEccSymbolSize != ECCSYMBOLSIZE_USE_BKDG) { + Size = (UserOptions.CfgEccSymbolSize == ECCSYMBOLSIZE_FORCE_X4) ? FALSE : TRUE; + } else { + if (X4DimmsOnly && MCTPtr->GangedMode) { + Size = FALSE; + } else { + Size = TRUE; + } + NBPtr->FamilySpecificHook[ForceEccSymbolSize] (NBPtr, &Size); + } + IDS_OPTION_HOOK (IDS_ECCSYMBOLSIZE, &Size, &(NBPtr->MemPtr->StdHeader)); + MemNSetBitFieldNb (NBPtr, BFEccSymbolSize, (UINT32) Size); +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function flushes the training pattern + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Address - System Address [47:16] + * @param[in] ClCount - Number of cache lines + * + */ + +VOID +MemNFlushPatternNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT16 ClCount + ) +{ + // Due to speculative execution during MemUReadCachelines, we must + // flush one more cache line than we read. + MemUProcIOClFlush (Address, ClCount + 1, NBPtr->MemPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function compares test pattern with data in buffer and + * return a pass/fail bitmap for 8 bytelanes (upper 8 bits are reserved) + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * @param[in] ByteCount - Byte count + * + * @return PASS - Bitmap of results of comparison + */ + +UINT16 +MemNCompareTestPatternNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + UINT16 i; + UINT16 Pass; + UINT8 ColumnCount; + UINT8 FailingBitMask[8]; + + ASSERT ((ByteCount == 18 * 64) || (ByteCount == 9 * 64) || (ByteCount == 64 * 64) || (ByteCount == 32 * 64) || (ByteCount == 3 * 64)); + + ColumnCount = NBPtr->ChannelPtr->ColumnCount; + Pass = 0xFFFF; + // + // Clear Failing Bit Mask + // + for (i = 0; i < sizeof (FailingBitMask); i++) { + FailingBitMask[i] = 0; + } + + if (NBPtr->Ganged && (NBPtr->Dct != 0)) { + i = 8; // DCT 1 in ganged mode + } else { + i = 0; + } + + for (; i < ByteCount; i++) { + if (Buffer[i] != Pattern[i]) { + // if bytelane n fails + Pass &= ~((UINT16)1 << (i % 8)); // clear bit n + FailingBitMask[i % NBPtr->TechPtr->MaxByteLanes ()] |= (Buffer[i] ^ Pattern[i]); + } + + if (NBPtr->Ganged && ((i & 7) == 7)) { + i += 8; // if ganged, skip over other Channel's Data + } + } + // + // Accumulate Failing bit data + // + for (i = 0; i < sizeof (FailingBitMask); i++) { + NBPtr->ChannelPtr->FailingBitMask[(ColumnCount * NBPtr->TechPtr->ChipSel) + i] &= + FailingBitMask[i]; + } + + return Pass; +} + +/*----------------------------------------------------------------------------- + * + * + * This function compares test pattern with data in buffer and + * return a pass/fail bitmap for 8 bytelanes (upper 8 bits are reserved) + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * @param[in] ByteCount - Byte count + * + * @retval PASS - Bitmap of results of comparison + * ---------------------------------------------------------------------------- + */ +UINT16 +MemNInsDlyCompareTestPatternNb ( + IN MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + UINT16 i; + UINT16 Pass; + UINT16 BeatOffset; + UINT16 BeatCnt; + UINT8 ColumnCount; + UINT8 FailingBitMask[8]; + + ASSERT ((ByteCount == 18 * 64) || (ByteCount == 9 * 64) || (ByteCount == 64 * 64) || (ByteCount == 32 * 64) || (ByteCount == 3 * 64)); + + ColumnCount = NBPtr->ChannelPtr->ColumnCount; + Pass = 0xFFFF; + // + // Clear Failing Bit Mask + // + for (i = 0; i < sizeof (FailingBitMask); i++) { + FailingBitMask[i] = 0; + } + + if (NBPtr->Ganged && (NBPtr->Dct != 0)) { + i = 8; // DCT 1 in ganged mode + } else { + i = 0; + } + + if (NBPtr->Ganged) { + BeatOffset = 16; + } else { + BeatOffset = 8; + } + + BeatCnt = 0; + for (; i < ByteCount; i++) { + + if (Buffer[i] != Pattern[i + BeatOffset]) { + // if bytelane n fails + Pass &= ~((UINT16)1 << (i % 8)); // clear bit n + FailingBitMask[i % NBPtr->TechPtr->MaxByteLanes ()] |= (Buffer[i] ^ Pattern[i + BeatOffset]); + } + + if ((i & 7) == 7) { + if (NBPtr->Ganged) { + i += 8; // if ganged, skip over other Channel's Data + } + BeatCnt++; + } + + if ((BeatCnt & 3) == 3) { + // Skip last data beat of a 4-beat burst. + BeatCnt++; + i = i + BeatOffset; + } + } + // + // Accumulate Failing bit data + // + for (i = 0; i < sizeof (FailingBitMask); i++) { + NBPtr->ChannelPtr->FailingBitMask[(ColumnCount * NBPtr->TechPtr->ChipSel) + i] &= + FailingBitMask[i]; + } + + return Pass; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the training control flow for UNB + * The DDR3 mode bit must be set prior to calling this function + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + */ +BOOLEAN +MemNTrainingFlowUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + memNTrainFlowControl[DDR3_TRAIN_FLOW] (NBPtr); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the ECC exclusion range for UNB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + */ +VOID +MemNSetEccExclusionRangeUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_PARAMETER_STRUCT *RefPtr; + RefPtr = NBPtr->RefPtr; + + NBPtr->SetBitField (NBPtr, BFECCExclusionBaseLow, (RefPtr->UmaBase << 16) | 1); + NBPtr->SetBitField (NBPtr, BFECCExclusionBaseHigh, RefPtr->UmaBase >> 16); + NBPtr->SetBitField (NBPtr, BFECCExclusionLimitLow, ((RefPtr->UmaBase + RefPtr->UmaSize) << 16) - 1); + NBPtr->SetBitField (NBPtr, BFECCExclusionLimitHigh, (RefPtr->UmaBase + RefPtr->UmaSize - 1) >> 16); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnS3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnS3.c new file mode 100644 index 0000000000..9ffde28e9b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnS3.c @@ -0,0 +1,949 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnS3.c + * + * Common Northbridge S3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mport.h" +#include "mm.h" +#include "mn.h" +#include "S3.h" +#include "mfs3.h" +#include "cpuFamilyTranslation.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +#define FILECODE PROC_MEM_NB_MNS3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +VOID +STATIC +MemNS3GetSetBitField ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN BOOLEAN IsSet, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +UINT16 +STATIC +MemNS3GetMemClkFreqUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 FreqId + ); +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function executes the S3 resume for a node on a UNB + * + * @param[in,out] *S3NBPtr - Pointer to the S3_MEM_NB_BLOCK + * @param[in] NodeID - The Node id of the target die + * + * @return BOOLEAN + * TRUE - This is the correct constructor for the targeted node. + * FALSE - This isn't the correct constructor for the targeted node. + */ +BOOLEAN +MemNS3ResumeUNb ( + IN OUT S3_MEM_NB_BLOCK *S3NBPtr, + IN UINT8 NodeID + ) +{ + UINT8 DCT; + MEM_NB_BLOCK *NBPtr; + MEM_DATA_STRUCT *MemPtr; + + NBPtr = S3NBPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + + // Errata before S3 resume sequence + + // Add a hook here + AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeExitSelfRef, &MemPtr->StdHeader); + if (AgesaHookBeforeExitSelfRefresh (0, MemPtr) == AGESA_SUCCESS) { + } + AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeExitSelfRef, &MemPtr->StdHeader); + + //Override the NB Pstate if needed + IDS_OPTION_HOOK (IDS_NB_PSTATE_DIDVID, S3NBPtr->NBPtr, &MemPtr->StdHeader); + // Set F2x[1,0]90[ExitSelfRef] + // Wait for F2x[1,0]90[ExitSelfRef]=0 + for (DCT = 0; DCT < NBPtr->DctCount; DCT ++) { + MemNSwitchDCTNb (NBPtr, DCT); + if (MemNGetBitFieldNb (NBPtr, BFDisDramInterface) == 0) { + MemNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 1); + MemNSetBitFieldNb (NBPtr, BFExitSelfRef, 1); + while (MemNGetBitFieldNb (NBPtr, BFExitSelfRef) != 0) {} + if (NBPtr->IsSupported[SetDllShutDown]) { + MemNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 0); + } + } + } + + // Errata After S3 resume sequence + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function reads register bitfield + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value be read. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3GetBitFieldNb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + MemNS3GetSetBitField (AccessWidth, Address, FALSE, Value, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function writes register bitfield + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3SetBitFieldNb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + MemNS3GetSetBitField (AccessWidth, Address, TRUE, Value, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function restores scrubber base register + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Node - The Node id of the target die + * + */ +VOID +MemNS3RestoreScrubNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Node + ) +{ + UINT32 ScrubAddrRJ16; + + ScrubAddrRJ16 = (MemNGetBitFieldNb (NBPtr, BFDramBaseReg0 + Node) & 0xFFFF0000) >> 8; + ScrubAddrRJ16 |= MemNGetBitFieldNb (NBPtr, BFDramBaseHiReg0 + Node) << 24; + MemNSetBitFieldNb (NBPtr, BFScrubAddrLoReg, ScrubAddrRJ16 << 16); + MemNSetBitFieldNb (NBPtr, BFScrubAddrHiReg, ScrubAddrRJ16 >> 16); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function retores Pre Driver Calibration with pre driver calibration code + * code valid bit set. + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3SetPreDriverCalUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT16 RegValue; + + RegValue = 0x8000 | *(UINT16 *) Value; + MemNS3SetBitFieldNb (AccessS3SaveWidth16, Address, &RegValue, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is used by families that use a separate DctCfgSel bit to + * select the current DCT which will be accessed by function 2. + * NOTE: This function must be called BEFORE the NBPtr->Dct variable is + * updated. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Dct - Pointer to ID of the target DCT + * + */ + +BOOLEAN +MemNS3DctCfgSelectUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *Dct + ) +{ + // Set the DctCfgSel to new DCT + // + MemNSetBitFieldNb (NBPtr, BFDctCfgSel, *(UINT8*)Dct); + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function write to a register that has one copy for each NB Pstate + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value be read. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3GetNBPStateDepRegUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT8 NBPstate; + UINT8 TempValue; + UINT8 Dct; + UINT32 Temp; + + Temp = Address.Address.Register; + NBPstate = (UINT8) (Temp >> 10); + Dct = (UINT8) Address.Address.Function; + Temp &= 0x3FF; + + // Switch Dct + // Function field contains DCT value + Address.Address.Function = FUNC_1; + Address.Address.Register = 0x10C; + LibAmdPciRead (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + TempValue = (TempValue & 0xC8) | ((NBPstate << 4) | Dct); + LibAmdPciWrite (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + + Address.Address.Function = FUNC_2; + Address.Address.Register = Temp; + LibAmdPciRead (AccessWidth, Address, Value, ConfigPtr); + + Address.Address.Function = FUNC_1; + Address.Address.Register = 0x10C; + TempValue = 0; + LibAmdPciWrite (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function write to a register that has one copy for each NB Pstate + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value be read. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3SetNBPStateDepRegUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT8 NBPstate; + UINT8 TempValue; + UINT8 Dct; + UINT32 Temp; + + Temp = Address.Address.Register; + NBPstate = (UINT8) (Temp >> 10); + Dct = (UINT8) Address.Address.Function; + Temp &= 0x3FF; + + // Switch Dct + // Function field contains DCT value + Address.Address.Function = FUNC_1; + Address.Address.Register = 0x10C; + LibAmdPciRead (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + TempValue = (TempValue & 0xCE) | ((NBPstate << 4) | Dct); + LibAmdPciWrite (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + + Address.Address.Function = FUNC_2; + Address.Address.Register = Temp; + LibAmdPciWrite (AccessWidth, Address, Value, ConfigPtr); + + Address.Address.Function = FUNC_1; + Address.Address.Register = 0x10C; + TempValue = 0; + LibAmdPciWrite (AccessS3SaveWidth32, Address, &TempValue, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function read the value of Function 2 PCI register. + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the NB register in PCI_ADDR format. + * @param[in] *Value - Pointer to the value be read. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3SaveNBRegisterUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT8 TempValue; + UINT8 Dct; + UINT32 Temp; + + Temp = Address.Address.Register; + Dct = (UINT8) Address.Address.Function; + + // Switch Dct + // Function field contains DCT value + Address.Address.Function = FUNC_1; + Address.Address.Register = 0x10C; + LibAmdPciRead (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + TempValue = (TempValue & 0xFE) | Dct; + LibAmdPciWrite (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + + Address.Address.Register = Temp; + Address.Address.Function = FUNC_2; + LibAmdPciRead (AccessWidth, Address, Value, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function set the value of Function 2 PCI register. + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the NB register in PCI_ADDR format. + * @param[in] *Value - Pointer to the value be write. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3RestoreNBRegisterUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT8 TempValue; + UINT8 Dct; + UINT32 Temp; + + Temp = Address.Address.Register; + Dct = (UINT8) Address.Address.Function; + + // Switch Dct + // Function field contains DCT value + Address.Address.Function = FUNC_1; + Address.Address.Register = 0x10C; + LibAmdPciRead (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + TempValue = (TempValue & 0xFE) | Dct; + LibAmdPciWrite (AccessS3SaveWidth8, Address, &TempValue, ConfigPtr); + + Address.Address.Register = Temp; + Address.Address.Function = FUNC_2; + LibAmdPciWrite (AccessWidth, Address, Value, ConfigPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets MemClkFreqVal bit. + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3SetMemClkFreqValUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT32 TempValue; + + // 1. Program MemClkFreqVal = 1 + MemNS3SaveNBRegisterUnb (AccessWidth, Address, &TempValue, ConfigPtr); + TempValue |= 0x80; + MemNS3RestoreNBRegisterUnb (AccessWidth, Address, &TempValue, ConfigPtr); + + // 2. Wait for FreqChgInPrg = 0 + MemNS3SaveNBRegisterUnb (AccessWidth, Address, &TempValue, ConfigPtr); + while ((TempValue & 0x200000) != 0) { + MemNS3SaveNBRegisterUnb (AccessWidth, Address, &TempValue, ConfigPtr); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function changes memory Pstate context + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. Target MemPState is in + * Address.Address.Register. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +VOID +MemNS3ChangeMemPStateContextNb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + UINT8 Die; + + IDS_SKIP_HOOK (IDS_BEFORE_S3_SPECIAL, &Address, ConfigPtr) { + // See which Node should be accessed + Die = (UINT8) (Address.Address.Device - 24); + + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[Die].NBPtr; + MemNChangeMemPStateContextNb (NBPtr, Address.Address.Register); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function forces NBPstate to NBP0 + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value be read or written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3ForceNBP0Unb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + UINT8 NbPstateMaxVal; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + BOOLEAN SkipTransToLo; + UINT64 MsrValue; + UINT64 PerfCtrlSave; + UINT64 PerfStsSave; + + IDS_SKIP_HOOK (IDS_BEFORE_S3_SPECIAL, &Address, ConfigPtr) { + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[0].NBPtr; + + // Find out if Current NBPstate is NBPstateLo or not + // If yes, skip the steps that transition the Pstate to Lo + SkipTransToLo = FALSE; + LibAmdMsrRead (MSR_NB_PERF_CTL3, &PerfCtrlSave, &(NBPtr->MemPtr->StdHeader)); + MsrValue = 0x00000006004004E9; + LibAmdMsrRead (MSR_NB_PERF_CTR3, &PerfStsSave, &(NBPtr->MemPtr->StdHeader)); + LibAmdMsrWrite (MSR_NB_PERF_CTL3, &MsrValue, &(NBPtr->MemPtr->StdHeader)); + MsrValue = 0; + LibAmdMsrWrite (MSR_NB_PERF_CTR3, &MsrValue, &(NBPtr->MemPtr->StdHeader)); + LibAmdMsrRead (MSR_NB_PERF_CTR3, &MsrValue, &(NBPtr->MemPtr->StdHeader)); + if (MsrValue != 0) { + SkipTransToLo = TRUE; + } + LibAmdMsrWrite (MSR_NB_PERF_CTL3, &PerfCtrlSave, &(NBPtr->MemPtr->StdHeader)); + LibAmdMsrWrite (MSR_NB_PERF_CTR3, &PerfStsSave, &(NBPtr->MemPtr->StdHeader)); + + if (MemNGetBitFieldNb (NBPtr, BFCurNbPstate) != 0) { + + NBPtr->NbPsCtlReg = MemNGetBitFieldNb (NBPtr, BFNbPstateCtlReg); + + // If current NBPstate is already in NBPstateLo, do not do transition to NBPstateLo. + if (!SkipTransToLo) { + // 2.Program D18F5x170 to transition the NB P-state: + // NbPstateLo = NbPstateMaxVal. (HW requires an intermediate transition to low) + // SwNbPstateLoDis = NbPstateDisOnP0 = NbPstateThreshold = 0. + NbPstateMaxVal = (UINT8) MemNGetBitFieldNb (NBPtr, BFNbPstateMaxVal); + MemNSetBitFieldNb (NBPtr, BFNbPstateLo, NbPstateMaxVal); + MemNSetBitFieldNb (NBPtr, BFNbPstateCtlReg, MemNGetBitFieldNb (NBPtr, BFNbPstateCtlReg) & 0xFFFF91FF); + // 3.Wait for D18F5x174[CurNbPstate] to equal NbPstateLo. + while (MemNGetBitFieldNb (NBPtr, BFCurNbPstate) != NbPstateMaxVal) {} + } + // 4.Program D18F5x170 to force the NB P-state: + // NbPstateHi = target NB P-state. + // SwNbPstateLoDis = 1 (triggers the transition) + MemNSetBitFieldNb (NBPtr, BFNbPstateHi, 0); + MemNSetBitFieldNb (NBPtr, BFSwNbPstateLoDis, 1); + // 5.Wait for D18F5x174[CurNbPstate] to equal the target NB P-state. + while (MemNGetBitFieldNb (NBPtr, BFCurNbPstate) != 0) {} + + // Update TSC rate + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &NBPtr->MemPtr->StdHeader); + FamilySpecificServices->GetTscRate (FamilySpecificServices, &NBPtr->MemPtr->TscRate, &NBPtr->MemPtr->StdHeader); + } + } else { + ASSERT (FALSE); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function releases NBPState force + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value be read or written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNS3ReleaseNBPSUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + + IDS_SKIP_HOOK (IDS_BEFORE_S3_SPECIAL, &Address, ConfigPtr) { + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[0].NBPtr; + + if (NBPtr->NbPsCtlReg != 0) { + // 6. Restore the initial D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0] values. + MemNSetBitFieldNb (NBPtr, BFNbPstateCtlReg, (MemNGetBitFieldNb (NBPtr, BFNbPstateCtlReg) & 0xFFFF9FFF) | (NBPtr->NbPsCtlReg & 0x6000)); + // 7. Restore the initial D18F5x170[NbPstateThreshold, NbPstateHi] values. + MemNSetBitFieldNb (NBPtr, BFNbPstateCtlReg, (MemNGetBitFieldNb (NBPtr, BFNbPstateCtlReg) & 0xFFFFF13F) | (NBPtr->NbPsCtlReg & 0x0EC0)); + // 8. Restore the initial D18F5x170[NbPstateLo] values. + MemNSetBitFieldNb (NBPtr, BFNbPstateLo, (NBPtr->NbPsCtlReg >> 3) & 3); + } + } else { + ASSERT (FALSE); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function saves hob data into NV Ram. + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNSaveHobDataUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + UINT8 Die; + + // See which Node should be accessed + Die = (UINT8) (Address.Address.Device - 24); + + if (Die == 0) { + // Only do this on first node + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[Die].NBPtr; + + // Only save value when RefPtr is not NULL + if (NBPtr->RefPtr != NULL) { + if (Address.Address.Function == S3_UMA_SIZE) { + *(UINT32 *) Value = NBPtr->RefPtr->UmaSize; + } else if (Address.Address.Function == S3_UMA_BASE) { + *(UINT32 *) Value = NBPtr->RefPtr->UmaBase; + } else if (Address.Address.Function == S3_UMA_MODE) { + *(UINT8 *) Value = (UINT8 ) NBPtr->RefPtr->UmaMode; + } else if (Address.Address.Function == S3_SUB_4G_CACHE_TOP) { + *(UINT32 *) Value = NBPtr->RefPtr->Sub4GCacheTop; + } else if (Address.Address.Function == S3_SYSLIMIT) { + *(UINT32 *) Value = NBPtr->RefPtr->SysLimit; + } else if (Address.Address.Function == S3_UMA_ATTRIBUTE) { + LocateBufferPtr.BufferHandle = AMD_UMA_INFO_HANDLE; + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + *(UINT32 *) Value = ((UMA_INFO *) LocateBufferPtr.BufferPtr)->UmaAttributes; + } + } else if (Address.Address.Function == S3_VDDIO) { + *(UINT8 *) Value = (UINT8) NBPtr->RefPtr->DDR3Voltage; + } else { + ASSERT (FALSE); + } + } + } else { + ASSERT (FALSE); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets hob data from NV Ram. + * + * @param[in] AccessWidth - Access width of the register. + * @param[in] Address - address in PCI_ADDR format. + * @param[in, out] *Value - Pointer to the value to be written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +MemNRestoreHobDataUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + S3_MEM_NB_BLOCK *S3NBPtr; + UINT8 Die; + + // See which Node should be accessed + Die = (UINT8) (Address.Address.Device - 24); + + if (Die == 0) { + // Only do this on first node + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[Die].NBPtr; + + // Only save value when RefPtr is not NULL + if (NBPtr->RefPtr != NULL) { + if (Address.Address.Function == S3_UMA_SIZE) { + NBPtr->RefPtr->UmaSize = *(UINT32 *) Value; + } else if (Address.Address.Function == S3_UMA_BASE) { + NBPtr->RefPtr->UmaBase = *(UINT32 *) Value; + } else if (Address.Address.Function == S3_UMA_MODE) { + NBPtr->RefPtr->UmaMode = (UMA_MODE) (*(UINT8 *) Value); + } else if (Address.Address.Function == S3_SUB_4G_CACHE_TOP) { + NBPtr->RefPtr->Sub4GCacheTop = *(UINT32 *) Value; + } else if (Address.Address.Function == S3_SYSLIMIT) { + NBPtr->RefPtr->SysLimit = *(UINT32 *) Value; + } else if (Address.Address.Function == S3_UMA_ATTRIBUTE) { + // Allocate heap for UMA_INFO + AllocHeapParams.RequestedBufferSize = sizeof (UMA_INFO); + AllocHeapParams.BufferHandle = AMD_UMA_INFO_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, ConfigPtr) == AGESA_SUCCESS) { + ((UMA_INFO *) AllocHeapParams.BufferPtr)->UmaAttributes = *(UINT32 *) Value; + ((UMA_INFO *) AllocHeapParams.BufferPtr)->UmaMode = (UINT8) NBPtr->RefPtr->UmaMode; + ((UMA_INFO *) AllocHeapParams.BufferPtr)->UmaBase = (UINT64) ((UINT64) NBPtr->RefPtr->UmaBase << 16); + ((UMA_INFO *) AllocHeapParams.BufferPtr)->UmaSize = (NBPtr->RefPtr->UmaSize) << 16; + ((UMA_INFO *) AllocHeapParams.BufferPtr)->MemClock = MemNS3GetMemClkFreqUnb (NBPtr, (UINT8) NBPtr->GetBitField (NBPtr, BFMemClkFreq)); + } + } else if (Address.Address.Function == S3_VDDIO) { + NBPtr->RefPtr->DDR3Voltage = (DIMM_VOLTAGE) *(UINT8 *) Value; + } else { + ASSERT (FALSE); + } + } + } else { + ASSERT (FALSE); + } + } +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function enables and disables the fixed MTRR modify bit. + * + * @param[in] MsrAddress - Target MrsAddress + * @param[in] *Value - Value to be written + * @param[in] *StdHeader - Pointer to standard header + */ +VOID +MemNModdifyMtrrFixDramModEn ( + IN UINT32 MsrAddress, + IN UINT64 *Value, + IN VOID *StdHeader + ) +{ + S_UINT64 SMsr; + if (MsrAddress == 0) { + // turn on modification enable bit for fixed MTRR + LibAmdMsrRead (SYS_CFG, (UINT64 *)&SMsr, StdHeader); + SMsr.lo |= 0x80000; + LibAmdMsrWrite (SYS_CFG, (UINT64 *)&SMsr, StdHeader); + } else { + // turn off modification enable bit for fixed MTRR + LibAmdMsrRead (SYS_CFG, (UINT64 *)&SMsr, StdHeader); + SMsr.lo &= ~0x80000; + LibAmdMsrWrite (SYS_CFG, (UINT64 *)&SMsr, StdHeader); + } +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *----------------------------------------------------------------------------*/ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function reads and writes register bitfield + * + * @param[in] AccessWidth - Access width of the register + * @param[in] Address - address of the CSR register in PCI_ADDR format. + * @param[in] IsSet - if this is a register read or write + * @param[in, out] *Value - Pointer to the value be read or written. + * @param[in, out] *ConfigPtr - Pointer to Config handle. + * @return none + */ +VOID +STATIC +MemNS3GetSetBitField ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN BOOLEAN IsSet, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ) +{ + BIT_FIELD_NAME BitField; + MEM_NB_BLOCK *NBPtr; + LOCATE_HEAP_PTR LocateBufferPtr; + S3_MEM_NB_BLOCK *S3NBPtr; + UINT32 RegValue; + UINT8 Die; + + RegValue = 0; + // See which Node should be accessed + Die = (UINT8) (Address.Address.Device - 24); + + LocateBufferPtr.BufferHandle = AMD_MEM_S3_NB_HANDLE; + if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) { + S3NBPtr = (S3_MEM_NB_BLOCK *) LocateBufferPtr.BufferPtr; + NBPtr = S3NBPtr[Die].NBPtr; + + // Function field contains the DCT number + NBPtr->SwitchDCT (NBPtr, (UINT8) Address.Address.Function); + + // Get the bitfield name to be accessed + // Register field contains the bitfield name + BitField = (BIT_FIELD_NAME) Address.Address.Register; + + if (IsSet) { + switch (AccessWidth) { + case AccessS3SaveWidth8: + RegValue = *(UINT8 *) Value; + break; + case AccessS3SaveWidth16: + RegValue = *(UINT16 *) Value; + break; + case AccessS3SaveWidth32: + RegValue = *(UINT32 *) Value; + break; + default: + ASSERT (FALSE); + } + MemNSetBitFieldNb (NBPtr, BitField, RegValue); + } else { + RegValue = MemNGetBitFieldNb (NBPtr, BitField); + + switch (AccessWidth) { + case AccessS3SaveWidth8: + *(UINT8 *) Value = (UINT8) RegValue; + break; + case AccessS3SaveWidth16: + *(UINT16 *) Value = (UINT16) RegValue; + break; + case AccessS3SaveWidth32: + *(UINT32 *) Value = RegValue; + break; + default: + ASSERT (FALSE); + } + } + } else { + ASSERT (FALSE); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function converts MemClkFreq Id value to MemClk frequency in MHz + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FreqId - FreqId from Register + * + * @return MemClk frequency in MHz + */ +UINT16 +STATIC +MemNS3GetMemClkFreqUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 FreqId + ) +{ + UINT16 MemClkFreq; + if (FreqId > 2) { + MemClkFreq = (FreqId == 14) ? 667 : (300 + ((FreqId - 3) * 33) + (FreqId - 3) / 3); + } else if (FreqId == 2) { + MemClkFreq = 200; + } else { + MemClkFreq = 50 + (50 * FreqId); + } + return MemClkFreq; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mndct.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mndct.c new file mode 100644 index 0000000000..cefa8dbc83 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mndct.c @@ -0,0 +1,1648 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mndct.c + * + * Common Northbridge DCT support + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 85818 $ @e \$Date: 2013-01-11 17:04:21 -0600 (Fri, 11 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mport.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mu.h" +#include "mftds.h" +#include "merrhdl.h" +#include "cpuFamilyTranslation.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_NB_MNDCT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define UNUSED_CLK 4 + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemNAfterStitchMemNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function combines all the memory into a contiguous map. + * Requires that Mask values for each bank be programmed first and that + * the chip-select population indicator is correctly set. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - An Error value lower than AGESA_FATAL may have occurred + * @return FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred + */ + +BOOLEAN +MemNStitchMemoryNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + BOOLEAN DSpareEn; + UINT32 NxtCSBase; + UINT32 CurCSBase; + UINT32 CsSize; + UINT32 BiggestBank; + UINT8 p; + UINT8 q; + UINT8 BiggestDimm; + MEM_PARAMETER_STRUCT *RefPtr; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + RefPtr = NBPtr->RefPtr; + MCTPtr = NBPtr->MCTPtr; + DCTPtr = NBPtr->DCTPtr; + DSpareEn = FALSE; + if (NBPtr->IsSupported[SetSpareEn]) { + DSpareEn = FALSE; + if (RefPtr->GStatus[GsbEnDIMMSpareNW]) { + DSpareEn = TRUE; + } + } + + DCTPtr->Timings.CsEnabled = 0; + NxtCSBase = 0; + for (p = 0; p < MAX_CS_PER_CHANNEL; p++) { + BiggestBank = 0; + BiggestDimm = 0; + for (q = 0; q < MAX_CS_PER_CHANNEL; q++) { + if (((DCTPtr->Timings.CsPresent & ~DCTPtr->Timings.CsTestFail) & ((UINT16)1 << q)) != 0) { + if ((MemNGetBitFieldNb (NBPtr, BFCSBaseAddr0Reg + q) & 7) == 0) { + // (CSEnable|Spare==1)bank is not enabled yet + CsSize = MemNGetBitFieldNb (NBPtr, BFCSMask0Reg + (q >> 1)); + if (CsSize != 0) { + CsSize += ((UINT32)1 << 19); + CsSize &= 0xFFF80000; + } + if (CsSize > BiggestBank) { + BiggestBank = CsSize; + BiggestDimm = q; + } + } + } + } + + if (BiggestBank != 0) { + CurCSBase = NxtCSBase; + if (NBPtr->IsSupported[CheckSpareEn]) { + if (DSpareEn) { + CurCSBase = ((UINT32)1 << BFSpare); + DSpareEn = FALSE; + } else { + CurCSBase |= ((UINT32)1 << BFCSEnable); + NxtCSBase += BiggestBank; + } + } else { + CurCSBase |= ((UINT32)1 << BFCSEnable); + NxtCSBase += BiggestBank; + } + if ((BiggestDimm & 1) != 0) { + if (!(MCTPtr->Status[SbLrdimms])) { + // For LRDIMMS, On Dimm Mirroring is enabled after SDI + if ((DCTPtr->Timings.DimmMirrorPresent & (1 << (BiggestDimm >> 1))) != 0) { + CurCSBase |= ((UINT32)1 << BFOnDimmMirror); + } + } + } + MemNSetBitFieldNb (NBPtr, BFCSBaseAddr0Reg + BiggestDimm, CurCSBase); + DCTPtr->Timings.CsEnabled |= (1 << BiggestDimm); + } + if ((DCTPtr->Timings.CsTestFail & ((UINT16)1 << p)) != 0) { + IDS_HDT_CONSOLE (MEM_FLOW, "Node %d Dct %d exclude CS %d\n", NBPtr->Node, NBPtr->Dct, p); + MemNSetBitFieldNb (NBPtr, (BFCSBaseAddr0Reg + p), (UINT32)1 << BFTestFail); + } + } + + if (NxtCSBase != 0) { + DCTPtr->Timings.DctMemSize = NxtCSBase >> 8; // Scale base address from [39:8] to [47:16] + MemNAfterStitchMemNb (NBPtr); + } + + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets platform specific config/timing values from the interface layer and + * programs them into DCT. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - An Error value lower than AGESA_FATAL may have occurred + * @return FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred + */ + +BOOLEAN +MemNPlatformSpecUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 MemClkDis; + UINT8 i; + UINT8 MemoryAllClocks; + UINT8 *MemClkDisMap; + UINT16 CsPresent; + + if (!MemNGetPlatformCfgNb (NBPtr)) { + IDS_ERROR_TRAP; + } + + if (!NBPtr->PsPtr->MemPDoPs (NBPtr)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\tDisable DCT%d due to unsupported DIMM configuration\n", NBPtr->Dct); + if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + NBPtr->DisableDCT (NBPtr); + } else { + + MemNProgramPlatformSpecNb (NBPtr); + MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_ODT, ALL_DIMMS); + + //====================================================================== + // Disable unused MemClk to save power + //====================================================================== + // + MemClkDis = 0; + MemoryAllClocks = UserOptions.CfgMemoryAllClocksOn; + IDS_OPTION_HOOK (IDS_ALL_MEMORY_CLOCK, &MemoryAllClocks, &(NBPtr->MemPtr->StdHeader)); + if (!MemoryAllClocks) { + // Special Jedec SPD diagnostic bit - "enable all clocks" + if (!NBPtr->MCTPtr->Status[SbDiagClks]) { + MemClkDisMap = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MEMCLK_DIS, NBPtr->MCTPtr->SocketId, NBPtr->Dct, 0, + &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); + if (MemClkDisMap == NULL) { + MemClkDisMap = NBPtr->ChannelPtr->MemClkDisMap; + } + + // Turn off unused clocks + CsPresent = NBPtr->DCTPtr->Timings.CsPresent; + + for (i = 0; i < 8; i++) { + if ((CsPresent & MemClkDisMap[i]) == 0) { + MemClkDis |= (UINT8) (1 << i); + } + } + + // Turn off unused chiplets + for (i = 0; i < 3; i++) { + if (((MemClkDis >> (i * 2)) & 0x3) == 0x3) { + MemNSetBitFieldNb (NBPtr, BFPhyClkConfig0 + i, 0x0010); + } + } + } + } + MemNSetBitFieldNb (NBPtr, BFMemClkDis, MemClkDis); + MemFInitTableDrive (NBPtr, MTAfterPlatformSpec); + } + + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function disables the DCT and mem clock for UNB + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNDisableDCTUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MemNSetBitFieldNb (NBPtr, BFExtendedParityEn, 0); + MemNSetBitFieldNb (NBPtr, BFParEn, 0); + MemNSetBitFieldNb (NBPtr, BFCKETri, 0x0F); + + //Wait for 24 MEMCLKs + MemNWaitXMemClksNb (NBPtr, 24); + + // To maximize power savings when DisDramInterface=1b, + // all of the MemClkDis bits should also be set. + // + MemNSetBitFieldNb (NBPtr, BFMemClkDis, 0xFF); + + MemNSetBitFieldNb (NBPtr, BFDisDramInterface, 1); + + if (NBPtr->Dct == 0) { + MemNSetBitFieldNb (NBPtr, BFPhyPSMasterChannel, 0x100); + } + + // If channel is disabled after dram init, set DisDllShutdownSR + if (MemNGetBitFieldNb (NBPtr, BFDramEnabled) == 1) { + MemNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 1); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the DRAM devices on all DCTs at the same time + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNStartupDCTUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + UINT16 FinalPllLockTime; + + if (NBPtr->MCTPtr->NodeMemSize != 0) { + // Update NB frequency for startup DDR speed + NBPtr->ChangeNbFrequency (NBPtr); + + if (!NBPtr->IsSupported[ForcePhyToM0]) { + // Program D18F2x[1,0]9C_x0000_000B = 80000000h. #109999. + MemNBrdcstSetNb (NBPtr, BFDramPhyStatusReg, 0x80000000); + + // Program D18F2x[1,0]9C_x0D0F_E013[PllRegWaitTime] = 0118h. #194060. + MemNBrdcstSetNb (NBPtr, BFPllRegWaitTime, 0x118); + } + + // Phy Voltage Level Programming + MemNPhyVoltageLevelNb (NBPtr); + + // Run frequency change sequence + MemNBrdcstSetNb (NBPtr, BFPllLockTime, NBPtr->FreqChangeParam->PllLockTimeDefault); + MemNBrdcstSetNb (NBPtr, BFMemClkFreq, NBPtr->GetMemClkFreqId (NBPtr, NBPtr->DCTPtr->Timings.Speed)); + NBPtr->FamilySpecificHook[SetSkewMemClk] (NBPtr, NULL); + NBPtr->ProgramNbPsDependentRegs (NBPtr); + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if ((NBPtr->DCTPtr->Timings.DctMemSize != 0)) { + MemNSetBitFieldNb (NBPtr, BFMemClkFreqVal, 1); + MemNPollBitFieldNb (NBPtr, BFFreqChgInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + } + } + FinalPllLockTime = 0xF; + NBPtr->FamilySpecificHook[AfterMemClkFreqVal] (NBPtr, &FinalPllLockTime); + if (!NBPtr->IsSupported[CsrPhyPllPdEn]) { + // IF (D18F2x[1,0]9C_x0D0F_E00A[CsrPhySrPllPdMode]==0) THEN program + // D18F2x[1,0]9C_x0D0F_E006[PllLockTime] = 0Fh + MemNBrdcstSetNb (NBPtr, BFPllLockTime, FinalPllLockTime); + } + + NBPtr->FamilySpecificHook[BeforePhyFenceTraining] (NBPtr, NBPtr); + + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + + // Phy fence programming + AGESA_TESTPOINT (TpProcMemPhyFenceTraining, &(NBPtr->MemPtr->StdHeader)); + NBPtr->PhyFenceTraining (NBPtr); + + // Phy compensation initialization + AGESA_TESTPOINT (TPProcMemPhyCompensation, &(NBPtr->MemPtr->StdHeader)); + NBPtr->MemNInitPhyComp (NBPtr); + MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_SLEWRATE, ALL_DIMMS); + } + } + + AGESA_TESTPOINT (TpProcMemBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); + NBPtr->MemNBeforeDramInitNb (NBPtr); + + AGESA_TESTPOINT (TpProcMemDramInit, &(NBPtr->MemPtr->StdHeader)); + IDS_HDT_CONSOLE (MEM_FLOW, "\nMemClkFreq: %d MHz\n", NBPtr->DCTPtr->Timings.Speed); + NBPtr->FeatPtr->DramInit (NBPtr->TechPtr); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function ramp up frequency to target frequency + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemNRampUpFrequencyUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + DIE_STRUCT *MCTPtr; + + MCTPtr = NBPtr->MCTPtr; + + // Do not change frequency when it is already at TargetSpeed + if (NBPtr->DCTPtr->Timings.Speed == NBPtr->DCTPtr->Timings.TargetSpeed) { + return TRUE; + } + + // BIOS must program both DCTs to the same frequency. + IDS_HDT_CONSOLE (MEM_FLOW, "\nMemClkFreq changed: %d MHz", NBPtr->DCTPtr->Timings.Speed); + for (Dct = 0; Dct < MCTPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + NBPtr->DCTPtr->Timings.Speed = NBPtr->DCTPtr->Timings.TargetSpeed; + } + IDS_HDT_CONSOLE (MEM_FLOW, " -> %d MHz", NBPtr->DCTPtr->Timings.TargetSpeed); + + NBPtr->ChangeFrequency (NBPtr); + + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function uses calculated values from DCT.Timings structure to + * program its registers for UNB + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNProgramCycTimingsUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + CONST CTENTRY TmgAdjTab[] = { + // BitField, Min, Max, Bias, Ratio_x2 + {BFTcl, 5, 14, 0, 2}, + {BFTrcd, 2, 19, 0, 2}, + {BFTrp, 2, 19, 0, 2}, + {BFTrtp, 4, 10, 0, 2}, + {BFTras, 8, 40, 0, 2}, + {BFTrc, 10, 56, 0, 2}, + {BFTwrDDR3, 5, 16, 0, 2}, + {BFTrrd, 4, 9, 0, 2}, + {BFTwtr, 4, 9, 0, 2}, + {BFFourActWindow, 6, 42, 0, 2} + }; + + DCT_STRUCT *DCTPtr; + UINT8 *MiniMaxTmg; + UINT8 *MiniMaxTrfc; + UINT8 Value8; + UINT8 j; + UINT8 Tcwl; + UINT8 RdOdtTrnOnDly; + BIT_FIELD_NAME BitField; + MEM_PARAMETER_STRUCT *RefPtr; + + DCTPtr = NBPtr->DCTPtr; + RefPtr = NBPtr->RefPtr; + //====================================================================== + // Program DRAM Timing values + //====================================================================== + // + MiniMaxTmg = &DCTPtr->Timings.CasL; + for (j = 0; j < GET_SIZE_OF (TmgAdjTab); j++) { + BitField = TmgAdjTab[j].BitField; + + if (BitField == BFTrp) { + if (NBPtr->IsSupported[AdjustTrp]) { + MiniMaxTmg[j] ++; + if (MiniMaxTmg[j] < 5) { + MiniMaxTmg[j] = 5; + } + } + } + + if (MiniMaxTmg[j] < TmgAdjTab[j].Min) { + MiniMaxTmg[j] = TmgAdjTab[j].Min; + } else if (MiniMaxTmg[j] > TmgAdjTab[j].Max) { + MiniMaxTmg[j] = TmgAdjTab[j].Max; + } + + Value8 = (UINT8) MiniMaxTmg[j]; + + if (BitField == BFTwrDDR3) { + if ((Value8 > 8) && ((Value8 & 1) != 0)) { + Value8++; + } + } + + MemNSetBitFieldNb (NBPtr, BitField, Value8); + } + + MiniMaxTrfc = &DCTPtr->Timings.Trfc0; + for (j = 0; j < 4; j++) { + if ((NBPtr->DCTPtr->Timings.DctDimmValid & (1 << j)) != 0) { + ASSERT (MiniMaxTrfc[j] <= 4); + MemNSetBitFieldNb (NBPtr, BFTrfc0 + j, MiniMaxTrfc[j]); + } + } + + Tcwl = (UINT8) (DCTPtr->Timings.Speed / 133) + 2; + Tcwl = (Tcwl > 5) ? Tcwl : 5; + MemNSetBitFieldNb (NBPtr, BFTcwl, Tcwl); + + if (RefPtr->DramDoubleRefreshRate) { + MemNSetBitFieldNb (NBPtr, BFTref, 3); // 3.9 us + } else { + MemNSetBitFieldNb (NBPtr, BFTref, 2); // 7.8 us + } + + RdOdtTrnOnDly = (DCTPtr->Timings.CasL > Tcwl) ? (DCTPtr->Timings.CasL - Tcwl) : 0; + MemNSetBitFieldNb (NBPtr, BFRdOdtTrnOnDly, RdOdtTrnOnDly); + NBPtr->FamilySpecificHook[ProgOdtControl] (NBPtr, NULL); + + // + // Program Tmod + // + MemNSetBitFieldNb (NBPtr, BFTmod, (DCTPtr->Timings.Speed < DDR1866_FREQUENCY) ? 0x0C : + (DCTPtr->Timings.Speed > DDR1866_FREQUENCY) ? 0x10 : 0x0E); + // + // Program Tzqcs and Tzqoper + // + // Tzqcs max(64nCK, 80ns) + MemNSetBitFieldNb (NBPtr, BFTzqcs, MIN (6, (MAX (64, MemUnsToMemClk (NBPtr->DCTPtr->Timings.Speed, 80)) + 15) / 16)); + // Tzqoper max(256nCK, 320ns) + MemNSetBitFieldNb (NBPtr, BFTzqoper, MIN (0xC, (MAX (256, MemUnsToMemClk (NBPtr->DCTPtr->Timings.Speed, 320)) + 31) / 32)); + + // Program power management timing + MemNDramPowerMngTimingNb (NBPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets platform specific settings for the current channel + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - All platform types defined have initialized successfully + * @return FALSE - At least one of the platform types gave not been initialized successfully + */ + +BOOLEAN +MemNGetPlatformCfgNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 p; + + for (p = 0; p < MAX_PLATFORM_TYPES; p++) { + ASSERT (NBPtr->MemPtr->GetPlatformCfg[p] != NULL); + if (NBPtr->MemPtr->GetPlatformCfg[p] (NBPtr->MemPtr, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr) == AGESA_SUCCESS) { + break; + } + } + return (p < MAX_PLATFORM_TYPES); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sends the ZQCL command + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNSendZQCmdNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + // 1.Program MrsAddress[10]=1 + MemNSetBitFieldNb (NBPtr, BFMrsAddress, (UINT32)1 << 10); + + // 2.Set SendZQCmd=1 + MemNSetBitFieldNb (NBPtr, BFSendZQCmd, 1); + + // 3.Wait for SendZQCmd=0 + MemNPollBitFieldNb (NBPtr, BFSendZQCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + + // 4.Wait 512 MEMCLKs + MemNWaitXMemClksNb (NBPtr, 512); +} + + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function is used to create the DRAM map + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + */ + +VOID +STATIC +MemNAfterStitchMemNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + if (NBPtr->MCTPtr->GangedMode) { + NBPtr->MCTPtr->NodeMemSize = NBPtr->DCTPtr->Timings.DctMemSize; + NBPtr->MCTPtr->NodeSysLimit = NBPtr->MCTPtr->NodeMemSize - 1; + NBPtr->MCTPtr->DctData[1].Timings.CsPresent = NBPtr->DCTPtr->Timings.CsPresent; + NBPtr->MCTPtr->DctData[1].Timings.CsEnabled = NBPtr->DCTPtr->Timings.CsEnabled; + NBPtr->MCTPtr->DctData[1].Timings.DctMemSize = NBPtr->DCTPtr->Timings.DctMemSize; + } else { + // In unganged mode, add DCT0 and DCT1 to NodeMemSize + NBPtr->MCTPtr->NodeMemSize += NBPtr->DCTPtr->Timings.DctMemSize; + NBPtr->MCTPtr->NodeSysLimit = NBPtr->MCTPtr->NodeMemSize - 1; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function swaps bits for OnDimmMirror support for Unb + * + * Dimm Mirroring Requires that, during MRS command cycles, the following + * bits are swapped by software + * + * A3 -> A4 A7 -> A8 + * A4 -> A3 BA0 -> BA1 + * A5 -> A6 BA1 -> BA0 + * A6 -> A5 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNSwapBitsUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 ChipSel; + UINT32 MRSBank; + UINT32 MRSAddr; + + ChipSel = (UINT8) MemNGetBitFieldNb (NBPtr, BFMrsChipSel); + if ((ChipSel & 1) != 0) { + if ((NBPtr->DCTPtr->Timings.DimmMirrorPresent & (1 << (ChipSel >> 1))) != 0) { + MRSBank = MemNGetBitFieldNb (NBPtr, BFMrsBank); + MRSAddr = MemNGetBitFieldNb (NBPtr, BFMrsAddress); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS%d MR%d %05x swapped to ->", + (ChipSel & 0x7), + (MRSBank & 0x7), + (MRSAddr & 0x3FFFF)); + // + // Swap Mrs Bank bits 0 with 1 + MRSBank = (MRSBank & 0x0100) | ((MRSBank & 0x01) << 1) | ((MRSBank & 0x02) >> 1); + // + // Swap Mrs Address bits 3 with 4, 5 with 6, and 7 with 8 + MRSAddr = (MRSAddr & 0x03FE07) | ((MRSAddr&0x000A8) << 1) | ((MRSAddr&0x00150) >> 1); + MemNSetBitFieldNb (NBPtr, BFMrsBank, MRSBank); + MemNSetBitFieldNb (NBPtr, BFMrsAddress, MRSAddr); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Programs Address/command timings, driver strengths, and tri-state fields. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNProgramPlatformSpecNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + CONST UINT8 PinType[3] = {PSO_CKE_TRI, PSO_ODT_TRI, PSO_CS_TRI}; + CONST UINT8 TabSize[3] = { 4, 4, 8}; + CONST BIT_FIELD_NAME BitField[3] = { BFCKETri, BFODTTri, BFChipSelTri}; + UINT8 *TabPtr; + UINT8 i; + UINT8 k; + UINT8 Value; + //=================================================================== + // Tristate unused CKE, ODT and chip select to save power + //=================================================================== + // + TabPtr = NULL; + for (k = 0; k < sizeof (PinType); k++) { + if (NBPtr->IsSupported[CheckFindPSOverideWithSocket]) { + TabPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PinType[k], NBPtr->MCTPtr->SocketId, MemNGetSocketRelativeChannelNb (NBPtr, NBPtr->Dct, 0), 0, + &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); + } + if (NBPtr->IsSupported[CheckFindPSDct]) { + TabPtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PinType[k], NBPtr->MCTPtr->SocketId, NBPtr->Dct, 0, + &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); + } + if (TabPtr == NULL) { + switch (k) { + case 0: + TabPtr = NBPtr->ChannelPtr->CKETriMap; + break; + case 1: + TabPtr = NBPtr->ChannelPtr->ODTTriMap; + break; + case 2: + TabPtr = NBPtr->ChannelPtr->ChipSelTriMap; + break; + default: + IDS_ERROR_TRAP; + } + } + ASSERT (TabPtr != NULL); + + Value = 0; + for (i = 0; i < TabSize[k]; i++) { + if ((NBPtr->DCTPtr->Timings.CsPresent & TabPtr[i]) == 0) { + Value |= (UINT8) (1 << i); + } + } + + if (k == PSO_CS_TRI) { + NBPtr->FamilySpecificHook[BeforeSetCsTri] (NBPtr, &Value); + } + + ASSERT (k < GET_SIZE_OF (BitField)); + MemNSetBitFieldNb (NBPtr, BitField[k], Value); + } + NBPtr->MemNBeforePlatformSpecNb (NBPtr); + + //=================================================================== + // Program Address/Command timings and driver strength + //=================================================================== + // + MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_ADDRTMG, ALL_DIMMS); + MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_ODCCONTROL, ALL_DIMMS); + + MemNSetBitFieldNb (NBPtr, BFSlowAccessMode, (NBPtr->ChannelPtr->SlowMode) ? 1 : 0); + NBPtr->FamilySpecificHook[ProgramPOdtOff] (NBPtr, &NBPtr->PsPtr->ProcessorOnDieTerminationOff); + MemNSetBitFieldNb (NBPtr, BFODCControl, NBPtr->ChannelPtr->DctOdcCtl); + MemNSetBitFieldNb (NBPtr, BFAddrTmgControl, NBPtr->ChannelPtr->DctAddrTmg); + NBPtr->FamilySpecificHook[SetDqsODT] (NBPtr, NBPtr); + + if (NBPtr->IsSupported[CheckODTControls]) { + MemNSetBitFieldNb (NBPtr, BFPhyRODTCSLow, NBPtr->ChannelPtr->PhyRODTCSLow); + MemNSetBitFieldNb (NBPtr, BFPhyRODTCSHigh, NBPtr->ChannelPtr->PhyRODTCSHigh); + MemNSetBitFieldNb (NBPtr, BFPhyWODTCSLow, NBPtr->ChannelPtr->PhyWODTCSLow); + MemNSetBitFieldNb (NBPtr, BFPhyWODTCSHigh, NBPtr->ChannelPtr->PhyWODTCSHigh); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function enables swapping interleaved region feature. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Base - Swap interleaved region base [47:27] + * @param[in] Limit - Swap interleaved region limit [47:27] + * + */ +VOID +MemNEnableSwapIntlvRgnNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Base, + IN UINT32 Limit + ) +{ + UINT32 Size; + UINT32 SizeOfAlign; + + // Swapped interleaving region must be below 16G + if (Limit < (1 << (34 - 27))) { + // Adjust Base and Size to meet : + // 1. The size of the swapped region must be less than or equal to the alignment of F2x10C[IntLvRegionBase]. + // 2. Entire UMA region is swapped with interleaving region. + Size = Limit - Base; + SizeOfAlign = (UINT32) 1 << LibAmdBitScanForward (Base); + while (SizeOfAlign <= Size) { + // In case of SizeOfAlign <= Size, UmaBase -= 128MB, SizeOfIntlvrgn += 128MB. + Base -= 1; + Size += 1; + SizeOfAlign = (UINT32) 1 << LibAmdBitScanForward (Base); + } + MemNSetBitFieldNb (NBPtr, BFIntLvRgnBaseAddr, Base); + MemNSetBitFieldNb (NBPtr, BFIntLvRgnLmtAddr, (Limit - 1)); + MemNSetBitFieldNb (NBPtr, BFIntLvRgnSize, Size); + MemNSetBitFieldNb (NBPtr, BFIntLvRgnSwapEn, 1); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function converts MemClk frequency in MHz to MemClkFreq value + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Speed - MemClk frequency in MHz + * + * @return MemClkFreq value + */ +UINT8 +MemNGetMemClkFreqIdUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT16 Speed + ) +{ + return (UINT8) ((Speed > DDR400_FREQUENCY) ? ((Speed / 33) - 6) : ((Speed == DDR400_FREQUENCY) ? 2 : (Speed / 55))); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function converts MemClkFreq Id value to MemClk frequency in MHz + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FreqId - FreqId from Register + * + * @return MemClk frequency in MHz + */ +UINT16 +MemNGetMemClkFreqUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 FreqId + ) +{ + UINT16 MemClkFreq; + if (FreqId > 2) { + MemClkFreq = (FreqId == 14) ? 667 : (300 + ((FreqId - 3) * 33) + (FreqId - 3) / 3); + } else if (FreqId == 2) { + MemClkFreq = 200; + } else { + MemClkFreq = 50 + (50 * FreqId); + } + return MemClkFreq; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function change MemClk frequency to the value that is specified by DCTPtr->Timings.Speed + * for UNB. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNChangeFrequencyUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 Dct; + UINT8 ChipSel; + UINT16 FinalPllLockTime; + BOOLEAN FrequencyChangeSuccess; + UINT64 OrgMMIOCfgBase; + UINT64 NewMMIOCfgBase; + + TechPtr = NBPtr->TechPtr; + + // Disable MMIO to prevent speculative DRAM reads during self refresh + LibAmdMsrRead (MSR_MMIO_Cfg_Base, &OrgMMIOCfgBase, &(NBPtr->MemPtr->StdHeader)); + NewMMIOCfgBase = OrgMMIOCfgBase & (~(BIT0)); + LibAmdMsrWrite (MSR_MMIO_Cfg_Base, &NewMMIOCfgBase, &(NBPtr->MemPtr->StdHeader)); + + MemNBrdcstSetNb (NBPtr, BFDisDllShutdownSR, 1); + + //Program F2x[1,0]90[EnterSelfRefresh]=1. + //Wait until the hardware resets F2x[1,0]90[EnterSelfRefresh]=0. + MemNBrdcstSetNb (NBPtr, BFEnterSelfRef, 1); + MemNPollBitFieldNb (NBPtr, BFEnterSelfRef, 0, PCI_ACCESS_TIMEOUT, TRUE); + + if (NBPtr->ChangeNbFrequency (NBPtr)) { + // Reprogram Twr, Tcwl, and Tcl based on the new MEMCLK frequency. + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + TechPtr->AutoCycTiming (TechPtr); + if (!MemNPlatformSpecUnb (NBPtr)) { + IDS_ERROR_TRAP; + } + } + } + + // 1. Program PllLockTime to Family-specific value + MemNBrdcstSetNb (NBPtr, BFPllLockTime, NBPtr->FreqChangeParam->PllLockTimeDefault); + + // 2. Program D18F2x[1,0]94[MemClkFreqVal] = 0. + MemNBrdcstSetNb (NBPtr, BFMemClkFreqVal, 0); + + // 3. Program D18F2x[1,0]94[MemClkFreq] to the desired DRAM frequency. + MemNBrdcstSetNb (NBPtr, BFMemClkFreq, NBPtr->GetMemClkFreqId (NBPtr, NBPtr->DCTPtr->Timings.Speed)); + + // 4. Program D18F2x[1,0]F4_x30[DbeGskFifoNumerator] and D18F2x[1,0]F4_x31[DbeGskFifoDenominator]. + // 5. Program D18F2x[1,0]F4_x32[DataTxFifoSchedDlyNegSlot1, DataTxFifoSchedDlySlot1, + // DataTxFifoSchedDlyNegSlot0, DataTxFifoSchedDlySlot0]. See 2.10.3.2.2.1 [DCT Transmit Fifo Schedule + // Delay Programming]. + // 6. D18F2x[1,0]78[RdPtrInit] = IF (D18F2x[1,0]94[MemClkFreq] >= 667 MHz) THEN 7 ELSE 8 ENDIF (Llano) + // THEN 2 ELSE 3 ENDIF (Ontario) + NBPtr->ProgramNbPsDependentRegs (NBPtr); + + IDS_OPTION_HOOK (IDS_BEFORE_MEM_FREQ_CHG, NBPtr, &(NBPtr->MemPtr->StdHeader)); + // 7. Program D18F2x[1,0]94[MemClkFreqVal] = 1. + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if ((NBPtr->DCTPtr->Timings.DctMemSize != 0)) { + MemNSetBitFieldNb (NBPtr, BFMemClkFreqVal, 1); + MemNPollBitFieldNb (NBPtr, BFFreqChgInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + } + } + FinalPllLockTime = 0xF; + NBPtr->FamilySpecificHook[AfterMemClkFreqVal] (NBPtr, &FinalPllLockTime); + + // 8. IF (D18F2x[1,0]9C_x0D0F_E00A[CsrPhySrPllPdMode]==0) THEN program + // D18F2x[1,0]9C_x0D0F_E006[PllLockTime] = 0Fh. + if (!NBPtr->IsSupported[CsrPhyPllPdEn]) { + MemNBrdcstSetNb (NBPtr, BFPllLockTime, FinalPllLockTime); + } + + FrequencyChangeSuccess = TRUE; + } else { + // If NB frequency cannot be updated, use the current speed as the target speed + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + NBPtr->DCTPtr->Timings.Speed = NBPtr->TechPtr->PrevSpeed; + NBPtr->DCTPtr->Timings.TargetSpeed = NBPtr->TechPtr->PrevSpeed; + } + FrequencyChangeSuccess = FALSE; + } + + if (FrequencyChangeSuccess) { + // Perform Phy Fence training and Phy comp init after frequency change + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + + // Phy fence programming + AGESA_TESTPOINT (TpProcMemPhyFenceTraining, &(NBPtr->MemPtr->StdHeader)); + NBPtr->PhyFenceTraining (NBPtr); + + // Phy compensation initialization + AGESA_TESTPOINT (TPProcMemPhyCompensation, &(NBPtr->MemPtr->StdHeader)); + NBPtr->MemNInitPhyComp (NBPtr); + MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_SLEWRATE, ALL_DIMMS); + // Hardware programs POdtOff for the current M-state (D18F2x9C_x0D0F_E006_dct[0][PhyPS]) with the value in D18F2x94_dct[0] + // [ProcOdtDis] (via D18F2x9C_x0000_000B_dct[0][ProcOdtDis]) when the memory frequency is updated. BIOS must reprogram this + // BIOS must reprogram this field after each frequency change if the target value differs from D18F2x94_dct[0][ProcOdtDis]. + NBPtr->FamilySpecificHook[ProgramPOdtOff] (NBPtr, &NBPtr->PsPtr->ProcessorOnDieTerminationOff); + } + } + } + + //Program F2x[1,0]90[ExitSelfRef]=1 for both DCTs. + //Wait until the hardware resets F2x[1, 0]90[ExitSelfRef]=0. + MemNBrdcstSetNb (NBPtr, BFExitSelfRef, 1); + MemNPollBitFieldNb (NBPtr, BFExitSelfRef, 0, PCI_ACCESS_TIMEOUT, TRUE); + if (NBPtr->IsSupported[SetDllShutDown]) { + MemNBrdcstSetNb (NBPtr, BFDisDllShutdownSR, 0); + } + + if (FrequencyChangeSuccess) { + NBPtr->FamilySpecificHook[AfterMemClkFreqChg] (NBPtr, NULL); + + //====================================================================== + // Calculate and program DRAM Timings at new frequency + //====================================================================== + // + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) { + if ((NBPtr->DCTPtr->Timings.CsPresent & ((UINT16)1 << ChipSel)) != 0) { + // if chip select present + if (!(TechPtr->TechnologySpecificHook[LrdimmSendAllMRCmds] (TechPtr, &ChipSel))) { + TechPtr->SendAllMRCmds (TechPtr, ChipSel); + } + } + } + // Wait 512 clocks for DLL-relock + MemNWaitXMemClksNb (NBPtr, 512); + } + } + } + + // Restore MMIO setting + LibAmdMsrWrite (MSR_MMIO_Cfg_Base, &OrgMMIOCfgBase, &(NBPtr->MemPtr->StdHeader)); + + MemFInitTableDrive (NBPtr, MTAfterFreqChg); +} + +/** + * + * + * This function overrides the ASR and SRT value in MRS command + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNSetASRSRTNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 MrsAddress; + UINT8 Dimm; + UINT8 *SpdBufferPtr; + BOOLEAN ASREn; + BOOLEAN SRTEn; + + // Look for MR2 + if (NBPtr->GetBitField (NBPtr, BFMrsBank) == 2) { + MrsAddress = NBPtr->GetBitField (NBPtr, BFMrsAddress); + // Clear A6(ASR) and A7(SRT) + MrsAddress &= (UINT32) ~0xC0; + if ((NBPtr->ChannelPtr->RegDimmPresent) || (NBPtr->ChannelPtr->LrDimmPresent)) { + // For registered dimm and LR dimm, MRS command is sent to all chipselects. + // So different ASR/SRT setting can be sent to each chip select. + Dimm = (UINT8) (NBPtr->GetBitField (NBPtr, BFMrsChipSel) >> 1); + // Make sure we access SPD of the second logical dimm of QR dimm correctly + if ((Dimm >= 2) && ((NBPtr->ChannelPtr->DimmQrPresent & (UINT8) (1 << Dimm)) != 0)) { + Dimm -= 2; + } + if (NBPtr->TechPtr->GetDimmSpdBuffer (NBPtr->TechPtr, &SpdBufferPtr, Dimm)) { + // Bit 2 is ASR + if (SpdBufferPtr[THERMAL_OPT] & 0x4) { + // when ASR is 1, set SRT to 0 + MrsAddress |= 0x40; + } else { + // Set SRT based on bit on of thermal byte + MrsAddress |= ((SpdBufferPtr[THERMAL_OPT] & 1) << 7); + } + } + } else { + // Udimm and unbuffered dimm, MSR command will be broadcasted during Dram Init. + // ASR/SRT value needs to be leveled across the DCT. Only if all dimms on the DCT + // support ASR or SRT can ASR or SRT be enabled. + ASREn = TRUE; + SRTEn = TRUE; + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm ++) { + if (NBPtr->TechPtr->GetDimmSpdBuffer (NBPtr->TechPtr, &SpdBufferPtr, Dimm)) { + // Bit 2 is ASR + if ((SpdBufferPtr[THERMAL_OPT] & 0x4) == 0) { + // when any dimm in the DCT does not support ASR, disable ASR for the DCT + ASREn = FALSE; + // When any dimm does not have SRT with a value of 1, set SRT to 0 for the DCT + if ((SpdBufferPtr[THERMAL_OPT] & 1) == 0) { + SRTEn = FALSE; + } + } + } + } + if (ASREn) { + MrsAddress |= 0x40; + } else { + MrsAddress |= (UINT8) SRTEn << 7; + } + } + + NBPtr->SetBitField (NBPtr, BFMrsAddress, MrsAddress); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function changes NB frequency foras below: + * NBP0-DDR800 -> NBP0-DDR1066 -> ... -> NBP0-DDRTarget -> NBP1-DDRTarget -> NBP2-DDRTarget -> NBP3-DDRTarget -> NBP0-DDRTarget + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +BOOLEAN +MemNChangeNbFrequencyUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + BOOLEAN Status; + + Status = FALSE; + + // State machine to change NB frequency and NB Pstate + switch (NBPtr->NbFreqChgState) { + case 0: + // Do not change NB Pstate, just to save initial NB Pstate value + Status = NBPtr->ChangeNbFrequencyWrap (NBPtr, 0); + if (NBPtr->DCTPtr->Timings.Speed == NBPtr->DCTPtr->Timings.TargetSpeed) { + // When MemClk has been ramped up to its max, transition to next state, which changes NBPstate to P1 + NBPtr->NbFreqChgState = 1; + IDS_OPTION_HOOK (IDS_NB_PSTATE_DIDVID, NBPtr, &(NBPtr->MemPtr->StdHeader)); + } + break; + + case 1: + case 2: + case 3: + // Change NB P-State to NBP1 for MaxRdLat training + if (NBPtr->ChangeNbFrequencyWrap (NBPtr, NBPtr->NbFreqChgState)) { + // Next state is to try all NBPstates + NBPtr->NbFreqChgState++; + + // Return TRUE to repeat MaxRdLat training + Status = TRUE; + } else { + // If transition to any NBPs fails, transition to exit state machine + NBPtr->NbFreqChgState = 4; + } + break; + + case 4: + // Change NB P-State back to NBP0 + Status = NBPtr->ChangeNbFrequencyWrap (NBPtr, 0); + ASSERT (Status); + + // Return FALSE to get out of MaxRdLat training loop + Status = FALSE; + + // Exit state machine + NBPtr->NbFreqChgState = 5; + break; + + default: + break; + } + + return Status; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets "Dram Term" value from data structure for Unb + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] ChipSel - Targeted chipsel + * + * @return Dram Term value + */ +UINT8 +MemNGetDramTermTblDrvNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ChipSel + ) +{ + UINT8 RttNom; + RttNom = NBPtr->PsPtr->RttNom[ChipSel]; + IDS_OPTION_HOOK (IDS_MEM_DRAM_TERM, &RttNom, &NBPtr->MemPtr->StdHeader); + return RttNom; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets "Dynamic Dram Term" value from data structure + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] ChipSel - Targeted chipsel + * + * @return Dynamic Dram Term value + */ +UINT8 +MemNGetDynDramTermTblDrvNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ChipSel + ) +{ + UINT8 RttWr; + RttWr = NBPtr->PsPtr->RttWr[ChipSel]; + IDS_OPTION_HOOK (IDS_MEM_DYN_DRAM_TERM, &RttWr, &NBPtr->MemPtr->StdHeader); + return RttWr; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns MR0[WR] value + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return MR0[WR] value + */ +UINT32 +MemNGetMR0WRTblDrvNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + return (UINT32) (((NBPtr->PsPtr->MR0WR & 0x7) << 9) | ((NBPtr->PsPtr->MR0WR & 0x8) << (13 - 3))); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns MR2[CWL] value for UNB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return MR0[CWL] value + */ +UINT32 +MemNGetMR2CWLUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 Value32; + + Value32 = (MemNGetBitFieldNb (NBPtr, BFTcwl) - 5) << 3; + + return Value32; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets Txp and Txpdll + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return none + */ +VOID +MemNSetTxpNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + CONST UINT8 Txp[] = {0xFF, 0xFF, 3, 3, 4, 4, 5, 6, 7}; + CONST UINT8 Txpdll[] = {0xFF, 0xFF, 0xA, 0xA, 0xD, 0x10, 0x14, 0x17, 0x1A}; + UINT8 i; + UINT8 TxpVal; + UINT8 TxpdllVal; + UINT16 Speed; + + Speed = NBPtr->DCTPtr->Timings.Speed; + i = (UINT8) ((Speed < DDR800_FREQUENCY) ? ((Speed / 66) - 3) : (Speed / 133)); + ASSERT (i < sizeof (Txp)); + ASSERT (i < sizeof (Txpdll)); + + TxpdllVal = Txpdll[i]; + + if ((NBPtr->MCTPtr->Status[SbLrdimms] || NBPtr->MCTPtr->Status[SbRegistered]) && + ((NBPtr->DCTPtr->Timings.Speed == DDR667_FREQUENCY) || (NBPtr->DCTPtr->Timings.Speed == DDR800_FREQUENCY)) && + (NBPtr->RefPtr->DDR3Voltage == VOLT1_25)) { + TxpVal = 4; + } else { + TxpVal = Txp[i]; + } + + if (TxpVal != 0xFF) { + MemNSetBitFieldNb (NBPtr, BFTxp, TxpVal); + } + if (TxpdllVal != 0xFF) { + NBPtr->FamilySpecificHook[AdjustTxpdll] (NBPtr, &TxpdllVal); + MemNSetBitFieldNb (NBPtr, BFTxpdll, TxpdllVal); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is a wrapper to handle or switch NB Pstate for UNB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *NBPstate - NB Pstate + * + * @return TRUE - Succeed + * @return FALSE - Fail + */ + +BOOLEAN +MemNChangeNbFrequencyWrapUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 NBPstate + ) +{ + BOOLEAN SkipTransToLo; + UINT8 TargetNbPs; + UINT32 FreqNumeratorInMHz; + UINT32 FreqDivisor; + UINT32 VoltageInuV; + UINT8 NbPstateMaxVal; + UINT64 MsrValue; + UINT64 PerfCtrlSave; + UINT64 PerfStsSave; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + SkipTransToLo = FALSE; + if (NBPtr->NbFreqChgState == 0) { + // While in state 0, keep NB Pstate at the highest supported + TargetNbPs = 0; + if (NBPtr->NbPsCtlReg == 0) { + // Save NbPsCtl register on the first run + NBPtr->NbPsCtlReg = MemNGetBitFieldNb (NBPtr, BFNbPstateCtlReg); + } else { + // Do not need to switch NB Pstate again if it is already at highest + return TRUE; + } + + // Find out if Current NBPstate is NBPstateLo or not + // If yes, skip the steps that transition the Pstate to Lo + LibAmdMsrRead (MSR_NB_PERF_CTL3, &PerfCtrlSave, &(NBPtr->MemPtr->StdHeader)); + MsrValue = 0x00000006004004E9; + LibAmdMsrRead (MSR_NB_PERF_CTR3, &PerfStsSave, &(NBPtr->MemPtr->StdHeader)); + LibAmdMsrWrite (MSR_NB_PERF_CTL3, &MsrValue, &(NBPtr->MemPtr->StdHeader)); + MsrValue = 0; + LibAmdMsrWrite (MSR_NB_PERF_CTR3, &MsrValue, &(NBPtr->MemPtr->StdHeader)); + LibAmdMsrRead (MSR_NB_PERF_CTR3, &MsrValue, &(NBPtr->MemPtr->StdHeader)); + if (MsrValue != 0) { + SkipTransToLo = TRUE; + } + LibAmdMsrWrite (MSR_NB_PERF_CTL3, &PerfCtrlSave, &(NBPtr->MemPtr->StdHeader)); + LibAmdMsrWrite (MSR_NB_PERF_CTR3, &PerfStsSave, &(NBPtr->MemPtr->StdHeader)); + } else if (NBPtr->NbFreqChgState < 4) { + // While in other states, go to the next lower NB Pstate + TargetNbPs = (UINT8) MemNGetBitFieldNb (NBPtr, BFCurNbPstate) + 1; + if (TargetNbPs == 1) { + // Set up intermediate NBPstate + NbPstateMaxVal = (UINT8) MemNGetBitFieldNb (NBPtr, BFNbPstateMaxVal); + MemNSetBitFieldNb (NBPtr, BFNbPsSel, NbPstateMaxVal); + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &NBPtr->MemPtr->StdHeader); + if (FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices, + NBPtr->MemPtr->PlatFormConfig, + &NBPtr->PciAddr, + (UINT32) NbPstateMaxVal, + &FreqNumeratorInMHz, + &FreqDivisor, + &VoltageInuV, + &(NBPtr->MemPtr->StdHeader))) { + // Get NCLK speed for intermediate NBPstate + NBPtr->NBClkFreq = FreqNumeratorInMHz / FreqDivisor; + NBPtr->ProgramNbPsDependentRegs (NBPtr); + } else { + ASSERT (FALSE); + } + } + } else { + // When done with training, release NB Pstate force by restoring NbPsCtl register + NBPtr->FamilySpecificHook[ReleaseNbPstate] (NBPtr, NBPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "\tRelease NB Pstate force\n"); + return TRUE; + } + + // Make sure target NB Pstate is enabled, else find next enabled NB Pstate + GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &NBPtr->MemPtr->StdHeader); + for (; TargetNbPs < 4; TargetNbPs++) { + if (FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices, + NBPtr->MemPtr->PlatFormConfig, + &NBPtr->PciAddr, + (UINT32) TargetNbPs, + &FreqNumeratorInMHz, + &FreqDivisor, + &VoltageInuV, + &(NBPtr->MemPtr->StdHeader))) { + // Record NCLK speed + NBPtr->NBClkFreq = FreqNumeratorInMHz / FreqDivisor; + break; + } + } + + if (TargetNbPs < 4) { + IDS_HDT_CONSOLE (MEM_FLOW, "\tNB P%d: %dMHz\n", TargetNbPs, NBPtr->NBClkFreq); + + // 1.Program the configuration registers which contain multiple internal copies for each NB P-state. See + // D18F1x10C[NbPsSel]. + MemNSetBitFieldNb (NBPtr, BFNbPsSel, TargetNbPs); + + /// Check to see if NB P-states have been disabled. @todo This should only be needed for + /// bring up, but must be included in any releases that occur before NB P-state operation + /// has been debugged/fixed. + if ((NBPtr->NbPsCtlReg & 0x00000003) != 0) { + NbPstateMaxVal = (UINT8) MemNGetBitFieldNb (NBPtr, BFNbPstateMaxVal); + // Set up RdPtrInit before transit to target NBPstate + if ((TargetNbPs > 0) && (TargetNbPs != NbPstateMaxVal)) { + NBPtr->ProgramNbPsDependentRegs (NBPtr); + } else { + NBPtr->GetMemClkFreqInCurrentContext (NBPtr); + } + + // If current NBPstate is already in NBPstateLo, do not do transition to NBPstateLo. + if ((TargetNbPs != 0) || !SkipTransToLo) { + // 2.Program D18F5x170 to transition the NB P-state: + // NbPstateLo = NbPstateMaxVal. (HW requires an intermediate transition to low) + // SwNbPstateLoDis = NbPstateDisOnP0 = NbPstateThreshold = 0. + MemNSetBitFieldNb (NBPtr, BFNbPstateLo, NbPstateMaxVal); + MemNSetBitFieldNb (NBPtr, BFNbPstateCtlReg, MemNGetBitFieldNb (NBPtr, BFNbPstateCtlReg) & 0xFFFF91FF); + + // 3.Wait for D18F5x174[CurNbPstate] to equal NbPstateLo. + MemNPollBitFieldNb (NBPtr, BFCurNbPstate, NbPstateMaxVal, PCI_ACCESS_TIMEOUT, FALSE); + } + // 4.Program D18F5x170 to force the NB P-state: + // NbPstateHi = target NB P-state. + // SwNbPstateLoDis = 1 (triggers the transition) + MemNSetBitFieldNb (NBPtr, BFNbPstateHi, TargetNbPs); + MemNSetBitFieldNb (NBPtr, BFSwNbPstateLoDis, 1); + + // 5.Wait for D18F5x174[CurNbPstate] to equal the target NB P-state. + MemNPollBitFieldNb (NBPtr, BFCurNbPstate, TargetNbPs, PCI_ACCESS_TIMEOUT, FALSE); + } + + // When NB frequency change succeeds, TSC rate may have changed. + // We need to update TSC rate + FamilySpecificServices->GetTscRate (FamilySpecificServices, &NBPtr->MemPtr->TscRate, &NBPtr->MemPtr->StdHeader); + // Switch MemPstate context if the current MemPstate does not sync with MemPstate context + if (MemNGetBitFieldNb (NBPtr, BFCurMemPstate) != MemNGetBitFieldNb (NBPtr, BFMemPsSel)) { + MemNChangeMemPStateContextNb (NBPtr, MemNGetBitFieldNb (NBPtr, BFCurMemPstate)); + } + } else { + // Cannot find a supported NB Pstate to switch to + // Release NB Pstate force by restoring NbPsCtl register + NBPtr->FamilySpecificHook[ReleaseNbPstate] (NBPtr, NBPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "\tRelease NB Pstate force\n"); + return FALSE; + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sends an MRS command for Unb + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNSendMrsCmdUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 MrsBank; + UINT16 MrsBuffer; + UINT8 MrsChipSel; + + MemNSetASRSRTNb (NBPtr); + MemNSwapBitsUnb (NBPtr); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS%d MR%d %05x\n", + (MemNGetBitFieldNb (NBPtr, BFMrsChipSel) & 0x7), + (MemNGetBitFieldNb (NBPtr, BFMrsBank) & 0x7), + (MemNGetBitFieldNb (NBPtr, BFMrsAddress) & 0x3FFFF)); + + // 1.Set SendMrsCmd=1 + MemNSetBitFieldNb (NBPtr, BFSendMrsCmd, 1); + + // 2.Wait for SendMrsCmd=0 + MemNPollBitFieldNb (NBPtr, BFSendMrsCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + + // Send MRS buffer if memory pstate is supported and enabled + if (NBPtr->MemPstateStage != 0) { + MrsChipSel = (UINT8) (MemNGetBitFieldNb (NBPtr, BFMrsChipSel) & 0x7); + // Only user even rank MRS to set MRS buffer + if ((MrsChipSel & 1) == 0) { + MrsBank = (UINT8) (MemNGetBitFieldNb (NBPtr, BFMrsBank) & 0x7); + MrsBuffer = (UINT16) (MemNGetBitFieldNb (NBPtr, BFMrsAddress) & 0xFFFF); + if (MrsBank == 0) { + MrsBuffer &= 0xFEFF; + MemNSetBitFieldNb (NBPtr, BFMxMr0, MrsBuffer); + } else if (MrsBank == 1) { + MemNSetBitFieldNb (NBPtr, BFMxMr1, MrsBuffer); + } else if (MrsBank == 2) { + MemNSetBitFieldNb (NBPtr, BFMxMr2, MrsBuffer); + } + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function returns MR0[CL] value with table driven support + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return MR0[CL] value + */ +UINT32 +MemNGetMR0CLTblDrvNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + return (UINT32) ((NBPtr->PsPtr->MR0CL31 << 4) | (NBPtr->PsPtr->MR0CL0 << 2)); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function programs dram power management timing related registers + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return none + * ---------------------------------------------------------------------------- + */ +VOID +MemNDramPowerMngTimingNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + STATIC CONST UINT8 Tckesr[] = {4, 4, 4, 5, 5, 6, 7, 2, 2}; + UINT8 Tck; + + // These timings are based on DDR3 spec + // Tcksrx = max(5 nCK, 10 ns) + Tck = (UINT8) MAX (5, (MemUnsToMemClk (NBPtr->DCTPtr->Timings.Speed, 10))); + MemNSetBitFieldNb (NBPtr, BFTcksrx, MIN (0xE, MAX (Tck, 2))); + + // Tcksre = max(5 nCK, 10 ns) + MemNSetBitFieldNb (NBPtr, BFTcksre, MIN (0x27, MAX (Tck, 5))); + + // Tckesr = tCKE(min) + 1 nCK + // tCKE(min) + // DDR-667 7.5ns = 3nCk max(3nCK, 7.5ns) + 1 = 3nCK + 1nCK = 4nCK + // DDR-800 7.5ns = 3nCk max(3nCK, 7.5ns) + 1 = 3nCK + 1nCK = 4nCK + // DDR-1066 5.625ns = 3nCK max(3nCK, 5.625ns) + 1 = 3nCL + 1nCK = 4nCK + // DDR-1333 5.625ns = 4nCK max(3nCK, 4nCK) + 1 = 4nCK + 1nCK = 5nCK + // DDR-1600 5ns = 4nCK max(3nCK, 4nCK) + 1 = 4nCK + 1nCK = 5nCK + // DDR-1866 5ns = 5nCK max(3nCK, 5nCK) + 1 = 5nCK + 1nCK = 6nCK + // DDR-2133 5ns = 6nCK max(3nCK, 6nCK) + 1 = 6nCK + 1nCK = 7nCK + ASSERT (((NBPtr->DCTPtr->Timings.Speed / 133) >= 2) && ((NBPtr->DCTPtr->Timings.Speed / 133) <= 10)); + MemNSetBitFieldNb (NBPtr, BFTckesr, Tckesr[(NBPtr->DCTPtr->Timings.Speed / 133) - 2]); + + // Tpd = tCKE(min) + MemNSetBitFieldNb (NBPtr, BFTpd, Tckesr[(NBPtr->DCTPtr->Timings.Speed / 133) - 2] - 1); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * The function resets Rcv Fifo + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Dummy - Dummy parameter + * + */ + +VOID +MemTResetRcvFifoUnb ( + IN OUT struct _MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dummy + ) +{ + // Program D18F2x9C_x0000_0050_dct[1:0]=00000000h + MemNSetBitFieldNb (TechPtr->NBPtr, BFRstRcvFifo, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets the memory width + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return Memory width + */ + +UINT32 +MemNGetMemoryWidthUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + DIE_STRUCT *MCTPtr; + MEM_SHARED_DATA *SharedPtr; + + MCTPtr = NBPtr->MCTPtr; + SharedPtr = NBPtr->SharedPtr; + + return 64 + ((SharedPtr->AllECC && MCTPtr->Status[SbEccDimms]) ? 8 : 0); +} + +/*----------------------------------------------------------------------------- + * + * + * This function displays AMP voltage values if applicable + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return FALSE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNAmpVoltageDispUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + IDS_HDT_CONSOLE (MEM_FLOW, "\nAMP VDDIO = 1.%dV\n", (NBPtr->RefPtr->AmpVoltage >= AMP_VOLT1_45) ? 50 - 5 * (NBPtr->RefPtr->AmpVoltage >> 4) : + 45 + 5 * NBPtr->RefPtr->AmpVoltage); + + // FALSE return to skip normal voltage display if wanted + return FALSE; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnfeat.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnfeat.c new file mode 100644 index 0000000000..e52c2168f9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnfeat.c @@ -0,0 +1,1241 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnfeat.c + * + * Common Northbridge features + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 84482 $ @e \$Date: 2012-12-16 22:48:10 -0600 (Sun, 16 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "PlatformMemoryConfiguration.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_NB_MNFEAT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemNGenHwRcvEnReadsUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address + ); + +VOID +STATIC +MemNEnableInfiniteWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +STATIC +MemNDisableInfiniteWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNInitDqsTrainRcvrEnHwNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNDisableDqsTrainRcvrEnHwNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNInitCPGUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes member functions of HW Rx En Training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNInitDqsTrainRcvrEnHwNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->MemNPrepareRcvrEnDlySeed = MemNPrepareRcvrEnDlySeedNb; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function disables member functions of Hw Rx En Training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNDisableDqsTrainRcvrEnHwNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->MemNPrepareRcvrEnDlySeed = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates RcvEn seed value for each rank + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNPrepareRcvrEnDlySeedNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + CH_DEF_STRUCT *ChannelPtr; + DIE_STRUCT *MCTPtr; + UINT16 SeedTotal; + UINT16 SeedFine; + UINT16 SeedGross; + UINT16 SeedPreGross; + UINT16 SeedTotalPreScaling; + UINT8 ByteLane; + UINT16 Speed; + UINT16 PlatEst; + UINT8 ChipSel; + UINT8 Pass; + UINT16 *PlatEstSeed; + UINT16 SeedValue[9]; + UINT16 SeedTtl[9]; + UINT16 SeedPre[9]; + + TechPtr = NBPtr->TechPtr; + MCTPtr = NBPtr->MCTPtr; + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + Speed = NBPtr->DCTPtr->Timings.Speed; + SeedTotalPreScaling = 0; + ChipSel = TechPtr->ChipSel; + Pass = TechPtr->Pass; + + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + TechPtr->Bytelane = ByteLane; + if (Pass == 1) { + // Get platform override seed + PlatEstSeed = (UINT16 *) FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_RXEN_SEED, MCTPtr->SocketId, ChannelPtr->ChannelID, ChipSel >> 1, + &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); + // For Pass1, BIOS starts with the delay value obtained from the first pass of write + // levelization training that was done in DDR3 Training and add a delay value of 3Bh. + PlatEst = 0x3B; + NBPtr->FamilySpecificHook[OverrideRcvEnSeed] (NBPtr, &PlatEst); + PlatEst = ((PlatEstSeed != NULL) ? PlatEstSeed[ByteLane] : PlatEst); + SeedTotal = ChannelPtr->WrDqsDlys[(ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane] + PlatEst; + SeedValue[ByteLane] = PlatEst; + } else { + // For Pass2 + // SeedTotalPreScaling = (the total delay values in D18F2x[1,0]9C_x0000_00[24:10] from pass 1 of + // DQS receiver enable training) - 20h. Subtract 1UI to get back to preamble left edge. + if ((((ChipSel & 1) == 0) || (NBPtr->CsPerDelay == 1)) && NBPtr->FamilySpecificHook[TrainingNibbleZero] (NBPtr, &ChipSel)) { + // Save Seed for odd CS SeedTotalPreScaling RxEn Value + TechPtr->PrevPassRcvEnDly[ByteLane] = ChannelPtr->RcvEnDlys[(ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane]; + } + NBPtr->FamilySpecificHook[OverridePrevPassRcvEnDly] (NBPtr, &TechPtr->PrevPassRcvEnDly[ByteLane]); + SeedTotalPreScaling = TechPtr->PrevPassRcvEnDly[ByteLane] - 0x20; + // SeedTotal = SeedTotalPreScaling*target frequency/lowest supported frequency. + SeedTotal = (UINT16) (((UINT32) SeedTotalPreScaling * Speed) / TechPtr->PrevSpeed); + NBPtr->FamilySpecificHook[OverrideRcvEnSeedPassN] (NBPtr, &SeedTotal); + } + SeedTtl[ByteLane] = SeedTotal; + + // SeedGross = SeedTotal DIV 32. + SeedGross = SeedTotal >> 5; + // SeedFine = SeedTotal MOD 32. + SeedFine = SeedTotal & 0x1F; + // Next, determine the gross component of SeedTotal. SeedGrossPass1=SeedTotal DIV 32. + // Then, determine the fine delay component of SeedTotal. SeedFinePass1=SeedTotal MOD 32. + // Use SeedGrossPass1 to determine SeedPreGrossPass1: + + if ((SeedGross & 0x1) != 0) { + //if SeedGross is odd + SeedPreGross = 1; + } else { + //if SeedGross is even + SeedPreGross = 2; + } + // (SeedGross - SeedPreGross) + TechPtr->DiffSeedGrossSeedPreGross[ByteLane] = (SeedGross - SeedPreGross) << 5; + + //BIOS programs registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52 with SeedPreGrossPass1 + //and SeedFinePass1 from the preceding steps. + + NBPtr->SetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (ChipSel / NBPtr->CsPerDelay, ByteLane), (SeedPreGross << 5) | SeedFine); + SeedPre[ByteLane] = (SeedPreGross << 5) | SeedFine; + + // 202688: Program seed value to RcvEnDly also. + NBPtr->FamilySpecificHook[AdjustHwRcvEnSeedGross] (NBPtr, &SeedGross); + // Keep seeded value of RcvEnDlys for MaxRdLatency calculation + ChannelPtr->RcvEnDlys[(ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane] = (SeedGross << 5) | SeedFine; + NBPtr->SetTrainDly (NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (ChipSel / NBPtr->CsPerDelay, ByteLane), SeedGross << 5); + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + if (Pass == 1) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSeedValue: "); + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedValue[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSeedTotal: "); + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedTtl[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t SeedPRE: "); + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedPre[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + ); + + NBPtr->FamilySpecificHook[RegAccessFence] (NBPtr, NULL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Waits specified number of MEMCLKs + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] MemClkCount - Number of MEMCLKs + * + * ---------------------------------------------------------------------------- + */ +VOID +MemNWaitXMemClksNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 MemClkCount + ) +{ + MemUWait10ns ((MemClkCount * 100 + NBPtr->DCTPtr->Timings.Speed - 1) / NBPtr->DCTPtr->Timings.Speed, NBPtr->MemPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function uses the PRBS generator in the DCT to send a DDR Activate command + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] ChipSelect - Chip select 0-7 + * @param[in] Bank - Bank Address 0-7 + * @param[in] RowAddress - Row Address [17:0] + * + */ + +VOID +MemNRrwActivateCmd ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ChipSelect, + IN UINT8 Bank, + IN UINT32 RowAddress + ) +{ + // Set Chip select + MemNSetBitFieldNb (NBPtr, BFCmdChipSelect, (1 << ChipSelect)); + // Set Bank Address + MemNSetBitFieldNb (NBPtr, BFCmdBank, Bank); + // Set Row Address + MemNSetBitFieldNb (NBPtr, BFCmdAddress, RowAddress); + // Send the command + MemNSetBitFieldNb (NBPtr, BFSendActCmd, 1); + // Wait for command complete + MemNPollBitFieldNb (NBPtr, BFSendActCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + // Wait 75 MEMCLKs + NBPtr->WaitXMemClks (NBPtr, 75); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function uses the PRBS generator in the DCT to send a DDR Precharge + * or Precharge All command + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] ChipSelect - Chip select 0-7 + * @param[in] Bank - Bank Address 0-7, PRECHARGE_ALL_BANKS = Precharge All + * + * + */ + +VOID +MemNRrwPrechargeCmd ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ChipSelect, + IN UINT8 Bank + ) +{ + // Wait 25 MEMCLKs + NBPtr->WaitXMemClks (NBPtr, 25); + // Set Chip select + NBPtr->SetBitField (NBPtr, BFCmdChipSelect, (1 << ChipSelect)); + if (Bank == PRECHARGE_ALL_BANKS) { + // Set Row Address, bit 10 + NBPtr->SetBitField (NBPtr, BFCmdAddress, NBPtr->GetBitField (NBPtr, BFCmdAddress) | (1 << 10) ); + } else { + // Clear Row Address, bit 10 + NBPtr->SetBitField (NBPtr, BFCmdAddress, NBPtr->GetBitField (NBPtr, BFCmdAddress) & (~(1 << 10)) ); + // Set Bank Address + NBPtr->SetBitField (NBPtr, BFCmdBank, Bank); + } + // Send the command + NBPtr->SetBitField (NBPtr, BFSendPchgCmd, 1); + // Wait for command complete + NBPtr->PollBitField (NBPtr, BFSendPchgCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + // Wait 25 MEMCLKs + NBPtr->WaitXMemClks (NBPtr, 25); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function generates a continuous burst of reads for HW RcvEn + * training using the Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Address - Unused by this function + * + */ +VOID +STATIC +MemNGenHwRcvEnReadsUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address + ) +{ + VOID *DummyPtr; + DummyPtr = NULL; + // + // Issue Stream of Reads from the Target Rank + // + NBPtr->ReadPattern (NBPtr, DummyPtr, 0, NBPtr->TechPtr->PatternLength); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function generates a continuous stream of reads from DRAM using the + * Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] Buffer - Unused by this function + * @param[in] Address - Unused by this function + * @param[in] ClCount - Number of cache lines to read + * + * Assumptions: + * + * + * + */ + +VOID +MemNContReadPatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ) +{ + MEM_TECH_BLOCK *TechPtr; + RRW_SETTINGS *Rrw; + UINT8 CmdTgt; + UINT8 ChipSel; + + TechPtr = NBPtr->TechPtr; + Rrw = &NBPtr->RrwSettings; + + ChipSel = TechPtr->ChipSel; + CmdTgt = Rrw->CmdTgt; + // + // Wait for RRW Engine to be ready and turn it on + // + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1); + // + // Depending upon the Cmd Target, send Row Activate and set Chipselect + // for the Row or Rows that will be used + // + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressA, Rrw->TgtRowAddressA); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, ChipSel); + if (CmdTgt == CMD_TGT_AB) { + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressB, Rrw->TgtRowAddressB); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectB, ChipSel); + } + // Set Comparison Masks + NBPtr->SetBitField (NBPtr, BFDramDqMaskLow, Rrw->CompareMaskLow); + NBPtr->SetBitField (NBPtr, BFDramDqMaskHigh, Rrw->CompareMaskHigh); + // + // If All Dimms are ECC Capable Test ECC. Otherwise, mask it off + // + NBPtr->SetBitField (NBPtr, BFDramEccMask, (NBPtr->MCTPtr->Status[SbEccDimms] == TRUE) ? Rrw->CompareMaskEcc : 0xFF); + // + // Program the PRBS Seed + // + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, Rrw->DataPrbsSeed); + // + // Set the Command Count + // + NBPtr->SetBitField (NBPtr, BFCmdCount, ClCount); + // + // Program the Bubble Count and CmdStreamLen + // + NBPtr->SetBitField (NBPtr, BFBubbleCnt, 0); + NBPtr->SetBitField (NBPtr, BFBubbleCnt2, 0); + NBPtr->SetBitField (NBPtr, BFCmdStreamLen, 1); + // + // Program the Starting Address + // + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA); + if (CmdTgt == CMD_TGT_AB) { + NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB); + NBPtr->SetBitField (NBPtr, BFTgtAddressB, Rrw->TgtColAddressB); + } + // + // Reset All Errors and Disable StopOnErr + // + NBPtr->SetBitField (NBPtr, BFResetAllErr, 1); + NBPtr->SetBitField (NBPtr, BFStopOnErr, 0); + // + // Program the CmdTarget + // + NBPtr->SetBitField (NBPtr, BFCmdTgt, CmdTgt); + // + // Set CmdType to read + // + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_READ); + // + // Start the Commands + // + AGESA_TESTPOINT (TpProcMemContinPatternGenRead, &(NBPtr->MemPtr->StdHeader)); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // + // Commands have started, wait for the reads to complete then clear the command + // + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + // + // Send the Precharge All Command + // + MemNRrwPrechargeCmd (NBPtr, ChipSel, PRECHARGE_ALL_BANKS); + // + // Turn Off the RRW Engine + // + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function generates a continuous stream of writes to DRAM using the + * Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] Address - Unused by this function + * @param[in] Pattern - Unused by this function + * @param[in] ClCount - Number of cache lines to write + * + */ + +VOID +MemNContWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ) +{ + MEM_TECH_BLOCK *TechPtr; + RRW_SETTINGS *Rrw; + UINT8 CmdTgt; + UINT8 ChipSel; + + TechPtr = NBPtr->TechPtr; + Rrw = &NBPtr->RrwSettings; + + ChipSel = TechPtr->ChipSel; + CmdTgt = Rrw->CmdTgt; + // + // Wait for RRW Engine to be ready and turn it on + // + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1); + // + // Depending upon the Cmd Target, send Row Activate and set Chipselect + // for the Row or Rows that will be used + // + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressA, Rrw->TgtRowAddressA); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, ChipSel); + if (CmdTgt == CMD_TGT_AB) { + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressB, Rrw->TgtRowAddressB); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectB, ChipSel); + } + // + // Program the PRBS Seed + // + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, Rrw->DataPrbsSeed); + // + // Set the Command Count + // + NBPtr->SetBitField (NBPtr, BFCmdCount, ClCount); + // + // Program the Bubble Count and CmdStreamLen + // + NBPtr->SetBitField (NBPtr, BFBubbleCnt, 0); + NBPtr->SetBitField (NBPtr, BFBubbleCnt2, 0); + NBPtr->SetBitField (NBPtr, BFCmdStreamLen, 1); + // + // Program the Starting Address + // + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA); + if (CmdTgt == CMD_TGT_AB) { + NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB); + NBPtr->SetBitField (NBPtr, BFTgtAddressB, Rrw->TgtColAddressB); + } + // + // Program the CmdTarget + // + NBPtr->SetBitField (NBPtr, BFCmdTgt, CmdTgt); + // + // Set CmdType to Write + // + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE); + // + // Start the Commands + // + AGESA_TESTPOINT (TpProcMemContinPatternGenWrite, &(NBPtr->MemPtr->StdHeader)); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // + // Commands have started, wait for the writes to complete then clear the command + // + // Wait for TestStatus = 1 and CmdSendInProg = 0. + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + // + // Send the Precharge All Command + // + MemNRrwPrechargeCmd (NBPtr, ChipSel, PRECHARGE_ALL_BANKS); + // + // Turn Off the RRW Engine + // + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function checks the Error status bits for comparison results + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Not used in this implementation + * @param[in] Pattern[] - Not used in this implementation + * @param[in] ByteCount - Not used in this implementation + * + * @return PASS - Bitmap of results of comparison + */ + +UINT16 +MemNCompareTestPatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + + + UINT16 i; + UINT16 Pass; + UINT8 ChipSel; + UINT8 ColumnCount; + UINT8* FailingBitMaskPtr; + UINT8 FailingBitMask[9]; + UINT32 NibbleErrSts; + + ChipSel = NBPtr->TechPtr->ChipSel; + ColumnCount = NBPtr->ChannelPtr->ColumnCount; + // Calculate Failing Bitmask pointer + FailingBitMaskPtr = &(NBPtr->ChannelPtr->FailingBitMask[(ColumnCount * NBPtr->TechPtr->ChipSel)]); + + // + // Get Failing bit data + // + *((UINT32*)FailingBitMask) = NBPtr->GetBitField (NBPtr, BFDQErrLow); + *((UINT32*)&FailingBitMask[4]) = NBPtr->GetBitField (NBPtr, BFDQErrHigh); + FailingBitMask[8] = (UINT8)NBPtr->GetBitField (NBPtr, BFEccErr); + + Pass = 0x0000; + // + // Get Comparison Results - Convert Nibble Masks to Byte Masks + // + NibbleErrSts = NBPtr->GetBitField (NBPtr, BFNibbleErrSts); + + for (i = 0; i < ColumnCount ; i++) { + Pass |= ((NibbleErrSts & 0x03) > 0 ) ? (1 << i) : 0; + NibbleErrSts >>= 2; + FailingBitMaskPtr[i] = FailingBitMask[i]; + } + Pass = ~Pass; + return Pass; +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function checks the Error status bits for offset comparison results + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * @param[in] ByteCount - Byte count + * + * @retval Bitmap of results of comparison + */ +UINT16 +STATIC +MemNInsDlyCompareTestPatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + UINT16 i; + UINT16 Pass; + UINT8 ColumnCount; + UINT32 NibbleErr180Sts; + + ColumnCount = NBPtr->ChannelPtr->ColumnCount; + Pass = 0x0000; + // + // Get Comparison Results - Convert Nibble Masks to Byte Masks + // + NibbleErr180Sts = NBPtr->GetBitField (NBPtr, BFNibbleErr180Sts); + + for (i = 0; i < ColumnCount ; i++) { + Pass |= ((NibbleErr180Sts & 0x03) > 0 ) ? (1 << i) : 0; + NibbleErr180Sts >>= 2; + } + Pass = ~Pass; + + return Pass; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function assigns read/write function pointers to CPG read/write modules. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNInitCPGUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->WritePattern = MemNContWritePatternUnb; + NBPtr->ReadPattern = MemNContReadPatternUnb; + NBPtr->GenHwRcvEnReads = MemNGenHwRcvEnReadsUnb; + NBPtr->FlushPattern = (VOID (*) (MEM_NB_BLOCK *, UINT32, UINT16)) memDefRet; + NBPtr->TrainingPatternInit = (AGESA_STATUS (*) (MEM_NB_BLOCK *)) memDefRetSuccess; + NBPtr->TrainingPatternFinalize = (AGESA_STATUS (*) (MEM_NB_BLOCK *)) memDefRetSuccess; + NBPtr->CompareTestPattern = MemNCompareTestPatternUnb; + NBPtr->InsDlyCompareTestPattern = MemNInsDlyCompareTestPatternUnb; + NBPtr->FamilySpecificHook[SetupHwTrainingEngine] = MemNSetupHwTrainingEngineUnb; + NBPtr->EnableInfiniteWritePattern = MemNEnableInfiniteWritePatternUnb; + NBPtr->DisableInfiniteWritePattern = MemNDisableInfiniteWritePatternUnb; + NBPtr->CPGInit = 0; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function generates a continuous stream of writes infinite writes to DRAM using the + * Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +STATIC +MemNEnableInfiniteWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 ByteLane; + UINT32 WrDatValue; + UINT32 WrDqsValue; + MEM_TECH_BLOCK *TechPtr; + RRW_SETTINGS *Rrw; + UINT8 CmdTgt; + UINT8 ChipSel; + TechPtr = NBPtr->TechPtr; + Rrw = &NBPtr->RrwSettings; + ChipSel = TechPtr->ChipSel; + CmdTgt = Rrw->CmdTgt; + + // Ensure that DisAutoRefresh and ZqCals are disabled during the use of RRWM + if (MemNGetBitFieldNb (NBPtr, BFDisAutoRefresh) == 0) { + NBPtr->OrigDisAutoRefreshState = FALSE; + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 1); + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 0); + } else { + NBPtr->OrigDisAutoRefreshState = TRUE; + } + + // + // Enable I/O Skew mode + // + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8) ; ByteLane++) { + //Move WrDQS settings from current DIMM to DIMM 0 + WrDqsValue = NBPtr->ChannelPtr->WrDqsDlys[(NBPtr->TechPtr->ChipSel / NBPtr->CsPerDelay) * NBPtr->TechPtr->DlyTableWidth () + ByteLane]; + NBPtr->SetTrainDly (NBPtr, AccessWrDqsDly, DIMM_BYTE_ACCESS (0, ByteLane), (UINT16)WrDqsValue); + //Move WrDat settings from current DIMM to DIMM 0 + WrDatValue = NBPtr->ChannelPtr->WrDatDlys[(NBPtr->TechPtr->ChipSel / NBPtr->CsPerDelay) * NBPtr->TechPtr->DlyTableWidth () + ByteLane]; + NBPtr->SetTrainDly (NBPtr, AccessWrDatDly, DIMM_BYTE_ACCESS (0, ByteLane), (UINT16)WrDatValue); + } + NBPtr->SetBitField (NBPtr, BFIoSkewMode, 0x0001); + + + // + // Enable PRBS + // + + // + // Wait for RRW Engine to be ready and turn it on + // + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1); + // + // Depending upon the Cmd Target, send Row Activate and set Chipselect + // for the Row or Rows that will be used + // + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressA, Rrw->TgtRowAddressA); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, ChipSel); + // + // Program the PRBS Seed + // + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, Rrw->DataPrbsSeed); + // + // Set the Command Count + // + NBPtr->SetBitField (NBPtr, BFCmdCount, 0); + // + // Program the Bubble Count and CmdStreamLen + // + NBPtr->SetBitField (NBPtr, BFBubbleCnt, 0); + NBPtr->SetBitField (NBPtr, BFBubbleCnt2, 0); + NBPtr->SetBitField (NBPtr, BFCmdStreamLen, 1); + // + // Program the Starting Address + // + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA); + // + // Program the CmdTarget + // + NBPtr->SetBitField (NBPtr, BFCmdTgt, CMD_TGT_A); + // + // Set CmdType to write + // + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE); + // + // Start the Commands + // + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function disables the infinite stream of writes to DRAM using the + * Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +STATIC +MemNDisableInfiniteWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 ByteLane; + UINT32 WrDatValue; + UINT32 WrDqsValue; + // + // Disable PRBS + NBPtr->SetBitField (NBPtr, BFCmdCount, 1); + //Wait for TestStatus = 1 and CmdSendInProg = 0 + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + // + // Disable I/O Skew Mode + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8) ; ByteLane++) { + //Move WrDqs settings from DIMM 0 from saved area back to register + WrDqsValue = NBPtr->ChannelPtr->WrDqsDlys[0 * NBPtr->TechPtr->DlyTableWidth () + ByteLane]; + NBPtr->SetTrainDly (NBPtr, AccessWrDqsDly, DIMM_BYTE_ACCESS (0, ByteLane), (UINT16)WrDqsValue); + //Move WrDat settings from DIMM 0 from saved area back to register + WrDatValue = NBPtr->ChannelPtr->WrDatDlys[0 * NBPtr->TechPtr->DlyTableWidth () + ByteLane]; + NBPtr->SetTrainDly (NBPtr, AccessWrDatDly, DIMM_BYTE_ACCESS (0, ByteLane), (UINT16)WrDatValue); + } + NBPtr->SetBitField (NBPtr, BFIoSkewMode, 0x0000); + // + // Turn Off the RRW Engine + // + MemNRrwPrechargeCmd (NBPtr, NBPtr->TechPtr->ChipSel, PRECHARGE_ALL_BANKS); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0); + // + // Restore DisAutoRefresh and ZQCals to original state + // + if (!NBPtr->OrigDisAutoRefreshState) { + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 0); + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 2); + } + +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function checks the 180 Error status bits for RD DQS 2D training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * @param[in] ByteCount - Byte count, + * + * @retval Bitmap of results of comparison + */ +UINT32 +MemN180CompareRdDqs2DPatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + return NBPtr->GetBitField (NBPtr, BFNibbleErr180Sts); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function checks the In Phase Error status bits for comparison results for RDDQS 2D training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Not used in this implementation + * @param[in] Pattern[] - Not used in this implementation + * @param[in] ByteCount - Not used in this implementation + * + * @return PASS - Bitmap of results of comparison + */ + +UINT32 +MemNInPhaseCompareRdDqs2DPatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + return NBPtr->GetBitField (NBPtr, BFNibbleErrSts); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function starts the Victim for 2D RdDqs Training Continuous Writes + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] SeedCount - Seed count + */ +VOID +MemNStartRdDqs2dVictimContinuousWritesUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 SeedCount + ) +{ + // Program the PRBS Seed + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, NBPtr->GetPrbs2dRdDqsSeed (NBPtr, SeedCount)); + + if (NBPtr->IsSupported[OptimizedPatternWrite2D]) { + // + // Set BankAddress according to seed + // + NBPtr->SetBitField (NBPtr, BFTgtBankA, (SeedCount * 2) + CPG_BANK_ADDRESS_A); + NBPtr->SetBitField (NBPtr, BFTgtBankB, (SeedCount * 2) + CPG_BANK_ADDRESS_B); + } else { + // + // Enable continuous writes on the victim channels + // + // Set the Command Count + NBPtr->SetBitField (NBPtr, BFCmdCount, 256); + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // Wait for TestStatus = 1 and CmdSendInProg = 0. + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + } + // + // Enable continuous reads on the victim channels + // + // Set the Command Count + ASSERT (NBPtr->MaxAggressorDimms[NBPtr->Dct] != 0); + NBPtr->SetBitField (NBPtr, BFCmdCount, (256 * NBPtr->RdRolloverMultiple / NBPtr->MaxAggressorDimms[NBPtr->Dct])); + // Reset All Errors and Disable StopOnErr + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_READ); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // Wait for TestStatus = 1 and CmdSendInProg = 0 + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + //} + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function Initializes the Victim chipSelects for 2D RdDqs Training Continuous Writes + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + */ +VOID +MemNInitializeRdDqs2dVictimChipSelContinuousWritesUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, NBPtr->TechPtr->ChipSel); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectB, NBPtr->TechPtr->ChipSel); + NBPtr->SetBitField (NBPtr, BFResetAllErr, 1); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finalizes the Victim for 2D RdDqs Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + */ +VOID +MemNFinalizeRdDqs2dVictimContinuousWritesUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 InitialCS; + UINT8 ChipSel; + InitialCS = NBPtr->TechPtr->ChipSel; + NBPtr->SetBitField (NBPtr, BFLfsrRollOver, 0); + for (ChipSel = InitialCS; ChipSel < (InitialCS + NBPtr->CsPerDelay); ChipSel++) { + // Ensure that Odd and Even CS are trained + if ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) == 0) { + continue; + } + NBPtr->TechPtr->ChipSel = ChipSel; + // Send the Precharge All Command + MemNRrwPrechargeCmd (NBPtr, ChipSel, PRECHARGE_ALL_BANKS); + } + // Turn Off the RRW Engine + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function Initializes the Victim for 2D RdDqs Training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + */ +VOID +MemNInitializeRdDqs2dVictimContinuousWritesUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + RRW_SETTINGS *Rrw; + UINT8 InitialCS; + UINT8 ChipSel; + UINT8 SeedCount; + InitialCS = NBPtr->TechPtr->ChipSel; + Rrw = &NBPtr->RrwSettings; + // Program the Bubble Count and CmdStreamLen + NBPtr->SetBitField (NBPtr, BFBubbleCnt, 32); + NBPtr->SetBitField (NBPtr, BFBubbleCnt2, 0); + NBPtr->SetBitField (NBPtr, BFCmdStreamLen, 63); + // Set Comparison Masks + NBPtr->SetBitField (NBPtr, BFDramDqMaskLow, Rrw->CompareMaskLow); + NBPtr->SetBitField (NBPtr, BFDramDqMaskHigh, Rrw->CompareMaskHigh); + // If All Dimms are ECC Capable Test ECC. Otherwise, mask it off + NBPtr->SetBitField (NBPtr, BFDramEccMask, (NBPtr->MCTPtr->Status[SbEccDimms] == TRUE) ? Rrw->CompareMaskEcc : 0xFF); + // Program the Starting Address + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA); + NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB); + NBPtr->SetBitField (NBPtr, BFTgtAddressB, Rrw->TgtColAddressB); + NBPtr->SetBitField (NBPtr, BFCmdTgt, CMD_TGT_AB); + // Wait for RRW Engine to be ready and turn it on + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1); + for (ChipSel = InitialCS; ChipSel < (InitialCS + NBPtr->CsPerDelay); ChipSel++) { + // Ensure that Odd and Even CS are trained + if ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) == 0) { + continue; + } + NBPtr->TechPtr->ChipSel = ChipSel; + for (SeedCount = 0; SeedCount < (NBPtr->IsSupported[OptimizedPatternWrite2D] ? NBPtr->MaxSeedCount : 1 ); SeedCount++) { + if (NBPtr->IsSupported[OptimizedPatternWrite2D]) { + // + // Set BankAddress according to seed + // + ASSERT (NBPtr->MaxSeedCount <= 4); + Rrw->TgtBankAddressA = (SeedCount * 2) + CPG_BANK_ADDRESS_A; + Rrw->TgtBankAddressB = (SeedCount * 2) + CPG_BANK_ADDRESS_B; + } + // + // Send ACTIVATE to all Banks + // + // Set Chip select + MemNSetBitFieldNb (NBPtr, BFCmdChipSelect, (1 << NBPtr->TechPtr->ChipSel)); + // Set Bank Address + MemNSetBitFieldNb (NBPtr, BFCmdBank, Rrw->TgtBankAddressA); + // Set Row Address + MemNSetBitFieldNb (NBPtr, BFCmdAddress, Rrw->TgtRowAddressA); + // Send the command + MemNSetBitFieldNb (NBPtr, BFSendActCmd, 1); + // Wait for command complete + MemNPollBitFieldNb (NBPtr, BFSendActCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + // Set Chip select + MemNSetBitFieldNb (NBPtr, BFCmdChipSelect, (1 << NBPtr->TechPtr->ChipSel)); + // Set Bank Address + MemNSetBitFieldNb (NBPtr, BFCmdBank, Rrw->TgtBankAddressB); + // Set Row Address + MemNSetBitFieldNb (NBPtr, BFCmdAddress, Rrw->TgtRowAddressB); + // Send the command + MemNSetBitFieldNb (NBPtr, BFSendActCmd, 1); + // Wait for command complete + MemNPollBitFieldNb (NBPtr, BFSendActCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + + if (NBPtr->IsSupported[OptimizedPatternWrite2D]) { + // + // Write the Pattern to the bank pairs for each seed. + // + MemNInitializeRdDqs2dVictimChipSelContinuousWritesUnb (NBPtr); + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB); + // Program the PRBS Seed + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, NBPtr->GetPrbs2dRdDqsSeed (NBPtr, SeedCount)); + // + // Enable continuous writes on the victim channels + // + // Set the Command Count + NBPtr->SetBitField (NBPtr, BFCmdCount, 256); + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // Wait for TestStatus = 1 and CmdSendInProg = 0. + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + } + } + } + NBPtr->SetBitField (NBPtr, BFLfsrRollOver, 1); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function enables continuous writes on unused channels + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *SeedCount - seed index + * + * @return Prbs Seed + * + */ + +UINT32 +MemNGetPrbs2dRdDqsSeedUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 SeedCount + ) +{ + UINT32 PrbsSeed; + CONST STATIC UINT32 PrbsSeedTbl[4] = {0x7ea05, 0x44443, 0x22b97, 0x3f167}; + CONST STATIC UINT32 CmdStreamLenTbl[4] = {13, 61, 127, 251}; + ASSERT (SeedCount <= (NBPtr->MaxSeedCount - 1)); + NBPtr->SetBitField (NBPtr, BFCmdStreamLen, CmdStreamLenTbl[SeedCount]); + PrbsSeed = PrbsSeedTbl[SeedCount]; + ASSERT (PrbsSeed != 0); + return PrbsSeed; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function enables/disables continuous writes on unused agressor channels + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] SeedCount - Seed count + * @param[in] TurnOnInfinite - TRUE - Enable Infinite Mode + * TurnOnInfinite - FALSE - Disable Infinite Mode + * + */ +VOID +MemNAgressorContinuousWritesUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 SeedCount, + IN BOOLEAN TurnOnInfinite + ) +{ + UINT8 CurrChipSel; + UINT8 CurrDct; + UINT8 Dct; + UINT32 Address; + UINT8 Die; + MEM_NB_BLOCK *TargetNBPtr; + BOOLEAN SkipContinuous; + CurrDct = NBPtr->Dct; + CurrChipSel = NBPtr->TechPtr->ChipSel; + SkipContinuous = FALSE; + for (Die = 0; Die < NBPtr->NodeCount; Die++) { + if (NBPtr->DieEnabled[Die]) { + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + // Make sure that we are not targeting current DCT, current Node + if (Die == NBPtr->Node) { + if (CurrDct == Dct) { + SkipContinuous = TRUE; + } else { + SkipContinuous = FALSE; + } + } else { + SkipContinuous = FALSE; + } + // Enable/Disable continuous on aggressors + if (SkipContinuous == FALSE) { + if (Die == NBPtr->Node) { + TargetNBPtr = NBPtr; + } else { + ASSERT (NBPtr->AdjacentDieNBPtr != NULL); + TargetNBPtr = NBPtr->AdjacentDieNBPtr; + } + // All context switched at this point + TargetNBPtr->SwitchDCT (TargetNBPtr, Dct); + if (TargetNBPtr->DCTPtr->Timings.DctMemSize != 0) { + // Set Targets for agressors + TargetNBPtr->TechPtr->ChipSel = TargetNBPtr->CurrentAggressorCSTarget[Dct]; + TargetNBPtr->GetSysAddr (TargetNBPtr, TargetNBPtr->TechPtr->ChipSel, &Address); + TargetNBPtr->RrwSettings.DataPrbsSeed = TargetNBPtr->GetPrbs2dRdDqsSeed (TargetNBPtr, 0); + if (TurnOnInfinite) { + // Enable continuous writes on aggressor channels + TargetNBPtr->EnableInfiniteWritePattern (TargetNBPtr); + } else { + // Disable continous writes on aggressor channels + TargetNBPtr->DisableInfiniteWritePattern (TargetNBPtr); + // Set the next target CS for aggressor channel + if (TargetNBPtr->CurrentAggressorCSTarget[Dct] == TargetNBPtr->MaxAggressorCSEnabled[Dct]) { + TargetNBPtr->CurrentAggressorCSTarget[Dct] = TargetNBPtr->InitialAggressorCSTarget[Dct]; + } else { + TargetNBPtr->CurrentAggressorCSTarget[Dct] = TargetNBPtr->CurrentAggressorCSTarget[Dct] + TargetNBPtr->CsPerDelay; + } + } + } + } + } + } + } + // Restore Node, DCT and ChipSel + NBPtr->TechPtr->ChipSel = CurrChipSel; + NBPtr->SwitchDCT (NBPtr, CurrDct); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnflow.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnflow.c new file mode 100644 index 0000000000..2c5cb8d69d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnflow.c @@ -0,0 +1,317 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnflow.c + * + * Common Northbridge initializer flow for MCT and DCT + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_NB_MNFLOW_FILECODE +/* features */ +#include "mftds.h" + +extern MEM_PSC_FLOW_BLOCK* memPlatSpecFlowArray[]; +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +STATIC +MemNInitDCTNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +STATIC +MemNCleanupDctRegsNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +STATIC +MemNGetPORFreqLimitTblDrvNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function programs the MCT with initial values + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - AGESA_FATAL error did not occur (it is possible to have an Error that is not AGESA_SUCCESS) + * @return FALSE - AGESA_FATAL error occurred + */ + +BOOLEAN +MemNInitMCTNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 Dct; + BOOLEAN Flag; + ID_INFO CallOutIdInfo; + + TechPtr = NBPtr->TechPtr; + // Switch Tech functions for Nb + NBPtr->TechBlockSwitch (NBPtr); + // Start Memory controller initialization sequence + Flag = FALSE; + if (TechPtr->DimmPresence (TechPtr)) { + AGESA_TESTPOINT (TpProcMemPlatformSpecificInit, &(NBPtr->MemPtr->StdHeader)); + if (NBPtr->MemNPlatformSpecificFormFactorInitNb (NBPtr)) { + AGESA_TESTPOINT (TpProcMemSpdTiming, &(NBPtr->MemPtr->StdHeader)); + if (TechPtr->SpdCalcWidth (TechPtr)) { + AGESA_TESTPOINT (TpProcMemSpeedTclConfig, &(NBPtr->MemPtr->StdHeader)); + if (TechPtr->SpdGetTargetSpeed (TechPtr)) { + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + + Flag |= MemNInitDCTNb (NBPtr); + } + + if (Flag && !NBPtr->IsSupported[TwoStageDramInit] && (NBPtr->MCTPtr->ErrCode != AGESA_FATAL)) { + MemFInitTableDrive (NBPtr, MTBeforeDInit); + AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); + IDS_PERF_TIMESTAMP (TP_BEGINAGESAHOOKBEFOREDRAMINIT, &(NBPtr->MemPtr->StdHeader)); + CallOutIdInfo.IdField.SocketId = NBPtr->MCTPtr->SocketId; + CallOutIdInfo.IdField.ModuleId = NBPtr->MCTPtr->DieId; + IDS_HDT_CONSOLE (MEM_FLOW, "\nCalling out to Platform BIOS on Socket %d Module %d...\n", CallOutIdInfo.IdField.SocketId, CallOutIdInfo.IdField.ModuleId); + AgesaHookBeforeDramInit ((UINTN) CallOutIdInfo.IdInformation, NBPtr->MemPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "\nVDDIO = 1.%dV\n", (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) ? 5 : + (NBPtr->RefPtr->DDR3Voltage == VOLT1_35) ? 35 : + (NBPtr->RefPtr->DDR3Voltage == VOLT1_25) ? 25 : 999); + AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); + IDS_PERF_TIMESTAMP (TP_ENDAGESAHOOKBEFOREDRAMINIT, &(NBPtr->MemPtr->StdHeader)); + IDS_OPTION_HOOK (IDS_BEFORE_DRAM_INIT, NBPtr, &(NBPtr->MemPtr->StdHeader)); + NBPtr->StartupDCT (NBPtr); + } + } + } + } + } + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode != AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes the platform specific block for families that support + * table driven form factor + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - AGESA_SUCCESS + */ + +BOOLEAN +MemNPlatformSpecificFormFactorInitTblDrvNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dct; + + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + NBPtr->PsPtr->MemPDoPs = MemPPSCFlow; + NBPtr->PsPtr->MemPGetPORFreqLimit = MemNGetPORFreqLimitTblDrvNb; + NBPtr->PsPtr->MemPGetPass1Seeds = MemPGetPSCPass1Seed; + } + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function programs the DCT with initial values + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - Error did not occur + * @return FALSE - Error occurred + */ + +BOOLEAN +STATIC +MemNInitDCTNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + TechPtr = NBPtr->TechPtr; + TechPtr->SetDramMode (TechPtr); + + if (!NBPtr->MCTPtr->GangedMode || (NBPtr->MCTPtr->Dct == 0)) { + if (NBPtr->DCTPtr->Timings.DctDimmValid == 0) { + NBPtr->DisableDCT (NBPtr); + } else { + MemNCleanupDctRegsNb (NBPtr); + if (TechPtr->AutoCycTiming (TechPtr)) { + if (TechPtr->SpdSetBanks (TechPtr)) { + if (NBPtr->StitchMemory (NBPtr)) { + // if all dimms on a DCT are disabled, the DCT needs to be disabled. + if (NBPtr->DCTPtr->Timings.CsEnabled != 0) { + if (NBPtr->AutoConfig (NBPtr)) { + if (NBPtr->PlatformSpec (NBPtr)) { + return TRUE; + } + } + } else { + NBPtr->DisableDCT (NBPtr); + } + } + } + } + } + } + return FALSE; +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function clears DCT registers + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +STATIC +MemNCleanupDctRegsNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + BIT_FIELD_NAME BitField; + + for (BitField = BFCSBaseAddr0Reg; BitField <= BFCSBaseAddr7Reg; BitField++) { + MemNSetBitFieldNb (NBPtr, BitField, 0); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This is function gets the POR speed limit for families supports table driven form factor + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +STATIC +MemNGetPORFreqLimitTblDrvNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 i; + + i = 0; + while (memPlatSpecFlowArray[i] != NULL) { + if ((memPlatSpecFlowArray[i])->MaxFrequency (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + break; + } + i++; + } + // Check if there is no table found across CPU families. If so, disable channels. + if (memPlatSpecFlowArray[i] == NULL) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nDCT %d: No MaxFreq table. This channel will be disabled.\n", NBPtr->Dct); + NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid; + PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + // Change target speed to highest value so it won't affect other channels when leveling frequency across the node. + NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY; + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnmct.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnmct.c new file mode 100644 index 0000000000..5111754a16 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnmct.c @@ -0,0 +1,871 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnmct.c + * + * Northbridge Common MCT supporting functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mport.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "GeneralServices.h" +#include "cpuFeatures.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_NB_MNMCT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define _16MB_RJ16 0x0100 + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemNSetMTRRrangeNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Base, + IN OUT UINT32 *LimitPtr, + IN UINT32 MtrrAddr, + IN UINT8 MtrrType + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * Get max frequency from OEM platform definition, from + * any user override (limiting) of max frequency, and + * from any Si Revision Specific information. Return + * the least of these three in DIE_STRUCT.Timings.TargetSpeed. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNSyncTargetSpeedNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + CONST UINT16 DdrMaxRateTab[] = { + UNSUPPORTED_DDR_FREQUENCY, + DDR1600_FREQUENCY, + DDR1333_FREQUENCY, + DDR1066_FREQUENCY, + DDR800_FREQUENCY, + DDR667_FREQUENCY, + DDR533_FREQUENCY, + DDR400_FREQUENCY + }; + + UINT8 Dct; + UINT8 Channel; + UINT16 MinSpeed; + UINT16 DdrMaxRate; + UINT32 *ChnlTmgMod; + UINT32 Mode[MAX_CHANNELS_PER_SOCKET]; + UINT32 MemClkFreq; + UINT32 ProposedFreq; + DCT_STRUCT *DCTPtr; + + ASSERT (NBPtr->DctCount <= sizeof (Mode)); + MinSpeed = 16000; + DdrMaxRate = 16000; + if (NBPtr->IsSupported[CheckMaxDramRate]) { + // Check maximum DRAM data rate that the processor is designed to support. + DdrMaxRate = DdrMaxRateTab[MemNGetBitFieldNb (NBPtr, BFDdrMaxRate)]; + NBPtr->FamilySpecificHook[GetDdrMaxRate] (NBPtr, &DdrMaxRate); + } + + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + DCTPtr = NBPtr->DCTPtr; + + // Check if input user time mode is valid or not + ASSERT ((NBPtr->RefPtr->UserTimingMode == TIMING_MODE_SPECIFIC) || + (NBPtr->RefPtr->UserTimingMode == TIMING_MODE_LIMITED) || + (NBPtr->RefPtr->UserTimingMode == TIMING_MODE_AUTO)); + Mode[Dct] = NBPtr->RefPtr->UserTimingMode; + // Check if input clock value is valid or not + ASSERT ((NBPtr->ChannelPtr->TechType == DDR3_TECHNOLOGY) ? + (NBPtr->RefPtr->MemClockValue >= DDR667_FREQUENCY) : + (NBPtr->RefPtr->MemClockValue <= DDR1066_FREQUENCY)); + MemClkFreq = NBPtr->RefPtr->MemClockValue; + if (DCTPtr->Timings.DctDimmValid != 0) { + Channel = MemNGetSocketRelativeChannelNb (NBPtr, Dct, 0); + ChnlTmgMod = (UINT32 *) FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_BUS_SPEED, NBPtr->MCTPtr->SocketId, Channel, 0, + &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); + if (ChnlTmgMod != NULL) { + // Check if input user timing mode is valid or not + ASSERT ((ChnlTmgMod[0] == TIMING_MODE_SPECIFIC) || (ChnlTmgMod[0] == TIMING_MODE_LIMITED) || + (ChnlTmgMod[0] != TIMING_MODE_AUTO)); + if (ChnlTmgMod[0] != TIMING_MODE_AUTO) { + Mode[Dct] = ChnlTmgMod[0]; + // Check if input clock value is valid or not + ASSERT ((NBPtr->ChannelPtr->TechType == DDR3_TECHNOLOGY) ? + (ChnlTmgMod[1] >= DDR667_FREQUENCY) : + (ChnlTmgMod[1] <= DDR1066_FREQUENCY)); + MemClkFreq = ChnlTmgMod[1]; + } + } + + ProposedFreq = UserOptions.CfgMemoryBusFrequencyLimit; + if (Mode[Dct] == TIMING_MODE_LIMITED) { + if (MemClkFreq < ProposedFreq) { + ProposedFreq = MemClkFreq; + } + } else if (Mode[Dct] == TIMING_MODE_SPECIFIC) { + ProposedFreq = MemClkFreq; + } + + if (Mode[Dct] == TIMING_MODE_SPECIFIC) { + DCTPtr->Timings.TargetSpeed = (UINT16) ProposedFreq; + } else { + // "limit" mode + if (DCTPtr->Timings.TargetSpeed > ProposedFreq) { + DCTPtr->Timings.TargetSpeed = (UINT16) ProposedFreq; + } + } + + if (DCTPtr->Timings.TargetSpeed > DdrMaxRate) { + if (Mode[Dct] == TIMING_MODE_SPECIFIC) { + PutEventLog (AGESA_ALERT, MEM_ALERT_USER_TMG_MODE_OVERRULED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ALERT, NBPtr->MCTPtr); + } + DCTPtr->Timings.TargetSpeed = DdrMaxRate; + } + + IDS_SKIP_HOOK (IDS_POR_MEM_FREQ, NBPtr, &NBPtr->MemPtr->StdHeader) { + // + //Call Platform POR Frequency Override + // + if (!MemProcessConditionalOverrides (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr, PSO_ACTION_SPEEDLIMIT, ALL_DIMMS)) { + // + // Get the POR frequency limit + // + NBPtr->PsPtr->MemPGetPORFreqLimit (NBPtr); + } + } + IDS_OPTION_HOOK (IDS_STRETCH_FREQUENCY_LIMIT, NBPtr, &NBPtr->MemPtr->StdHeader); + + if (MinSpeed > DCTPtr->Timings.TargetSpeed) { + MinSpeed = DCTPtr->Timings.TargetSpeed; + } + } + } + + if (MinSpeed == DDR667_FREQUENCY) { + NBPtr->StartupSpeed = DDR667_FREQUENCY; + } + + // Sync all DCTs to the same speed + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + NBPtr->DCTPtr->Timings.TargetSpeed = MinSpeed; + } + + NBPtr->MemNCapSpeedBatteryLife (NBPtr); + +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Program system DRAM map to this node + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNSyncAddrMapToAllNodesNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Node; + UINT32 NodeSysBase; + UINT32 NodeSysLimit; + UINT8 WeReMask; + MEM_PARAMETER_STRUCT *RefPtr; + + RefPtr = NBPtr->RefPtr; + for (Node = 0; Node < NBPtr->NodeCount; Node++) { + NodeSysBase = NBPtr->SharedPtr->NodeMap[Node].SysBase; + NodeSysLimit = NBPtr->SharedPtr->NodeMap[Node].SysLimit; + if (NBPtr->SharedPtr->NodeMap[Node].IsValid) { + WeReMask = 3; + } else { + WeReMask = 0; + } + // Set the Dram base and set the WE and RE flags in the base. + MemNSetBitFieldNb (NBPtr, BFDramBaseReg0 + Node, (NodeSysBase << 8) | WeReMask); + MemNSetBitFieldNb (NBPtr, BFDramBaseHiReg0 + Node, NodeSysBase >> 24); + // Set the Dram limit and set DstNode. + MemNSetBitFieldNb (NBPtr, BFDramLimitReg0 + Node, (NodeSysLimit << 8) | Node); + MemNSetBitFieldNb (NBPtr, BFDramLimitHiReg0 + Node, NodeSysLimit >> 24); + + if (RefPtr->GStatus[GsbHWHole]) { + MemNSetBitFieldNb (NBPtr, BFDramMemHoistValid, 1); + MemNSetBitFieldNb (NBPtr, BFDramHoleBase, (RefPtr->HoleBase >> 8)); + } + } + + NBPtr->FamilySpecificHook[InitExtMMIOAddr] (NBPtr, NULL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates the critical delay difference (CDD) + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDlyType1 - Type of first Gross Delay parameter + * @param[in] TrnDlyType2 - Type of second Gross Delay parameter + * @param[in] SameDimm - CDD of same DIMMs + * @param[in] DiffDimm - CDD of different DIMMs + * + * @return CDD term - in 1/2 MEMCLK + */ +INT16 +MemNCalcCDDNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN TRN_DLY_TYPE TrnDlyType1, + IN TRN_DLY_TYPE TrnDlyType2, + IN BOOLEAN SameDimm, + IN BOOLEAN DiffDimm + ) +{ + INT16 CDD; + INT16 CDDtemp; + UINT16 TrnDly1; + UINT16 TrnDly2; + UINT8 i; + UINT8 j; + UINT8 ByteLane; + UINT16 CsEnabled; + BOOLEAN SameDlyType; + + SameDlyType = (BOOLEAN) (TrnDlyType1 == TrnDlyType2); + CsEnabled = NBPtr->DCTPtr->Timings.CsEnabled; + CDD = -127; + // If the two delay types compared are the same type, then no need to compare the same + // pair twice. Adjustments are made in the upper bound and lower bound of the loop to + // handle this. + for (i = 0; i < (SameDlyType ? (NBPtr->CsPerChannel - NBPtr->CsPerDelay) : NBPtr->CsPerChannel); i = i + NBPtr->CsPerDelay) { + if ((CsEnabled & ((UINT16) ((NBPtr->CsPerDelay == 2) ? 3 : 1) << i)) != 0) { + for (j = SameDlyType ? (i + NBPtr->CsPerDelay) : 0; j < NBPtr->CsPerChannel; j = j + NBPtr->CsPerDelay) { + if (((CsEnabled & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << j)) != 0) && + ((SameDimm && ((i / 2) == (j / 2))) || (DiffDimm && ((i / 2) != (j / 2))))) { + for (ByteLane = 0; ByteLane < ((NBPtr->MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8); ByteLane++) { + /// @todo: Gross delay mask should not be constant. + TrnDly1 = GetTrainDlyFromHeapNb (NBPtr, TrnDlyType1, DIMM_BYTE_ACCESS (i / NBPtr->CsPerDelay, ByteLane)) >> 5; // Gross delay only + TrnDly2 = GetTrainDlyFromHeapNb (NBPtr, TrnDlyType2, DIMM_BYTE_ACCESS (j / NBPtr->CsPerDelay, ByteLane)) >> 5; // Gross delay only + + CDDtemp = TrnDly1 - TrnDly2; + // If the 2 delay types to be compared are the same, then keep the absolute difference + if ((SameDlyType) && (CDDtemp < 0)) { + CDDtemp = (-CDDtemp); + } + + CDD = (CDD < CDDtemp) ? CDDtemp : CDD; + } + } + } + } + } + + return CDD; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets DQS timing from data saved in heap. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDlyType - type of delay to be set + * @param[in] Drbn - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * + * @return value of the target timing. + */ +UINT16 +GetTrainDlyFromHeapNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN TRN_DLY_TYPE TrnDlyType, + IN DRBN Drbn + ) +{ + UINT8 Dimm; + UINT8 Byte; + UINT16 TrainDly; + CH_DEF_STRUCT *ChannelPtr; + MEM_TECH_BLOCK *TechPtr; + + Dimm = DRBN_DIMM (Drbn); + Byte = DRBN_BYTE (Drbn); + ChannelPtr = NBPtr->ChannelPtr; + TechPtr = NBPtr->TechPtr; + + ASSERT (Dimm < (NBPtr->CsPerChannel / NBPtr->CsPerDelay)); + ASSERT (Byte <= ECC_DLY); + + if (NBPtr->MemPstate == MEMORY_PSTATE1) { + switch (TrnDlyType) { + case AccessRcvEnDly: + TrainDly = ChannelPtr->RcvEnDlysMemPs1[Dimm * TechPtr->DlyTableWidth () + Byte]; + break; + case AccessWrDqsDly: + TrainDly = ChannelPtr->WrDqsDlysMemPs1[Dimm * TechPtr->DlyTableWidth () + Byte]; + break; + case AccessWrDatDly: + TrainDly = ChannelPtr->WrDatDlysMemPs1[Dimm * TechPtr->DlyTableWidth () + Byte]; + break; + case AccessRdDqsDly: + TrainDly = ChannelPtr->RdDqsDlysMemPs1[Dimm * TechPtr->DlyTableWidth () + Byte]; + break; + default: + TrainDly = 0; + IDS_ERROR_TRAP; + } + } else { + switch (TrnDlyType) { + case AccessRcvEnDly: + TrainDly = ChannelPtr->RcvEnDlys[Dimm * TechPtr->DlyTableWidth () + Byte]; + break; + case AccessWrDqsDly: + TrainDly = ChannelPtr->WrDqsDlys[Dimm * TechPtr->DlyTableWidth () + Byte]; + break; + case AccessWrDatDly: + TrainDly = ChannelPtr->WrDatDlys[Dimm * TechPtr->DlyTableWidth () + Byte]; + break; + case AccessRdDqsDly: + TrainDly = ChannelPtr->RdDqsDlys[Dimm * TechPtr->DlyTableWidth () + Byte]; + break; + default: + TrainDly = 0; + IDS_ERROR_TRAP; + } + } + + return TrainDly; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the fixed MTRRs for common legacy ranges. + * It sets TOP_MEM and TOM2 and some variable MTRRs with WB Uncacheable type. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - An Error value lower than AGESA_FATAL may have occurred + * @return FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred + */ + +BOOLEAN +MemNCPUMemTypingNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 Bottom32bIO; + UINT32 Bottom40bIO; + UINT32 Cache32bTOP; + S_UINT64 SMsr; + + MEM_DATA_STRUCT *MemPtr; + MEM_PARAMETER_STRUCT *RefPtr; + RefPtr = NBPtr->RefPtr; + MemPtr = NBPtr->MemPtr; + + // + //====================================================================== + // Set temporary top of memory from Node structure data. + // Adjust temp top of memory down to accommodate 32-bit IO space. + //====================================================================== + //Bottom40bIO=top of memory, right justified 16 bits (defines dram versus IO space type) + //Bottom32bIO=sub 4GB top of memory, right justified 16 bits (defines dram versus IO space type) + //Cache32bTOP=sub 4GB top of WB cacheable memory, right justified 16 bits + // + if (RefPtr->HoleBase != 0) { + Bottom32bIO = RefPtr->HoleBase; + } else if (RefPtr->BottomIo != 0) { + Bottom32bIO = (UINT32)RefPtr->BottomIo << (24 - 16); + } else { + Bottom32bIO = (UINT32)1 << (24 - 16); + } + + Cache32bTOP = RefPtr->SysLimit + 1; + if (Cache32bTOP < _4GB_RJ16) { + Bottom40bIO = 0; + if (Bottom32bIO >= Cache32bTOP) { + Bottom32bIO = Cache32bTOP; + } + } else { + Bottom40bIO = Cache32bTOP; + } + + Cache32bTOP = Bottom32bIO; + + + // + //====================================================================== + // Set default values for CPU registers + //====================================================================== + // + LibAmdMsrRead (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + SMsr.lo |= 0x1C0000; // turn on modification enable bit and + // mtrr enable bits + LibAmdMsrWrite (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + SMsr.lo = SMsr.hi = 0x1E1E1E1E; + LibAmdMsrWrite (0x250, (UINT64 *)&SMsr, &MemPtr->StdHeader); // 0 - 512K = WB Mem + LibAmdMsrWrite (0x258, (UINT64 *)&SMsr, &MemPtr->StdHeader); // 512K - 640K = WB Mem + + // + //====================================================================== + // Set variable MTRR values + //====================================================================== + // + MemNSetMTRRrangeNb (NBPtr, 0, &Cache32bTOP, 0x200, 6); + + RefPtr->Sub4GCacheTop = Cache32bTOP << 16; + + // + //====================================================================== + // Set TOP_MEM and TOM2 CPU registers + //====================================================================== + // + SMsr.hi = Bottom32bIO >> (32 - 16); + SMsr.lo = Bottom32bIO << 16; + LibAmdMsrWrite (TOP_MEM, (UINT64 *)&SMsr, &MemPtr->StdHeader); + IDS_HDT_CONSOLE (MEM_FLOW, "TOP_MEM: %08x0000\n", Bottom32bIO); + + if (Bottom40bIO) { + SMsr.hi = Bottom40bIO >> (32 - 16); + SMsr.lo = Bottom40bIO << 16; + } else { + SMsr.hi = 0; + SMsr.lo = 0; + } + LibAmdMsrWrite (TOP_MEM2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + LibAmdMsrRead (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + if (Bottom40bIO) { + IDS_HDT_CONSOLE (MEM_FLOW, "TOP_MEM2: %08x0000\n", Bottom40bIO); + IDS_HDT_CONSOLE (MEM_FLOW, "Sub1THoleBase: %08x0000\n", RefPtr->Sub1THoleBase); + // Enable TOM2 + SMsr.lo |= 0x00600000; + } else { + // Disable TOM2 + SMsr.lo &= ~0x00600000; + } + SMsr.lo &= 0xFFF7FFFF; // turn off modification enable bit + LibAmdMsrWrite (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function runs on the BSP only, it sets the fixed MTRRs for common legacy ranges. + * It sets TOP_MEM and TOM2 and some variable MTRRs with WB Uncacheable type. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNUMAMemTypingNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 Bottom32bIO; + UINT32 Bottom32bUMA; + UINT32 Cache32bTOP; + UINT32 Value32; + UINT8 BitCount; + UINT8 i; + + MEM_PARAMETER_STRUCT *RefPtr; + RefPtr = NBPtr->RefPtr; + BitCount = 0; + // + //====================================================================== + // Adjust temp top of memory down to accommodate UMA memory start + //====================================================================== + // Bottom32bIO=sub 4GB top of memory, right justified 16 bits (defines dram versus IO space type) + // Cache32bTOP=sub 4GB top of WB cacheable memory, right justified 16 bits + // + Bottom32bIO = RefPtr->Sub4GCacheTop >> 16; + Bottom32bUMA = RefPtr->UmaBase; + + if (Bottom32bUMA < Bottom32bIO) { + Cache32bTOP = Bottom32bUMA; + RefPtr->Sub4GCacheTop = Bottom32bUMA << 16; + // + //====================================================================== + //Set variable MTRR values + //====================================================================== + // + Value32 = Cache32bTOP; + //Pre-check the bit count of bottom Uma to see if it is potentially running out of Mtrr while typing. + while (Value32 != 0) { + i = LibAmdBitScanForward (Value32); + Value32 &= ~ (1 << i); + BitCount++; + } + + if (BitCount > 5) { + NBPtr->RefPtr->GStatus[GsbMTRRshort] = TRUE; + MemNSetMTRRUmaRegionUCNb (NBPtr, &Cache32bTOP, &Bottom32bIO); + } else { + MemNSetMTRRrangeNb (NBPtr, 0, &Cache32bTOP, 0x200, 6); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Program MTRRs to describe given range as given cache type. Use MTRR pairs + * starting with the given MTRRphys Base address, and use as many as is + * required up to (excluding) MSR 020C, which is reserved for OS. + * + * "Limit" in the context of this procedure is not the numerically correct + * limit, but rather the Last address+1, for purposes of coding efficiency + * and readability. Size of a region is then Limit-Base. + * + * 1. Size of each range must be a power of two + * 2. Each range must be naturally aligned (Base is same as size) + * + * There are two code paths: the ascending path and descending path (analogous + * to bsf and bsr), where the next limit is a function of the next set bit in + * a forward or backward sequence of bits (as a function of the Limit). We + * start with the ascending path, to ensure that regions are naturally aligned, + * then we switch to the descending path to maximize MTRR usage efficiency. + * Base=0 is a special case where we start with the descending path. + * Correct Mask for region is 2comp(Size-1)-1, + * which is 2comp(Limit-Base-1)-1 * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Base - Base address[47:16] of specified range. + * @param[in] *LimitPtr - Limit address[47:16] of specified range. + * @param[in] MtrrAddr - address of var MTRR pair to start using. + * @param[in] MtrrType - Cache type for the range. + * + * @return TRUE - No failure occurred + * @return FALSE - Failure occurred because run out of variable-size MTRRs before completion. + */ + +BOOLEAN +STATIC +MemNSetMTRRrangeNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Base, + IN OUT UINT32 *LimitPtr, + IN UINT32 MtrrAddr, + IN UINT8 MtrrType + ) +{ + S_UINT64 SMsr; + UINT32 CurBase; + UINT32 CurLimit; + UINT32 CurSize; + UINT32 CurAddr; + UINT32 Value32; + + CurBase = Base; + CurLimit = *LimitPtr; + CurAddr = MtrrAddr; + + while ((CurAddr >= 0x200) && (CurAddr < 0x20A) && (CurBase < *LimitPtr)) { + CurSize = CurLimit = (UINT32)1 << LibAmdBitScanForward (CurBase); + CurLimit += CurBase; + if ((CurBase == 0) || (*LimitPtr < CurLimit)) { + CurLimit = *LimitPtr - CurBase; + CurSize = CurLimit = (UINT32)1 << LibAmdBitScanReverse (CurLimit); + CurLimit += CurBase; + } + + // prog. MTRR with current region Base + SMsr.lo = (CurBase << 16) | (UINT32)MtrrType; + SMsr.hi = CurBase >> (32 - 16); + LibAmdMsrWrite (CurAddr, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + + // prog. MTRR with current region Mask + CurAddr++; // other half of MSR pair + Value32 = CurSize - (UINT32)1; + Value32 = ~Value32; + SMsr.hi = (Value32 >> (32 - 16)) & NBPtr->VarMtrrHiMsk; + SMsr.lo = (Value32 << 16) | ((UINT32)1 << MTRR_VALID); + LibAmdMsrWrite (CurAddr, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + + CurBase = CurLimit; + CurAddr++; // next MSR pair + } + + if (CurLimit < *LimitPtr) { + // Announce failure + *LimitPtr = CurLimit; + IDS_ERROR_TRAP; + } + + while ((CurAddr >= 0x200) && (CurAddr < 0x20C)) { + SMsr.lo = SMsr.hi = 0; + LibAmdMsrWrite (CurAddr, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + CurAddr++; + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * Program one MTRR to describe Uma region as UC cache type if we detect running out of + * Mtrr circumstance. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *BasePtr - Base address[47:24] of specified range. + * @param[in] *LimitPtr - Limit address[47:24] of specified range. + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemNSetMTRRUmaRegionUCNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 *BasePtr, + IN OUT UINT32 *LimitPtr + ) +{ + S_UINT64 SMsr; + UINT32 Mtrr; + UINT32 Size; + UINT32 Value32; + + Size = *LimitPtr - *BasePtr; + // Check if Size is a power of 2 + if ((Size & (Size - 1)) != 0) { + for (Mtrr = 0x200; Mtrr < 0x20A; Mtrr += 2) { + LibAmdMsrRead (Mtrr + 1, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + if ((SMsr.lo & ((UINT32) 1 << 11)) == 0) { + MemNSetMTRRrangeNb (NBPtr, *BasePtr, LimitPtr, Mtrr, 0); + break; + } + } + if (Mtrr == 0x20A) { + // Run out of MTRRs + IDS_ERROR_TRAP; + } + } else { + Mtrr = 0x20A; //Reserved pair of MTRR for UMA region. + + // prog. MTRR with current region Base + SMsr.lo = *BasePtr << 16; + SMsr.hi = *BasePtr >> (32 - 16); + LibAmdMsrWrite (Mtrr, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + + // prog. MTRR with current region Mask + Mtrr++; // other half of MSR pair + Value32 = Size - (UINT32)1; + Value32 = ~Value32; + SMsr.hi = (Value32 >> (32 - 16)) & NBPtr->VarMtrrHiMsk; + SMsr.lo = (Value32 << 16) | ((UINT32)1 << MTRR_VALID); + LibAmdMsrWrite (Mtrr, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function readjusts TOPMEM and MTRRs after allocating storage for C6 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNC6AdjustMSRs ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT32 SysLimit; + UINT32 CurAddr; + S_UINT64 SMsr; + + SysLimit = NBPtr->RefPtr->SysLimit + 1; + SMsr.hi = SysLimit >> (32 - 16); + SMsr.lo = SysLimit << 16; + if (SysLimit < _4GB_RJ16) { + LibAmdMsrWrite (TOP_MEM, (UINT64 *)&SMsr, &(NBPtr->MemPtr->StdHeader)); + IDS_HDT_CONSOLE (MEM_FLOW, "TOP_MEM: %08x0000\n", SysLimit); + // If there is no UMA buffer, then set top of cache and MTRR. + // Otherwise, top of cache and MTRR will be set when UMA buffer is set up. + if (NBPtr->RefPtr->UmaMode == UMA_NONE) { + NBPtr->RefPtr->Sub4GCacheTop = (SysLimit << 16); + // Find unused MTRR to set C6 region to UC + for (CurAddr = 0x200; CurAddr < 0x20C; CurAddr += 2) { + LibAmdMsrRead (CurAddr + 1, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + if ((SMsr.lo & ((UINT32) 1 << 11)) == 0) { + // Set region base as TOM + SMsr.hi = SysLimit >> (32 - 16); + SMsr.lo = SysLimit << 16; + LibAmdMsrWrite (CurAddr, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + + // set region mask to 16MB + SMsr.hi = NBPtr->VarMtrrHiMsk; + SMsr.lo = 0xFF000800; + LibAmdMsrWrite (CurAddr + 1, (UINT64 *)&SMsr, &NBPtr->MemPtr->StdHeader); + + break; + } + } + } + } else { + LibAmdMsrWrite (TOP_MEM2, (UINT64 *)&SMsr, &(NBPtr->MemPtr->StdHeader)); + IDS_HDT_CONSOLE (MEM_FLOW, "TOP_MEM2: %08x0000\n", SysLimit); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Family-specific hook to override the DdrMaxRate value for families with a + * non-GH-compatible encoding for BFDdrMaxRate + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *DdrMaxRate - Void pointer to DdrMaxRate. Used as INT16. + * + * @return TRUE + * + */ +BOOLEAN +MemNGetMaxDdrRateUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *DdrMaxRate + ) +{ + UINT8 DdrMaxRateEncoded; + + DdrMaxRateEncoded = (UINT8) MemNGetBitFieldNb (NBPtr, BFDdrMaxRate); + + if (DdrMaxRateEncoded == 0) { + * (UINT16 *) DdrMaxRate = UNSUPPORTED_DDR_FREQUENCY; + } else { + * (UINT16 *) DdrMaxRate = MemNGetMemClkFreqUnb (NBPtr, DdrMaxRateEncoded); + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function performs the action after save/restore execution + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * + */ + +BOOLEAN +MemNAfterSaveRestoreUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + // Sync. up DctCfgSel value with NBPtr->Dct + MemNSetBitFieldNb (NBPtr, BFDctCfgSel, NBPtr->Dct); + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnphy.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnphy.c new file mode 100644 index 0000000000..773e7b2d61 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnphy.c @@ -0,0 +1,1345 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnphy.c + * + * Common Northbridge Phy support + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 87494 $ @e \$Date: 2013-02-04 12:06:47 -0600 (Mon, 04 Feb 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mport.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mu.h" +#include "PlatformMemoryConfiguration.h" +#include "heapManager.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) +#define FILECODE PROC_MEM_NB_MNPHY_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define UNUSED_CLK 4 + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/// Type of an entry for processing phy init compensation for client NB +typedef struct { + BIT_FIELD_NAME IndexBitField; ///< Bit field on which the value is decided + BIT_FIELD_NAME StartTargetBitField; ///< First bit field to be modified + BIT_FIELD_NAME EndTargetBitField; ///< Last bit field to be modified + UINT16 ExtraValue; ///< Extra value needed to be written to bit field + CONST UINT16 (*TxPrePN)[3][5]; ///< Pointer to slew rate table +} PHY_COMP_INIT_CLIENTNB; + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets a delay value a PCI register during training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * + * @return Value read + */ + +UINT32 +MemNGetTrainDlyNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar + ) +{ + return NBPtr->MemNcmnGetSetTrainDly (NBPtr, 0, TrnDly, DrbnVar, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets a delay value a PCI register during training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * @param[in] Field - Value to be programmed + * + */ + +VOID +MemNSetTrainDlyNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ) +{ + NBPtr->MemNcmnGetSetTrainDly (NBPtr, 1, TrnDly, DrbnVar, Field); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function executes prototypical Phy fence training function. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNPhyFenceTrainingUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 FenceThresholdTxDll; + UINT8 FenceThresholdRxDll; + UINT8 FenceThresholdTxPad; + UINT16 Fence2Data; + + MemNSetBitFieldNb (NBPtr, BFDataFence2, 0); + MemNSetBitFieldNb (NBPtr, BFFence2, 0); + // 1. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=10b. + // 2. Perform phy fence training. + // 3. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdTxDll]. + MemNSetBitFieldNb (NBPtr, BFFenceTrSel, 2); + MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 30, 26, BFPhyFence); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tFenceThresholdTxDll\n"); + MemNTrainPhyFenceNb (NBPtr); + FenceThresholdTxDll = (UINT8) MemNGetBitFieldNb (NBPtr, BFPhyFence); + NBPtr->FamilySpecificHook[DetectMemPllError] (NBPtr, &FenceThresholdTxDll); + + // 4. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]0F[AlwaysEnDllClks]=001b. + MemNSetBitFieldNb (NBPtr, BFAlwaysEnDllClks, 0x1000); + + // 5. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=01b. + // 6. Perform phy fence training. + // 7. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdRxDll]. + MemNSetBitFieldNb (NBPtr, BFFenceTrSel, 1); + MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 25, 21, BFPhyFence); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFenceThresholdRxDll\n"); + MemNTrainPhyFenceNb (NBPtr); + FenceThresholdRxDll = (UINT8) MemNGetBitFieldNb (NBPtr, BFPhyFence); + NBPtr->FamilySpecificHook[DetectMemPllError] (NBPtr, &FenceThresholdRxDll); + + // 8. Program D18F2x[1,0]9C_x0D0F_0[F,7:0]0F[AlwaysEnDllClks]=000b. + MemNSetBitFieldNb (NBPtr, BFAlwaysEnDllClks, 0x0000); + + // 9. Program D18F2x[1,0]9C_x0000_0008[FenceTrSel]=11b. + // 10. Perform phy fence training. + // 11. Write the calculated fence value to D18F2x[1,0]9C_x0000_000C[FenceThresholdTxPad]. + MemNSetBitFieldNb (NBPtr, BFFenceTrSel, 3); + MAKE_TSEFO (NBPtr->NBRegTable, DCT_PHY_ACCESS, 0x0C, 20, 16, BFPhyFence); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFenceThresholdTxPad\n"); + MemNTrainPhyFenceNb (NBPtr); + FenceThresholdTxPad = (UINT8) MemNGetBitFieldNb (NBPtr, BFPhyFence); + NBPtr->FamilySpecificHook[DetectMemPllError] (NBPtr, &FenceThresholdTxPad); + + // Program Fence2 threshold for Clk, Cmd, and Addr + if (FenceThresholdTxPad < 16) { + MemNSetBitFieldNb (NBPtr, BFClkFence2, FenceThresholdTxPad | 0x10); + MemNSetBitFieldNb (NBPtr, BFCmdFence2, FenceThresholdTxPad | 0x10); + MemNSetBitFieldNb (NBPtr, BFAddrFence2, FenceThresholdTxPad | 0x10); + } else { + MemNSetBitFieldNb (NBPtr, BFClkFence2, 0); + MemNSetBitFieldNb (NBPtr, BFCmdFence2, 0); + MemNSetBitFieldNb (NBPtr, BFAddrFence2, 0); + } + + // Program Fence2 threshold for data + Fence2Data = 0; + if (FenceThresholdTxPad < 16) { + Fence2Data |= FenceThresholdTxPad | 0x10; + } + if (FenceThresholdRxDll < 16) { + Fence2Data |= (FenceThresholdRxDll | 0x10) << 10; + } + if (FenceThresholdTxDll < 16) { + Fence2Data |= (FenceThresholdTxDll | 0x10) << 5; + } + MemNSetBitFieldNb (NBPtr, BFDataFence2, Fence2Data); + NBPtr->FamilySpecificHook[ProgramFence2RxDll] (NBPtr, &Fence2Data); + + if (NBPtr->MCTPtr->Status[SbLrdimms]) { + // 18. If motherboard routing requires CS[7:6] to adopt address timings, e.g. 3 LRDIMMs/ch with CS[7:6] + // routed across all DIMM sockets, BIOS performs the following: + if (FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_NO_LRDIMM_CS67_ROUTING, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, NULL, NULL) != NULL) { + // A. Program D18F2xA8_dct[1:0][CSTimingMux67] = 1. + MemNSetBitFieldNb (NBPtr, BFCSTimingMux67, 1); + // B. Program D18F2x9C_x0D0F_8021_dct[1:0]: + // - DiffTimingEn = 1. + // - IF (D18F2x9C_x0000_0004_dct[1:0][AddrCmdFineDelay] >= + // D18F2x9C_x0D0F_E008_dct[1:0][FenceValue]) THEN Fence = 1 ELSE Fence = 0. + // - Delay = D18F2x9C_x0000_0004_dct[1:0][AddrCmdFineDelay]. + // + MemNSetBitFieldNb (NBPtr, BFDiffTimingEn, 1); + MemNSetBitFieldNb (NBPtr, BFFence, (MemNGetBitFieldNb (NBPtr, BFAddrCmdFineDelay) >= MemNGetBitFieldNb (NBPtr, BFFenceValue)) ? 1 : 0); + MemNSetBitFieldNb (NBPtr, BFDelay, (MemNGetBitFieldNb (NBPtr, BFAddrCmdFineDelay))); + } + } + + // 19. Reprogram F2x9C_04. + MemNSetBitFieldNb (NBPtr, BFAddrTmgControl, MemNGetBitFieldNb (NBPtr, BFAddrTmgControl)); + +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function executes Phy fence training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNTrainPhyFenceNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Byte; + INT16 Avg; + UINT8 PREvalue; + + if (MemNGetBitFieldNb (NBPtr, BFDisDramInterface)) { + return; + } + + // 1. BIOS first programs a seed value to the phase recovery + // engine registers. + // + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tSeeds: "); + for (Byte = 0; Byte < MAX_BYTELANES_PER_CHANNEL; Byte++) { + // This includes ECC as byte 8 + MemNSetTrainDlyNb (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (0, Byte), 19); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", 19); + } + + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tPhyFenceTrEn = 1"); + // 2. Set F2x[1, 0]9C_x08[PhyFenceTrEn]=1. + MemNSetBitFieldNb (NBPtr, BFPhyFenceTrEn, 1); + + if (!NBPtr->IsSupported[UnifiedNbFence]) { + // 3. Wait 200 MEMCLKs. + MemNWaitXMemClksNb (NBPtr, 200); + } else { + // 3. Wait 2000 MEMCLKs. + MemNWaitXMemClksNb (NBPtr, 2000); + } + + // 4. Clear F2x[1, 0]9C_x08[PhyFenceTrEn]=0. + MemNSetBitFieldNb (NBPtr, BFPhyFenceTrEn, 0); + + // 5. BIOS reads the phase recovery engine registers + // F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52. + // 6. Calculate the average value of the fine delay and subtract 8. + // + Avg = 0; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t PRE: "); + for (Byte = 0; Byte < MAX_BYTELANES_PER_CHANNEL; Byte++) { + // + // This includes ECC as byte 8. ECC Byte lane (8) is ignored by MemNGetTrainDlyNb function where + // ECC is not supported. + // + PREvalue = (UINT8) (0x1F & MemNGetTrainDlyNb (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (0, Byte))); + Avg = Avg + ((INT16) PREvalue); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", PREvalue); + } + Avg = ((Avg + 8) / 9); // round up + + NBPtr->MemNPFenceAdjustNb (NBPtr, &Avg); + + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFence: %02x\n", Avg); + + // 7. Write the value to F2x[1, 0]9C_x0C[PhyFence]. + MemNSetBitFieldNb (NBPtr, BFPhyFence, Avg); + + // 8. BIOS rewrites F2x[1, 0]9C_x04, DRAM Address/Command Timing Control + // Register delays for both channels. This forces the phy to recompute + // the fence. + // + MemNSetBitFieldNb (NBPtr, BFAddrTmgControl, MemNGetBitFieldNb (NBPtr, BFAddrTmgControl)); +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * Returns the parameters for a requested delay value to be used in training + * The correct Min, Max and Mask are determined based on the type of Delay, + * and the frequency + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - Type of delay + * @param[in,out] *Parms - Pointer to the TRN_DLY-PARMS struct + * + */ + +VOID +MemNGetTrainDlyParmsUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN TRN_DLY_TYPE TrnDly, + IN OUT TRN_DLY_PARMS *Parms + ) +{ + Parms->Min = 0; + + if ((TrnDly == AccessWrDatDly) || (TrnDly == AccessRdDqsDly)) { + Parms->Max = 0x1F; + Parms->Mask = 0x01F; + } +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets or set DQS timing during training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +MemNcmnGetSetTrainDlyUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ) +{ + UINT16 Index; + UINT16 Offset; + UINT32 Value; + UINT32 Address; + UINT8 Dimm; + UINT8 Rank; + UINT8 Byte; + UINT8 Nibble; + UINT8 DimmNibble; + + Dimm = DRBN_DIMM (DrbnVar); + Rank = DRBN_RANK (DrbnVar); + Byte = DRBN_BYTE (DrbnVar); + Nibble = DRBN_NBBL (DrbnVar); + DimmNibble = DRBN_DIMM_NBBL (DrbnVar); + + ASSERT (Dimm < (NBPtr->CsPerChannel / NBPtr->CsPerDelay)); + ASSERT (Byte <= ECC_DLY); + if ((Byte == ECC_DLY) && (!NBPtr->MCTPtr->Status[SbEccDimms] || !NBPtr->IsSupported[EccByteTraining])) { + // When ECC is not enabled + if (IsSet) { + // On write, ignore + return 0; + } else { + // On read, redirect to byte 0 to correct fence averaging + Byte = 0; + } + } + + switch (TrnDly) { + case AccessRcvEnDly: + Index = 0x10; + break; + case AccessWrDqsDly: + Index = 0x30; + break; + case AccessWrDatDly: + Index = 0x01; + break; + case AccessRdDqsDly: + Index = 0x05; + break; + case AccessRdDqs2dDly: + Index = 0x00; + break; + case AccessPhRecDly: + Index = 0x50; + break; + default: + Index = 0; + IDS_ERROR_TRAP; + } + + switch (TrnDly) { + case AccessRcvEnDly: + case AccessWrDqsDly: + Index += (Dimm * 3); + if (Byte & 0x04) { + // if byte 4,5,6,7 + Index += 0x10; + } + if (Byte & 0x02) { + // if byte 2,3,6,7 + Index++; + } + if (Byte > 7) { + Index += 2; + } + Offset = 16 * (Byte % 2); + Index |= (Rank << 8); + Index |= (Nibble << 9); + Address = Index; + break; + + case AccessRdDqsDly: + case AccessWrDatDly: + + if (NBPtr->IsSupported[DimmBasedOnSpeed]) { + if (NBPtr->DCTPtr->Timings.Speed < DDR800_FREQUENCY) { + // if DDR speed is below 800, use DIMM 0 delays for all DIMMs. + Dimm = 0; + } + } + + Index += (Dimm * 0x100); + if (Nibble) { + if (Rank) { + Index += 0xA0; + } else { + Index += 0x70; + } + } else if (Rank) { + Index += 0x60; + } + // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need + // to run AccessPhRecDly sequence. + case AccessPhRecDly: + Index += (Byte / 4); + Offset = 8 * (Byte % 4); + Address = Index; + break; + case AccessRdDqs2dDly: + Address = 0x0D0F0000; + Index += (DimmNibble >> 1) * 0x100; + Index += 0x20; + Index = Index + Dimm; + Offset = 4 * ((DimmNibble & 0x01) * 2); + Address += Index; + break; + default: + Offset = 0; + IDS_ERROR_TRAP; + Address = Index; + } + MemNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + MemNPollBitFieldNb (NBPtr, BFDctAccessDone, 1, PCI_ACCESS_TIMEOUT, FALSE); + Value = MemNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + if (TrnDly == AccessRdDqsDly) { + NBPtr->FamilySpecificHook[AdjustRdDqsDlyOffset] (NBPtr, &Offset); + } + + if (IsSet) { + if (TrnDly == AccessPhRecDly) { + Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03]; + } + if (TrnDly != AccessRdDqs2dDly) { + Value = ((UINT32)Field << Offset) | (Value & (~((UINT32) ((TrnDly == AccessRcvEnDly) ? 0x3FF : 0xFF) << Offset))); + } else { + Value = ((UINT32)Field << Offset) | (Value & (~((UINT32) 0x1F << Offset))); + } + ASSERT (!NBPtr->IsSupported[ScrubberEn]); // Phy CSR write is not allowed after scrubber is enabled + MemNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + MemNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + MemNPollBitFieldNb (NBPtr, BFDctAccessDone, 1, PCI_ACCESS_TIMEOUT, FALSE); + if (TrnDly == AccessPhRecDly) { + NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value; + } + } else { + if (TrnDly != AccessRdDqs2dDly) { + Value = (Value >> Offset) & (UINT32) ((TrnDly == AccessRcvEnDly) ? 0x3FF : 0xFF); + } else { + Value = (Value >> Offset) & (UINT32) (0x1F); + } + } + return Value; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the training pattern. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return AGESA_STATUS - Result + * AGESA_SUCCESS - Training pattern is ready to use + * AGESA_ERROR - Unable to initialize the pattern. + */ + +AGESA_STATUS +MemNTrainingPatternInitNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + TRAIN_PATTERN TrainPattern; + AGESA_STATUS Status; + + TechPtr = NBPtr->TechPtr; + TrainPattern = 0; + // + // Check the training type + // + if (TechPtr->TrainingType == TRN_DQS_POSITION) { + // + // DQS Position Training + // + if (NBPtr->PosTrnPattern == POS_PATTERN_256B) { + // + // 256 Bit pattern + // + if (NBPtr->MCTPtr->Status[Sb128bitmode]) { + TrainPattern = TestPatternJD256B; + TechPtr->PatternLength = 64; + } else { + TrainPattern = TestPatternJD256A; + TechPtr->PatternLength = 32; + } + } else { + // + // 72 bit pattern will be used if PosTrnPattern is not specified + // + if (NBPtr->MCTPtr->Status[Sb128bitmode]) { + TrainPattern = TestPatternJD1B; + TechPtr->PatternLength = 18; + } else { + TrainPattern = TestPatternJD1A; + TechPtr->PatternLength = 9; + } + } + } else if (TechPtr->TrainingType == TRN_MAX_READ_LATENCY) { + // + // Max Read Latency Training + // + TrainPattern = TestPatternML; + TechPtr->PatternLength = (NBPtr->MCTPtr->Status[Sb128bitmode]) ? 6 : 3; + } else { + // + // Error - TechPtr->Training Type must be set to one of the types handled in this function + // + ASSERT (FALSE); + } + // + // Allocate training buffer + // + AllocHeapParams.RequestedBufferSize = (TechPtr->PatternLength * 64 * 2) + 16; + AllocHeapParams.BufferHandle = AMD_MEM_TRAIN_BUFFER_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + Status = HeapAllocateBuffer (&AllocHeapParams, &NBPtr->MemPtr->StdHeader); + ASSERT (Status == AGESA_SUCCESS); + if (Status != AGESA_SUCCESS) { + return Status; + } + TechPtr->PatternBufPtr = AllocHeapParams.BufferPtr; + AlignPointerTo16Byte (&TechPtr->PatternBufPtr); + TechPtr->TestBufPtr = TechPtr->PatternBufPtr + (TechPtr->PatternLength * 64); + + // Prepare training pattern + MemUFillTrainPattern (TrainPattern, TechPtr->PatternBufPtr, TechPtr->PatternLength * 64); + + return Status; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determined the settings for the Reliable Read/Write engine + * for each specific type of training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *OptParam - Pointer to an Enum of TRAINING_TYPE + * + * @return TRUE + */ + +BOOLEAN +MemNSetupHwTrainingEngineUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *OptParam + ) +{ + TRAINING_TYPE TrnType; + RRW_SETTINGS *Rrw; + + TrnType = *(TRAINING_TYPE*) OptParam; + Rrw = &NBPtr->RrwSettings; + // + // Common Settings + // + Rrw->TgtBankAddressA = CPG_BANK_ADDRESS_A; + Rrw->TgtRowAddressA = CPG_ROW_ADDRESS_A; + Rrw->TgtColAddressA = CPG_COL_ADDRESS_A; + Rrw->TgtBankAddressB = CPG_BANK_ADDRESS_B; + Rrw->TgtRowAddressB = CPG_ROW_ADDRESS_B; + Rrw->TgtColAddressB = CPG_COL_ADDRESS_B; + Rrw->CompareMaskHigh = CPG_COMPARE_MASK_HI; + Rrw->CompareMaskLow = CPG_COMPARE_MASK_LOW; + Rrw->CompareMaskEcc = CPG_COMPARE_MASK_ECC; + + switch (TrnType) { + case TRN_RCVR_ENABLE: + // + // Receiver Enable Training + // + NBPtr->TechPtr->PatternLength = 192; + break; + case TRN_MAX_READ_LATENCY: + // + // Max Read Latency Training + // + Rrw->CmdTgt = CMD_TGT_A; + NBPtr->TechPtr->PatternLength = 32; + Rrw->DataPrbsSeed = PRBS_SEED_32; + break; + case TRN_DQS_POSITION: + // + // Read/Write DQS Position training + // + Rrw->CmdTgt = CMD_TGT_AB; + NBPtr->TechPtr->PatternLength = 256; + Rrw->DataPrbsSeed = PRBS_SEED_256; + break; + default: + ASSERT (FALSE); + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finalizes the training pattern. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Index - Index of Write Data Delay Value + * @param[in,out] *Value - Write Data Delay Value + * @return BOOLEAN - TRUE - Use the value returned. + * FALSE - No more values in table. + */ + +BOOLEAN +MemNGetApproximateWriteDatDelayNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Index, + IN OUT UINT8 *Value + ) +{ + CONST UINT8 WriteDatDelayValue[] = {0x10, 0x4, 0x8, 0xC, 0x14, 0x18, 0x1C, 0x1F}; + if (Index < GET_SIZE_OF (WriteDatDelayValue)) { + *Value = WriteDatDelayValue[Index]; + return TRUE; + } + return FALSE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finalizes the training pattern. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return AGESA_STATUS - Result + * AGESA_SUCCESS - Training pattern has been finalized. + * AGESA_ERROR - Unable to initialize the pattern. + */ + +AGESA_STATUS +MemNTrainingPatternFinalizeNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + AGESA_STATUS Status; + // + // Deallocate training buffer + // + Status = HeapDeallocateBuffer (AMD_MEM_TRAIN_BUFFER_HANDLE, &NBPtr->MemPtr->StdHeader); + ASSERT (Status == AGESA_SUCCESS); + return Status; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns the number of Chipselects controlled by each set + * of Delay registers under current conditions. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return + */ + +UINT8 +MemNCSPerDelayNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + if (MemNGetBitFieldNb (NBPtr, BFPerRankTimingEn) == 1) { + return 1; + } else { + return 2; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns the minimum data eye width in 32nds of a UI for + * the type of data eye(Rd/Wr) that is being trained. This value will + * be the minimum number of consecutive delays that yield valid data. + * Uses TechPtr->Direction to determine read or write. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return + */ + +UINT8 +MemNMinDataEyeWidthNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 MinRdDataeye; + UINT8 MinWrDataeye; + UINT8 *MinRdWrDataeyePtr; + + MinRdWrDataeyePtr = FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MIN_RD_WR_DATAEYE_WIDTH, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, + &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); + + if (NBPtr->TechPtr->Direction == DQS_READ_DIR) { + if (MinRdWrDataeyePtr != NULL) { + MinRdDataeye = MinRdWrDataeyePtr[0]; + return MinRdDataeye; + } else { + return MIN_RD_DATAEYE_WIDTH_NB; + } + } else { + if (MinRdWrDataeyePtr != NULL) { + MinWrDataeye = MinRdWrDataeyePtr[1]; + return MinWrDataeye; + } else { + return MIN_WR_DATAEYE_WIDTH_NB; + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the phy registers according to the desired phy VDDIO voltage level + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNPhyVoltageLevelNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + BIT_FIELD_NAME BitField; + BIT_FIELD_NAME BFEnd; + UINT16 BFValue; + UINT16 RegValue; + + BFValue = (UINT16) CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage) << 3; + BFEnd = NBPtr->IsSupported[ProgramCsrComparator] ? BFCsrComparator : BFCmpVioLvl; + + for (BitField = BFDataRxVioLvl; BitField <= BFEnd; BitField++) { + RegValue = BFValue; + if (BitField == BFCsrComparator) { + RegValue >>= (3 - 2); + // Setting this bit in DCT0 adjusts the comparator for DCT0 and DCT1. Setting this bit in DCT1 has no effect. + NBPtr->SwitchDCT (NBPtr, 0); + MemNSetBitFieldNb (NBPtr, BitField, RegValue); + break; + } else if (BitField == BFCmpVioLvl) { + RegValue <<= (14 - 3); + // Must set this bit on DCT0 even when DCT0 has no memory + NBPtr->SwitchDCT (NBPtr, 0); + MemNSetBitFieldNb (NBPtr, BitField, RegValue); + } + MemNBrdcstSetNb (NBPtr, BitField, RegValue); + } + // Program D18F2x9C_x0D0F_4006_dct[0][VrefSel] = 0. + MemNSetBitFieldNb (NBPtr, BFObsrvVrefSel, 0); + // Program D18F2x9C_x0D0F_4007_dct[0] per platform requirements. + NBPtr->FamilySpecificHook[PhyInitVref] (NBPtr, NULL); +} + +/*----------------------------------------------------------------------------- + * + * + * This function calculates the value of WrDqDqsEarly and programs it into + * the DCT and adds it to the WrDqsGrossDelay of each byte lane on each + * DIMM of the channel. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNCalcWrDqDqsEarlyUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + MEM_TECH_BLOCK *TechPtr; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + UINT8 Dimm; + UINT8 ByteLane; + UINT8 *WrDqsDlysPtr; + UINT8 WrDqDqsEarly; + UINT8 ChipSel; + + ASSERT ((NBPtr->IsSupported[WLSeedAdjust]) && (NBPtr->IsSupported[WLNegativeDelay])); + + TechPtr = NBPtr->TechPtr; + ChannelPtr = NBPtr->ChannelPtr; + DCTPtr = NBPtr->DCTPtr; + + ASSERT (NBPtr != NULL); + ASSERT (ChannelPtr != NULL); + ASSERT (DCTPtr != NULL); + // + // For each DIMM: + // - The Critical Gross Delay (CGD) is the minimum GrossDly of all byte lanes and all DIMMs. + // - If (CGD < 0) Then + // - D18F2xA8_dct[1:0][WrDqDqsEarly] = ABS(CGD) + // - WrDqsGrossDly = GrossDly + WrDqDqsEarly + // - Else + // - D18F2xA8_dct[1:0][WrDqDqsEarly] = 0. + // - WrDqsGrossDly = GrossDly + // + WrDqDqsEarly = 0; + if (TechPtr->WLCriticalDelay < 0) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCalculating WrDqDqsEarly, adjusting WrDqs.\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMin. Critical Delay: %x\n", TechPtr->WLCriticalDelay); + // We've saved the entire negative delay value, so take the ABS and convert to GrossDly. + WrDqDqsEarly = (UINT8) (0x00FF &((((ABS (TechPtr->WLCriticalDelay)) + 0x1F) / 0x20))); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tWrDqDqsEarly : %02x\n\n", WrDqDqsEarly); + // + // Loop through All WrDqsDlys on all DIMMs + // + for (ChipSel = 0; ChipSel < NBPtr->CsPerChannel; ChipSel = ChipSel + NBPtr->CsPerDelay) { + if ((NBPtr->MCTPtr->Status[SbLrdimms]) ? ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0) : + ((DCTPtr->Timings.CsEnabled & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSel)) != 0)) { + // + // If LRDIMMs, only include the physical dimms, not logical Dimms + // + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS %x:", ChipSel); + Dimm = ChipSel / NBPtr->CsPerDelay; + + WrDqsDlysPtr = &(ChannelPtr->WrDqsDlys[(Dimm * TechPtr->DlyTableWidth ())]); + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + WrDqsDlysPtr[ByteLane] += (WrDqDqsEarly << 5); + NBPtr->SetTrainDly (NBPtr, AccessWrDqsDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), WrDqsDlysPtr[ByteLane]); + IDS_HDT_CONSOLE (MEM_FLOW, " %02x", WrDqsDlysPtr[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + } + } + MemNSetBitFieldNb (NBPtr, BFWrDqDqsEarly, WrDqDqsEarly); + return TRUE; +} + +/*----------------------------------------------------------------------------- + * + * + * This function forces phy to M0 state + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return none + * ---------------------------------------------------------------------------- + */ +VOID +MemNForcePhyToM0Unb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + IDS_SKIP_HOOK (IDS_FORCE_PHY_TO_M0, NBPtr, &(NBPtr->MemPtr->StdHeader)) { + // 1. Program D18F2x9C_x0D0F_E013_dct[1:0] = 0118h. + MemNBrdcstSetUnConditionalNb (NBPtr, BFPllRegWaitTime, 0x118); + // 2. For each byte lane and each memory P-state: Program D18F2x9C_x0D0F_0[F,7:0][53,13]_dct[1:0][RxSsbMntClkEn] = 0. + MemNBrdcstSetUnConditionalNb (NBPtr, BFRxSsbMntClkEn, 0); + // 3. D18F2xA8_dct[1:0][MemPhyPllPdMode] = 00b. + MemNBrdcstSetUnConditionalNb (NBPtr, BFMemPhyPllPdMode, 0); + // 4. Force the phy to M0 with the following sequence: + // A. Program D18F2x9C_x0D0F_E006_dct[1:0][PllLockTime] = 190h. Restore the default PLL lock time. + MemNBrdcstSetUnConditionalNb (NBPtr, BFPllLockTime, NBPtr->FreqChangeParam->PllLockTimeDefault); + // B. For each DCT: Program D18F2x9C_x0000_000B_dct[1:0] = 80800000h. + MemNBrdcstSetUnConditionalNb (NBPtr, BFDramPhyStatusReg, 0x80800000); + NBPtr->SwitchDCT (NBPtr, 0); + // C. Program D18F2x9C_x0D0F_E018_dct[0][PhyPSMasterChannel] = 0. + MemNSetBitFieldNb (NBPtr, BFPhyPSMasterChannel, 0); + // D. Program D18F2x9C_x0000_000B_dct[0] = 40000000h. CH0 only; + MemNSetBitFieldNb (NBPtr, BFDramPhyStatusReg, 0x40000000); + // E. For each DCT: Program D18F2x9C_x0000_000B_dct[1:0] = 80000000h. + MemNBrdcstSetUnConditionalNb (NBPtr, BFDramPhyStatusReg, 0x80000000); + } +} + +/*----------------------------------------------------------------------------- + * + * + * This function sets SkewMemClk before enabling MemClk + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Optional parameter + * + * @return TRUE - always + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNSetSkewMemClkUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 Dct; + + // SkewMemClk is set to 1 if all DCTs are enabled, else 0. + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + MemNSwitchDCTNb (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize == 0) { + break; + } + } + MemNSwitchDCTNb (NBPtr, 0); + if (Dct == NBPtr->DctCount) { + MemNSetBitFieldNb (NBPtr, BFSkewMemClk, 0x10); + } else { + MemNSetBitFieldNb (NBPtr, BFSkewMemClk, 0); + } + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function masks the RdDqsDly Bit 0 before writing to register for UNB. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *Offset - Bit offset of the field to be programmed + * + * @return TRUE + */ +BOOLEAN +MemNAdjustRdDqsDlyOffsetUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *Offset + ) +{ + *(UINT16*) Offset = *(UINT16*) Offset + 1; + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function initializes RxEn Delays for RxEn seedless training + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNInitializeRxEnSeedlessTrainingUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 ByteLane; + // Save original PRE based RxEnDly for RxEn Seedless training + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + NBPtr->TechPtr->RxOrig[ByteLane] = NBPtr->ChannelPtr->RcvEnDlys[(NBPtr->TechPtr->ChipSel / NBPtr->CsPerDelay) * NBPtr->TechPtr->DlyTableWidth () + ByteLane]; + } + return TRUE; +} +/*----------------------------------------------------------------------------- + * + * + * This function checks each bytelane for no window error. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNTrackRxEnSeedlessRdWrNoWindBLErrorUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + MemTTrackRxEnSeedlessRdWrNoWindBLError (NBPtr->TechPtr, OptParam); + return TRUE; +} +/*----------------------------------------------------------------------------- + * + * + * This function checks each bytelane for small window error. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNTrackRxEnSeedlessRdWrSmallWindBLErrorUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + MemTTrackRxEnSeedlessRdWrSmallWindBLError (NBPtr->TechPtr, OptParam); + return TRUE; +} +/*----------------------------------------------------------------------------- + * + * + * This function initializes a ByteLaneError error. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNInitialzeRxEnSeedlessByteLaneErrorUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 ByteLane; + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + NBPtr->TechPtr->ByteLaneError[ByteLane] = FALSE; // All Bytelanes have no errors + } + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets phy power saving related settings in different MPstate context. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return none + * ---------------------------------------------------------------------------- + */ +VOID +MemNPhyPowerSavingMPstateUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + STATIC UINT8 Sequence[] = {8, 4, 3, 5, 2, 6, 1, 7, 0}; + UINT16 DllPower[9]; + UINT8 NumLanes; + UINT8 DllWakeTime; + UINT8 MaxRxStggrDly; + UINT8 MinRcvEnGrossDly; + UINT8 MinWrDatGrossDly; + UINT8 dRxStggrDly; + UINT8 dTxStggrDly; + UINT8 TempStggrDly; + UINT8 MaxTxStggrDly; + UINT8 Tcwl; + UINT8 i; + + IDS_HDT_CONSOLE (MEM_FLOW, "Start Phy power saving setting for memory Pstate %d\n", NBPtr->MemPstate); + // 4. Program D18F2x9C_x0D0F_0[F,8:0]13_dct[1:0][DllDisEarlyU] = 1b. + // 5. Program D18F2x9C_x0D0F_0[F,8:0]13_dct[1:0][DllDisEarlyL] = 1b. + // 6. D18F2x9C_x0D0F_0[F,7:0][53,13]_dct[1:0][RxDqsUDllPowerDown] = 1. + MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0F13, MemNGetBitFieldNb (NBPtr, BFPhy0x0D0F0F13) | 0x83); + // 7. D18F2x9C_x0D0F_812F_dct[1:0][PARTri] = ~D18F2x90_dct[1:0][ParEn]. + // 8. D18F2x9C_x0D0F_812F_dct[1:0][Add17Tri, Add16Tri] = {1b, 1b} + if (NBPtr->MemPstate == MEMORY_PSTATE0) { + MemNSetBitFieldNb (NBPtr, BFAddrCmdTri, MemNGetBitFieldNb (NBPtr, BFAddrCmdTri) | 0xA1); + } + // 9. IF (DimmsPopulated == 1)&& ((D18F2x9C_x0000_0000_dct[1:0]_mp[1:0][CkeDrvStren]==010b) || + // (D18F2x9C_x0000_0000_dct[1:0]_mp[1:0][CkeDrvStren]==011b)) THEN THEN + // program D18F2x9C_x0D0F_C0[40,00]_dct[1:0][LowPowerDrvStrengthEn] = 1 + // ELSE program D18F2x9C_x0D0F_C0[40,00]_dct[1:0][LowPowerDrvStrengthEn] = 0 ENDIF. + if ((NBPtr->ChannelPtr->Dimms == 1) && ((MemNGetBitFieldNb (NBPtr, BFCkeDrvStren) == 2) || (MemNGetBitFieldNb (NBPtr, BFCkeDrvStren) == 3))) { + MemNSetBitFieldNb (NBPtr, BFLowPowerDrvStrengthEn, 0x100); + } + // 10. Program D18F2x9C_x0D0F_0[F,7:0][50,10]_dct[1:0][EnRxPadStandby] = IF + // (D18F2x94_dct[1:0][MemClkFreq] <= 800 MHz) THEN 1 ELSE 0 ENDIF. + MemNSetBitFieldNb (NBPtr, BFEnRxPadStandby, (NBPtr->DCTPtr->Timings.Speed <= DDR1600_FREQUENCY) ? 0x1000 : 0); + // 11. Program D18F2x9C_x0000_000D_dct[1:0]_mp[1:0] as follows: + // If (DDR rate < = 1600) TxMaxDurDllNoLock = RxMaxDurDllNoLock = 8h + // else TxMaxDurDllNoLock = RxMaxDurDllNoLock = 7h. + if (NBPtr->DCTPtr->Timings.Speed <= DDR1600_FREQUENCY) { + MemNSetBitFieldNb (NBPtr, BFTxMaxDurDllNoLock, 8); + MemNSetBitFieldNb (NBPtr, BFRxMaxDurDllNoLock, 8); + } else { + MemNSetBitFieldNb (NBPtr, BFTxMaxDurDllNoLock, 7); + MemNSetBitFieldNb (NBPtr, BFRxMaxDurDllNoLock, 7); + } + // TxCPUpdPeriod = RxCPUpdPeriod = 011b. + MemNSetBitFieldNb (NBPtr, BFTxCPUpdPeriod, 3); + MemNSetBitFieldNb (NBPtr, BFRxCPUpdPeriod, 3); + // TxDLLWakeupTime = RxDLLWakeupTime = 11b. + MemNSetBitFieldNb (NBPtr, BFTxDLLWakeupTime, 3); + MemNSetBitFieldNb (NBPtr, BFRxDLLWakeupTime, 3); + + if (NBPtr->IsSupported[DllStaggerEn]) { + // 12. Program D18F2x9C_x0D0F_0[F,7:0][5C,1C]_dct[1:0] as follows. + // Let Numlanes = 8. = 9 with ECC. + NumLanes = (NBPtr->MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8; + // RxDllStggrEn = TxDllStggrEn = 1. + for (i = 0; i < 9; i ++) { + DllPower[i] = 0x8080; + } + // If (DDR rate > = 1866) DllWakeTime = 1, Else DllWakeTime = 0. + DllWakeTime = (NBPtr->DCTPtr->Timings.Speed >= DDR1866_FREQUENCY) ? 1 : 0; + // Let MaxRxStggrDly = (Tcl*2) + MIN(DqsRcvEnGrossDelay for all byte lanes (see D18F2x9C_x0000_00[2A:10]_dct[1:0]_mp[1:0])) - 4. + MinRcvEnGrossDly = NBPtr->TechPtr->GetMinMaxGrossDly (NBPtr->TechPtr, AccessRcvEnDly, FALSE); + ASSERT ((NBPtr->DCTPtr->Timings.CasL * 2 + MinRcvEnGrossDly) >= 4); + MaxRxStggrDly = NBPtr->DCTPtr->Timings.CasL * 2 + MinRcvEnGrossDly - 4; + // Let (real) dRxStggrDly = (MaxRxStggrDly - DllWakeTime) / (Numlanes - 1). + ASSERT (MaxRxStggrDly >= DllWakeTime); + dRxStggrDly = (MaxRxStggrDly - DllWakeTime) / (NumLanes - 1); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMinimum RcvEnGrossDly: 0x%02x MaxRxStggrDly: 0x%02x dRxStggrDly: 0x%02x\n", MinRcvEnGrossDly, MaxRxStggrDly, dRxStggrDly); + // For each byte lane in the ordered sequence {8, 4, 3, 5, 2, 6, 1, 7, 0}, program RxDllStggrDly[5:0] = an + // increasing value, starting with 0 for the first byte lane in the sequence and increasing at a rate of dRxStggrDly + // for each subsequent byte lane. Convert the real to integer by rounding down or using C (int) typecast after linearization. + i = 9 - NumLanes; + TempStggrDly = 0; + for (; i < 9; i ++) { + DllPower[Sequence[i]] |= ((TempStggrDly & 0x3F) << 8); + TempStggrDly = TempStggrDly + dRxStggrDly; + } + + // Let MaxTxStggrDly = (Tcwl*2) + MIN(MIN (WrDatGrossDly for all byte lanes (see + // D18F2x9C_x0000_0[3:0]0[2:1]_dct[1:0]_mp[1:0])), MIN(DqsRcvEnGrossDelay for all byte lanes (see + // D18F2x9C_x0000_00[2A:10]_dct[1:0]_mp[1:0])) - 4. + Tcwl = (UINT8) MemNGetBitFieldNb (NBPtr, BFTcwl); + MinWrDatGrossDly = NBPtr->TechPtr->GetMinMaxGrossDly (NBPtr->TechPtr, AccessWrDatDly, FALSE); + MaxTxStggrDly = Tcwl * 2 + MIN (MinRcvEnGrossDly, MinWrDatGrossDly) - 4; + // Let dTxStggrDly = (MaxTxStggrDly - DllWakeTime) / (Numlanes - 1). + ASSERT (MaxTxStggrDly >= DllWakeTime); + dTxStggrDly = (MaxTxStggrDly - DllWakeTime) / (NumLanes - 1); + // For each byte lane in the ordered sequence {8, 4, 3, 5, 2, 6, 1, 7, 0}, program TxDllStggrDly[5:0] = an + // increasing integer value, starting with 0 for the first byte lane in the sequence and increasing at a rate of + // dTxStggrDly for each subsequent byte lane. + IDS_HDT_CONSOLE (MEM_FLOW, "\tMinimum WrDatGrossDly: 0x%02x MaxTxStggrDly: 0x%02x dTxStggrDly: 0x%02x\n", MinWrDatGrossDly, MaxTxStggrDly, dTxStggrDly); + i = 9 - NumLanes; + TempStggrDly = 0; + for (; i < 9; i ++) { + DllPower[Sequence[i]] |= (TempStggrDly & 0x3F); + TempStggrDly = TempStggrDly + dTxStggrDly; + } + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tByte Lane : ECC 07 06 05 04 03 02 01 00\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tDll Power : %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", + DllPower[8], DllPower[7], DllPower[6], DllPower[5], DllPower[4], DllPower[3], DllPower[2], DllPower[1], DllPower[0]); + + for (i = 0; i < NumLanes; i ++) { + MemNSetBitFieldNb (NBPtr, BFDataByteDllPowerMgnByte0 + i, (MemNGetBitFieldNb (NBPtr, BFDataByteDllPowerMgnByte0 + i) & 0x4040) | DllPower[i]); + } + } + // 13. Program D18F2x248_dct[1:0]_mp[1:0] and then D18F2x9C_x0D0F_0[F,7:0][53,13]_dct[1:0] as follows: + // For M1 context program RxChMntClkEn=RxSsbMntClkEn=0. + // For M0 context program RxChMntClkEn=RxSsbMntClkEn=1. + if (NBPtr->MemPstate == MEMORY_PSTATE1 || NBPtr->IsSupported[RxChnMntClksEn] == FALSE) { + MemNSetBitFieldNb (NBPtr, BFRxChMntClkEn, 0); + MemNSetBitFieldNb (NBPtr, BFRxSsbMntClkEn, 0); + } else { + MemNSetBitFieldNb (NBPtr, BFRxChMntClkEn, 1); + MemNSetBitFieldNb (NBPtr, BFRxSsbMntClkEn, 0x100); + } + + IDS_OPTION_HOOK (IDS_PHY_DLL_STANDBY_CTRL, NBPtr, &NBPtr->MemPtr->StdHeader); +} + +/* -----------------------------------------------------------------------------*/ +/** + * This function adjusts the Phase Mask based on ECC. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNAdjust2DPhaseMaskBasedOnEccUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + NBPtr->PhaseLaneMask = NBPtr->PhaseLaneMask & (UINT32) (NBPtr->MCTPtr->Status[SbEccDimms] ? 0x0FFFF : 0x3FFFF); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function adjusts WrDqsBias before seed scaling + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *WrDqsBias - Pointer to WrDqsBias + * + * @return FALSE - Supported + * @return TRUE - Not supported + */ + +BOOLEAN +MemNAdjustWrDqsBeforeSeedScalingUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *WrDqsBias + ) +{ + // Subtract (0x20 * WrDqDqsEarly) since it is a non-scalable component + * (INT16 *) WrDqsBias = (INT16) (0x20 * MemNGetBitFieldNb (NBPtr, BFWrDqDqsEarly)); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function adjust RdDqsDly used for MaxRdLatency calculation + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *OptParam - Optional parameter + * + * @return FALSE - Supported + * @return TRUE - Not supported + */ + +BOOLEAN +MemNAdjustRdDqsDlyForMaxRdLatUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + // Set RdDqsDlyForMaxRdLat to 0 so that actual RdDqsDly is used for MaxRdLatency calculation + NBPtr->RdDqsDlyForMaxRdLat = 0; + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * This function collects data for Eye Rim Search + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ +BOOLEAN +MemN2DRdDQSEyeRimSearchUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + return MemT2DRdDQSEyeRimSearch (NBPtr->TechPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnreg.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnreg.c new file mode 100644 index 0000000000..c8fa9f4bd3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mnreg.c @@ -0,0 +1,601 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnreg.c + * + * Common Northbridge register access functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB/) + * @e \$Revision: 84482 $ @e \$Date: 2012-12-16 22:48:10 -0600 (Sun, 16 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "merrhdl.h" +#include "heapManager.h" +#include "Filecode.h" +#include "GeneralServices.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_NB_MNREG_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the current DCT to work on. + * Should be called before accessing a certain DCT + * All data structures will be updated to point to the current DCT + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Dct - ID of the target DCT + * + */ + +VOID +MemNSwitchDCTNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ) +{ + ASSERT (NBPtr->DctCount > Dct); + // + // Set the DctCfgSel to new DCT + // + NBPtr->FamilySpecificHook[DCTSelectSwitch] (NBPtr, &Dct); + NBPtr->Dct = Dct; + NBPtr->MCTPtr->Dct = NBPtr->Dct; + NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]); + NBPtr->PsPtr = &(NBPtr->PSBlock[NBPtr->Dct]); + NBPtr->DctCachePtr = &(NBPtr->DctCache[NBPtr->Dct]); + + MemNSwitchChannelNb (NBPtr, NBPtr->Channel); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is used by families that use a separate DctCfgSel bit to + * select the current DCT which will be accessed by function 2. + * NOTE: This function must be called BEFORE the NBPtr->Dct variable is + * updated. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Dct - Pointer to ID of the target DCT + * + */ + +BOOLEAN +MemNDctCfgSelectUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *Dct + ) +{ + // + // Sanity check the current DctCfgSel setting + // + ASSERT (NBPtr->Dct == NBPtr->GetBitField (NBPtr, BFDctCfgSel)); + // + // Set the DctCfgSel to new DCT + // + NBPtr->SetBitField (NBPtr, BFDctCfgSel, *(UINT8*)Dct); + + return TRUE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the current channel to work on. + * Should be called before accessing a certain channel + * All data structures will be updated to point to the current channel + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Channel - ID of the target channel + * + */ + +VOID +MemNSwitchChannelNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ) +{ + NBPtr->Channel = Channel ? 1 : 0; + NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function gets a bit field from PCI register + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Field name + * + * @return Bit field value + */ + +UINT32 +MemNGetBitFieldNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BIT_FIELD_NAME FieldName + ) +{ + UINT32 Value; + + Value = NBPtr->MemNCmnGetSetFieldNb (NBPtr, 0, FieldName, 0); + return Value; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets a bit field from PCI register + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Field name + * @param[in] Field - Value to be stored in PCT register + * + */ + +VOID +MemNSetBitFieldNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + NBPtr->MemNCmnGetSetFieldNb (NBPtr, 1, FieldName, Field); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Check if bitfields of all enabled DCTs on a die have the expected value. Ignore + * DCTs that are disabled. + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Bit Field name + * @param[in] Field - Value to be checked + * + * @return TRUE - All enabled DCTs have the expected value on the bitfield. + * @return FALSE - Not all enabled DCTs have the expected value on the bitfield. + * + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNBrdcstCheckNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + UINT8 Dct; + UINT8 CurrentDCT; + Dct = NBPtr->Dct; + for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) { + MemNSwitchDCTNb (NBPtr, CurrentDCT); + if ((NBPtr->DCTPtr->Timings.DctMemSize != 0) && !((CurrentDCT == 1) && NBPtr->Ganged)) { + if (MemNGetBitFieldNb (NBPtr, FieldName) != Field) { + MemNSwitchDCTNb (NBPtr, Dct); + return FALSE; + } + } + } + MemNSwitchDCTNb (NBPtr, Dct); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Set bitfields of all enabled DCTs on a die to a value. Ignore + * DCTs that are disabled. + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Bit Field name + * @param[in] Field - Value to be set + * + * ---------------------------------------------------------------------------- + */ +VOID +MemNBrdcstSetNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + UINT8 Dct; + UINT8 CurrentDCT; + Dct = NBPtr->Dct; + for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) { + MemNSwitchDCTNb (NBPtr, CurrentDCT); + if ((NBPtr->DCTPtr->Timings.DctMemSize != 0) && !((CurrentDCT == 1) && NBPtr->Ganged)) { + MemNSetBitFieldNb (NBPtr, FieldName, Field); + } + } + MemNSwitchDCTNb (NBPtr, Dct); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Set bitfields of all DCTs regardless of if they are being enabled or not on a + * die to a value. + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Bit Field name + * @param[in] Field - Value to be set + * + * ---------------------------------------------------------------------------- + */ +VOID +MemNBrdcstSetUnConditionalNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + UINT8 Dct; + UINT8 CurrentDCT; + Dct = NBPtr->Dct; + for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) { + MemNSwitchDCTNb (NBPtr, CurrentDCT); + MemNSetBitFieldNb (NBPtr, FieldName, Field); + } + MemNSwitchDCTNb (NBPtr, Dct); +} + +/*-----------------------------------------------------------------------------*/ +/** + * This function calculates the memory channel index relative to the + * socket, taking the Die number, the Dct, and the channel. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Dct + * @param[in] Channel + * + */ +UINT8 +MemNGetSocketRelativeChannelNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct, + IN UINT8 Channel + ) +{ + return ((NBPtr->MCTPtr->DieId * NBPtr->DctCount) + Dct); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Poll a bitfield. If the bitfield does not get set to the target value within + * specified microseconds, it times out. + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Bit Field name + * @param[in] Field - Value to be set + * @param[in] MicroSecond - Number of microsecond to wait + * @param[in] IfBroadCast - Need to broadcast to both DCT or not + * + * ---------------------------------------------------------------------------- + */ +VOID +MemNPollBitFieldNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field, + IN UINT32 MicroSecond, + IN BOOLEAN IfBroadCast + ) +{ + BOOLEAN ErrorRecovery; + BOOLEAN IgnoreErr; + UINT8 ExcludeDCT; + UINT16 ExcludeChipSelMask; + UINT32 EventInfo; + UINT64 InitTSC; + UINT64 CurrentTSC; + UINT64 TimeOut; + AGESA_STATUS EventClass; + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + BOOLEAN TimeoutEn; + + MemPtr = NBPtr->MemPtr; + MCTPtr = NBPtr->MCTPtr; + ExcludeDCT = EXCLUDE_ALL_DCT; + ExcludeChipSelMask = EXCLUDE_ALL_CHIPSEL; + TimeoutEn = TRUE; + IDS_TIMEOUT_CTL (&TimeoutEn); + + CurrentTSC = 0; + LibAmdMsrRead (TSC, &InitTSC, &MemPtr->StdHeader); + TimeOut = InitTSC + ((UINT64) MicroSecond * MemPtr->TscRate); + + while ((CurrentTSC < TimeOut) || !TimeoutEn) { + if (IfBroadCast) { + if (NBPtr->BrdcstCheck (NBPtr, FieldName, Field)) { + break; + } + } else { + if (MemNGetBitFieldNb (NBPtr, FieldName) == Field) { + break; + } + } + LibAmdMsrRead (TSC, &CurrentTSC, &MemPtr->StdHeader); + } + + if ((CurrentTSC >= TimeOut) && TimeoutEn) { + ErrorRecovery = TRUE; + IgnoreErr = FALSE; + IDS_OPTION_HOOK (IDS_MEM_ERROR_RECOVERY, &ErrorRecovery, &MemPtr->StdHeader); + IDS_OPTION_HOOK (IDS_MEM_IGNORE_ERROR, &IgnoreErr, &MemPtr->StdHeader); + + // Default event class + // If different event class is needed in one entry, override it. + EventClass = AGESA_ERROR; + switch (FieldName) { + case BFDramEnabled: + EventInfo = MEM_ERROR_DRAM_ENABLED_TIME_OUT; + IDS_HDT_CONSOLE (MEM_FLOW, "\tDramEnabled bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFDctAccessDone: + EventInfo = MEM_ERROR_DCT_ACCESS_DONE_TIME_OUT; + ExcludeDCT = NBPtr->Dct; + IDS_HDT_CONSOLE (MEM_FLOW, "\tDctAccessDone bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFSendCtrlWord: + EventInfo = MEM_ERROR_SEND_CTRL_WORD_TIME_OUT; + ExcludeDCT = NBPtr->Dct; + IDS_HDT_CONSOLE (MEM_FLOW, "\tSendCtrlWord bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFPrefDramTrainMode: + EventInfo = MEM_ERROR_PREF_DRAM_TRAIN_MODE_TIME_OUT; + ExcludeDCT = NBPtr->Dct; + IDS_HDT_CONSOLE (MEM_FLOW, "\tPrefDramTrainMode bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFEnterSelfRef: + EventInfo = MEM_ERROR_ENTER_SELF_REF_TIME_OUT; + IDS_HDT_CONSOLE (MEM_FLOW, "\tEnterSelfRef bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFFreqChgInProg: + EventInfo = MEM_ERROR_FREQ_CHG_IN_PROG_TIME_OUT; + ExcludeDCT = NBPtr->Dct; + IDS_HDT_CONSOLE (MEM_FLOW, "\tFreqChgInProg bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFExitSelfRef: + EventInfo = MEM_ERROR_EXIT_SELF_REF_TIME_OUT; + IDS_HDT_CONSOLE (MEM_FLOW, "\tExitSelfRef bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFSendMrsCmd: + EventInfo = MEM_ERROR_SEND_MRS_CMD_TIME_OUT; + ExcludeDCT = NBPtr->Dct; + IDS_HDT_CONSOLE (MEM_FLOW, "\tSendMrsCmd bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFSendZQCmd: + EventInfo = MEM_ERROR_SEND_ZQ_CMD_TIME_OUT; + ExcludeDCT = NBPtr->Dct; + IDS_HDT_CONSOLE (MEM_FLOW, "\tSendZQCmd bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFDctExtraAccessDone: + EventInfo = MEM_ERROR_DCT_EXTRA_ACCESS_DONE_TIME_OUT; + ExcludeDCT = NBPtr->Dct; + IDS_HDT_CONSOLE (MEM_FLOW, "\tDctExtraAccessDone bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFMemClrBusy: + EventInfo = MEM_ERROR_MEM_CLR_BUSY_TIME_OUT; + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClrBusy bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFMemCleared: + EventInfo = MEM_ERROR_MEM_CLEARED_TIME_OUT; + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemCleared bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFFlushWr: + EventInfo = MEM_ERROR_FLUSH_WR_TIME_OUT; + ExcludeDCT = NBPtr->Dct; + IDS_HDT_CONSOLE (MEM_FLOW, "\tFlushWr bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + case BFCurNbPstate: + EventInfo = MEM_ERROR_NBPSTATE_TRANSITION_TIME_OUT; + IDS_HDT_CONSOLE (MEM_FLOW, "\tCurNBPstate bitfield times out.\n"); + ASSERT (ErrorRecovery || IgnoreErr); + break; + default: + EventClass = 0; + EventInfo = 0; + IDS_ERROR_TRAP; + } + + PutEventLog (EventClass, EventInfo, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &MemPtr->StdHeader); + SetMemError (EventClass, MCTPtr); + if (!MemPtr->ErrorHandling (MCTPtr, ExcludeDCT, ExcludeChipSelMask, &MemPtr->StdHeader)) { + ASSERT (FALSE); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function changes memory Pstate context + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] MemPstate - Target Memory Pstate + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +VOID +MemNChangeMemPStateContextNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSTATE MemPstate + ) +{ + UINT8 PSMasterChannel; + UINT8 Dct; + + ASSERT ((MemPstate == 0) || (MemPstate == 1)); + ASSERT (NBPtr->MemPstate == ((MemNGetBitFieldNb (NBPtr, BFMemPsSel) == 0) ? MEMORY_PSTATE0 : MEMORY_PSTATE1)); + + IDS_HDT_CONSOLE (MEM_SETREG, "\nGo to Memory Pstate Conext %d\n", MemPstate); + Dct = NBPtr->Dct; + MemNSwitchDCTNb (NBPtr, 0); + // Figure out what is the master channel + PSMasterChannel = (UINT8) (MemNGetBitFieldNb (NBPtr, BFPhyPSMasterChannel) >> 8); + + // Switch to the master channel to change PStateToAccess + // PStateToAccess is only effective on the master channel + MemNSwitchDCTNb (NBPtr, PSMasterChannel); + MemNSetBitFieldNb (NBPtr, BFMemPsSel, MemPstate); + MemNSetBitFieldNb (NBPtr, BFPStateToAccess, MemPstate << 8); + + NBPtr->MemPstate = (MemPstate == 0) ? MEMORY_PSTATE0 : MEMORY_PSTATE1; + MemNSwitchDCTNb (NBPtr, Dct); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function allocates buffer for NB register table + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Handle - Handle for heap allocation for NBRegTable + * + * @return TRUE - Successfully allocates buffer the first time + * @return FALSE - Buffer already allocated or fails to allocate + */ + +BOOLEAN +MemNAllocateNBRegTableNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN NB_REG_TAB_HANDLE Handle + ) +{ + ALLOCATE_HEAP_PARAMS AllocHeapParams; + LOCATE_HEAP_PTR LocHeap; + + // If NBRegTable for this family exists, use it + LocHeap.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_NB_REG_TABLE, Handle, 0, 0); + if (HeapLocateBuffer (&LocHeap, &(NBPtr->MemPtr->StdHeader)) == AGESA_SUCCESS) { + NBPtr->NBRegTable = (TSEFO *) LocHeap.BufferPtr; + return FALSE; + } + + // Allocate new buffer for NBRegTable if it has not been allocated + AllocHeapParams.RequestedBufferSize = sizeof (TSEFO) * BFEndOfList; + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_NB_REG_TABLE, Handle, 0, 0); + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (AGESA_SUCCESS != HeapAllocateBuffer (&AllocHeapParams, &(NBPtr->MemPtr->StdHeader))) { + ASSERT(FALSE); // NB and Tech Block Heap allocate error + return FALSE; + } + NBPtr->NBRegTable = (TSEFO *)AllocHeapParams.BufferPtr; + return TRUE; +} + +/*----------------------------------------------------------------------------- + * + * + * This function is an empty function used to intialize FamilySpecificHook array + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE - always + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNDefaultFamilyHookNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mntrain3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mntrain3.c new file mode 100644 index 0000000000..f1b53d70f2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/mntrain3.c @@ -0,0 +1,243 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mntrain3.c + * + * Common Northbridge function for training flow for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_NB_MNTRAIN3_FILECODE +/* features */ +#include "mftds.h" +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +STATIC +MemNHwWlPart2Nb ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern MEM_FEAT_TRAIN_SEQ memTrainSequenceDDR3[]; +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initiates DQS training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +BOOLEAN +MemNDQSTiming3Nb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 i; + BOOLEAN Retval; + TechPtr = NBPtr->TechPtr; + Retval = TRUE; + if (TechPtr->NBPtr->MCTPtr->NodeMemSize) { + //Execute Technology specific training features + i = 0; + while (memTrainSequenceDDR3[i].TrainingSequenceEnabled != 0) { + if (memTrainSequenceDDR3[i].TrainingSequenceEnabled (NBPtr)) { + NBPtr->TrainingSequenceIndex = i; + Retval = memTrainSequenceDDR3[i].TrainingSequence (NBPtr); + break; + } + i++; + } + } + return Retval; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initiates DQS training for Server NB + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +BOOLEAN +memNSequenceDDR3Nb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + UINT8 i; + TechPtr = NBPtr->TechPtr; + i = NBPtr->TrainingSequenceIndex; + if (TechPtr->NBPtr->MCTPtr->NodeMemSize != 0) { + AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDQSTraining, &NBPtr->MemPtr->StdHeader); + IDS_HDT_CONSOLE (MEM_FLOW, "\nCalling out to Platform BIOS...\n"); + if (AgesaHookBeforeDQSTraining (NBPtr->MCTPtr->SocketId, TechPtr->NBPtr->MemPtr) == AGESA_SUCCESS) { + // Right now we do not have anything to do if the callout is implemented + } + AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDQSTraining, &NBPtr->MemPtr->StdHeader); + //Execute Technology specific training features + if (memTrainSequenceDDR3[i].MemTechFeatBlock->EnterHardwareTraining (TechPtr)) { + TechPtr->TechnologySpecificHook[LrdimmBuf2DramTrain] (TechPtr, NULL); + if (memTrainSequenceDDR3[i].MemTechFeatBlock->SwWLTraining (TechPtr)) { + MemFInitTableDrive (NBPtr, MTAfterSwWLTrn); + if (memTrainSequenceDDR3[i].MemTechFeatBlock->HwBasedWLTrainingPart1 (TechPtr)) { + MemFInitTableDrive (NBPtr, MTAfterHwWLTrnP1); + if (memTrainSequenceDDR3[i].MemTechFeatBlock->HwBasedDQSReceiverEnableTrainingPart1 (TechPtr)) { + MemFInitTableDrive (NBPtr, MTAfterHwRxEnTrnP1); + // If target speed is higher than start-up speed, do frequency change and second pass of WL + do { + if (MemNHwWlPart2Nb (TechPtr)) { + if (memTrainSequenceDDR3[i].MemTechFeatBlock->TrainExitHwTrn (TechPtr)) { + IDS_OPTION_HOOK (IDS_PHY_DLL_STANDBY_CTRL, NBPtr, &(NBPtr->MemPtr->StdHeader)); + if (memTrainSequenceDDR3[i].MemTechFeatBlock->NonOptimizedSWDQSRecEnTrainingPart1 (TechPtr)) { + if (memTrainSequenceDDR3[i].MemTechFeatBlock->OptimizedSwDqsRecEnTrainingPart1 (TechPtr)) { + MemFInitTableDrive (NBPtr, MTAfterSwRxEnTrn); + if (memTrainSequenceDDR3[i].MemTechFeatBlock->NonOptimizedSRdWrPosTraining (TechPtr)) { + if (memTrainSequenceDDR3[i].MemTechFeatBlock->OptimizedSRdWrPosTraining (TechPtr)) { + MemFInitTableDrive (NBPtr, MTAfterDqsRwPosTrn); + if (!NBPtr->FamilySpecificHook[MemPstateStageChange] (NBPtr, NULL)) { + continue; + } + if (NBPtr->Execute1dMaxRdLatTraining) { + do { + if (memTrainSequenceDDR3[i].MemTechFeatBlock->MaxRdLatencyTraining (TechPtr)) { + MemFInitTableDrive (NBPtr, MTAfterMaxRdLatTrn); + } + } while (NBPtr->ChangeNbFrequency (NBPtr)); + } else { + // If not running MRL training, set everything back for 2D Training + memTrainSequenceDDR3[i].MemTechFeatBlock->TrainExitHwTrn (TechPtr); + } + } + } + } + } + } + } + } while (NBPtr->MemPstateStage == MEMORY_PSTATE_2ND_STAGE); + } + } + } + } + MemTMarkTrainFail (TechPtr); + } + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes HW WL at multiple speeds + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @return TRUE - No errors occurred + * FALSE - errors occurred + */ + +BOOLEAN +STATIC +MemNHwWlPart2Nb ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + BOOLEAN retVal; + UINT8 i; + retVal = TRUE; + i = TechPtr->NBPtr->TrainingSequenceIndex; + while ((TechPtr->NBPtr->DCTPtr->Timings.TargetSpeed > TechPtr->NBPtr->DCTPtr->Timings.Speed) && (TechPtr->NBPtr->MemPstateStage != MEMORY_PSTATE_1ST_STAGE)) { + TechPtr->PrevSpeed = TechPtr->NBPtr->DCTPtr->Timings.Speed; + if (TechPtr->NBPtr->RampUpFrequency (TechPtr->NBPtr)) { + TechPtr->TechnologySpecificHook[LrdimmBuf2DramTrain] (TechPtr, NULL); + if (!memTrainSequenceDDR3[i].MemTechFeatBlock->HwBasedWLTrainingPart2 (TechPtr)) { + retVal = FALSE; + break; + } + MemFInitTableDrive (TechPtr->NBPtr, MTAfterHwWLTrnP2); + if (!memTrainSequenceDDR3[i].MemTechFeatBlock->HwBasedDQSReceiverEnableTrainingPart2 (TechPtr)) { + retVal = FALSE; + break; + } + MemFInitTableDrive (TechPtr->NBPtr, MTAfterHwRxEnTrnP2); + } else { + retVal = FALSE; + break; + } + } + return retVal; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/FT3/mpSkbft3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/FT3/mpSkbft3.c new file mode 100644 index 0000000000..f04c4a3e43 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/FT3/mpSkbft3.c @@ -0,0 +1,130 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mpSkbfT3.c + * + * Platform specific settings for KB DDR3 SO-DIMM FT3 system + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps/KB/FT3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "mport.h" +#include "ma.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "mm.h" +#include "mn.h" +#include "mp.h" +#include "mu.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_PS_KB_FT3_MPSKBFT3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define SOCKET_FT3_KB 0 + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ +// +// MemClkDis +// +STATIC CONST UINT8 ROMDATA KBSODdr3CLKDisFT3[] = {0xFF, 0xFF, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00}; +CONST PSC_TBL_ENTRY KBClkDisMapEntSOFT3 = { + {PSCFG_CLKDIS, SODIMM_TYPE + UDIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, SOCKET_FT3_KB, DDR3_TECHNOLOGY}, + sizeof (KBSODdr3CLKDisFT3) / sizeof (UINT8), + (VOID *)&KBSODdr3CLKDisFT3 +}; + +// +// ODT tri-state +// +STATIC CONST UINT8 ROMDATA KBSODdr3ODTTriFT3[] = {0xFF, 0xFF, 0x00, 0x00}; +CONST PSC_TBL_ENTRY KBSODdr3ODTTriEntFT3 = { + {PSCFG_ODTTRI, SODIMM_TYPE + UDIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, SOCKET_FT3_KB, DDR3_TECHNOLOGY}, + sizeof (KBSODdr3ODTTriFT3) / sizeof (UINT8), + (VOID *)&KBSODdr3ODTTriFT3 +}; + +// +// ChipSel tri-state +// +STATIC CONST UINT8 ROMDATA KBSODdr3CSTriFT3[] = {0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +CONST PSC_TBL_ENTRY KBSODdr3CSTriEntFT3 = { + {PSCFG_CSTRI, SODIMM_TYPE + UDIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, SOCKET_FT3_KB, DDR3_TECHNOLOGY}, + sizeof (KBSODdr3CSTriFT3) / sizeof (UINT8), + (VOID *)&KBSODdr3CSTriFT3 +}; + +// 2D training configuratrions +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, 2D +// +STATIC CONST PSCFG_S2D_ENTRY KBUDdr3S2DFT3[] = { + // DimmPerCh,Frequency,VDDIO,DIMM0,DIMM1,DIMM2,Enable2DTraining + {1, ANY_SPEED, VOLT_ALL, NP + DIMM_SR + DIMM_DR, NP, NP, 1}, + {2, ANY_SPEED, VOLT_ALL, NP + DIMM_SR + DIMM_DR, NP + DIMM_SR + DIMM_DR, NP, 1} + }; +CONST PSC_TBL_ENTRY S2DTblEntUFT3 = { + {PSCFG_S2D, UDIMM_TYPE + SODIMM_TYPE + SODWN_SODIMM_TYPE, NOD_DONT_CARE, {AMD_FAMILY_16_KB, AMD_F16_ALL}, SOCKET_FT3_KB, DDR3_TECHNOLOGY}, + sizeof (KBUDdr3S2DFT3) / sizeof (PSCFG_S2D_ENTRY), + (VOID *)&KBUDdr3S2DFT3 +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpSkb3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpSkb3.c new file mode 100644 index 0000000000..76b85e5420 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpSkb3.c @@ -0,0 +1,345 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mpSkb.c + * + * Platform specific settings for KB DDR3 SO-DIMM system + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps/KB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "mport.h" +#include "ma.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "mm.h" +#include "mn.h" +#include "mp.h" +#include "mu.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_PS_KB_MPSKB3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ +// Slow mode, POdtOff, Address timing and Output drive compensation for SODIMM ONLY configuration +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, SlowMode, AddTmgCtl, ODC, POdtOff +// +STATIC CONST PSCFG_SAO_ENTRY KBSODdr3SAO[] = { + {_1DIMM, DDR667 + DDR800, VOLT_ALL, DIMM_SR + DIMM_DR, NP, NP, 0, 0x00000000, 0x00002222, 0}, + {_1DIMM, DDR1066, VOLT_ALL, DIMM_SR, NP, NP, 0, 0x003D3D3D, 0x10002222, 0}, + {_1DIMM, DDR1066, VOLT_ALL, DIMM_DR, NP, NP, 0, 0x00000000, 0x10002222, 0}, + {_1DIMM, DDR1333, VOLT_ALL, DIMM_SR, NP, NP, 0, 0x003D3D3D, 0x20112222, 0}, + {_1DIMM, DDR1333, VOLT_ALL, DIMM_DR, NP, NP, 0, 0x00003D3D, 0x20112222, 0}, + {_1DIMM, DDR1600, V1_5 + V1_35, DIMM_SR, NP, NP, 0, 0x003C3C3C, 0x30332222, 0}, + {_1DIMM, DDR1600, V1_5 + V1_35, DIMM_DR, NP, NP, 1, 0x00003C3C, 0x30332222, 0}, + {_1DIMM, DDR1866, V1_5, DIMM_SR, NP, NP, 0, 0x003C3C3C, 0x30332222, 0}, + {_1DIMM, DDR1866, V1_5, DIMM_DR, NP, NP, 1, 0x00003C3C, 0x30332222, 0}, + {_2DIMM, DDR667 + DDR800, VOLT_ALL, NP, DIMM_SR + DIMM_DR, NP, 0, 0x00000000, 0x00002222, 0}, + {_2DIMM, DDR667, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x10222323, 0}, + {_2DIMM, DDR800, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x20222323, 0}, + {_2DIMM, DDR1066, VOLT_ALL, NP, DIMM_SR, NP, 0, 0x003D3D3D, 0x10002222, 0}, + {_2DIMM, DDR1066, VOLT_ALL, NP, DIMM_DR, NP, 0, 0x00000000, 0x10002222, 0}, + {_2DIMM, DDR1066, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x30222323, 0}, + {_2DIMM, DDR1333, VOLT_ALL, NP, DIMM_SR, NP, 0, 0x003D3D3D, 0x20112222, 0}, + {_2DIMM, DDR1333, VOLT_ALL, NP, DIMM_DR, NP, 0, 0x00003D3D, 0x20112222, 0}, + {_2DIMM, DDR1333, V1_5 + V1_35, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x30222323, 0}, + {_2DIMM, DDR1333, V1_25, DIMM_SR, DIMM_SR, NP, 1, 0x00000000, 0x30222323, 0}, + {_2DIMM, DDR1600, V1_5 + V1_35, NP, DIMM_SR, NP, 0, 0x003C3C3C, 0x30332222, 0}, + {_2DIMM, DDR1600, V1_5 + V1_35, NP, DIMM_DR, NP, 1, 0x00003C3C, 0x30332222, 0}, + {_2DIMM, DDR1600, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x30222323, 0}, + {_2DIMM, DDR1600, V1_35, DIMM_SR, DIMM_SR, NP, 1, 0x00000000, 0x30222323, 0}, + {_2DIMM, DDR1866, V1_5, NP, DIMM_SR, NP, 0, 0x003C3C3C, 0x30332222, 0}, + {_2DIMM, DDR1866, V1_5, NP, DIMM_DR, NP, 1, 0x00003C3C, 0x30332222, 0}, +}; +CONST PSC_TBL_ENTRY KBSAOTblEntSO3 = { + {PSCFG_SAO, SODIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBSODdr3SAO) / sizeof (PSCFG_SAO_ENTRY), + (VOID *)&KBSODdr3SAO +}; + +// Slow mode, POdtOff, Address timing and Output drive compensation for SODIMM plus Solder-down DRAM configuration +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, SlowMode, AddTmgCtl, ODC, POdtOff +// +STATIC CONST PSCFG_SAO_ENTRY KBSoDwnPlusSODIMMDdr3SAO[] = { + {_1DIMM, DDR667 + DDR800, VOLT_ALL, NP, DIMM_SR + DIMM_DR, NP, 0, 0x00000000, 0x00002222, 0}, + {_1DIMM, DDR667, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x10222323, 0}, + {_1DIMM, DDR800, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x20222323, 0}, + {_1DIMM, DDR1066, VOLT_ALL, NP, DIMM_SR, NP, 0, 0x003D3D3D, 0x10002222, 0}, + {_1DIMM, DDR1066, VOLT_ALL, NP, DIMM_DR, NP, 0, 0x00000000, 0x10002222, 0}, + {_1DIMM, DDR1066, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x30222323, 0}, + {_1DIMM, DDR1333, V1_5 + V1_35, NP, DIMM_SR, NP, 0, 0x003D3D3D, 0x20112222, 0}, + {_1DIMM, DDR1333, V1_5 + V1_35, NP, DIMM_DR, NP, 0, 0x00003D3D, 0x20112222, 0}, + {_1DIMM, DDR1333, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x30222323, 0}, + {_1DIMM, DDR1333, V1_35, DIMM_SR, DIMM_SR, NP, 1, 0x00000000, 0x30222323, 0}, +}; +CONST PSC_TBL_ENTRY KBSAOTblEntSoDwnPlusSODIMM3 = { + {PSCFG_SAO, SODWN_SODIMM_TYPE, _1DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBSoDwnPlusSODIMMDdr3SAO) / sizeof (PSCFG_SAO_ENTRY), + (VOID *)&KBSoDwnPlusSODIMMDdr3SAO +}; + +// Slow mode, POdtOff, Address timing and Output drive compensation for Solder-down DRAM ONLY configuration +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, SlowMode, AddTmgCtl, ODC, POdtOff +// +STATIC CONST PSCFG_SAO_ENTRY KBSoDwnDdr3SAO[] = { + {_DIMM_NONE, DDR667, VOLT_ALL, DIMM_SR + DIMM_DR, NP, NP, 0, 0x00000000, 0x00000000, 1}, + {_DIMM_NONE, DDR800, VOLT_ALL, DIMM_SR + DIMM_DR, NP, NP, 0, 0x00000000, 0x00000000, 0}, + {_DIMM_NONE, DDR1066, VOLT_ALL, DIMM_SR, NP, NP, 0, 0x003D3D3D, 0x10000000, 0}, + {_DIMM_NONE, DDR1066, VOLT_ALL, DIMM_DR, NP, NP, 0, 0x00000000, 0x10000000, 0}, + {_DIMM_NONE, DDR1333, VOLT_ALL, DIMM_SR, NP, NP, 0, 0x003D3D3D, 0x20000000, 0}, + {_DIMM_NONE, DDR1333, VOLT_ALL, DIMM_DR, NP, NP, 0, 0x00003D3D, 0x20110000, 0}, + {_DIMM_NONE, DDR1600, V1_5 + V1_35, DIMM_SR, NP, NP, 0, 0x003C3C3C, 0x30110000, 0}, + {_DIMM_NONE, DDR1600, V1_5 + V1_35, DIMM_DR, NP, NP, 1, 0x00003C3C, 0x30110000, 0}, + {_DIMM_NONE, DDR1866, V1_5, DIMM_SR, NP, NP, 0, 0x003C3C3C, 0x30110000, 0}, + {_DIMM_NONE, DDR1866, V1_5, DIMM_DR, NP, NP, 1, 0x00003C3C, 0x30110000, 0}, +}; +CONST PSC_TBL_ENTRY KBSAOTblEntSoDwn3 = { + {PSCFG_SAO, SODWN_SODIMM_TYPE, _DIMM_NONE, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBSoDwnDdr3SAO) / sizeof (PSCFG_SAO_ENTRY), + (VOID *)&KBSoDwnDdr3SAO +}; + +// Dram Term and Dynamic Dram Term for SODIMM ONLY configuration +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, Dimm, Rank, RttNom, RttWr +// +// RttNom: +// 0 On die termination disabled +// 1 60ohms +// 2 120ohms +// 3 40ohms +// 4 20ohms +// 5 30ohms +// RttWr: +// 0 Dynamic termination for writes disabled. +// 1 60ohms +// 2 120ohms +STATIC CONST PSCFG_RTT_ENTRY KBDramTermSODIMM3[] = { + {_1DIMM, DDR667 + DDR800 + DDR1066, VOLT_ALL, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 2, 0}, + {_1DIMM, DDR1333, VOLT_ALL, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_1DIMM, DDR1600, V1_5 + V1_35, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_1DIMM, DDR1866, V1_5, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_2DIMM, DDR667 + DDR800 + DDR1066, VOLT_ALL, NP, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 2, 0}, + {_2DIMM, DDR667 + DDR800, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 3, 2}, + {_2DIMM, DDR1066, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 5, 2}, + {_2DIMM, DDR1333, VOLT_ALL, NP, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_2DIMM, DDR1333, V1_5 + V1_35, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 5, 2}, + {_2DIMM, DDR1333, V1_25, DIMM_SR, DIMM_SR, NP, DIMM_SR + DIMM_DR, R0 + R1, 5, 2}, + {_2DIMM, DDR1600, V1_5 + V1_35, NP, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_2DIMM, DDR1600, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 4, 1}, + {_2DIMM, DDR1600, V1_35, DIMM_SR, DIMM_SR, NP, DIMM_SR + DIMM_DR, R0 + R1, 4, 1}, + {_2DIMM, DDR1866, V1_5, NP, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, +}; +CONST PSC_TBL_ENTRY KBDramTermTblEntSO3 = { + {PSCFG_RTT, SODIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBDramTermSODIMM3) / sizeof (PSCFG_RTT_ENTRY), + (VOID *)&KBDramTermSODIMM3 +}; + +// Dram Term and Dynamic Dram Term for SODIMM plus Solder-down DRAM configuration +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, Dimm, Rank, RttNom, RttWr +// +// RttNom: +// 0 On die termination disabled +// 1 60ohms +// 2 120ohms +// 3 40ohms +// 4 20ohms +// 5 30ohms +// RttWr: +// 0 Dynamic termination for writes disabled. +// 1 60ohms +// 2 120ohms +STATIC CONST PSCFG_RTT_ENTRY KBDramTermSoDwnPlusSODIMM3[] = { + {_1DIMM, DDR667 + DDR800 + DDR1066, VOLT_ALL, NP, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 2, 0}, + {_1DIMM, DDR667 + DDR800, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 3, 2}, + {_1DIMM, DDR1066, VOLT_ALL, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 5, 2}, + {_1DIMM, DDR1333, V1_5 + V1_35, NP, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_1DIMM, DDR1333, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 5, 2}, + {_1DIMM, DDR1333, V1_35, DIMM_SR, DIMM_SR, NP, DIMM_SR + DIMM_DR, R0 + R1, 5, 2}, +}; +CONST PSC_TBL_ENTRY KBDramTermTblEntSoDwnPlusSODIMM3 = { + {PSCFG_RTT, SODWN_SODIMM_TYPE, _1DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBDramTermSoDwnPlusSODIMM3) / sizeof (PSCFG_RTT_ENTRY), + (VOID *)&KBDramTermSoDwnPlusSODIMM3 +}; + +// Dram Term and Dynamic Dram Term for Solder-down DRAM ONLY configuration +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, Dimm, Rank, RttNom, RttWr +// +// RttNom: +// 0 On die termination disabled +// 1 60ohms +// 2 120ohms +// 3 40ohms +// 4 20ohms +// 5 30ohms +// RttWr: +// 0 Dynamic termination for writes disabled. +// 1 60ohms +// 2 120ohms +STATIC CONST PSCFG_RTT_ENTRY KBDramTermSoDwn3[] = { + {_DIMM_NONE, DDR667, VOLT_ALL, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 0, 0}, + {_DIMM_NONE, DDR800 + DDR1066, VOLT_ALL, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 2, 0}, + {_DIMM_NONE, DDR1333, VOLT_ALL, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_DIMM_NONE, DDR1600, V1_5 + V1_35, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_DIMM_NONE, DDR1866, V1_5, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, +}; +CONST PSC_TBL_ENTRY KBDramTermTblEntSoDwn3 = { + {PSCFG_RTT, SODWN_SODIMM_TYPE, _DIMM_NONE, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBDramTermSoDwn3) / sizeof (PSCFG_RTT_ENTRY), + (VOID *)&KBDramTermSoDwn3 +}; + +// Max Freq. for SODIMM ONLY <6-layer Motherboard Design> configuration +// Format : +// DimmPerCh, Dimms, SR, DR, QR, Speed1_5V, Speed1_35V, Speed1_25V +// +STATIC CONST PSCFG_MAXFREQ_ENTRY ROMDATA KBMaxFreqSODIMM6L[] = { + {{_1DIMM, 1, 1, 0, 0, DDR1600_FREQUENCY, DDR1600_FREQUENCY, DDR1333_FREQUENCY}}, + {{_1DIMM, 1, 0, 1, 0, DDR1600_FREQUENCY, DDR1600_FREQUENCY, DDR1333_FREQUENCY}}, + {{_2DIMM, 1, 1, 0, 0, DDR1600_FREQUENCY, DDR1600_FREQUENCY, DDR1333_FREQUENCY}}, + {{_2DIMM, 1, 0, 1, 0, DDR1600_FREQUENCY, DDR1600_FREQUENCY, DDR1333_FREQUENCY}}, + {{_2DIMM, 2, 2, 0, 0, DDR1600_FREQUENCY, DDR1333_FREQUENCY, DDR1333_FREQUENCY}}, + {{_2DIMM, 2, 1, 1, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_2DIMM, 2, 0, 2, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, +}; +CONST PSC_TBL_ENTRY KBMaxFreqTblEntSO6L = { + {PSCFG_MAXFREQ, SODIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBMaxFreqSODIMM6L) / sizeof (PSCFG_MAXFREQ_ENTRY), + (VOID *)&KBMaxFreqSODIMM6L +}; + +// Max Freq. for SODIMM ONLY <4-layer Motherboard Design> configuration +// Format : +// DimmPerCh, Dimms, SR, DR, QR, Speed1_5V, Speed1_35V, Speed1_25V +// +STATIC CONST PSCFG_MAXFREQ_ENTRY ROMDATA KBMaxFreqSODIMM4L[] = { + {{_1DIMM, 1, 1, 0, 0, DDR1600_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 1, 0, 1, 0, DDR1600_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_2DIMM, 1, 1, 0, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_2DIMM, 1, 0, 1, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_2DIMM, 2, 2, 0, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_2DIMM, 2, 1, 1, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_2DIMM, 2, 0, 2, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, +}; +CONST PSC_TBL_ENTRY KBMaxFreqTblEntSO4L = { + {PSCFG_MAXFREQ, SODIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBMaxFreqSODIMM4L) / sizeof (PSCFG_MAXFREQ_ENTRY), + (VOID *)&KBMaxFreqSODIMM4L +}; + +// Max Freq. for SODIMM plus Solder-down DRAM <6-layer Motherboard Design> configuration +// Format : +// DimmPerCh, Dimms, SR, DR, QR, Speed1_5V, Speed1_35V, Speed1_25V +// +STATIC CONST PSCFG_MAXFREQ_ENTRY ROMDATA KBMaxFreqSoDwnPlusSODIMM6L[] = { + {{_1DIMM, 1, 1, 0, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 1, 0, 1, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 2, 2, 0, 0, DDR1333_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 2, 1, 1, 0, DDR1066_FREQUENCY, DDR1066_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 2, 0, 2, 0, DDR1066_FREQUENCY, DDR1066_FREQUENCY, DDR1066_FREQUENCY}}, +}; +CONST PSC_TBL_ENTRY KBMaxFreqTblEntSoDwnPlusSODIMM6L = { + {PSCFG_MAXFREQ, SODWN_SODIMM_TYPE, _1DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBMaxFreqSoDwnPlusSODIMM6L) / sizeof (PSCFG_MAXFREQ_ENTRY), + (VOID *)&KBMaxFreqSoDwnPlusSODIMM6L +}; + +// Max Freq. for SODIMM plus Solder-down DRAM <4-layer Motherboard Design> configuration +// Format : +// DimmPerCh, Dimms, SR, DR, QR, Speed1_5V, Speed1_35V, Speed1_25V +// +STATIC CONST PSCFG_MAXFREQ_ENTRY ROMDATA KBMaxFreqSoDwnPlusSODIMM4L[] = { + {{_1DIMM, 1, 1, 0, 0, DDR1066_FREQUENCY, DDR1066_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 1, 0, 1, 0, DDR1066_FREQUENCY, DDR1066_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 2, 2, 0, 0, DDR1066_FREQUENCY, DDR1066_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 2, 1, 1, 0, DDR1066_FREQUENCY, DDR1066_FREQUENCY, DDR1066_FREQUENCY}}, + {{_1DIMM, 2, 0, 2, 0, DDR1066_FREQUENCY, DDR1066_FREQUENCY, DDR1066_FREQUENCY}}, +}; +CONST PSC_TBL_ENTRY KBMaxFreqTblEntSoDwnPlusSODIMM4L = { + {PSCFG_MAXFREQ, SODWN_SODIMM_TYPE, _1DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBMaxFreqSoDwnPlusSODIMM4L) / sizeof (PSCFG_MAXFREQ_ENTRY), + (VOID *)&KBMaxFreqSoDwnPlusSODIMM4L +}; + +// Max Freq. for Solder-down DRAM ONLY <4-layer/6-layer Motherboard Design> configuration +// Format : +// DimmPerCh, Dimms, SR, DR, QR, Speed1_5V, Speed1_35V, Speed1_25V +// +STATIC CONST PSCFG_MAXFREQ_ENTRY ROMDATA KBMaxFreqSoDwn[] = { + {{_DIMM_NONE, 1, 1, 0, 0, DDR1600_FREQUENCY, DDR1600_FREQUENCY, DDR1066_FREQUENCY}}, + {{_DIMM_NONE, 1, 0, 1, 0, DDR1600_FREQUENCY, DDR1600_FREQUENCY, DDR1066_FREQUENCY}}, +}; +CONST PSC_TBL_ENTRY KBMaxFreqTblEntSoDwn = { + {PSCFG_MAXFREQ, SODWN_SODIMM_TYPE, _DIMM_NONE, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBMaxFreqSoDwn) / sizeof (PSCFG_MAXFREQ_ENTRY), + (VOID *)&KBMaxFreqSoDwn +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpUkb3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpUkb3.c new file mode 100644 index 0000000000..c18af0a6c7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpUkb3.c @@ -0,0 +1,180 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mpUkb3.c + * + * Platform specific settings for KB DDR3 UDIMM system + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps/KB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "PlatformMemoryConfiguration.h" +#include "mport.h" +#include "ma.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "mm.h" +#include "mn.h" +#include "mp.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_PS_KB_MPUKB3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ +// Slow mode, POdtOff, Address timing and Output drive compensation +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, SlowMode, AddTmgCtl, ODC, POdtOff +// +STATIC CONST PSCFG_SAO_ENTRY KBUDdr3SAO[] = { + {_1DIMM, DDR667 + DDR800, V1_5, DIMM_SR + DIMM_DR, NP, NP, 0, 0x00000000, 0x00002222, 0}, + {_1DIMM, DDR1066, V1_5, DIMM_SR, NP, NP, 0, 0x003D3D3D, 0x10002222, 0}, + {_1DIMM, DDR1066, V1_5, DIMM_DR, NP, NP, 0, 0x00000000, 0x10002222, 0}, + {_1DIMM, DDR1333, V1_5, DIMM_SR, NP, NP, 0, 0x003D3D3D, 0x20112222, 0}, + {_1DIMM, DDR1333, V1_5, DIMM_DR, NP, NP, 0, 0x00003D3D, 0x20112222, 0}, + {_1DIMM, DDR1600 + DDR1866, V1_5, DIMM_SR, NP, NP, 0, 0x003C3C3C, 0x30332222, 0}, + {_1DIMM, DDR1600 + DDR1866, V1_5, DIMM_DR, NP, NP, 1, 0x00003C3C, 0x30332222, 0}, + {_2DIMM, DDR667 + DDR800, V1_5, NP, DIMM_SR + DIMM_DR, NP, 0, 0x00000000, 0x00002222, 0}, + {_2DIMM, DDR667, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x10222323, 0}, + {_2DIMM, DDR800, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x20222323, 0}, + {_2DIMM, DDR1066, V1_5, NP, DIMM_SR, NP, 0, 0x003D3D3D, 0x10002222, 0}, + {_2DIMM, DDR1066, V1_5, NP, DIMM_DR, NP, 0, 0x00000000, 0x10002222, 0}, + {_2DIMM, DDR1066 + DDR1333 + DDR1600, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, 1, 0x00000000, 0x30222323, 0}, + {_2DIMM, DDR1333, V1_5, NP, DIMM_SR, NP, 0, 0x003D3D3D, 0x20112222, 0}, + {_2DIMM, DDR1333, V1_5, NP, DIMM_DR, NP, 0, 0x00003D3D, 0x20112222, 0}, + {_2DIMM, DDR1600 + DDR1866, V1_5, NP, DIMM_SR, NP, 0, 0x003C3C3C, 0x30332222, 0}, + {_2DIMM, DDR1600 + DDR1866, V1_5, NP, DIMM_DR, NP, 1, 0x00003C3C, 0x30332222, 0}, +}; +CONST PSC_TBL_ENTRY KBSAOTblEntU3 = { + {PSCFG_SAO, UDIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBUDdr3SAO) / sizeof (PSCFG_SAO_ENTRY), + (VOID *)&KBUDdr3SAO +}; + +// Dram Term and Dynamic Dram Term +// Format : +// DimmPerCh, DDRrate, VDDIO, Dimm0, Dimm1, Dimm2, Dimm, Rank, RttNom, RttWr +// +// RttNom: +// 0 On die termination disabled +// 1 60ohms +// 2 120ohms +// 3 40ohms +// 4 20ohms +// 5 30ohms +// RttWr: +// 0 Dynamic termination for writes disabled. +// 1 60ohms +// 2 120ohms +STATIC CONST PSCFG_RTT_ENTRY DramTermKBUDIMM[] = { + {_1DIMM, DDR667 + DDR800 + DDR1066, V1_5, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 2, 0}, + {_1DIMM, DDR1333 + DDR1600 + DDR1866, V1_5, DIMM_SR + DIMM_DR, NP, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_2DIMM, DDR667 + DDR800 + DDR1066, V1_5, NP, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 2, 0}, + {_2DIMM, DDR667 + DDR800, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 3, 2}, + {_2DIMM, DDR1066 + DDR1333, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 5, 2}, + {_2DIMM, DDR1333 + DDR1600 + DDR1866, V1_5, NP, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 1, 0}, + {_2DIMM, DDR1600, V1_5, DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, NP, DIMM_SR + DIMM_DR, R0 + R1, 4, 1}, +}; +CONST PSC_TBL_ENTRY KBDramTermTblEntU = { + {PSCFG_RTT, UDIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (DramTermKBUDIMM) / sizeof (PSCFG_RTT_ENTRY), + (VOID *)&DramTermKBUDIMM +}; + +// Max Freq. for UDIMM <6-layer Motherboard Design> configuration +// Format : +// DimmPerCh, Dimms, SR, DR, QR, Speed1_5V, Speed1_35V, Speed1_25V +// +STATIC CONST PSCFG_MAXFREQ_ENTRY ROMDATA MaxFreqKBUDIMM6L[] = { + {{_1DIMM, 1, 1, 0, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_1DIMM, 1, 0, 1, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 1, 1, 0, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 1, 0, 1, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 2, 2, 0, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 2, 1, 1, 0, DDR1333_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 2, 0, 2, 0, DDR1333_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, +}; +CONST PSC_TBL_ENTRY KBMaxFreqTblEntU6L = { + {PSCFG_MAXFREQ, UDIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (MaxFreqKBUDIMM6L) / sizeof (PSCFG_MAXFREQ_ENTRY), + (VOID *)&MaxFreqKBUDIMM6L +}; + +// Max Freq. for UDIMM <4-layer Motherboard Design> configuration +// Format : +// DimmPerCh, Dimms, SR, DR, QR, Speed1_5V, Speed1_35V, Speed1_25V +// +STATIC CONST PSCFG_MAXFREQ_ENTRY ROMDATA MaxFreqKBUDIMM4L[] = { + {{_1DIMM, 1, 1, 0, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_1DIMM, 1, 0, 1, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 1, 1, 0, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 1, 0, 1, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 2, 2, 0, 0, DDR1600_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 2, 1, 1, 0, DDR1333_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, + {{_2DIMM, 2, 0, 2, 0, DDR1333_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY, UNSUPPORTED_DDR_FREQUENCY}}, +}; +CONST PSC_TBL_ENTRY KBMaxFreqTblEntU4L = { + {PSCFG_MAXFREQ, UDIMM_TYPE, _1DIMM + _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (MaxFreqKBUDIMM4L) / sizeof (PSCFG_MAXFREQ_ENTRY), + (VOID *)&MaxFreqKBUDIMM4L +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpkb3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpkb3.c new file mode 100644 index 0000000000..2e4a2ee67d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpkb3.c @@ -0,0 +1,172 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mpkb3.c + * + * Platform specific settings for KB + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps/KB) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "mport.h" +#include "ma.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "mm.h" +#include "mn.h" +#include "mp.h" +#include "Filecode.h" + +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + + + +#define FILECODE PROC_MEM_PS_KB_MPKB3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ +// +// Common tables of KB platform specific configuration +// + +// MR0[WR] +// Format : +// D18F2x22C_dct[1:0][Twr], MR0[WR] +// +CONST PSCFG_MR0WR_ENTRY KBMR0WR[] = { + {0x10, 0}, + {0x05, 1}, + {0x06, 2}, + {0x07, 3}, + {0x08, 4}, + {0x0A, 5}, + {0x0C, 6}, + {0x0E, 7}, + {0x12, 9} +}; +CONST PSC_TBL_ENTRY KBMR0WrTblEntry = { + {PSCFG_MR0WR, DT_DONT_CARE, NOD_DONT_CARE, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBMR0WR) / sizeof (PSCFG_MR0WR_ENTRY), + (VOID *)&KBMR0WR +}; + +// MR0[CL] +// Format : +// D18F2x200_dct[1:0][Tcl], MR0[CL][3:1], MR0[CL][0] +// +CONST PSCFG_MR0CL_ENTRY KBMR0CL[] = { + {0x05, 1, 0}, + {0x06, 2, 0}, + {0x07, 3, 0}, + {0x08, 4, 0}, + {0x09, 5, 0}, + {0x0A, 6, 0}, + {0x0B, 7, 0}, + {0x0C, 0, 1}, + {0x0D, 1, 1}, + {0x0E, 2, 1}, + {0x0F, 3, 1}, + {0x10, 4, 1} +}; +CONST PSC_TBL_ENTRY KBMR0CLTblEntry = { + {PSCFG_MR0CL, DT_DONT_CARE, NOD_DONT_CARE, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBMR0CL) / sizeof (PSCFG_MR0CL_ENTRY), + (VOID *)&KBMR0CL +}; + +// ODT pattern for 1 DPC +// Format: +// Dimm0, RdODTCSHigh, RdODTCSLow, WrODTCSHigh, WrODTCSLow +// +STATIC CONST PSCFG_1D_ODTPAT_ENTRY KB1DOdtPat[] = { + {DIMM_SR, 0x00000000, 0x00000000, 0x00000000, 0x00000001}, + {DIMM_DR, 0x00000000, 0x00000000, 0x00000000, 0x00000201}, +}; +CONST PSC_TBL_ENTRY KB1DOdtPatTblEnt = { + {PSCFG_ODT_PAT_1D, DT_DONT_CARE, _1DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KB1DOdtPat) / sizeof (PSCFG_1D_ODTPAT_ENTRY), + (VOID *)&KB1DOdtPat +}; + +// ODT pattern for 2 DPC +// Format: +// Dimm0, Dimm1 RdODTCSHigh, RdODTCSLow, WrODTCSHigh, WrODTCSLow +// +STATIC CONST PSCFG_2D_ODTPAT_ENTRY KB2DOdtPat[] = { + {NP, DIMM_SR, 0x00000000, 0x00000000, 0x00000000, 0x00040000}, + {NP, DIMM_DR, 0x00000000, 0x00000000, 0x00000000, 0x08040000}, + {DIMM_SR + DIMM_DR, DIMM_SR + DIMM_DR, 0x00000000, 0x01010404, 0x00000000, 0x09050605} +}; +CONST PSC_TBL_ENTRY KB2DOdtPatTblEnt = { + {PSCFG_ODT_PAT_2D, DT_DONT_CARE, _2DIMM, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KB2DOdtPat) / sizeof (PSCFG_2D_ODTPAT_ENTRY), + (VOID *)&KB2DOdtPat +}; + +// +// CKE tri-state +// +STATIC CONST UINT8 ROMDATA KBDdr3CKETri[] = {0xFF, 0xFF, 0xFF, 0xFF}; +CONST PSC_TBL_ENTRY KBDdr3CKETriEnt = { + {PSCFG_CKETRI, DT_DONT_CARE, NOD_DONT_CARE, {AMD_FAMILY_16_KB, AMD_F16_ALL}, PT_DONT_CARE, DDR3_TECHNOLOGY}, + sizeof (KBDdr3CKETri) / sizeof (UINT8), + (VOID *)&KBDdr3CKETri +}; diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mp.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mp.c new file mode 100644 index 0000000000..348f7041e1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mp.c @@ -0,0 +1,1336 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mp.c + * + * Common platform specific configuration. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps) + * @e \$Revision: 85646 $ @e \$Date: 2013-01-10 03:52:13 -0600 (Thu, 10 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mu.h" +#include "ma.h" +#include "mp.h" +#include "merrhdl.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_PS_MP_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define PSO_TYPE 0 +#define PSO_LENGTH 1 +#define PSO_DATA 2 + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemPPSCGen ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ); + +BOOLEAN +STATIC +MemPCheckTblDrvOverrideConfig ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +BOOLEAN +STATIC +MemPCheckTblDrvOverrideConfigSpeedLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +VOID +STATIC +MemPTblDrvOverrideSpeedLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +UINT8 +STATIC +MemPTblDrvOverrideODT ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +VOID +STATIC +MemPTblDrvOverrideODTPattern ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +UINT8 +STATIC +MemPTblDrvOverrideRC2IBT ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer, + IN UINT8 NumOfReg + ); + +BOOLEAN +STATIC +MemPTblDrvOverrideMR0WR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +BOOLEAN +STATIC +MemPTblDrvOverrideMR0CL ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +BOOLEAN +STATIC +MemPTblDrvOverrideMR10OpSpeed ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern MEM_PSC_FLOW_BLOCK* memPlatSpecFlowArray[]; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This is the default return function of the Platform Specific block. The function always + * returns AGESA_UNSUPPORTED + * + * @param[in,out] *MemPtr Pointer to MEM_DATA_STRUCTURE + * @param[in] *ChannelPtr Pointer to CH_DEF_STRUCT + * @param[in] *PsPtr Pointer to MEM_PS_BLOCK + * + * @return AGESA_UNSUPPORTED AGESA status indicating that default is unsupported + * + */ + +AGESA_STATUS +MemPConstructPsUDef ( + IN OUT MEM_DATA_STRUCT *MemPtr, + IN OUT CH_DEF_STRUCT *ChannelPtr, + IN OUT MEM_PS_BLOCK *PsPtr + ) +{ + return AGESA_UNSUPPORTED; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function will set the DramTerm and DramTermDyn in the structure of a channel. + * + * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK + * @param[in] ArraySize Size of the array of DramTerm + * @param[in] *DramTermPtr Address the array of DramTerm + * + * @return TRUE - Find DramTerm and DramTermDyn for corresponding platform and dimm population. + * @return FALSE - Fail to find DramTerm and DramTermDyn for corresponding platform and dimm population. + * + */ +BOOLEAN +MemPGetDramTerm ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ArraySize, + IN CONST DRAM_TERM_ENTRY *DramTermPtr + ) +{ + UINT8 Dimms; + UINT8 QR_Dimms; + UINT8 i; + Dimms = NBPtr->ChannelPtr->Dimms; + QR_Dimms = 0; + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i ++) { + if (((NBPtr->ChannelPtr->DimmQrPresent & (UINT16) (1 << i)) != 0) && (i < 2)) { + QR_Dimms ++; + } + } + + for (i = 0; i < ArraySize; i ++) { + if ((DramTermPtr[i].Speed & ((UINT32) 1 << (NBPtr->DCTPtr->Timings.Speed / 66))) != 0) { + if ((((UINT8) (1 << (Dimms - 1)) & DramTermPtr[i].Dimms) != 0) || (DramTermPtr[i].Dimms == ANY_NUM)) { + if (((QR_Dimms == 0) && (DramTermPtr[i].QR_Dimms == NO_DIMM)) || + ((QR_Dimms > 0) && (((UINT8) (1 << (QR_Dimms - 1)) & DramTermPtr[i].QR_Dimms) != 0)) || + (DramTermPtr[i].QR_Dimms == ANY_NUM)) { + NBPtr->PsPtr->DramTerm = DramTermPtr[i].DramTerm; + NBPtr->PsPtr->QR_DramTerm = DramTermPtr[i].QR_DramTerm; + NBPtr->PsPtr->DynamicDramTerm = DramTermPtr[i].DynamicDramTerm; + break; + } + } + } + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets the highest POR supported speed. + * + * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK + * @param[in] FreqLimitSize Size of the array of Frequency Limit + * @param[in] *FreqLimitPtr Address the array of Frequency Limit + * + * @return UINT8 - frequency limit + * + */ +UINT16 +MemPGetPorFreqLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 FreqLimitSize, + IN CONST POR_SPEED_LIMIT *FreqLimitPtr + ) +{ + UINT8 i; + UINT8 j; + UINT8 DimmTpMatch; + UINT16 SpeedLimit; + UINT16 DIMMRankType; + UINT16 _DIMMRankType; + + SpeedLimit = 0; + DIMMRankType = MemAGetPsRankType (NBPtr->ChannelPtr); + for (i = 0; i < FreqLimitSize; i++, FreqLimitPtr++) { + if (NBPtr->ChannelPtr->Dimms != FreqLimitPtr->Dimms) { + continue; + } + DimmTpMatch = 0; + _DIMMRankType = DIMMRankType & FreqLimitPtr->DIMMRankType; + for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j ++) { + if ((_DIMMRankType & (UINT16) 0x0F << (j << 2)) != 0) { + DimmTpMatch++; + } + } + if (DimmTpMatch == FreqLimitPtr->Dimms) { + if (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) { + SpeedLimit = FreqLimitPtr->SpeedLimit_1_5V; + break; + } else if (NBPtr->RefPtr->DDR3Voltage == VOLT1_25) { + SpeedLimit = FreqLimitPtr->SpeedLimit_1_25V; + break; + } else { + SpeedLimit = FreqLimitPtr->SpeedLimit_1_35V; + break; + } + } + } + + return SpeedLimit; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is the default function for getting POR speed limit. When a + * package does not need to cap the speed, it should use this function to initialize + * the corresponding function pointer. + * + * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK + * + */ +VOID +MemPGetPORFreqLimitDef ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets the seed value of WL and HW RxEn pass 1 training. + * + * @param[in,out] *NBPtr Pointer to MEM_NB_BLOCK + * + * @return TRUE - Entries are found + * @return FALSE - Entries are not found + * + */ +BOOLEAN +MemPGetPSCPass1Seed ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 i; + UINT8 Dct; + + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + i = 0; + while (memPlatSpecFlowArray[i] != NULL) { + if (!(memPlatSpecFlowArray[i])->TrainingSeedVal (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + return FALSE; + } + i++; + } + } + + return TRUE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets platform specific configuration such as Max Freq., Slow Mode, Dram Term, + * and so on. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - Successfully execute platform specific configuration flow. + * @return FALSE - Fail to execute platform specific configuration flow. + * + */ +BOOLEAN +MemPPSCFlow ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 i; + BOOLEAN Result; + + Result = TRUE; + i = 0; + + IDS_OPTION_HOOK (IDS_BEFORE_PLAT_TABLES, NBPtr, &(NBPtr->MemPtr->StdHeader)); + + while (memPlatSpecFlowArray[i] != NULL) { + if ((memPlatSpecFlowArray[i])->DramTerm (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if ((memPlatSpecFlowArray[i])->ODTPattern (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if ((memPlatSpecFlowArray[i])->SAO (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if ((memPlatSpecFlowArray[i])->MR0WrCL (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if ((memPlatSpecFlowArray[i])->RC2IBT (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if ((memPlatSpecFlowArray[i])->RC10OpSpeed (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if ((memPlatSpecFlowArray[i])->LRIBT (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if ((memPlatSpecFlowArray[i])->LRNPR (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if ((memPlatSpecFlowArray[i])->LRNLR (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + if (MemPPSCGen (NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + break; + } + } + } + } + } + } + } + } + } + } + i++; + } + + IDS_SKIP_HOOK (IDS_ENFORCE_PLAT_TABLES, NBPtr, &(NBPtr->MemPtr->StdHeader)) { + if (memPlatSpecFlowArray[i] == NULL) { + Result = FALSE; + } + } + return Result; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function constructs the rank type map of Dimm0, Dimm1, Dimm2. Also it counts the number + * of dimm in the table. + * + * @param[in] Dimm0 Rank type of Dimm0 + * @param[in] Dimm1 Rank type of Dimm1 + * @param[in] Dimm2 Rank type of Dimm2 + * @param[in, out] *RankTypeInTable Pointer to RankTypeInTable variable + * + * + */ +VOID +MemPConstructRankTypeMap ( + IN UINT16 Dimm0, + IN UINT16 Dimm1, + IN UINT16 Dimm2, + IN OUT UINT16 *RankTypeInTable + ) +{ + UINT8 i; + UINT16 RT; + UINT8 BitShift; + + *RankTypeInTable = 0; + RT = 0; + BitShift = 0; + + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) { + switch (i) { + case 0: + RT = (Dimm0 == 0) ? NP : Dimm0; + BitShift = 0; + break; + case 1: + RT = (Dimm1 == 0) ? NP : Dimm1; + BitShift = 4; + break; + case 2: + RT = (Dimm2 == 0) ? NP : Dimm2; + BitShift = 8; + break; + default: + // dimm3 is not used, fills nibble3 with "NP" + RT = NP; + BitShift = 12; + } + *RankTypeInTable |= RT << BitShift; + } +} + +/*-----------------------------------------------------------------------------*/ +/** + * MemPIsIdSupported + * This function matches the CPU_LOGICAL_ID and PackageType with certain criteria to + * determine if it is supported by this NB type. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] LogicalId - CPU_LOGICAL_ID + * @param[in] PackageType - Package Type + * + * @return TRUE - NB type is matched ! + * @return FALSE - NB type is not matched ! + * + */ +BOOLEAN +MemPIsIdSupported ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID LogicalId, + IN UINT8 PackageType + ) +{ + CPUID_DATA CpuId; + UINT8 PkgType; + + LibAmdCpuidRead (AMD_CPUID_FMF, &CpuId, &(NBPtr->MemPtr->StdHeader)); + PkgType = (UINT8) (CpuId.EBX_Reg >> 28) & 0xF; // bit 31:28 + + if (((NBPtr->MCTPtr->LogicalCpuid.Family & LogicalId.Family) != 0) + && ((NBPtr->MCTPtr->LogicalCpuid.Revision & LogicalId.Revision) != 0)) { + if ((PackageType == PT_DONT_CARE) || (PackageType == PkgType)) { + return TRUE; + } + } + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns the rank type map of a channel. + * + * @param[in] *CurrentChannel Pointer to CH_DEF_STRUCT + * + * @return UINT16 - The map of rank type. + * + */ +UINT16 +MemPGetPsRankType ( + IN CH_DEF_STRUCT *CurrentChannel + ) +{ + UINT8 i; + UINT16 DIMMRankType; + + DIMMRankType = 0; + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) { + if (CurrentChannel->MCTPtr->Status[SbLrdimms]) { + // For LrDimm, we construct the map according to Dimm present bits rather than rank type bits + if ((CurrentChannel->LrDimmPresent & (UINT8) 1 << i) != 0) { + DIMMRankType |= (UINT16) DIMM_LR << (i << 2); + } else { + DIMMRankType |= (UINT16) NP << (i << 2); + } + } else { + if ((CurrentChannel->DimmQrPresent & (UINT8) 1 << i) != 0) { + if (i < 2) { + DIMMRankType |= (UINT16) DIMM_QR << (i << 2); + } + } else if ((CurrentChannel->DimmDrPresent & (UINT8) 1 << i) != 0) { + DIMMRankType |= (UINT16) DIMM_DR << (i << 2); + } else if ((CurrentChannel->DimmSRPresent & (UINT8) 1 << i) != 0) { + DIMMRankType |= (UINT16) DIMM_SR << (i << 2); + } else { + DIMMRankType |= (UINT16) NP << (i << 2); + } + } + } + + return DIMMRankType; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function performs the action for the rest of platform specific configuration such as + * tri-state stuff + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *EntryOfTables Pointer to MEM_PSC_TABLE_BLOCK + * + * @return TRUE - No error occurred. + * @return FALSE - Error occurred. + * + */ +BOOLEAN +STATIC +MemPPSCGen ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ) +{ + UINT8 i; + PSCFG_TYPE PSCType; + DIMM_TYPE DimmType; + UINT8 MaxDimmPerCh; + UINT8 NOD; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + CH_DEF_STRUCT *CurrentChannel; + UINT32 EventInfo; + + CurrentChannel = NBPtr->ChannelPtr; + + PackageType = 0; + LogicalCpuid.Family = AMD_FAMILY_UNKNOWN; + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + NOD = (UINT8) 1 << (MaxDimmPerCh - 1); + + if (CurrentChannel->RegDimmPresent != 0) { + DimmType = RDIMM_TYPE; + } else if (CurrentChannel->SODimmPresent != 0) { + DimmType = SODIMM_TYPE; + } else if (CurrentChannel->LrDimmPresent != 0) { + DimmType = LRDIMM_TYPE; + } else { + DimmType = UDIMM_TYPE; + } + + for (PSCType = PSCFG_GEN_START + 1; PSCType < PSCFG_GEN_END; PSCType++) { + i = 0; + while (EntryOfTables->TblEntryOfGen[i] != NULL) { + if ((EntryOfTables->TblEntryOfGen[i])->Header.PSCType == PSCType) { + if (((EntryOfTables->TblEntryOfGen[i])->Header.DimmType & DimmType) != 0) { + if (((EntryOfTables->TblEntryOfGen[i])->Header.NumOfDimm & NOD) != 0) { + // + // Determine if this is the expected NB Type + // + LogicalCpuid = (EntryOfTables->TblEntryOfGen[i])->Header.LogicalCpuid; + PackageType = (EntryOfTables->TblEntryOfGen[i])->Header.PackageType; + if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) { + break; + } + } + } + } + i++; + } + + // Check whether no table entry is found. + if (EntryOfTables->TblEntryOfGen[i] == NULL) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo %s Table\n", (PSCType == PSCFG_CLKDIS) ? "ClkDis" : ((PSCType == PSCFG_CKETRI) ? "CkeTri" : ((PSCType == PSCFG_ODTTRI) ? "OdtTri" : "CsTri"))); + EventInfo = (PSCType == PSCFG_CLKDIS) ? MEM_ERROR_CLK_DIS_MAP_NOT_FOUND : ((PSCType == PSCFG_CKETRI) ? MEM_ERROR_CKE_TRI_MAP_NOT_FOUND : ((PSCType == PSCFG_ODTTRI) ? MEM_ERROR_ODT_TRI_MAP_NOT_FOUND : MEM_ERROR_CS_TRI_MAP_NOT_FOUND)); + PutEventLog (AGESA_ERROR, EventInfo, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + return FALSE; + } + + // Perform the action for specific PSCType. + if (PSCType == PSCFG_CLKDIS) { + CurrentChannel->MemClkDisMap = (UINT8 *) (EntryOfTables->TblEntryOfGen[i])->TBLPtr; + } else if (PSCType == PSCFG_CKETRI) { + CurrentChannel->CKETriMap = (UINT8 *) (EntryOfTables->TblEntryOfGen[i])->TBLPtr; + } else if (PSCType == PSCFG_ODTTRI) { + CurrentChannel->ODTTriMap = (UINT8 *) (EntryOfTables->TblEntryOfGen[i])->TBLPtr; + } else if (PSCType == PSCFG_CSTRI) { + CurrentChannel->ChipSelTriMap = (UINT8 *) (EntryOfTables->TblEntryOfGen[i])->TBLPtr; + } + } + + CurrentChannel->DctEccDqsLike = 0x0403; + CurrentChannel->DctEccDqsScale = 0x70; + + return TRUE; +} + + + /* -----------------------------------------------------------------------------*/ +/** + * + * This function proceeds Table Driven Overriding. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] PlatformMemoryConfiguration - Pointer to Platform config table + * @param[in] ProceededPSOType - Proceeded PSO type + * + * @return bit0 ~ bit7 - Overriding CS or DIMM map. + * @return bit15 - Invalid entry found if set. + * + */ +UINT16 +MemPProceedTblDrvOverride ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 ProceededPSOType + ) +{ + UINT8 *Buffer; + UINT8 *PSOStartPtr; + UINT8 NumOfReg; + UINT8 RetVal; + UINT16 RetVal16; + BOOLEAN ConfigMatched; + BOOLEAN FirstGoThrough; + BOOLEAN FindNewConfig; + BOOLEAN InvertRetVal; + BOOLEAN InvalidConfigDetected; + + + ASSERT (PlatformMemoryConfiguration != NULL); + ASSERT ((ProceededPSOType >= PSO_TBLDRV_START) && (ProceededPSOType <= PSO_TBLDRV_END)); + + NumOfReg = 0; + RetVal = 0; + RetVal16 = 0; + FirstGoThrough = TRUE; + InvertRetVal = FALSE; + InvalidConfigDetected = FALSE; + // + // << P E R S P E C T I V E >> + // + // PlatformMemoryConfiguration [] = { + // . . . . . . . . . . . . . . . . . . . + // . . . . . . . . . . . . . . . . . . . + // TBLDRV_CONFIG_TO_OVERRIDE (2, DDR1600, VOLT1_5_ + VOLT1_35_, SR_DIMM0 + DR_DIMM1), + // TBLDRV_CONFIG_ENTRY_RTTNOM (CS2_ + CS3_, 2), + // TBLDRV_CONFIG_ENTRY_RTTWR (CS2_, 2), + // TBLDRV_CONFIG_ENTRY_RTTWR (CS3_, 1), + // TBLDRV_CONFIG_ENTRY_ADDRTMG (0x003C3C3C), + // TBLDRV_CONFIG_ENTRY_ODCCTRL (0x20112222), + // + // TBLDRV_SPEEDLIMIT_CONFIG_TO_OVERRIDE (2, 2, 0, 0) + // TBLDRV_CONFIG_ENTRY_SPEEDLIMIT (DDR1600_FREQUENCY, DDR1333_FREQUENCY, DDR1066_FREQUENCY), + // + // TBLDRV_CONFIG_TO_OVERRIDE (2, DDR1333, VOLT1_5_ + VOLT1_35_, SR_DIMM0 + DR_DIMM1), + // TBLDRV_CONFIG_ENTRY_RTTNOM (CS2_ + CS3_, 3), + // TBLDRV_CONFIG_ENTRY_RTTWR (CS2_ + CS3_, 0), + // + // TBLDRV_OVERRIDE_MR0_WR (3, 5) + // TBLDRV_OVERRIDE_MR0_WR (4, 6) + // + // TBLDRV_OVERRIDE_MR0_CL (3, 5) + // TBLDRV_OVERRIDE_MR0_CL (4, 6) + // . . . . . . . . . . . . . . . . . . . + // . . . . . . . . . . . . . . . . . . . + // + // PSO_END + // } + // + Buffer = PlatformMemoryConfiguration; + // Look for configuration descriptor and its sub-descriptor. + while (Buffer[PSO_TYPE] != PSO_END) { + FindNewConfig = FALSE; + ConfigMatched = FALSE; + if (Buffer[PSO_TYPE] == PSO_TBLDRV_CONFIG) { + // + // Config. descriptor is found, check its sub-descriptor to execute different checking routine. + // + if ((Buffer[PSO_DATA] == CONFIG_SPEEDLIMIT) && (ProceededPSOType == PSO_TBLDRV_SPEEDLIMIT)) { + if (MemPCheckTblDrvOverrideConfigSpeedLimit (NBPtr, &Buffer[PSO_DATA + 1])) { + ConfigMatched = TRUE; + } + } else if (Buffer[PSO_DATA] == CONFIG_DONT_CARE) { + ConfigMatched = TRUE; + } else { + if (MemPCheckTblDrvOverrideConfig (NBPtr, &Buffer[PSO_DATA + 1])) { + ConfigMatched = TRUE; + if ((Buffer[PSO_DATA] == CONFIG_RC2IBT) && (ProceededPSOType == PSO_TBLDRV_RC2_IBT)) { + NumOfReg = Buffer[PSO_DATA + 9]; + } + } + } + } + + if (ConfigMatched) { + // + // If config. is matched, parsing "Table Driven PSO" macros behinds this config. macro until PSO_END is reached. + // + PSOStartPtr = Buffer + (Buffer[PSO_LENGTH] + 2); + // Look for the current proceeded PSO type in PlatformMemoryConfiguration array. + while ((PSOStartPtr[PSO_TYPE] != PSO_END)) { + if (PSOStartPtr[PSO_TYPE] == PSO_TBLDRV_CONFIG) { + // + // If there is an additional config. macro existed, break this while loop, + // then check its content with real platform config. again. + // If matched, parsing "Table Driven PSO" macros behind it. + // + Buffer = PSOStartPtr; + FindNewConfig = TRUE; + break; + } else if (PSOStartPtr[PSO_TYPE] == PSO_TBLDRV_INVALID_TYPE) { + InvalidConfigDetected = TRUE; + break; + } + + if (PSOStartPtr[PSO_TYPE] == ProceededPSOType) { + // + // Pre-set overriding Cs/Dimm map to "0xFF" for the types which are regardless of Cs/Dimm + // for the first time going through the overriding routines. + // + if (FirstGoThrough) { + RetVal = 0xFF; + } + switch (ProceededPSOType) { + case PSO_TBLDRV_SPEEDLIMIT : + MemPTblDrvOverrideSpeedLimit (NBPtr, &PSOStartPtr[PSO_DATA]); + break; + + case PSO_TBLDRV_ODT_RTTNOM : + case PSO_TBLDRV_ODT_RTTWR : + // Mask off Cs overridng map to record which Cs has been overridden. + RetVal &= ~ MemPTblDrvOverrideODT (NBPtr, &PSOStartPtr[PSO_TYPE]); + // Indicate RetVal is inverted. + InvertRetVal = TRUE; + break; + + case PSO_TBLDRV_ODTPATTERN : + MemPTblDrvOverrideODTPattern (NBPtr, &PSOStartPtr[PSO_DATA]); + break; + + case PSO_TBLDRV_ADDRTMG : + NBPtr->ChannelPtr->DctAddrTmg = *(UINT32 *)&PSOStartPtr[PSO_DATA]; + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: AddrTmg = 0x%x for Dct%d\n\n", *(UINT32 *)&PSOStartPtr[PSO_DATA], NBPtr->Dct); + break; + + case PSO_TBLDRV_ODCCTRL : + NBPtr->ChannelPtr->DctOdcCtl = *(UINT32 *)&PSOStartPtr[PSO_DATA]; + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: OdcCtl = 0x%x for Dct%d\n\n", *(UINT32 *)&PSOStartPtr[PSO_DATA], NBPtr->Dct); + break; + + case PSO_TBLDRV_SLOWACCMODE : + NBPtr->ChannelPtr->SlowMode = (PSOStartPtr[PSO_DATA] == 1) ? TRUE : FALSE; + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: Slow Access Mode = %d for Dct%d\n\n", PSOStartPtr[PSO_DATA], NBPtr->Dct); + break; + + case PSO_TBLDRV_RC2_IBT : + // Mask off Dimm overridng map to record which Dimm has been overridden. + RetVal &= ~ MemPTblDrvOverrideRC2IBT (NBPtr, &PSOStartPtr[PSO_DATA], NumOfReg); + // Indicate RetVal is inverted. + InvertRetVal = TRUE; + break; + + case PSO_TBLDRV_MR0_CL : + RetVal = 0; + if (MemPTblDrvOverrideMR0WR (NBPtr, &PSOStartPtr[PSO_DATA])) { + RetVal = 0xFF; + } + break; + + case PSO_TBLDRV_MR0_WR : + RetVal = 0; + if (MemPTblDrvOverrideMR0CL (NBPtr, &PSOStartPtr[PSO_DATA])) { + RetVal = 0xFF; + } + break; + + case PSO_TBLDRV_RC10_OPSPEED : + RetVal = 0; + if (MemPTblDrvOverrideMR10OpSpeed (NBPtr, &PSOStartPtr[PSO_DATA])) { + RetVal = 0xFF; + } + break; + + case PSO_TBLDRV_LRDIMM_IBT : + NBPtr->PsPtr->F0RC8 = PSOStartPtr[PSO_DATA]; + NBPtr->PsPtr->F1RC0 = PSOStartPtr[PSO_DATA + 1]; + NBPtr->PsPtr->F1RC1 = PSOStartPtr[PSO_DATA + 2]; + NBPtr->PsPtr->F1RC2 = PSOStartPtr[PSO_DATA + 3]; + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: LRDIMM IBT for Dct%d\n", NBPtr->Dct); + IDS_HDT_CONSOLE (MEM_FLOW, "\nF0RC8 = %d, F1RC0 = %d, F1RC1 = %d, F1RC2 = %d", PSOStartPtr[PSO_DATA], PSOStartPtr[PSO_DATA + 1], \ + PSOStartPtr[PSO_DATA + 2], PSOStartPtr[PSO_DATA + 3]); + break; + + case PSO_TBLDRV_2D_TRAINING : + RetVal = 0x1; + NBPtr->Override2DTraining = (PSOStartPtr[PSO_DATA] == 1) ? TRUE : FALSE; + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: 2D Trainig = %d for Dct%d\n\n", PSOStartPtr[PSO_DATA], NBPtr->Dct); + break; + + default: + ASSERT (FALSE); + } + FirstGoThrough = FALSE; + } + PSOStartPtr += (PSOStartPtr[PSO_LENGTH] + 2); + } + + if (FindNewConfig) { + continue; + } + RetVal = (InvertRetVal) ? ~RetVal : RetVal; + RetVal16 = (UINT16) RetVal; + if (InvalidConfigDetected) { + RetVal16 |= INVALID_CONFIG_FLAG; + } + + return RetVal16; + } + Buffer += (Buffer[PSO_LENGTH] + 2); + } + + RetVal = (InvertRetVal) ? ~RetVal : RetVal; + RetVal16 = (UINT16) RetVal; + if (InvalidConfigDetected) { + RetVal16 |= INVALID_CONFIG_FLAG; + } + return RetVal16; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides the speed limit. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * + */ +VOID +STATIC +MemPTblDrvOverrideSpeedLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + UINT8 CurrentVoltage; + + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: Max. Memory Speed for Dct%d\n", NBPtr->Dct); + + LibAmdMemCopy (NBPtr->PsPtr->SpeedLimit, Buffer, 6, &(NBPtr->MemPtr->StdHeader)); + + for (CurrentVoltage = VOLT1_5_ENCODED_VAL; CurrentVoltage <= VOLT1_25_ENCODED_VAL; CurrentVoltage ++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%s -> %dMHz\t", (CurrentVoltage == VOLT1_5_ENCODED_VAL) ? "1.5V" : ((CurrentVoltage == VOLT1_35_ENCODED_VAL) ? "1.35V" : "1.25V"), NBPtr->PsPtr->SpeedLimit[CurrentVoltage]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides the ODTs (RttNom and RttWr). + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * + * @return Target CS overriding bit map + * + */ +UINT8 +STATIC +MemPTblDrvOverrideODT ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + UINT16 i; + UINT8 TgtCS; + + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: ODT for Dct%d\n", NBPtr->Dct); + if (Buffer[0] == PSO_TBLDRV_ODT_RTTNOM) { + IDS_HDT_CONSOLE (MEM_FLOW, "RttNom = %d for ", Buffer[3]); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "RttWr = %d for ", Buffer[3]); + } + ); + + TgtCS = Buffer[2]; + for (i = 0; i < MAX_CS_PER_CHANNEL; i++) { + if ((NBPtr->DCTPtr->Timings.CsEnabled & (UINT16) (1 << i)) != 0) { + if ((TgtCS & (UINT8) 1 << i) != 0) { + IDS_HDT_CONSOLE (MEM_FLOW, "CS%d ", i); + if (Buffer[0] == PSO_TBLDRV_ODT_RTTNOM) { + NBPtr->PsPtr->RttNom[i] = Buffer[3]; + } else { + NBPtr->PsPtr->RttWr[i] = Buffer[3]; + } + } + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + + return TgtCS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides the ODT patterns. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * + */ +VOID +STATIC +MemPTblDrvOverrideODTPattern ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: ODT pattern for Dct%d\n", NBPtr->Dct); + IDS_HDT_CONSOLE (MEM_FLOW, "\nRODTCSHigh = 0x%x\n", *(UINT32 *)&Buffer[0]); + IDS_HDT_CONSOLE (MEM_FLOW, "\nRODTCSLow = 0x%x\n", *(UINT32 *)&Buffer[4]); + IDS_HDT_CONSOLE (MEM_FLOW, "\nWODTCSHigh = 0x%x\n", *(UINT32 *)&Buffer[8]); + IDS_HDT_CONSOLE (MEM_FLOW, "\nWODTCSLow = 0x%x\n", *(UINT32 *)&Buffer[12]); + + CurrentChannel->PhyRODTCSHigh = *(UINT32 *)&Buffer[0]; + CurrentChannel->PhyRODTCSLow = *(UINT32 *)&Buffer[4]; + CurrentChannel->PhyWODTCSHigh = *(UINT32 *)&Buffer[8]; + CurrentChannel->PhyWODTCSLow = *(UINT32 *)&Buffer[12]; + + //WL ODTs need to be modified as well while overriding... + CurrentChannel->PhyWLODT[0] = (UINT8) (CurrentChannel->PhyWODTCSLow & 0x0F); + CurrentChannel->PhyWLODT[1] = (UINT8) ((CurrentChannel->PhyWODTCSLow >> 16) & 0x0F); + CurrentChannel->PhyWLODT[2] = (UINT8) (CurrentChannel->PhyWODTCSHigh & 0x0F); + CurrentChannel->PhyWLODT[3] = (UINT8) ((CurrentChannel->PhyWODTCSHigh >> 16) & 0x0F); + + IDS_HDT_CONSOLE (MEM_FLOW, "\n\n"); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides the Ctrl Word 2 and 8. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * @param[in] NumOfReg - Number of registers + * + * @return Target DIMM overridng bit map + * + */ +UINT8 +STATIC +MemPTblDrvOverrideRC2IBT ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer, + IN UINT8 NumOfReg + ) +{ + UINT16 i; + UINT8 TgtDimm; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: RC2[IBT] for Dct%d\n", NBPtr->Dct); + IDS_HDT_CONSOLE (MEM_FLOW, "RC2[IBT] = %d for ", Buffer[1]); + + TgtDimm = Buffer[0]; + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) { + if ((CurrentChannel->ChDimmValid & (UINT16) (1 << i)) != 0) { + if (((TgtDimm & (UINT8) 1 << i) != 0) && (NBPtr->PsPtr->NumOfReg[i] == NumOfReg)) { + IDS_HDT_CONSOLE (MEM_FLOW, "DIMM%d ", i); + CurrentChannel->CtrlWrd02[i] = (Buffer[1] & 0x1) << 2; + CurrentChannel->CtrlWrd08[i] = (Buffer[1] & 0xE) >> 1; + } + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + + return TgtDimm; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides MR0[WR]. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * + * @return TRUE : Overridden + * @return FALSE : Not overriden + * + */ +BOOLEAN +STATIC +MemPTblDrvOverrideMR0WR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + if (Buffer[0] == (UINT8) NBPtr->GetBitField (NBPtr, BFTcl)) { + NBPtr->PsPtr->MR0CL31 = Buffer[1]; + NBPtr->PsPtr->MR0CL0 = Buffer[2]; + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: MR0[CL][3:1] = %d,\tMR0[CL][0] = %d for Dct%d\n", \ + Buffer[1], Buffer[2], NBPtr->Channel); + IDS_HDT_CONSOLE (MEM_FLOW, "Tcl = %d\n\n", (UINT8) NBPtr->GetBitField (NBPtr, BFTcl)); + return TRUE; + } + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides MR0[WR]. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * + * @return TRUE : Overridden + * @return FALSE : Not overriden + * + */ +BOOLEAN +STATIC +MemPTblDrvOverrideMR0CL ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + if (Buffer[0] == (UINT8) NBPtr->GetBitField (NBPtr, BFTwrDDR3)) { + NBPtr->PsPtr->MR0WR = Buffer[1]; + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: MR0[WR] = %d for Dct%d\n", Buffer[1], NBPtr->Dct); + IDS_HDT_CONSOLE (MEM_FLOW, "Twr = %d\n\n", (UINT8) NBPtr->GetBitField (NBPtr, BFTwrDDR3)); + return TRUE; + } + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function overrides MR10[OperatingSpeed]. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * + * @return TRUE : Overridden + * @return FALSE : Not overriden + * + */ +BOOLEAN +STATIC +MemPTblDrvOverrideMR10OpSpeed ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + UINT32 CurDDRrate; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66)); + + if ((Buffer[0] & CurDDRrate) != 0) { + NBPtr->PsPtr->RC10OpSpd = Buffer[1]; + IDS_HDT_CONSOLE (MEM_FLOW, "\nTable Driven Platform Override: MR10[OperatingSpeed] = %d for Dct%d\n", Buffer[1], NBPtr->Dct); + return TRUE; + } + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function checks if platform configuration is matched or not. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * + * @return TRUE : Configuration is matched + * @return FALSE : Configuration is not matched + * + */ +BOOLEAN +STATIC +MemPCheckTblDrvOverrideConfig ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + UINT8 MaxDimmPerCh; + UINT32 CurDDRrate; + UINT8 DDR3Voltage; + UINT16 RankTypeOfPopulatedDimm; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + + // Get platform configuration. + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66)); + DDR3Voltage = (UINT8) (1 << CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage)); + RankTypeOfPopulatedDimm = MemAGetPsRankType (CurrentChannel); + + if ((MaxDimmPerCh == Buffer[0]) && ((DDR3Voltage & Buffer[1]) != 0) && + ((CurDDRrate & *(UINT32 *)&Buffer[2]) != 0) && ((RankTypeOfPopulatedDimm & *(UINT16 *)&Buffer[6]) != 0)) { + return TRUE; + } + + return FALSE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function checks if platform configuration is matched or not. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *Buffer - Pointer to Platform config table + * + * @return TRUE : Configuration is matched + * @return FALSE : Configuration is not matched + * + */ +BOOLEAN +STATIC +MemPCheckTblDrvOverrideConfigSpeedLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 *Buffer + ) +{ + UINT8 MaxDimmPerCh; + UINT8 NumOfSR; + UINT8 NumOfDR; + UINT8 NumOfQR; + UINT8 NumOfLRDimm; + UINT8 i; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + NumOfSR = 0; + NumOfDR = 0; + NumOfQR = 0; + NumOfLRDimm = 0; + + // Get platform configuration. + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) { + if ((CurrentChannel->DimmSRPresent & (UINT8) (1 << i)) != 0) { + NumOfSR += 1; + } else if ((CurrentChannel->DimmDrPresent & (UINT16) (1 << i)) != 0) { + NumOfDR += 1; + } else if ((CurrentChannel->DimmQrPresent & (UINT16) (1 << i)) != 0) { + if (i < 2) { + NumOfQR += 1; + } + } else if ((CurrentChannel->LrDimmPresent & (UINT16) (1 << i))) { + NumOfLRDimm += 1; + } + } + + if ((Buffer[0] == MaxDimmPerCh) && (Buffer[1] == CurrentChannel->Dimms)) { + if (NBPtr->MCTPtr->Status[SbLrdimms] == TRUE) { + if (Buffer[5] == NumOfLRDimm) { + return TRUE; + } + } else { + if ((Buffer[2] == NumOfSR) && (Buffer[3] == NumOfDR) && (Buffer[4] == NumOfQR)) { + return TRUE; + } + } + } + + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Prepare PS table look-up conditions (ie. DIMM type, rank type,...) + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemPPreparePsTabLookupConditions ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 MaxDimmPerCh; + UINT8 MaxDimmSlotPerCh; + DIMM_TYPE DimmType; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + + PackageType = 0; + LogicalCpuid.Family = AMD_FAMILY_UNKNOWN; + + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + MaxDimmSlotPerCh = MaxDimmPerCh - GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + + if (CurrentChannel->RegDimmPresent != 0) { + DimmType = RDIMM_TYPE; + } else if (CurrentChannel->SODimmPresent != 0) { + DimmType = SODIMM_TYPE; + } else if (CurrentChannel->LrDimmPresent != 0) { + DimmType = LRDIMM_TYPE; + } else { + DimmType = UDIMM_TYPE; + } + + // Check if it is "SODIMM plus soldered-down DRAM" or "Soldered-down DRAM only" configuration, + // DimmType is changed to 'SODWN_SODIMM_TYPE' if soldered-down DRAM exist + if (MaxDimmSlotPerCh != MaxDimmPerCh) { + // SODIMM plus soldered-down DRAM + DimmType = SODWN_SODIMM_TYPE; + } else if (FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_SOLDERED_DOWN_SODIMM_TYPE, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, NULL, NULL) != NULL) { + // Soldered-down DRAM only + DimmType = SODWN_SODIMM_TYPE; + MaxDimmSlotPerCh = 0; + } + + NBPtr->PsPtr->NumOfDimmSlots = (UINT8) (MaxDimmSlotPerCh != 0) ? (1 << (MaxDimmSlotPerCh - 1)) : _DIMM_NONE; + NBPtr->PsPtr->DimmType = (UINT8) DimmType; + NBPtr->PsPtr->RankType = MemPGetPsRankType (CurrentChannel); + +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Select and return the pointer to the table that supports currently populated + * processor, DIMMs, and platform + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *ListOfTables - Pointer to PSC_TBL_ENTRY array of pointers + * @param[in] *TableSize - Size of the selected table + * + * @return Pointer to the selected PSC_TBL_ENTRY table + * + */ +PSC_TBL_ENTRY * +MemPGetTableEntry ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN PSC_TBL_ENTRY *ListOfTables[], + OUT UINT8 *TableSize + ) +{ + UINT8 i; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + + PackageType = 0; + LogicalCpuid.Family = AMD_FAMILY_UNKNOWN; + + i = 0; + // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type. + while (ListOfTables[i] != NULL) { + if (((ListOfTables[i])->Header.DimmType & NBPtr->PsPtr->DimmType) != 0) { + if (((ListOfTables[i])->Header.NumOfDimm & NBPtr->PsPtr->NumOfDimmSlots) != 0) { + // + // Determine if this is the expected NB Type + // + LogicalCpuid = (ListOfTables[i])->Header.LogicalCpuid; + PackageType = (ListOfTables[i])->Header.PackageType; + if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) { + *TableSize = (ListOfTables[i])->TableSize; + break; + } + } + } + i++; + } + + // Check whether no table entry is found. + if (ListOfTables[i] == NULL) { + return NULL; + } else { + return ((ListOfTables[i])->TBLPtr); + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c new file mode 100644 index 0000000000..1302396909 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c @@ -0,0 +1,325 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mpmaxfreq.c + * + * A sub-engine which extracts max. frequency limit value. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mu.h" +#include "ma.h" +#include "mp.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) +#define FILECODE PROC_MEM_PS_MPMAXFREQ_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +typedef struct { + UINT16 Dimms:4; + UINT16 SR:4; + UINT16 DR:4; + UINT16 QR:4; +} CDNMaxFreq; + +typedef struct { + UINT16 Dimms:4; + UINT16 LR:12; +} CDNLMaxFreq; +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemPGetMaxFreqSupported ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * A sub-function which extracts the value of max frequency supported from a input table and + * compares it with DCTPtr->Timings.TargetSpeed + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK + * + * @return TRUE - Succeed in extracting the table value + * @return FALSE - Fail to extract the table value + * + */ +BOOLEAN +MemPGetMaxFreqSupported ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ) +{ + UINT8 i; + UINT8 MaxDimmSlotPerCh; + UINT8 MaxDimmPerCh; + UINT8 NOD; + UINT8 TableSize; + PSCFG_TYPE Type; + UINT16 CDN; + UINT16 MaxFreqSupported; + UINT16 *SpeedArray; + UINT8 DDR3Voltage; + UINT8 CurrentVoltage; + DIMM_TYPE DimmType; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + BOOLEAN DisDct; + UINT8 PsoMaskMaxFreq; + UINT16 PsoMaskMaxFreq16; + UINT8 NumDimmSlotInTable; + UINT16 DimmPopInTable; + PSCFG_MAXFREQ_ENTRY *TblPtr; + CH_DEF_STRUCT *CurrentChannel; + PSC_TBL_ENTRY **TblEntryOfMaxFreq; + + CurrentChannel = NBPtr->ChannelPtr; + + DisDct = FALSE; + Type = PSCFG_MAXFREQ; + TblPtr = NULL; + TableSize = 0; + PackageType = 0; + NumDimmSlotInTable = 0; + DimmPopInTable = 0; + LogicalCpuid.Family = AMD_FAMILY_UNKNOWN; + SpeedArray = NULL; + + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + MaxDimmSlotPerCh = MaxDimmPerCh - GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + + if (CurrentChannel->RegDimmPresent != 0) { + DimmType = RDIMM_TYPE; + } else if (CurrentChannel->SODimmPresent != 0) { + DimmType = SODIMM_TYPE; + } else if (CurrentChannel->LrDimmPresent != 0) { + DimmType = LRDIMM_TYPE; + } else { + DimmType = UDIMM_TYPE; + } + + // Check if it is "SODIMM plus soldered-down DRAM" or "Soldered-down DRAM only" configuration, + // DimmType is changed to 'SODWN_SODIMM_TYPE' if soldered-down DRAM exist + if (MaxDimmSlotPerCh != MaxDimmPerCh) { + // SODIMM plus soldered-down DRAM + DimmType = SODWN_SODIMM_TYPE; + } else if (FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_SOLDERED_DOWN_SODIMM_TYPE, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, NULL, NULL) != NULL) { + // Soldered-down DRAM only + DimmType = SODWN_SODIMM_TYPE; + MaxDimmSlotPerCh = 0; + } + NOD = (UINT8) (MaxDimmSlotPerCh != 0) ? (1 << (MaxDimmSlotPerCh - 1)) : _DIMM_NONE; + + TblEntryOfMaxFreq = EntryOfTables->TblEntryOfMaxFreq; + IDS_OPTION_HOOK (IDS_GET_STRETCH_FREQUENCY_LIMIT, &TblEntryOfMaxFreq, &NBPtr->MemPtr->StdHeader); + + NBPtr->FamilySpecificHook[RelocatePscTblEntryByMotherBoardLayer] (NBPtr, (VOID *) &TblEntryOfMaxFreq); + + i = 0; + // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type. + while (TblEntryOfMaxFreq[i] != NULL) { + if (((TblEntryOfMaxFreq[i])->Header.DimmType & DimmType) != 0) { + if (((TblEntryOfMaxFreq[i])->Header.NumOfDimm & NOD) != 0) { + // + // Determine if this is the expected NB Type + // + LogicalCpuid = (TblEntryOfMaxFreq[i])->Header.LogicalCpuid; + PackageType = (TblEntryOfMaxFreq[i])->Header.PackageType; + if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) { + TblPtr = (PSCFG_MAXFREQ_ENTRY *) ((TblEntryOfMaxFreq[i])->TBLPtr); + TableSize = (TblEntryOfMaxFreq[i])->TableSize; + Type = (TblEntryOfMaxFreq[i])->Header.PSCType; + break; + } + } + } + i++; + } + + // Check whether no table entry is found. + if (TblEntryOfMaxFreq[i] == NULL) { + return FALSE; + } + + MaxFreqSupported = UNSUPPORTED_DDR_FREQUENCY; + CDN = 0; + DDR3Voltage = (UINT8) CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage); + + // Construct the condition value + ((CDNMaxFreq *)&CDN)->Dimms = CurrentChannel->Dimms; + if (Type == PSCFG_MAXFREQ) { + for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) { + if ((CurrentChannel->DimmSRPresent & (UINT8) (1 << i)) != 0) { + ((CDNMaxFreq *)&CDN)->SR += 1; + } + if ((CurrentChannel->DimmDrPresent & (UINT16) (1 << i)) != 0) { + ((CDNMaxFreq *)&CDN)->DR += 1; + } + if ((CurrentChannel->DimmQrPresent & (UINT16) (1 << i)) != 0) { + if (i < 2) { + ((CDNMaxFreq *)&CDN)->QR += 1; + } + } + } + } else { + ((CDNLMaxFreq *)&CDN)->LR = CurrentChannel->Dimms; + } + + for (i = 0; i < TableSize; i++) { + NumDimmSlotInTable = TblPtr->MAXFREQ_ENTRY.DimmSlotPerCh; + DimmPopInTable = (Type == PSCFG_MAXFREQ) ? TblPtr->MAXFREQ_ENTRY.CDN : ((PSCFG_LR_MAXFREQ_ENTRY *)TblPtr)->LR_MAXFREQ_ENTRY.CDN; + if (((NumDimmSlotInTable & NOD) != 0) && (CDN == DimmPopInTable)) { + if (Type == PSCFG_MAXFREQ) { + SpeedArray = TblPtr->MAXFREQ_ENTRY.Speed; + } else { + SpeedArray = ((PSCFG_LR_MAXFREQ_ENTRY *)TblPtr)->LR_MAXFREQ_ENTRY.Speed; + } + break; + } + TblPtr++; + } + + PsoMaskMaxFreq16 = MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_SPEEDLIMIT); + if ((PsoMaskMaxFreq16 & INVALID_CONFIG_FLAG) == 0) { + PsoMaskMaxFreq = (UINT8) PsoMaskMaxFreq16; + if (PsoMaskMaxFreq != 0) { + SpeedArray = NBPtr->PsPtr->SpeedLimit; + } + } else { + SpeedArray = NULL; + } + + if (SpeedArray != NULL) { + if (NBPtr->SharedPtr->VoltageMap != VDDIO_DETERMINED) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nCheck speed supported for each VDDIO for Node%d DCT%d: ", NBPtr->Node, NBPtr->Dct); + for (CurrentVoltage = VOLT1_5_ENCODED_VAL; CurrentVoltage <= VOLT1_25_ENCODED_VAL; CurrentVoltage ++) { + if (NBPtr->SharedPtr->VoltageMap & (1 << CurrentVoltage)) { + IDS_HDT_CONSOLE (MEM_FLOW, "%s -> %dMHz ", (CurrentVoltage == VOLT1_5_ENCODED_VAL) ? "1.5V" : ((CurrentVoltage == VOLT1_35_ENCODED_VAL) ? "1.35V" : "1.25V"), SpeedArray[CurrentVoltage]); + if (NBPtr->DCTPtr->Timings.TargetSpeed > SpeedArray[CurrentVoltage]) { + MaxFreqSupported = SpeedArray[CurrentVoltage]; + } else { + MaxFreqSupported = NBPtr->DCTPtr->Timings.TargetSpeed; + } + if (NBPtr->MaxFreqVDDIO[CurrentVoltage] > MaxFreqSupported) { + NBPtr->MaxFreqVDDIO[CurrentVoltage] = MaxFreqSupported; + } + } else { + NBPtr->MaxFreqVDDIO[CurrentVoltage] = 0; + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + ASSERT (DDR3Voltage <= VOLT1_25_ENCODED_VAL); + for (CurrentVoltage = DDR3Voltage; CurrentVoltage >= VOLT1_5_ENCODED_VAL; CurrentVoltage --) { + if (NBPtr->SharedPtr->VoltageMap & (1 << CurrentVoltage)) { + MaxFreqSupported = SpeedArray[CurrentVoltage]; + if (MaxFreqSupported != UNSUPPORTED_DDR_FREQUENCY) { + NBPtr->RefPtr->DDR3Voltage = CONVERT_ENCODED_TO_VDDIO (CurrentVoltage); + IDS_HDT_CONSOLE (MEM_FLOW, "\nVDDIO leveraged to %s\n", (CurrentVoltage == VOLT1_5_ENCODED_VAL) ? "1.5V" : ((CurrentVoltage == VOLT1_35_ENCODED_VAL) ? "1.35V" : "1.25V")); + break; + } + } + } + } + + if (MaxFreqSupported == UNSUPPORTED_DDR_FREQUENCY) { + // No entry in the table for current dimm population is found + IDS_HDT_CONSOLE (MEM_FLOW, "\nDCT %d: No entry is found in the Max Frequency table\n", NBPtr->Dct); + DisDct = TRUE; + } else if (MaxFreqSupported != 0) { + if ((NBPtr->DCTPtr->Timings.TargetSpeed > MaxFreqSupported) && !NBPtr->IsSupported[AMPIsEnabled]) { + NBPtr->DCTPtr->Timings.TargetSpeed = MaxFreqSupported; + } + } else if (NBPtr->SharedPtr->VoltageMap == VDDIO_DETERMINED) { + // Dimm population is not supported at current voltage + // Also if there is no performance optimization, disable the DCT + DisDct = TRUE; + } + + if (DisDct) { + NBPtr->DCTPtr->Timings.DimmExclude |= NBPtr->DCTPtr->Timings.DctDimmValid; + PutEventLog (AGESA_ERROR, MEM_ERROR_UNSUPPORTED_DIMM_CONFIG, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + // Change target speed to highest value so it won't affect other channels when leveling frequency across the node. + NBPtr->DCTPtr->Timings.TargetSpeed = UNSUPPORTED_DDR_FREQUENCY; + } + + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmr0.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmr0.c new file mode 100644 index 0000000000..feb3807ad7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmr0.c @@ -0,0 +1,195 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mpmr0.c + * + * A sub-engine which extracts MR0[WR] and MR0[CL] value. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "ma.h" +#include "mp.h" +#include "merrhdl.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) +#define FILECODE PROC_MEM_PS_MPMR0_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemPGetMR0WrCL ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * A sub-function which extracts MR0[WR] or MR0[CL] value from a input table and store the + * value to a specific address. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK + * + * @return TRUE - Succeed in extracting the table value + * @return FALSE - Fail to extract the table value + * + */ +BOOLEAN +MemPGetMR0WrCL ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ) +{ + + UINT8 i; + UINT8 j; + UINT8 p; + UINT32 Value32; + UINT8 TableSize; + PSCFG_TYPE Type; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + UINT8 PsoMaskMR0; + PSCFG_MR0CL_ENTRY *TblPtr; + PSC_TBL_ENTRY **ptr; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + TblPtr = NULL; + TableSize = 0; + PsoMaskMR0 = 0; + + // Extract MR0[WR] value, then MR0[CL] value + for (i = 0; i < 2; i++) { + if (i == 0) { + ptr = EntryOfTables->TblEntryOfMR0WR; + Type = PSCFG_MR0WR; + } else { + ptr = EntryOfTables->TblEntryOfMR0CL; + Type = PSCFG_MR0CL; + } + + p = 0; + // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type. + while (ptr[p] != NULL) { + // + // Determine if this is the expected NB Type + // + LogicalCpuid = (ptr[p])->Header.LogicalCpuid; + PackageType = (ptr[p])->Header.PackageType; + if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) { + TblPtr = (PSCFG_MR0CL_ENTRY *) ((ptr[p])->TBLPtr); + TableSize = (ptr[p])->TableSize; + break; + } + p++; + } + + // Check whether no table entry is found. + if (ptr[p] == NULL) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo MR0 table\n"); + return FALSE; + } + + Value32 = (Type == PSCFG_MR0WR) ? NBPtr->GetBitField (NBPtr, BFTwrDDR3) : NBPtr->GetBitField (NBPtr, BFTcl); + for (j = 0; j < TableSize; j++, TblPtr++) { + if (Value32 == (UINT32) TblPtr->Timing) { + if (Type == PSCFG_MR0WR) { + NBPtr->PsPtr->MR0WR = (UINT8) TblPtr->Value; + break; + } else { + NBPtr->PsPtr->MR0CL31 = (UINT8) TblPtr->Value; + NBPtr->PsPtr->MR0CL0 = (UINT8) TblPtr->Value1; + break; + } + } + } + + // + // If there is no entry, check if overriding value existed. If not, return FALSE. + // + PsoMaskMR0 = (UINT8) MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, ((i == 0) ? PSO_TBLDRV_MR0_WR : PSO_TBLDRV_MR0_CL)); + if ((PsoMaskMR0 == 0) && (j == TableSize)) { + IDS_HDT_CONSOLE (MEM_FLOW, (i == 0) ? "\nNo MR0[WR] entries\n" : "\nNo MR0[CL] entries\n"); + PutEventLog (AGESA_ERROR, MEM_ERROR_MR0_NOT_FOUND, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + return FALSE; + } + } + + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpodtpat.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpodtpat.c new file mode 100644 index 0000000000..b763cd4e4b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpodtpat.c @@ -0,0 +1,216 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mpodtpat.c + * + * A sub-engine which extracts ODT pattern value. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mu.h" +#include "ma.h" +#include "mp.h" +#include "merrhdl.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) +#define FILECODE PROC_MEM_PS_MPODTPAT_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemPGetODTPattern ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * A sub-function which extracts ODT Pattern value from a input table and stores extracted + * value to a specific address. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK + * + * @return TRUE - Table values can be extracted per dimm population and ranks type. + * @return FALSE - Table values cannot be extracted per dimm population and ranks type. + * + */ +BOOLEAN +MemPGetODTPattern ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ) +{ + UINT8 i; + UINT16 RankTypeInTable; + UINT16 RankTypeOfPopulatedDimm; + UINT8 MaxDimmPerCh; + UINT8 NOD; + UINT8 TableSize; + DIMM_TYPE DimmType; + UINT8 PsoMaskOdtPat; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + PSCFG_3D_ODTPAT_ENTRY *TblPtr; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + + TblPtr = NULL; + TableSize = 0; + PackageType = 0; + LogicalCpuid.Family = AMD_FAMILY_UNKNOWN; + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + NOD = (UINT8) 1 << (MaxDimmPerCh - 1); + + if (CurrentChannel->RegDimmPresent != 0) { + DimmType = RDIMM_TYPE; + } else if (CurrentChannel->SODimmPresent != 0) { + DimmType = SODIMM_TYPE; + } else if (CurrentChannel->LrDimmPresent != 0) { + DimmType = LRDIMM_TYPE; + } else { + DimmType = UDIMM_TYPE; + } + + i = 0; + // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type. + while (EntryOfTables->TblEntryOfODTPattern[i] != NULL) { + if (((EntryOfTables->TblEntryOfODTPattern[i])->Header.DimmType & DimmType) != 0) { + if (((EntryOfTables->TblEntryOfODTPattern[i])->Header.NumOfDimm & NOD) != 0) { + // + // Determine if this is the expected NB Type + // + LogicalCpuid = (EntryOfTables->TblEntryOfODTPattern[i])->Header.LogicalCpuid; + PackageType = (EntryOfTables->TblEntryOfODTPattern[i])->Header.PackageType; + if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) { + TblPtr = (PSCFG_3D_ODTPAT_ENTRY *) ((EntryOfTables->TblEntryOfODTPattern[i])->TBLPtr); + TableSize = (EntryOfTables->TblEntryOfODTPattern[i])->TableSize; + break; + } + } + } + i++; + } + + // Check whether no table entry is found. + if (EntryOfTables->TblEntryOfODTPattern[i] == NULL) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo ODT table\n"); + return FALSE; + } + + RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel); + + for (i = 0; i < TableSize; i++) { + MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable); + if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) { + CurrentChannel->PhyRODTCSHigh = TblPtr->RdODTCSHigh; + CurrentChannel->PhyRODTCSLow = TblPtr->RdODTCSLow; + CurrentChannel->PhyWODTCSHigh = TblPtr->WrODTCSHigh; + CurrentChannel->PhyWODTCSLow = TblPtr->WrODTCSLow; + + //WL ODT + if (MemNGetBitFieldNb (NBPtr, BFPerRankTimingEn) == 0) { + CurrentChannel->PhyWLODT[0] = (UINT8) (CurrentChannel->PhyWODTCSLow & 0x0F); + CurrentChannel->PhyWLODT[1] = (UINT8) ((CurrentChannel->PhyWODTCSLow >> 16) & 0x0F); + CurrentChannel->PhyWLODT[2] = (UINT8) (CurrentChannel->PhyWODTCSHigh & 0x0F); + CurrentChannel->PhyWLODT[3] = (UINT8) ((CurrentChannel->PhyWODTCSHigh >> 16) & 0x0F); + } else { + *(UINT32 *) &(CurrentChannel->PhyWLODT[0]) = CurrentChannel->PhyWODTCSLow & 0xF0F0F0F; + } + + break; + } + TblPtr++; + } + + // + // If there is no entry, check if overriding value existed. If not, return FALSE + // + PsoMaskOdtPat = (UINT8) MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_ODTPATTERN); + if ((PsoMaskOdtPat == 0) && (i == TableSize)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo ODT entries\n"); + PutEventLog (AGESA_ERROR, MEM_ERROR_ODT_PATTERN_NOT_FOUND, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + return FALSE; + } + + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mprtt.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mprtt.c new file mode 100644 index 0000000000..aef8e98aee --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mprtt.c @@ -0,0 +1,281 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mprtt.c + * + * A sub-engine which extracts RttNom and RttWr (Dram Term and Dynamic Dram Term) value. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mu.h" +#include "ma.h" +#include "mp.h" +#include "merrhdl.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_PS_MPRTT_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define _DONT_CARE 0xFF + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemPGetRttNomWr ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * A sub-function which extracts RttNom and RttWr value from a input table and stores extracted + * value to a specific address. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK + * + * @return TRUE - Table values can be extracted for all present dimms/ranks + * @return FALSE - Table values cannot be extracted for all present dimms/ranks + * + */ +BOOLEAN +MemPGetRttNomWr ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ) +{ + UINT8 i; + UINT8 MaxDimmPerCh; + UINT8 MaxDimmSlotPerCh; + UINT8 NOD; + UINT8 TableSize; + UINT32 CurDDRrate; + UINT8 DDR3Voltage; + UINT16 RankTypeOfPopulatedDimm; + UINT16 RankTypeInTable; + DIMM_TYPE DimmType; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + UINT8 TgtDimmType; + UINT8 TgtRank; + UINT8 Chipsel; + UINT8 PsoCsMaskRtt; + UINT16 PsoCsMaskRtt16; + UINT8 NoEntryCsMask; + PSCFG_RTT_ENTRY *TblPtr; + PSCFG_RTT_ENTRY *OrgTblPtr; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + + PsoCsMaskRtt = 0; + NoEntryCsMask = 0; + TblPtr = NULL; + TableSize = 0; + PackageType = 0; + LogicalCpuid.Family = AMD_FAMILY_UNKNOWN; + + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + MaxDimmSlotPerCh = MaxDimmPerCh - GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + + if (CurrentChannel->RegDimmPresent != 0) { + DimmType = RDIMM_TYPE; + } else if (CurrentChannel->SODimmPresent != 0) { + DimmType = SODIMM_TYPE; + } else if (CurrentChannel->LrDimmPresent != 0) { + DimmType = LRDIMM_TYPE; + } else { + DimmType = UDIMM_TYPE; + } + + // Check if it is "SODIMM plus soldered-down DRAM" or "Soldered-down DRAM only" configuration, + // DimmType is changed to 'SODWN_SODIMM_TYPE' if soldered-down DRAM exist + if (MaxDimmSlotPerCh != MaxDimmPerCh) { + // SODIMM plus soldered-down DRAM + DimmType = SODWN_SODIMM_TYPE; + } else if (FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_SOLDERED_DOWN_SODIMM_TYPE, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, NULL, NULL) != NULL) { + // Soldered-down DRAM only + DimmType = SODWN_SODIMM_TYPE; + MaxDimmSlotPerCh = 0; + } + NOD = (UINT8) (MaxDimmSlotPerCh != 0) ? (1 << (MaxDimmSlotPerCh - 1)) : _DIMM_NONE; + + i = 0; + // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type. + while (EntryOfTables->TblEntryOfDramTerm[i] != NULL) { + if (((EntryOfTables->TblEntryOfDramTerm[i])->Header.DimmType & DimmType) != 0) { + if (((EntryOfTables->TblEntryOfDramTerm[i])->Header.NumOfDimm & NOD) != 0) { + // + // Determine if this is the expected NB Type + // + LogicalCpuid = (EntryOfTables->TblEntryOfDramTerm[i])->Header.LogicalCpuid; + PackageType = (EntryOfTables->TblEntryOfDramTerm[i])->Header.PackageType; + if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) { + TblPtr = (PSCFG_RTT_ENTRY *) ((EntryOfTables->TblEntryOfDramTerm[i])->TBLPtr); + TableSize = (EntryOfTables->TblEntryOfDramTerm[i])->TableSize; + break; + } + } + } + i++; + } + + // Check whether no table entry is found. + if (EntryOfTables->TblEntryOfDramTerm[i] == NULL) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo RTT table\n"); + return FALSE; + } + + CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66)); + DDR3Voltage = (UINT8) (1 << CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage)); + RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel); + + OrgTblPtr = TblPtr; + for (Chipsel = 0; Chipsel < MAX_CS_PER_CHANNEL; Chipsel++) { + TblPtr = OrgTblPtr; + if ((NBPtr->DCTPtr->Timings.CsPresent & (UINT16) (1 << Chipsel)) != 0) { + if ((CurrentChannel->DimmQrPresent & (UINT8) (1 << (Chipsel >> 1))) != 0) { + TgtDimmType = DIMM_QR; + TgtRank = (UINT8) ((Chipsel < 4) ? 1 << (Chipsel & 1) : 4 << (Chipsel & 1)); + } else if ((CurrentChannel->DimmDrPresent & (UINT8) (1 << (Chipsel >> 1))) != 0) { + TgtDimmType = DIMM_DR; + TgtRank = (UINT8) 1 << (Chipsel & 1); + } else { + TgtDimmType = DIMM_SR; + TgtRank = (UINT8) 1 << (Chipsel & 1); + } + + if (DimmType == LRDIMM_TYPE) { + TgtDimmType = _DONT_CARE; + TgtRank = _DONT_CARE; + } + + for (i = 0; i < TableSize; i++) { + MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable); + if ((TblPtr->DimmPerCh & NOD) != 0) { + if ((TblPtr->DDRrate & CurDDRrate) != 0) { + if ((TblPtr->VDDIO & DDR3Voltage) != 0) { + if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) { + if (((TblPtr->Dimm & TgtDimmType) != 0) || (TgtDimmType == _DONT_CARE)) { + if (((TblPtr->Rank & TgtRank) != 0) || (TgtRank == _DONT_CARE)) { + NBPtr->PsPtr->RttNom[Chipsel] = (UINT8) TblPtr->RttNom; + NBPtr->PsPtr->RttWr[Chipsel] = (UINT8) TblPtr->RttWr; + break; + } + } + } + } + } + } + TblPtr++; + } + // Record which Cs(s) have no entries. Later on, we will check if there are overriding values for them. + if ((i == TableSize) && (NBPtr->SharedPtr->VoltageMap == VDDIO_DETERMINED)) { + NoEntryCsMask |= (UINT8) 1 << Chipsel; + } + } + } + + PsoCsMaskRtt16 = MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_ODT_RTTNOM); + PsoCsMaskRtt16 &= MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_ODT_RTTWR); + // + // Check to see if invalid entry exist ? + // + if ((PsoCsMaskRtt16 & INVALID_CONFIG_FLAG) != 0) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nInvalid entry is found\n\n"); + return FALSE; + } + + // + // If there are no entries for certain Cs(s), we need to check if overriding values (both RttNom and RttWr) existed for them. + // Otherwise, return FALSE. + // + PsoCsMaskRtt = (UINT8) PsoCsMaskRtt16; + if (NoEntryCsMask != 0) { + if ((PsoCsMaskRtt & NoEntryCsMask) != NoEntryCsMask) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo Rtt entries\n"); + PutEventLog (AGESA_ERROR, MEM_ERROR_RTT_NOT_FOUND, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + return FALSE; + } + } + + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mps2d.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mps2d.c new file mode 100644 index 0000000000..328ab6a667 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mps2d.c @@ -0,0 +1,233 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mps2d.c + * + * A sub-engine determine which configs should use 2D training. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mu.h" +#include "ma.h" +#include "mp.h" +#include "merrhdl.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_PS_MPS2D_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemPGetS2D ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ); + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * A sub-function which determine if 2D should be run + * from a input table + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK + * + * @return TRUE - Table values can be extracted per dimm population and ranks type. + * @return FALSE - Table values cannot be extracted per dimm population and ranks type. + * + */ +BOOLEAN +MemPGetS2D ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ) +{ + + UINT8 i; + UINT8 MaxDimmPerCh; + UINT8 MaxDimmSlotPerCh; + UINT8 NOD; + UINT8 TableSize; + UINT32 CurDDRrate; + UINT8 DDR3Voltage; + UINT16 RankTypeOfPopulatedDimm; + UINT16 RankTypeInTable; + BOOLEAN FoundValue; + DIMM_TYPE DimmType; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + PSCFG_S2D_ENTRY *TblPtr; + CH_DEF_STRUCT *CurrentChannel; + UINT16 P2dTraingOveride; + + CurrentChannel = NBPtr->ChannelPtr; + + TblPtr = NULL; + TableSize = 0; + PackageType = 0; + LogicalCpuid.Family = AMD_FAMILY_UNKNOWN; + + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + MaxDimmSlotPerCh = MaxDimmPerCh - GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + + if (CurrentChannel->RegDimmPresent != 0) { + DimmType = RDIMM_TYPE; + } else if (CurrentChannel->SODimmPresent != 0) { + DimmType = SODIMM_TYPE; + } else if (CurrentChannel->LrDimmPresent != 0) { + DimmType = LRDIMM_TYPE; + } else { + DimmType = UDIMM_TYPE; + } + + // Check if it is "SODIMM plus soldered-down DRAM" or "Soldered-down DRAM only" configuration, + // DimmType is changed to 'SODWN_SODIMM_TYPE' if soldered-down DRAM exist + if (MaxDimmSlotPerCh != MaxDimmPerCh) { + // SODIMM plus soldered-down DRAM + DimmType = SODWN_SODIMM_TYPE; + } else if (FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_SOLDERED_DOWN_SODIMM_TYPE, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, NULL, NULL) != NULL) { + // Soldered-down DRAM only + DimmType = SODWN_SODIMM_TYPE; + MaxDimmSlotPerCh = 0; + } + NOD = (UINT8) (MaxDimmSlotPerCh != 0) ? (1 << (MaxDimmSlotPerCh - 1)) : _DIMM_NONE; + + i = 0; + // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type. + while (EntryOfTables->TblEntryOfS2D[i] != NULL) { + if (((EntryOfTables->TblEntryOfS2D[i])->Header.DimmType & DimmType) != 0) { + if (((EntryOfTables->TblEntryOfS2D[i])->Header.NumOfDimm & NOD) != 0) { + // + // Determine if this is the expected NB Type + // + LogicalCpuid = (EntryOfTables->TblEntryOfS2D[i])->Header.LogicalCpuid; + PackageType = (EntryOfTables->TblEntryOfS2D[i])->Header.PackageType; + if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) { + TblPtr = (PSCFG_S2D_ENTRY *) ((EntryOfTables->TblEntryOfS2D[i])->TBLPtr); + TableSize = (EntryOfTables->TblEntryOfS2D[i])->TableSize; + break; + } + } + } + i++; + } + + // Check whether no table entry is found. + if (EntryOfTables->TblEntryOfS2D[i] == NULL) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo 2D training Config table\n"); + return FALSE; + } + CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66)); + DDR3Voltage = (UINT8) (1 << CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage)); + RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel); + FoundValue = FALSE; + for (i = 0; i < TableSize; i++) { + MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable); + if ((TblPtr->DimmPerCh & NOD) != 0) { + if ((TblPtr->DDRrate & CurDDRrate) != 0) { + if ((TblPtr->VDDIO & DDR3Voltage) != 0) { + if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) { + if (TblPtr->Enable2D == 1) { + FoundValue = TRUE; + break; + } + } + } + } + } + TblPtr++; + } + P2dTraingOveride = MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_2D_TRAINING); + if (P2dTraingOveride != 0) { + if (NBPtr->Override2DTraining) { + FoundValue = TRUE; + } else { + FoundValue = FALSE; + } + } + // + // If there is no entry, check if overriding 2D training existed. If not, show no entry found. + // + if (FoundValue == FALSE || ((P2dTraingOveride & INVALID_CONFIG_FLAG) != 0)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo 2D training config entries\n"); + return FALSE; + } else { + return TRUE; + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpsao.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpsao.c new file mode 100644 index 0000000000..aa9c1cbda3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpsao.c @@ -0,0 +1,239 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mpsao.c + * + * A sub-engine which extracts Slow access mode, Address timing and Output driver compensation value. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ps) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mu.h" +#include "ma.h" +#include "mp.h" +#include "merrhdl.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_PS_MPSAO_FILECODE + + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemPGetSAO ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * A sub-function which extracts Slow mode, Address timing and Output driver compensation value + * from a input table and store those value to a specific address. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK + * + * @return TRUE - Table values can be extracted per dimm population and ranks type. + * @return FALSE - Table values cannot be extracted per dimm population and ranks type. + * + */ +BOOLEAN +MemPGetSAO ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN MEM_PSC_TABLE_BLOCK *EntryOfTables + ) +{ + + UINT8 i; + UINT8 MaxDimmPerCh; + UINT8 MaxDimmSlotPerCh; + UINT8 NOD; + UINT8 TableSize; + UINT32 CurDDRrate; + UINT8 DDR3Voltage; + UINT16 RankTypeOfPopulatedDimm; + UINT16 RankTypeInTable; + UINT8 PsoMaskSAO; + DIMM_TYPE DimmType; + CPU_LOGICAL_ID LogicalCpuid; + UINT8 PackageType; + PSCFG_SAO_ENTRY *TblPtr; + CH_DEF_STRUCT *CurrentChannel; + + CurrentChannel = NBPtr->ChannelPtr; + + TblPtr = NULL; + TableSize = 0; + PackageType = 0; + LogicalCpuid.Family = AMD_FAMILY_UNKNOWN; + + MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + MaxDimmSlotPerCh = MaxDimmPerCh - GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID); + + if (CurrentChannel->RegDimmPresent != 0) { + DimmType = RDIMM_TYPE; + } else if (CurrentChannel->SODimmPresent != 0) { + DimmType = SODIMM_TYPE; + } else if (CurrentChannel->LrDimmPresent != 0) { + DimmType = LRDIMM_TYPE; + } else { + DimmType = UDIMM_TYPE; + } + + // Check if it is "SODIMM plus soldered-down DRAM" or "Soldered-down DRAM only" configuration, + // DimmType is changed to 'SODWN_SODIMM_TYPE' if soldered-down DRAM exist + if (MaxDimmSlotPerCh != MaxDimmPerCh) { + // SODIMM plus soldered-down DRAM + DimmType = SODWN_SODIMM_TYPE; + } else if (FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_SOLDERED_DOWN_SODIMM_TYPE, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, NULL, NULL) != NULL) { + // Soldered-down DRAM only + DimmType = SODWN_SODIMM_TYPE; + MaxDimmSlotPerCh = 0; + } + NOD = (UINT8) (MaxDimmSlotPerCh != 0) ? (1 << (MaxDimmSlotPerCh - 1)) : _DIMM_NONE; + + i = 0; + // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type. + while (EntryOfTables->TblEntryOfSAO[i] != NULL) { + if (((EntryOfTables->TblEntryOfSAO[i])->Header.DimmType & DimmType) != 0) { + if (((EntryOfTables->TblEntryOfSAO[i])->Header.NumOfDimm & NOD) != 0) { + // + // Determine if this is the expected NB Type + // + LogicalCpuid = (EntryOfTables->TblEntryOfSAO[i])->Header.LogicalCpuid; + PackageType = (EntryOfTables->TblEntryOfSAO[i])->Header.PackageType; + if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) { + TblPtr = (PSCFG_SAO_ENTRY *) ((EntryOfTables->TblEntryOfSAO[i])->TBLPtr); + TableSize = (EntryOfTables->TblEntryOfSAO[i])->TableSize; + break; + } + } + } + i++; + } + + // Check whether no table entry is found. + if (EntryOfTables->TblEntryOfSAO[i] == NULL) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo SlowAccMode, AddrTmg and ODCCtrl table\n"); + return FALSE; + } + + CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66)); + DDR3Voltage = (UINT8) (1 << CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage)); + RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel); + + for (i = 0; i < TableSize; i++) { + MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable); + if ((TblPtr->DimmPerCh & NOD) != 0) { + if ((TblPtr->DDRrate & CurDDRrate) != 0) { + if ((TblPtr->VDDIO & DDR3Voltage) != 0) { + if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) { + CurrentChannel->DctAddrTmg = TblPtr->AddTmgCtl; + CurrentChannel->DctOdcCtl = TblPtr->ODC; + CurrentChannel->SlowMode = (TblPtr->SlowMode == 1) ? TRUE : FALSE; + NBPtr->PsPtr->ProcessorOnDieTerminationOff = (TblPtr->POdtOff == 1) ? TRUE : FALSE; + break; + } + } + } + } + TblPtr++; + } + + // + // If there is no entry, check if overriding values (SlowAccMode, AddrTmg and ODCCtrl) existed. If not, show no entry found. + // + PsoMaskSAO = (UINT8) MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_SLOWACCMODE); + PsoMaskSAO &= (UINT8) MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_ODCCTRL); + PsoMaskSAO &= (UINT8) MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_ADDRTMG); + if ((PsoMaskSAO == 0) && (i == TableSize)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\nNo SlowAccMode, AddrTmg and ODCCtrl entries\n"); + } else { + return TRUE; + } + + if (NBPtr->SharedPtr->VoltageMap != VDDIO_DETERMINED) { + return TRUE; + } + + PutEventLog (AGESA_ERROR, MEM_ERROR_SAO_NOT_FOUND, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + return FALSE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.c new file mode 100644 index 0000000000..113386e20b --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.c @@ -0,0 +1,235 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mt3.c + * + * Common Technology functions for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mt3.h" +#include "mtspd3.h" +#include "mtot3.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +/* features */ +#define FILECODE PROC_MEM_TECH_DDR3_MT3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function Constructs the technology block + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +BOOLEAN +MemConstructTechBlock3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + TECHNOLOGY_TYPE *TechTypePtr; + UINT8 Dct; + UINT8 Channel; + UINT8 i; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + UINT8 DimmSlots; + + + TechTypePtr = (TECHNOLOGY_TYPE *) FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MEM_TECH, NBPtr->MCTPtr->SocketId, 0, 0, NULL, NULL); + if (TechTypePtr != NULL) { + // Ensure the platform override value is valid + ASSERT ((*TechTypePtr == DDR3_TECHNOLOGY) || (*TechTypePtr == DDR2_TECHNOLOGY)); + if (*TechTypePtr != DDR3_TECHNOLOGY) { + return FALSE; + } + } + + TechPtr->NBPtr = NBPtr; + TechPtr->RefPtr = NBPtr->RefPtr; + MCTPtr = NBPtr->MCTPtr; + + TechPtr->SendAllMRCmds = MemTSendAllMRCmds3; + TechPtr->FreqChgCtrlWrd = FreqChgCtrlWrd3; + TechPtr->SetDramMode = MemTSetDramMode3; + TechPtr->DimmPresence = MemTDIMMPresence3; + TechPtr->SpdCalcWidth = MemTSPDCalcWidth3; + TechPtr->SpdGetTargetSpeed = MemTSPDGetTargetSpeed3; + TechPtr->AutoCycTiming = MemTAutoCycTiming3; + TechPtr->SpdSetBanks = MemTSPDSetBanks3; + TechPtr->SetDqsEccTmgs = MemTSetDQSEccTmgs; + TechPtr->GetCSIntLvAddr = MemTGetCSIntLvAddr3; + TechPtr->AdjustTwrwr = MemTAdjustTwrwr3; + TechPtr->AdjustTwrrd = MemTAdjustTwrrd3; + TechPtr->GetDimmSpdBuffer = MemTGetDimmSpdBuffer3; + TechPtr->GetLD = MemTGetLD3; + TechPtr->MaxFilterDly = 0; + + // + // Map the Logical Dimms on this channel to the SPD that should be used for that logical DIMM. + // The pointers to the DIMM SPD information is as follows (2 Dimm/Ch and 3 Dimm/Ch examples). + // + // DIMM Spd Buffer Current Channel DimmSpdPtr[MAX_DIMMS_PER_CHANNEL] array + // (Number of dimms varies by platform) (Array size is determined in AGESA.H) Dimm operations loop + // on this array only) + // 2 DIMMS PER CHANNEL + // + // Socket N Channel N Dimm 0 SR/DR DIMM <--------------DimmSpdPtr[0] + // Dimm 1 SR/DR DIMM <--------------DimmSpdPtr[1] + // DimmSpdPtr[2]------->NULL + // DimmSpdPtr[3]------->NULL + // + // Socket N Channel N Dimm 0 SR/DR DIMM <--------------DimmSpdPtr[0] + // Dimm 1 QR DIMM <---------+----DimmSpdPtr[1] + // | DimmSpdPtr[2]------->NULL + // +----DimmSpdPtr[3] + // + // Socket N Channel N Dimm 0 QR DIMM <-----+--------DimmSpdPtr[0] + // Dimm 1 QR DIMM <-----|---+----DimmSpdPtr[1] + // +-- | ---DimmSpdPtr[2] + // +----DimmSpdPtr[3] + // + // 3 DIMMS PER CHANNEL + // + // Socket N Channel N Dimm 0 SR/DR DIMM <--------------DimmSpdPtr[0] + // Dimm 1 SR/DR DIMM <--------------DimmSpdPtr[1] + // Dimm 3 SR/DR DIMM <--------------DimmSpdPtr[2] + // DimmSpdPtr[3]------->NULL + // + // Socket N Channel N Dimm 0 SR/DR DIMM <--------------DimmSpdPtr[0] + // Dimm 1 QR DIMM <---------+----DimmSpdPtr[1] + // Dimm 3 SR/DR DIMM <-------- | ---DimmSpdPtr[2] + // +----DimmSpdPtr[3] + // + // + // FOR LRDIMMS + // + // This code will assign SPD pointers on the basis of Physical ranks, even though + // an LRDIMM may only use one or two logical ranks, that determination will have to + // be made from downstream code. An LRDIMM with greater than 2 Physical ranks will have + // its DimmSpdPtr[] mapped as if it were a QR in the above diagrams. + + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + DCTPtr = NBPtr->DCTPtr; + for (Channel = 0; Channel < NBPtr->ChannelCount; Channel++) { + NBPtr->SwitchChannel (NBPtr, Channel); + ChannelPtr = NBPtr->ChannelPtr; + ChannelPtr->TechType = DDR3_TECHNOLOGY; + ChannelPtr->MCTPtr = MCTPtr; + ChannelPtr->DCTPtr = DCTPtr; + + DimmSlots = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + MCTPtr->SocketId, + NBPtr->GetSocketRelativeChannel (NBPtr, Dct, Channel) + ); + // + // Initialize the SPD pointers for each Dimm + // + for (i = 0 ; i < (sizeof (ChannelPtr->DimmSpdPtr) / sizeof (ChannelPtr->DimmSpdPtr[0])) ; i++) { + ChannelPtr->DimmSpdPtr[i] = NULL; + } + for (i = 0 ; i < DimmSlots; i++) { + ChannelPtr->DimmSpdPtr[i] = &(ChannelPtr->SpdPtr[i]); + if ( (i + 2) < (sizeof (ChannelPtr->DimmSpdPtr) / sizeof (ChannelPtr->DimmSpdPtr[0]))) { + if (ChannelPtr->DimmSpdPtr[i]->DimmPresent) { + if ((((ChannelPtr->DimmSpdPtr[i]->Data[SPD_RANKS] >> 3) & 0x07) + 1) > 2) { + ChannelPtr->DimmSpdPtr[i + 2] = &(ChannelPtr->SpdPtr[i]); + } + } + } + } + } + } + // Initialize Common technology functions + MemTCommonTechInit (TechPtr); + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.h new file mode 100644 index 0000000000..d737449b05 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mt3.h @@ -0,0 +1,134 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mt3.h + * + * Common Technology + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MT3_H_ +#define _MT3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemConstructTechBlock3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT MEM_NB_BLOCK *NBPtr + ); +BOOLEAN +MemTSetDramMode3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTDIMMPresence3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTSPDCalcWidth3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTSPDGetTargetSpeed3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTAutoCycTiming3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTSPDSetBanks3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemTGetCSIntLvAddr3 ( + IN UINT8 BankEnc, + OUT UINT8 *LowBit, + OUT UINT8 *HiBit + ); + +VOID +MemTSendAllMRCmds3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 ChipSel + ); + +VOID +FreqChgCtrlWrd3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + + +BOOLEAN +MemTGetDimmSpdBuffer3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT UINT8 **SpdBuffer, + IN UINT8 Dimm + ); +#endif /* _MT3_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtlrdimm3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtlrdimm3.h new file mode 100644 index 0000000000..1ace78b00d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtlrdimm3.h @@ -0,0 +1,132 @@ +/** + * @file + * + * mtlrdimm3.h + * + * Definitions and declarations for DDR3 LRDIMM support + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MTLRDIMM3_H_ +#define _MTLRDIMM3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define RCW_FN_SELECT 7 + +#define F0 0 +#define F1 1 +#define F2 2 +#define F3 3 +#define F4 4 +#define F5 5 +#define F6 6 +#define F7 7 +#define F8 8 +#define F9 9 +#define F10 10 +#define F11 11 +#define F12 12 +#define F13 13 +#define F14 14 +#define F15 15 + +#define RC0 0 +#define RC1 1 +#define RC2 2 +#define RC3 3 +#define RC4 4 +#define RC5 5 +#define RC6 6 +#define RC7 7 +#define RC8 8 +#define RC9 9 +#define RC10 10 +#define RC11 11 +#define RC12 12 +#define RC13 13 +#define RC14 14 +#define RC15 15 + +#define SPD_NONE 0 +#define SPD_67 67 +#define SPD_68 68 +#define SPD_69 69 +#define SPD_70 70 +#define SPD_71 71 + +#define SPD_MDQ_800_1066 72 +#define SPD_QXODT_800_1066 73 +#define SPD_MR1_MR2_800_1066 77 +#define SPD_PERSONALITY_BYTE 102 +#define SPD_FREQ_DIFF_OFFSET 6 + +#define SPECIAL_CASE 0xFF +#define WAIT_6US 0xF6 + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/// LRDIMM SPECIALIZED HOOK ENTRY POINTS +typedef enum { + AFTER_TSTAB, ///< Time point after tStab + AFTER_RCW, ///< Time point after LrDimm Rcw commands are sent + BEFORE_BUFFERTRN, ///< Time point just before Buffer training + AFTER_BUFFERTRN, ///< Time point just after Buffer training + BEFORE_HOST_WL, ///< Time point before host WL + AFTER_HOST_WL ///< Time point after host WL +} LRDIMM_HOOK_ENTRYPOINT; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +#endif /* _MTLRDIMM3_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.c new file mode 100644 index 0000000000..41834f103a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.c @@ -0,0 +1,167 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtot3.c + * + * Technology Non-SPD Timings for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mtot3.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_DDR3_MTOT3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function adjusts the Twrwr value for DDR3. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTAdjustTwrwr3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + DCT_STRUCT *DCTPtr; + + DCTPtr = TechPtr->NBPtr->DCTPtr; + + // For DDR3, value 0000b-0001b and >= 1011b of Twrwr is reserved. + if (DCTPtr->Timings.Twrwr < 2) { + DCTPtr->Timings.Twrwr = 2; + } else if (DCTPtr->Timings.Twrwr > 10) { + DCTPtr->Timings.Twrwr = 10; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function adjusts the Twrrd value for DDR3. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTAdjustTwrrd3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + DCT_STRUCT *DCTPtr; + + DCTPtr = TechPtr->NBPtr->DCTPtr; + + // For DDR3, value 0000b, 0001b, and > 1010b of Twrrd is reserved. + if (DCTPtr->Timings.Twrrd < 2) { + DCTPtr->Timings.Twrrd = 2; + } else if (DCTPtr->Timings.Twrrd > 10) { + DCTPtr->Timings.Twrrd = 10; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets the LD value for DDR3. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return Value of LD + */ + +INT8 +MemTGetLD3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + INT8 LD; + MEM_NB_BLOCK *NBPtr; + NBPtr = TechPtr->NBPtr; + // + // For DDR3, BIOS calculates the latency difference (Ld) as equal to read CAS latency minus write CAS + // latency, in MEMCLKs (see F2x[1, 0]88[Tcl] and F2x[1, 0]84[Tcwl]) which can be a negative or positive + // value. + // + LD = ((INT8) NBPtr->GetBitField (NBPtr, BFTcl) + 4) - ((INT8) NBPtr->GetBitField (NBPtr, BFTcwl) + 5); + + return LD; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.h new file mode 100644 index 0000000000..05f0c41a72 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtot3.h @@ -0,0 +1,90 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtot3.h + * + * Technology Non-SPD timings for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MTOT3_H_ +#define _MTOT3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + + +VOID +MemTAdjustTwrwr3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemTAdjustTwrrd3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +INT8 +MemTGetLD3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +#endif /* _MTOT3_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.c new file mode 100644 index 0000000000..bc7a5a0b08 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.c @@ -0,0 +1,318 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtrci3.c + * + * Technology Control word initialization for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mt3.h" +#include "mtrci3.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_DDR3_MTRCI3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sends control words + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTDramControlRegInit3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 ChipSel; + UINT8 i; + UINT8 RawCard; + UINT8 Data; + UINT16 CsPresent; + + MEM_DATA_STRUCT *MemPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + CsPresent = NBPtr->DCTPtr->Timings.CsPresent; + + MemUWait10ns (800, MemPtr); // wait 8us TACT must be changed to optimize to 8 MEM CLKs + + // Set EnDramInit to start DRAM initialization + + MemUWait10ns (600, MemPtr); // wait 6us for PLL LOCK + + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel += 2) { + // + // If chip select present + // + if ((CsPresent & ((UINT16)3 << ChipSel)) != 0) { + NBPtr->SetBitField (NBPtr, BFMrsChipSel, ChipSel); + + // 2. Program F2x[1, 0]A8[CtrlWordCS]=bit mask for target chip selects. + NBPtr->SetBitField (NBPtr, BFCtrlWordCS, 3 << (ChipSel & 0xFE)); + + RawCard = NBPtr->ChannelPtr->RefRawCard[ChipSel >> 1]; + + for (i = 0; i <= 15; i++) { + // wait 8us for TMRD, must be changed to optimize to 8 MEM CLKs + MemUWait10ns (800, MemPtr); + if ((i != 6) && (i != 7)) { + Data = MemTGetCtlWord3 (TechPtr, i, RawCard, ChipSel); + MemTSendCtlWord3 (TechPtr, i, Data); + } + } + } + } + MemUWait10ns (600, MemPtr); // wait 6us for TSTAB +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates the ControlRC value + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] CtrlWordNum - control Word number. + * @param[in] RawCard - Raw Card + * @param[in] ChipSel - Target Chip Select + * @return Control Word value + */ + +UINT8 +MemTGetCtlWord3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 CtrlWordNum, + IN UINT8 RawCard, + IN UINT8 ChipSel + ) +{ + UINT8 Data; + UINT8 PowerDownMode; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + + DCTPtr = TechPtr->NBPtr->DCTPtr; + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + + Data = 0; //Default value for all control words is 0 + switch (CtrlWordNum) { + case 0: + Data = 0x02; // DA4=1 + break; + case 1: + if (DCTPtr->Timings.DimmSRPresent & ((UINT16) 1 << (ChipSel >> 1))) { + Data = 0x0C; // if single rank, set DBA1 and DBA0 + } + break; + case 2: + Data = ChannelPtr->CtrlWrd02[ChipSel >> 1]; + break; + case 3: + Data = ChannelPtr->CtrlWrd03[ChipSel >> 1]; + break; + case 4: + Data = ChannelPtr->CtrlWrd04[ChipSel >> 1]; + break; + case 5: + Data = ChannelPtr->CtrlWrd05[ChipSel >> 1]; + break; + case 8: + Data = ChannelPtr->CtrlWrd08[ChipSel >> 1]; + break; + case 9: + // RC9 = 0xD except when partial powerdown mode is enabled and mix SR/DR or SR/QR configurations, + // RC9 should be 0x9 for SR and and 0xD for DR or QR RDIMMs. + PowerDownMode = (UINT8) UserOptions.CfgPowerDownMode; + PowerDownMode = (!TechPtr->NBPtr->IsSupported[ChannelPDMode]) ? PowerDownMode : 0; + IDS_OPTION_HOOK (IDS_POWERDOWN_MODE, &PowerDownMode, &(TechPtr->NBPtr->MemPtr->StdHeader)); + if ((PowerDownMode == 1) && + (DCTPtr->Timings.DimmSRPresent & ((UINT16) 1 << (ChipSel >> 1))) && + ((DCTPtr->Timings.DimmDrPresent != 0) || (DCTPtr->Timings.DimmQrPresent != 0))) { + Data = 0x09; + } else { + Data = 0x0D; + } + break; + case 11: + Data = CONVERT_VDDIO_TO_ENCODED (TechPtr->RefPtr->DDR3Voltage); + break; + default:; + } + + return (Data & 0x0F); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sends control word command + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] CmdNum - control number. + * @param[in] Value - value to send + * + */ + +VOID +MemTSendCtlWord3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 CmdNum, + IN UINT8 Value + ) +{ + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + + // 1. Program MrsBank and MrsAddress. + // n = [BA2, A2, A1, A0]. + // data = [BA1, BA0, A4, A3]. + // Set all other bits in MrsAddress to zero. + // + NBPtr->SetBitField (NBPtr, BFMrsBank, ((CmdNum & 8) >> 1) | (Value >> 2)); + NBPtr->SetBitField (NBPtr, BFMrsAddress, ((Value & 3) << 3) | (CmdNum & 7)); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS%d RC%02d %04x\n", (MemNGetBitFieldNb (NBPtr, BFMrsChipSel) & 7), CmdNum, Value); + + // 2.Set SendCtrlWord=1 + NBPtr->SetBitField (NBPtr, BFSendCtrlWord, 1); + // 3.Wait for BFSendCtrlWord=0 + NBPtr->PollBitField (NBPtr, BFSendCtrlWord, 0, PCI_ACCESS_TIMEOUT, FALSE); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sends specific control words commands before frequency change for certain DRAM buffers. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +FreqChgCtrlWrd3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 ChipSel; + UINT16 Speed; + UINT16 CsPresent; + + MEM_DATA_STRUCT *MemPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + Speed = NBPtr->DCTPtr->Timings.Speed; + CsPresent = NBPtr->DCTPtr->Timings.CsPresent; + + + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel += 2) { + // + // If chip select present. + // + if ((CsPresent & ((UINT16)3 << ChipSel)) != 0) { + + NBPtr->SetBitField (NBPtr, BFMrsChipSel, ChipSel); + // program F2x[1, 0]A8[CtrlWordCS]=bit mask for target chip selects. + NBPtr->SetBitField (NBPtr, BFCtrlWordCS, 3 << (ChipSel & 0xFE)); + + //wait 8us for TMRD, must be changed to optimize to 8 MEM CLKs + MemUWait10ns (800, MemPtr); + if (Speed == DDR800_FREQUENCY) { + MemTSendCtlWord3 (TechPtr, 0x0A, 0); + } else if (Speed == DDR1066_FREQUENCY) { + MemTSendCtlWord3 (TechPtr, 0x0A, 1); + } else if (Speed == DDR1333_FREQUENCY) { + MemTSendCtlWord3 (TechPtr, 0x0A, 2); + } else if (Speed == DDR1600_FREQUENCY) { + MemTSendCtlWord3 (TechPtr, 0x0A, 3); + } else if (Speed == DDR1866_FREQUENCY) { + MemTSendCtlWord3 (TechPtr, 0x0A, 4); + } else { + ASSERT (FALSE); + } + } + } +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.h new file mode 100644 index 0000000000..7b2db43f8f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtrci3.h @@ -0,0 +1,87 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtrci3.h + * + * Technology control word init for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MTRCI3_H_ +#define _MTRCI3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +UINT8 +MemTGetCtlWord3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 CtrlWordNum, + IN UINT8 RawCard, + IN UINT8 ChipSel + ); + +VOID +MemTDramControlRegInit3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +#endif /* _MTRCI3_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.c new file mode 100644 index 0000000000..a023705110 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.c @@ -0,0 +1,503 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtsdi3.c + * + * Technology Software DRAM Init for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mt3.h" +#include "mtsdi3.h" +#include "mtrci3.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) +#define FILECODE PROC_MEM_TECH_DDR3_MTSDI3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initiates software DRAM init for both DCTs + * at the same time. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +BOOLEAN +MemTDramInitSw3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 Dct; + UINT8 ChipSel; + + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + MCTPtr = NBPtr->MCTPtr; + + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart Dram Init\n"); + // 3.Program F2x[1,0]7C[EnDramInit]=1 + IDS_HDT_CONSOLE (MEM_FLOW, "\tEnDramInit = 1 for both DCTs\n"); + NBPtr->BrdcstSet (NBPtr, BFEnDramInit, 1); + NBPtr->PollBitField (NBPtr, BFDctAccessDone, 1, PCI_ACCESS_TIMEOUT, TRUE); + + // 4.wait 200us + MemUWait10ns (20000, MemPtr); + + // 5.Program F2x[1, 0]7C[DeassertMemRstX] = 1. + NBPtr->BrdcstSet (NBPtr, BFDeassertMemRstX, 1); + + // 6.wait 500us + MemUWait10ns (50000, MemPtr); + + // Do Phy Fence training before sending MRS commands + if (!NBPtr->IsSupported[FenceTrnBeforeDramInit]) { + AGESA_TESTPOINT (TpProcMemPhyFenceTraining, &(NBPtr->MemPtr->StdHeader)); + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->PhyFenceTraining (NBPtr); + } + } + } + + // 7.NOP or deselect & take CKE high + NBPtr->BrdcstSet (NBPtr, BFAssertCke, 1); + + // 8.wait 360ns + MemUWait10ns (36, MemPtr); + + // The following steps are performed once for each channel with unbuffered DIMMs + // and once for each chip select on registered DIMMs: + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + + // Enable Dram Parity if appropriate. + NBPtr->FamilySpecificHook[EnableParityAfterMemRst] (NBPtr, NULL); + + // The following steps are performed with registered DIMMs only and + // must be done for each chip select pair: + if (MCTPtr->Status[SbRegistered]) { + MemTDramControlRegInit3 (TechPtr); + } + + // Initialize LRDIMM's register + TechPtr->TechnologySpecificHook[LrdimmControlRegInit] (TechPtr, NULL); + + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) { + if ((NBPtr->DCTPtr->Timings.CsPresent & ((UINT16)1 << ChipSel)) != 0) { + IDS_HDT_CONSOLE (MEM_STATUS, "\t\tCS %d\n", ChipSel); + // if chip select present + if (!(TechPtr->TechnologySpecificHook[LrdimmSendAllMRCmds] (TechPtr, &ChipSel))) { + MemTSendAllMRCmds3 (TechPtr, ChipSel); + } + // NOTE: wait 512 clocks for DLL-relock + MemUWait10ns (50000, NBPtr->MemPtr); // wait 500us + if (!(MCTPtr->Status[SbRegistered] || MCTPtr->Status[SbLrdimms])) { + break; + } + } + } + + // 17.Send two ZQCL commands (to even then odd chip select) + NBPtr->sendZQCmd (NBPtr); + NBPtr->sendZQCmd (NBPtr); + } + } + + // 18.Program F2x[1,0]7C[EnDramInit]=0 + NBPtr->BrdcstSet (NBPtr, BFEnDramInit, 0); + NBPtr->PollBitField (NBPtr, BFDctAccessDone, 1, PCI_ACCESS_TIMEOUT, TRUE); + // + // For Unbuffered Dimms, Issue MRS for remaining CS without EnDramInit + // + NBPtr->FamilySpecificHook[SendMrsCmdsPerCs] (NBPtr, NBPtr); + + IDS_HDT_CONSOLE (MEM_FLOW, "End Dram Init\n\n"); + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates the EMRS1 value + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Wl - Indicates if WL mode should be enabled + * @param[in] TargetDIMM - DIMM target for WL + */ + +VOID +MemTEMRS13 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN BOOLEAN Wl, + IN UINT8 TargetDIMM + ) +{ + UINT16 MrsAddress; + UINT8 MaxDimmPerCH; + UINT8 ChipSel; + UINT8 Value8; + + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MaxDimmPerCH = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + NBPtr->MCTPtr->SocketId, + NBPtr->ChannelPtr->ChannelID); + ChipSel = (UINT8) (0x0FF & NBPtr->GetBitField (NBPtr, BFMrsChipSel)); + + // BA2=0,BA1=0,BA0=1 + NBPtr->SetBitField (NBPtr, BFMrsBank, 1); + + MrsAddress = 0; + + // program MrsAddress[5,1]=output driver impedance control (DIC): + // based on F2x[1,0]84[DrvImpCtrl] + if (!(NBPtr->IsSupported[CheckDrvImpCtrl])) { + Value8 = (UINT8)NBPtr->GetBitField (NBPtr, BFDrvImpCtrl); + if ((Value8 & ((UINT8) 1 << 1)) != 0) { + MrsAddress |= ((UINT16) 1 << 5); + } + if ((Value8 & ((UINT8) 1 << 0)) != 0) { + MrsAddress |= ((UINT16) 1 << 1); + } + } else { + MrsAddress |= ((UINT16) 1 << 1); + } + // program MrsAddress[9,6,2]=nominal termination resistance of ODT (RTT): + // Different CS may have different RTT. + // + Value8 = NBPtr->MemNGetDramTerm (NBPtr, ChipSel); + + // + // If Write Leveling this DIMM + // + if (Wl) { + if ((ChipSel / NBPtr->CsPerDelay) == TargetDIMM) { + // Program MrsAddress[7] = 1 for Write leveling enable + MrsAddress |= ((UINT16) 1 << 7); + if (ChipSel & 1) { + // Output buffer disabled, MrsAddress[7] (Qoff = 1) + MrsAddress |= ((UINT16) 1 << 12); + } + // Set Rtt_Nom = Rtt_Wr if there are 2 or more dimms + if ((NBPtr->ChannelPtr->DimmQrPresent != 0) || (NBPtr->ChannelPtr->Dimms >= 2)) { + Value8 = NBPtr->MemNGetDynDramTerm (NBPtr, ChipSel); + } else if (NBPtr->IsSupported[WlRttNomFor1of3Cfg] && (MaxDimmPerCH == 3)) { + // For some family, set Rtt_Nom = Rtt_Wr in one of three DIMMs per channel configurations + Value8 = NBPtr->MemNGetDynDramTerm (NBPtr, ChipSel); + } + } + NBPtr->FamilySpecificHook[WLMR1] (NBPtr, &MrsAddress); + } + // + // Turn off Rtt_Nom (DramTerm=0) for certain CS in certain configs. + // + // All odd CS for 4 Dimm Systems + if (MaxDimmPerCH == 4) { + if (ChipSel & 0x01) { + Value8 = 0; + } + // CS 1 and 5 for 3 Dimm configs + } else if (MaxDimmPerCH == 3) { + if ((ChipSel == 1) || (ChipSel == 5)) { + Value8 = 0; + } + } + // All odd CS of any QR Dimms + if ((NBPtr->ChannelPtr->DimmQrPresent & ((UINT8) (1 << (ChipSel >> 1)))) != 0) { + if (ChipSel & 0x01) { + Value8 = 0; + } + } + if ((Value8 & ((UINT8) 1 << 2)) != 0) { + MrsAddress |= ((UINT16) 1 << 9); + } + if ((Value8 & ((UINT8) 1 << 1)) != 0) { + MrsAddress |= ((UINT16) 1 << 6); + } + if ((Value8 & ((UINT8) 1 << 0)) != 0) { + MrsAddress |= ((UINT16) 1 << 2); + } + + // program MrsAddress[12]=output disable (QOFF): + // based on F2x[1,0]84[Qoff] + + if (!NBPtr->IsSupported[CheckQoff]) { + if (NBPtr->GetBitField (NBPtr, BFQoff) != 0) { + MrsAddress |= ((UINT16) 1 << 12); + } + } + + // program MrsAddress[11]=TDQS: + // based on F2x[1,0]94[RDqsEn] + + if ((NBPtr->DCTPtr->Timings.Dimmx4Present != 0) && (NBPtr->DCTPtr->Timings.Dimmx8Present != 0)) { + if (!(NBPtr->IsSupported[SetTDqsForx8DimmOnly]) || ((NBPtr->DCTPtr->Timings.Dimmx8Present & ((UINT8) 1 << (ChipSel >> 1))) != 0)) { + MrsAddress |= ((UINT16) 1 << 11); + } + } + + NBPtr->SetBitField (NBPtr, BFMrsAddress, MrsAddress); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates the EMRS2 value + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTEMRS23 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT32 MrsAddress; + UINT8 DramTermDyn; + UINT8 MaxDimmPerCH; + UINT8 ChipSel; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + + MaxDimmPerCH = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID ); + ChipSel = (UINT8) (0x0FF & NBPtr->GetBitField (NBPtr, BFMrsChipSel)); + + // BA2=0,BA1=1,BA0=0 + NBPtr->SetBitField (NBPtr, BFMrsBank, 2); + + // program MrsAddress[5:3]=CAS write latency (CWL): + MrsAddress = NBPtr->MemNGetMR2CWL (NBPtr); + + // program MrsAddress[6]=auto self refresh method (ASR): + // program MrsAddress[7]=self refresh temperature range (SRT): + MrsAddress |= 1 << 6; + MrsAddress &= ( ~ (1 << 7)); + + // program MrsAddress[10:9]=dynamic termination during writes (RTT_WR): + DramTermDyn = NBPtr->MemNGetDynDramTerm (NBPtr, ChipSel); + // Special Case for 1 DR Unbuffered Dimm in 3 Dimm/Ch + if (!(NBPtr->MCTPtr->Status[SbRegistered])) { + if (MaxDimmPerCH == 3) { + if (NBPtr->ChannelPtr->Dimms == 1) { + if ((NBPtr->ChannelPtr->DimmDrPresent & ((UINT8) (1 << (ChipSel >> 1)))) != 0) { + DramTermDyn = 1; + } + } + } + } + MrsAddress |= (UINT16) DramTermDyn << 9; + + NBPtr->SetBitField (NBPtr, BFMrsAddress, MrsAddress); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates the EMRS3 value + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTEMRS33 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + + // BA2=0,BA1=1,BA0=1 + NBPtr->SetBitField (NBPtr, BFMrsBank, 3); + + // program MrsAddress[1:0]=multi purpose register address location + // (MPR Location):based on F2x[1,0]84[MprLoc] + // program MrsAddress[2]=multi purpose register + // (MPR):based on F2x[1,0]84[MprEn] + NBPtr->SetBitField (NBPtr, BFMrsAddress, (NBPtr->GetBitField (NBPtr, BFDramMRSReg) >> 24) & 0x0007); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This sets MRS value + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTMRS3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT32 MrsAddress; + MEM_NB_BLOCK *NBPtr; + UINT32 Ppd; + + NBPtr = TechPtr->NBPtr; + + // BA2=0,BA1=0,BA0=0 + NBPtr->SetBitField (NBPtr, BFMrsBank, 0); + + // program MrsAddress[1:0]=burst length and control method + // (BL):based on F2x[1,0]84[BurstCtrl] + MrsAddress = NBPtr->GetBitField (NBPtr, BFBurstCtrl); + + // program MrsAddress[3]=1 (BT):interleaved + MrsAddress |= (UINT16) 1 << 3; + + // program MrsAddress[6:4,2]=read CAS latency + MrsAddress |= NBPtr->MemNGetMR0CL (NBPtr); + + // program MrsAddress[11:9]=write recovery for auto-precharge + MrsAddress |= NBPtr->MemNGetMR0WR (NBPtr); + + // program MrsAddress[12] (PPD):based on F2x[1,0]84[PChgPDModeSel] + Ppd = NBPtr->GetBitField (NBPtr, BFPchgPDModeSel); + NBPtr->FamilySpecificHook[MR0_PPD] (NBPtr, &Ppd); + IDS_OPTION_HOOK (IDS_MEM_MR0, &Ppd, &TechPtr->NBPtr->MemPtr->StdHeader); + MrsAddress |= Ppd << 12; + + // program MrsAddress[8]=1 (DLL):DLL reset + MrsAddress |= (UINT32) 1 << 8; + + // During memory initialization, the value sent to MR0 is saved for S3 resume + NBPtr->MemNSaveMR0 (NBPtr, MrsAddress); + + NBPtr->SetBitField (NBPtr, BFMrsAddress, MrsAddress); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This send all MR commands to a rank in sequence 2-3-1-0 + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] ChipSel - Target Chip Select + */ + +VOID +MemTSendAllMRCmds3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 ChipSel + ) +{ + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + + NBPtr->SetBitField (NBPtr, BFMrsChipSel, ChipSel); + + // 13.Send EMRS(2) + MemTEMRS23 (TechPtr); + AGESA_TESTPOINT (TpProcMemSendMRS2, &(NBPtr->MemPtr->StdHeader)); + NBPtr->SendMrsCmd (NBPtr); + + // 14.Send EMRS(3). Ordinarily at this time, MrsAddress[2:0]=000b + MemTEMRS33 (TechPtr); + AGESA_TESTPOINT (TpProcMemSendMRS3, &(NBPtr->MemPtr->StdHeader)); + NBPtr->SendMrsCmd (NBPtr); + + // 15.Send EMRS(1). + MemTEMRS13 (TechPtr, FALSE, (ChipSel >> 1)); + AGESA_TESTPOINT (TpProcMemSendMRS1, &(NBPtr->MemPtr->StdHeader)); + NBPtr->SendMrsCmd (NBPtr); + + // 16.Send MRS with MrsAddress[8]=1(reset the DLL) + MemTMRS3 (TechPtr); + AGESA_TESTPOINT (TpProcMemSendMRS0, &(NBPtr->MemPtr->StdHeader)); + NBPtr->SendMrsCmd (NBPtr); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.h new file mode 100644 index 0000000000..69461e3957 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtsdi3.h @@ -0,0 +1,96 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtsdi3.h + * + * Technology software DRAM init for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MTSDI3_H_ +#define _MTSDI3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +VOID +MemTEMRS33 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemTMRS3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemTEMRS13 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN BOOLEAN Wl, + IN UINT8 TargetDIMM + ); + +VOID +MemTEMRS23 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +#endif /* _MTSDI3_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.c new file mode 100644 index 0000000000..5e20a3fde7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.c @@ -0,0 +1,1202 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtspd3.c + * + * Technology SPD supporting functions for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 85961 $ @e \$Date: 2013-01-14 19:58:20 -0600 (Mon, 14 Jan 2013) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "Ids.h" +#include "mport.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mt3.h" +#include "mu.h" +#include "mtspd3.h" +#include "mftds.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_DDR3_MTSPD3_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemTCRCCheck3 ( + IN OUT UINT8 *SPDPtr + ); + +UINT8 +STATIC +MemTSPDGetTCL3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +STATIC +MemTCheckBankAddr3 ( + IN UINT8 Encode, + OUT UINT8 *Index + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the DRAM mode + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - indicates that the DRAM mode is set to DDR3 + */ + +BOOLEAN +MemTSetDramMode3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFLegacyBiosMode, 0); + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFDdr3Mode, 1); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines if DIMMs are present. It checks checksum and interrogates the SPDs + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - indicates that a FATAL error has not occurred + * @return FALSE - indicates that a FATAL error has occurred + */ + +BOOLEAN +MemTDIMMPresence3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 Dct; + UINT8 Channel; + UINT8 i; + MEM_PARAMETER_STRUCT *RefPtr; + UINT8 *SpdBufferPtr; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + MEM_NB_BLOCK *NBPtr; + BOOLEAN SPDCtrl; + UINT8 Devwidth; + UINT8 MaxDimms; + UINT8 NumDimmslots; + UINT8 Value8; + UINT16 DimmMask; + UINT32 DimmValidMask; + + NBPtr = TechPtr->NBPtr; + RefPtr = NBPtr->RefPtr; + MCTPtr = NBPtr->MCTPtr; + + SPDCtrl = UserOptions.CfgIgnoreSpdChecksum; + DimmValidMask = 0; + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + DCTPtr = NBPtr->DCTPtr; + for (Channel = 0; Channel < NBPtr->ChannelCount; Channel++) { + NBPtr->SwitchChannel (NBPtr, Channel); + ChannelPtr = NBPtr->ChannelPtr; + ChannelPtr->DimmQrPresent = 0; + // + // Get the maximum number of DIMMs + // + MaxDimms = MAX_DIMMS_PER_CHANNEL; + NumDimmslots = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, + MCTPtr->SocketId, + ChannelPtr->ChannelID); + DimmValidMask |= (NumDimmslots == 3) ? 0x7 : 0x3; + + for (i = 0; i < MaxDimms; i++) { + // Bitmask representing dimm #i. + DimmMask = (UINT16)1 << i; + // + if (MemTGetDimmSpdBuffer3 (TechPtr, &SpdBufferPtr, i)) { + MCTPtr->DimmPresent |= DimmMask; + // + // Check for valid checksum value + // + AGESA_TESTPOINT (TpProcMemSPDChecking, &(NBPtr->MemPtr->StdHeader)); + if (SpdBufferPtr[SPD_TYPE] == JED_DDR3SDRAM) { + ChannelPtr->ChDimmValid |= DimmMask; + MCTPtr->DimmValid |= DimmMask; + } else if (NBPtr->IsSupported[G5DimmInD3Socket]) { + // If a non-DDR3 DIMM is installed, mark all DIMMs of that channel as not present + MCTPtr->DimmPresent &= ~((UINT32) 0xFF << Dct); + MCTPtr->DimmValid &= ~((UINT32) 0xFF << Dct); + ChannelPtr->ChDimmValid = 0; + DCTPtr->Timings.DctDimmValid = 0; + MCTPtr->ErrStatus[EsbDimmMismatchM] = TRUE; + PutEventLog (AGESA_ERROR, MEM_ERROR_MODULE_TYPE_MISMATCH_DIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + continue; + } else { + // Current socket is set up to only support DDR3 dimms. + IDS_ERROR_TRAP; + } + if (!MemTCRCCheck3 (SpdBufferPtr) && !SPDCtrl && !NBPtr->IsSupported[AMPIsEnabled]) { + // + // NV_SPDCHK_RESTRT is set to 0, + // cannot ignore faulty SPD checksum + // + // Indicate checksum error + ChannelPtr->DimmSpdCse |= DimmMask; + PutEventLog (AGESA_ERROR, MEM_ERROR_CHECKSUM_NV_SPDCHK_RESTRT_ERROR, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + } + // + // Check module type information. + // + if (SpdBufferPtr[SPD_DIMM_TYPE] == JED_LRDIMM) { + // + // LRDIMMS + // + if (i < NumDimmslots) { + ChannelPtr->LrDimmPresent |= DimmMask; + MCTPtr->LrDimmPresent |= DimmMask; + + if (!UserOptions.CfgMemoryLRDimmCapable) { + PutEventLog (AGESA_WARNING, MEM_WARNING_UNSUPPORTED_LRDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + IDS_ERROR_TRAP; + } + TechPtr->TechnologySpecificHook[LrdimmPresence] (TechPtr, &i); + } + } + if (SpdBufferPtr[SPD_DIMM_TYPE] == JED_RDIMM || SpdBufferPtr[SPD_DIMM_TYPE] == JED_MINIRDIMM) { + // + // RDIMMS + // + ChannelPtr->RegDimmPresent |= DimmMask; + MCTPtr->RegDimmPresent |= DimmMask; + if (!UserOptions.CfgMemoryRDimmCapable) { + PutEventLog (AGESA_WARNING, MEM_WARNING_UNSUPPORTED_RDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + IDS_ERROR_TRAP; + } + } + if ((SpdBufferPtr[SPD_DIMM_TYPE] == JED_UDIMM) && !UserOptions.CfgMemoryUDimmCapable) { + PutEventLog (AGESA_WARNING, MEM_WARNING_UNSUPPORTED_UDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + IDS_ERROR_TRAP; + } + if ((SpdBufferPtr[SPD_DIMM_TYPE] == JED_SODIMM) || (SpdBufferPtr[SPD_DIMM_TYPE] == JED_72B_SOUDIMM)) { + ChannelPtr->SODimmPresent |= DimmMask; + if (!UserOptions.CfgMemorySODimmCapable) { + PutEventLog (AGESA_WARNING, MEM_WARNING_UNSUPPORTED_SODIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + IDS_ERROR_TRAP; + } + } + // + // Check error correction type + // + if ((SpdBufferPtr[SPD_ECCBITS] & JED_ECC) != 0) { + MCTPtr->DimmEccPresent |= DimmMask; // Dimm has ECC + } + // + // Get the Dimm width data + // + Devwidth = SpdBufferPtr[SPD_DEV_WIDTH] & 0x7; + switch (Devwidth) { + case 0: + ChannelPtr->Dimmx4Present |= DimmMask; + if ((ChannelPtr->LrDimmPresent & DimmMask) == 0) { + // + // DimmNibbleAccess indicates that a DIMM will use nibble signaling and use nibble training. + // LRDIMMs will not use Nibble based signaling even if x4 parts are present. + // + if (i < NumDimmslots) { + ChannelPtr->DimmNibbleAccess |= DimmMask; + } + } + Devwidth = 4; + break; + case 1: + ChannelPtr->Dimmx8Present |= DimmMask; + Devwidth = 8; + break; + case 2: + ChannelPtr->Dimmx16Present |= DimmMask; + Devwidth = 16; + break; + default: + IDS_ERROR_TRAP; + } + // + // Check for 'analysis probe installed' + // if (SpdBufferPtr[SPD_ATTRIB] & JED_PROBE_MSK) + // + // Determine the geometry of the DIMM module + // if (SpdBufferPtr[SPD_DM_BANKS] & SP_DPL_BIT) + // + // specify the number of ranks + // + Value8 = ((SpdBufferPtr[SPD_RANKS] >> 3) & 0x07) + 1; + if (Value8 == 5) { + // Octal Rank + Value8 = 8; + } + // + // For LRDIMMS we will assume that if there are at least 4 Physical ranks, then it Could be used + // as a QR RDIMM with a rank Mux of x1 and therefore all four CS will be used. So an 8R LRDIMM will + // be marked as a QR even if Rank multiplication allows it to use only 2 logical ranks. + // + if ((ChannelPtr->LrDimmPresent & DimmMask) != 0) { + // + // LRDIMM Physical Ranks + // + ChannelPtr->LrdimmPhysicalRanks[i] = Value8; + } + if (Value8 > 2) { + if (!UserOptions.CfgMemoryQuadRankCapable) { + PutEventLog (AGESA_WARNING, MEM_WARNING_UNSUPPORTED_QRDIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + } + // + // Mark this Dimm as Quad Rank + // + ChannelPtr->DimmQrPresent |= DimmMask; + Value8 = 2; + } else if (Value8 == 2) { + ChannelPtr->DimmDrPresent |= DimmMask; // Dual rank dimms + } else { + ChannelPtr->DimmSRPresent |= DimmMask; // Single rank dimms + } + // + // Calculate bus loading per Channel + if (Devwidth == 16) { + Devwidth = 4; + } else if (Devwidth == 4) { + Devwidth = 16; + } + // + // Double Addr bus load value for dual rank DIMMs (Unless LRDIMM) + // + if (((ChannelPtr->LrDimmPresent & DimmMask) == 0) && (Value8 == 2) ) { + Devwidth = Devwidth << 1; + } + // + ChannelPtr->Ranks = ChannelPtr->Ranks + Value8; + ChannelPtr->Loads = ChannelPtr->Loads + Devwidth; + if ((i < NumDimmslots) || ((ChannelPtr->DimmQrPresent & DimmMask) == 0)) { + ChannelPtr->Dimms++; + } + // + // Check address mirror support for Unbuffered Dimms or LRDimms + // + if ((ChannelPtr->RegDimmPresent & DimmMask) == 0) { + if ((SpdBufferPtr[SPD_ADDRMAP] & 1) != 0) { + ChannelPtr->DimmMirrorPresent |= DimmMask; + } + } + // + // Get byte62: Reference Raw Card information + // + ChannelPtr->RefRawCard[i] = SpdBufferPtr[SPD_RAWCARD] & 0x1F; + // + // Get control word values for RC3, RC4 and RC5 + // + ChannelPtr->CtrlWrd03[i] = SpdBufferPtr[SPD_CTLWRD03] >> 4; + ChannelPtr->CtrlWrd04[i] = SpdBufferPtr[SPD_CTLWRD04] & 0x0F; + ChannelPtr->CtrlWrd05[i] = SpdBufferPtr[SPD_CTLWRD05] >> 4; + // + // Temporarily store info. of SPD byte 63 into CtrlWrd02(s), + // and they will be used late to calculate real RC2 and RC8 value + // + ChannelPtr->CtrlWrd02[i] = SpdBufferPtr[SPD_ADDRMAP] & 0x03; + // + // Copy the number of registers to the Ps Block to persist across frequency changes + // + NBPtr->PsPtr->NumOfReg[i] = SpdBufferPtr[SPD_ADDRMAP] & 0x03; + // + // Workaround for early revisions of DIMMs which SPD byte 63 is 0 + // + if (NBPtr->PsPtr->NumOfReg[i] == JED_UNDEFINED) { + NBPtr->PsPtr->NumOfReg[i] = 1; + } + } // if DIMM present + } // Dimm loop + + if (Channel == 0) { + DCTPtr->Timings.DctDimmValid = ChannelPtr->ChDimmValid; + DCTPtr->Timings.DimmMirrorPresent = ChannelPtr->DimmMirrorPresent; + DCTPtr->Timings.DimmSpdCse = ChannelPtr->DimmSpdCse; + DCTPtr->Timings.DimmQrPresent = ChannelPtr->DimmQrPresent; + DCTPtr->Timings.DimmDrPresent = ChannelPtr->DimmDrPresent; + DCTPtr->Timings.DimmSRPresent = ChannelPtr->DimmSRPresent; + DCTPtr->Timings.Dimmx4Present = ChannelPtr->Dimmx4Present; + DCTPtr->Timings.Dimmx8Present = ChannelPtr->Dimmx8Present; + DCTPtr->Timings.Dimmx16Present = ChannelPtr->Dimmx16Present; + } + if ((Channel != 1) || (Dct != 1)) { + MCTPtr->DimmPresent <<= 8; + MCTPtr->DimmValid <<= 8; + MCTPtr->RegDimmPresent <<= 8; + MCTPtr->LrDimmPresent <<= 8; + MCTPtr->DimmEccPresent <<= 8; + MCTPtr->DimmParPresent <<= 8; + DimmValidMask <<= 8; + } + } // Channel loop + } // DCT loop + + // If we have DIMMs, some further general characteristics checking + if (MCTPtr->DimmValid != 0) { + // If there are registered dimms, all the dimms must be registered + if (MCTPtr->RegDimmPresent == MCTPtr->DimmValid) { + // All dimms registered + MCTPtr->Status[SbRegistered] = TRUE; + MCTPtr->Status[SbParDimms] = TRUE; // All DDR3 RDIMMs are parity capable + TechPtr->SetDqsEccTmgs = MemTSetDQSEccTmgsRDdr3; // Change the function pointer for DQS ECC timing + } else if (MCTPtr->RegDimmPresent != 0) { + // We have an illegal DIMM mismatch + PutEventLog (AGESA_FATAL, MEM_ERROR_MODULE_TYPE_MISMATCH_DIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_FATAL, MCTPtr); + } + // If there are LrDimms, all the dimms must be LrDimms + if (MCTPtr->LrDimmPresent == (MCTPtr->DimmValid & DimmValidMask)) { + // All dimms LRDIMMs + MCTPtr->Status[SbLrdimms] = TRUE; + MCTPtr->Status[SbParDimms] = TRUE; // All DDR3 RDIMMs are parity capable + } else if (MCTPtr->LrDimmPresent != 0) { + // We have an illegal DIMM mismatch + PutEventLog (AGESA_FATAL, MEM_ERROR_MODULE_TYPE_MISMATCH_DIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_FATAL, MCTPtr); + } + + // check the ECC capability of the DIMMs + if (MCTPtr->DimmEccPresent == MCTPtr->DimmValid) { + MCTPtr->Status[SbEccDimms] = TRUE; // All dimms ECC capable + } + } else { + } + + NBPtr->SwitchDCT (NBPtr, 0); + NBPtr->SwitchChannel (NBPtr, 0); + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the maximum frequency that each channel is capable to run at. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - indicates that a FATAL error has not occurred + * @return FALSE - indicates that a FATAL error has occurred + */ + +BOOLEAN +MemTSPDGetTargetSpeed3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 *SpdBufferPtr; + UINT8 Dimm; + UINT8 Dct; + UINT8 Channel; + INT32 MTB_ps; + INT32 FTB_ps; + INT32 TCKmin_ps; + INT32 Value32; + MEM_NB_BLOCK *NBPtr; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + + NBPtr = TechPtr->NBPtr; + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + DCTPtr = NBPtr->DCTPtr; + TCKmin_ps = 0; + for (Channel = 0; Channel < NBPtr->ChannelCount; Channel++) { + NBPtr->SwitchChannel (NBPtr, Channel); + ChannelPtr = NBPtr->ChannelPtr; + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) { + if ((ChannelPtr->ChDimmValid & ((UINT8)1 << Dimm)) != 0) { + MemTGetDimmSpdBuffer3 (TechPtr, &SpdBufferPtr, Dimm); + + // Determine tCKmin(all) which is the largest tCKmin + // value for all modules on the memory Channel (SPD byte 12). + // + MTB_ps = ((INT32) SpdBufferPtr[SPD_DIVIDENT] * 1000) / SpdBufferPtr[SPD_DIVISOR]; + FTB_ps = (SpdBufferPtr[SPD_FTB] >> 4) / (SpdBufferPtr[SPD_FTB] & 0xF); + Value32 = (MTB_ps * SpdBufferPtr[SPD_TCK]) + (FTB_ps * (INT8) SpdBufferPtr[SPD_TCK_FTB]) ; + if (TCKmin_ps < Value32) { + TCKmin_ps = Value32; + } + } + } + } + if (TCKmin_ps <= 938) { + DCTPtr->Timings.TargetSpeed = DDR2133_FREQUENCY; + } else if (TCKmin_ps <= 1071) { + DCTPtr->Timings.TargetSpeed = DDR1866_FREQUENCY; + } else if (TCKmin_ps <= 1250) { + DCTPtr->Timings.TargetSpeed = DDR1600_FREQUENCY; + } else if (TCKmin_ps <= 1500) { + DCTPtr->Timings.TargetSpeed = DDR1333_FREQUENCY; + } else if (TCKmin_ps <= 1875) { + DCTPtr->Timings.TargetSpeed = DDR1066_FREQUENCY; + } else if (TCKmin_ps <= 2500) { + DCTPtr->Timings.TargetSpeed = DDR800_FREQUENCY; + } else { + DCTPtr->Timings.TargetSpeed = DDR667_FREQUENCY; + } + } + + // Ensure the target speed can be applied to all channels of the current node + NBPtr->SyncTargetSpeed (NBPtr); + + // Set the start-up frequency + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + NBPtr->DCTPtr->Timings.Speed = TechPtr->NBPtr->StartupSpeed; + } + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function check the symmetry of DIMM pairs (DIMM on Channel A matching with + * DIMM on Channel B), the overall DIMM population, and determine the width mode: + * 64-bit, 64-bit muxed, 128-bit. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - indicates that a FATAL error has not occurred + * @return FALSE - indicates that a FATAL error has occurred + */ + +BOOLEAN +MemTSPDCalcWidth3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 *SpdBufferAPtr; + UINT8 *SpdBufferBPtr; + MEM_NB_BLOCK *NBPtr; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + UINT8 i; + UINT16 DimmMask; + UINT8 UngangMode; + + NBPtr = TechPtr->NBPtr; + MCTPtr = NBPtr->MCTPtr; + DCTPtr = NBPtr->DCTPtr; + UngangMode = UserOptions.CfgMemoryModeUnganged; + // Does not support ganged mode for DDR3 dimms + ASSERT (UngangMode); + IDS_OPTION_HOOK (IDS_GANGING_MODE, &UngangMode, &(NBPtr->MemPtr->StdHeader)); + + // Check symmetry of channel A and channel B dimms for 128-bit mode + // capability. + // + AGESA_TESTPOINT (TpProcMemModeChecking, &(NBPtr->MemPtr->StdHeader)); + i = 0; + if (!UngangMode) { + if (MCTPtr->DctData[0].Timings.DctDimmValid == MCTPtr->DctData[1].Timings.DctDimmValid) { + for (; i < MAX_DIMMS_PER_CHANNEL; i++) { + DimmMask = (UINT16)1 << i; + if ((DCTPtr->Timings.DctDimmValid & DimmMask) != 0) { + NBPtr->SwitchDCT (NBPtr, 0); + MemTGetDimmSpdBuffer3 (TechPtr, &SpdBufferAPtr, i); + NBPtr->SwitchDCT (NBPtr, 1); + MemTGetDimmSpdBuffer3 (TechPtr, &SpdBufferBPtr, i); + // compare rows and columns + if ((SpdBufferAPtr[SPD_ROW_SZ]&0x3F) != (SpdBufferBPtr[SPD_ROW_SZ]&0x3F)) { + break; + } + if ((SpdBufferAPtr[SPD_DENSITY]&0x0F) != (SpdBufferBPtr[SPD_DENSITY]&0x0F)) { + break; + } + // compare ranks and devwidth + if ((SpdBufferAPtr[SPD_DEV_WIDTH]&0x7F) != (SpdBufferBPtr[SPD_DEV_WIDTH]&0x7F)) { + break; + } + } + } + } + if (i < MAX_DIMMS_PER_CHANNEL) { + PutEventLog (AGESA_ALERT, MEM_ALERT_ORG_MISMATCH_DIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ALERT, MCTPtr); + } else { + NBPtr->Ganged = TRUE; + MCTPtr->GangedMode = TRUE; + MCTPtr->Status[Sb128bitmode] = TRUE; + NBPtr->SetBitField (NBPtr, BFDctGangEn, 1); + } + } + + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * Initialize DCT Timing registers as per DIMM SPD. + * For primary timing (T, CL) use best case T value. + * For secondary timing params., use most aggressive settings + * of slowest DIMM. + * + * Note: + * There are three components to determining "maximum frequency": SPD component, + * Bus load component, and "Preset" max frequency component. + * The SPD component is a function of the min cycle time specified by each DIMM, + * and the interaction of cycle times from all DIMMs in conjunction with CAS + * latency. The SPD component only applies when user timing mode is 'Auto'. + * + * The Bus load component is a limiting factor determined by electrical + * characteristics on the bus as a result of varying number of device loads. The + * Bus load component is specific to each platform but may also be a function of + * other factors. The bus load component only applies when user timing mode is + * ' Auto'. + * + * The Preset component is subdivided into three items and is the minimum of + * the set: Silicon revision, user limit setting when user timing mode is 'Auto' and + * memclock mode is 'Limit', OEM build specification of the maximum frequency. + * The Preset component only applies when user timing mode is 'Auto'. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - indicates that a FATAL error has not occurred + * @return FALSE - indicates that a FATAL error has occurred + */ + +BOOLEAN +MemTAutoCycTiming3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + CONST UINT8 SpdIndexes[] = { + SPD_TRCD, + SPD_TRP, + SPD_TRTP, + SPD_TRAS, + SPD_TRC, + SPD_TWR, + SPD_TRRD, + SPD_TWTR, + SPD_TFAW + }; + + CONST UINT8 SpdFTBIndexes[] = { + SPD_TRCD_FTB, + SPD_TRP_FTB, + 0, + 0, + SPD_TRC_FTB, + 0, + 0, + 0, + 0 + }; + + UINT8 *SpdBufferPtr; + INT32 MiniMaxTmg[GET_SIZE_OF (SpdIndexes)]; + UINT8 MiniMaxTrfc[4]; + + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + MEM_NB_BLOCK *NBPtr; + UINT16 DimmMask; + INT32 Value32; + INT32 MTB_ps; + INT32 FTB_ps; + INT32 TCK_ps; + UINT8 i; + UINT8 j; + UINT8 Value8; + UINT8 *StatTmgPtr; + UINT16 *StatDimmTmgPtr; + + NBPtr = TechPtr->NBPtr; + MCTPtr = NBPtr->MCTPtr; + DCTPtr = NBPtr->DCTPtr; + // initialize mini-max arrays + for (j = 0; j < GET_SIZE_OF (MiniMaxTmg); j++) { + MiniMaxTmg[j] = 0; + } + for (j = 0; j < GET_SIZE_OF (MiniMaxTrfc); j++) { + MiniMaxTrfc[j] = 0; + } + + // ====================================================================== + // Get primary timing (CAS Latency and Cycle Time) + // ====================================================================== + // Get OEM specific load variant max + // + + //====================================================================== + // Gather all DIMM mini-max values for cycle timing data + //====================================================================== + // + DimmMask = 1; + for (i = 0; i < (MAX_CS_PER_CHANNEL / 2); i++) { + if ((DCTPtr->Timings.DctDimmValid & DimmMask) != 0) { + MemTGetDimmSpdBuffer3 (TechPtr, &SpdBufferPtr, i); + MTB_ps = ((INT32) SpdBufferPtr[SPD_DIVIDENT] * 1000) / SpdBufferPtr[SPD_DIVISOR]; + FTB_ps = (SpdBufferPtr[SPD_FTB] >> 4) / (SpdBufferPtr[SPD_FTB] & 0xF); + + for (j = 0; j < GET_SIZE_OF (SpdIndexes); j++) { + Value32 = (UINT16)SpdBufferPtr[SpdIndexes[j]]; + if (SpdIndexes[j] == SPD_TRC) { + Value32 |= ((UINT16)SpdBufferPtr[SPD_UPPER_TRC] & 0xF0) << 4; + } else if (SpdIndexes[j] == SPD_TRAS) { + Value32 |= ((UINT16)SpdBufferPtr[SPD_UPPER_TRAS] & 0x0F) << 8; + } else if (SpdIndexes[j] == SPD_TFAW) { + Value32 |= ((UINT16)SpdBufferPtr[SPD_UPPER_TFAW] & 0x0F) << 8; + } + + Value32 *= MTB_ps; + if (SpdFTBIndexes[j] != 0) { + Value32 += (FTB_ps * (INT8) SpdBufferPtr[SpdFTBIndexes[j]]) ; + } + if (MiniMaxTmg[j] < Value32) { + MiniMaxTmg[j] = Value32; + } + } + + // get Trfc0 - Trfc3 values + Value8 = SpdBufferPtr[SPD_DENSITY] & 0x0F; + if (MiniMaxTrfc[i] < Value8) { + MiniMaxTrfc[i] = Value8; + } + } + DimmMask <<= 1; + } + + // ====================================================================== + // Convert DRAM CycleTiming values and store into DCT structure + // ====================================================================== + // + TCK_ps = 1000500 / DCTPtr->Timings.Speed; + + StatDimmTmgPtr = &DCTPtr->Timings.DIMMTrcd; + StatTmgPtr = &DCTPtr->Timings.Trcd; + for (j = 0; j < GET_SIZE_OF (SpdIndexes); j++) { + Value32 = MiniMaxTmg[j]; + + MiniMaxTmg[j] = (MiniMaxTmg[j] + TCK_ps - 1) / TCK_ps; + + StatDimmTmgPtr[j] = (UINT16) (Value32 / (1000 / 40)); + StatTmgPtr[j] = (UINT8) MiniMaxTmg[j]; + } + DCTPtr->Timings.Trfc0 = MiniMaxTrfc[0]; + DCTPtr->Timings.Trfc1 = MiniMaxTrfc[1]; + DCTPtr->Timings.Trfc2 = MiniMaxTrfc[2]; + DCTPtr->Timings.Trfc3 = MiniMaxTrfc[3]; + + DCTPtr->Timings.CasL = MemTSPDGetTCL3 (TechPtr); + + //====================================================================== + // Program DRAM Timing values + //====================================================================== + // + NBPtr->ProgramCycTimings (NBPtr); + + MemFInitTableDrive (NBPtr, MTAfterAutoCycTiming); + + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the bank addressing, program Mask values and build a chip-select population map. + * This routine programs PCI 0:24N:2x80 config register. + * This routine programs PCI 0:24N:2x60,64,68,6C config registers (CS Mask 0-3) + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - indicates that a FATAL error has not occurred + * @return FALSE - indicates that a FATAL error has occurred + */ + +BOOLEAN +MemTSPDSetBanks3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 *SpdBufferPtr; + UINT8 i; + UINT8 ChipSel; + UINT8 DimmID; + UINT8 Value8; + UINT8 Rows; + UINT8 Cols; + UINT8 Ranks; + UINT8 Banks; + UINT32 BankAddrReg; + UINT32 CsMask; + UINT16 CSSpdCSE; + UINT16 CSExclude; + UINT16 DimmQRDR; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MCTPtr = NBPtr->MCTPtr; + DCTPtr = NBPtr->DCTPtr; + BankAddrReg = 0; + CSSpdCSE = 0; + CSExclude = 0; + + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel += 2) { + DimmID = ChipSel >> 1; + + DimmQRDR = (DCTPtr->Timings.DimmQrPresent) | (DCTPtr->Timings.DimmDrPresent); + if ((DCTPtr->Timings.DimmSpdCse & ((UINT16) 1 << DimmID)) != 0) { + CSSpdCSE |= (UINT16) ((DimmQRDR & (UINT16) 1 << DimmID) ? 3 : 1) << ChipSel; + } + if ((DCTPtr->Timings.DimmExclude & ((UINT16) 1 << DimmID)) != 0) { + CSExclude |= (UINT16) ((DimmQRDR & (UINT16) 1 << DimmID) ? 3: 1) << ChipSel; + } + + if ((DCTPtr->Timings.DctDimmValid & ((UINT16)1 << DimmID)) != 0) { + MemTGetDimmSpdBuffer3 (TechPtr, &SpdBufferPtr, DimmID); + + // Get the basic data + Rows = (SpdBufferPtr[SPD_ROW_SZ] >> 3) & 0x7; + Cols = SpdBufferPtr[SPD_COL_SZ] & 0x7; + Banks = (SpdBufferPtr[SPD_L_BANKS] >> 4) & 0x7; + Ranks = ((SpdBufferPtr[SPD_RANKS] >> 3) & 0x07) + 1; + if (Ranks == 5) { + Ranks = 8; + } + // + // Configure the bank encoding + // Use a 6-bit key into a lookup table. + // Key (index) = RRRBCC, where CC is the number of Columns minus 9, + // RRR is the number of Rows minus 12, and B is the number of banks + // minus 3. + // + Value8 = Cols; + Value8 |= (Banks == 1) ? 4 : 0; + Value8 |= Rows << 3; + + if (MemTCheckBankAddr3 (Value8, &i)) { + // + // Mask value=(2pow(rows+cols+banks+3)-1)>>8, + // or 2pow(rows+cols+banks-5)-1 + // + Value8 = (Rows + 12) + (Cols + 9) + (Banks + 3) + 3 - 8; + if (MCTPtr->Status[Sb128bitmode]) { + Value8++; + } + + DCTPtr->Timings.CsPresent |= (UINT16)1 << ChipSel; + + if (Ranks >= 2) { + DCTPtr->Timings.CsPresent |= (UINT16)1 << (ChipSel + 1); + } + // + // Determine LRDIMM Rank Multiplication + // + if (TechPtr->TechnologySpecificHook[LrdimmRankMultiplication] (TechPtr, &DimmID)) { + // + // Increase the CS Size by the rank multiplication factor + // + Value8 += ((NBPtr->ChannelPtr->LrDimmRankMult[DimmID]) >> 1); + CsMask = ((UINT32)1 << Value8) - 1; + CsMask &= NBPtr->CsRegMsk; + CsMask |= (NBPtr->GetBitField (NBPtr, BFRankDef0 + DimmID) & 0x03); + } else { + CsMask = ((UINT32)1 << Value8) - 1; + CsMask &= NBPtr->CsRegMsk; + } + // + // Update the DRAM CS Mask and BankAddrReg for this chipselect + // + if ((DCTPtr->Timings.CsPresent & (UINT16)3 << ChipSel) != 0) { + NBPtr->SetBitField (NBPtr, BFCSMask0Reg + (ChipSel >> 1), (CsMask)); + BankAddrReg |= ((UINT32)i << (ChipSel << 1)); + } + } else { + // + // Dimm is not supported, as no address mapping is found. + // + DCTPtr->Timings.CsPresent |= (UINT16)1 << ChipSel; + DCTPtr->Timings.CsTestFail |= (UINT16)1 << ChipSel; + if (Ranks >= 2) { + DCTPtr->Timings.CsPresent |= (UINT16)1 << (ChipSel + 1); + DCTPtr->Timings.CsTestFail |= (UINT16)1 << (ChipSel + 1); + } + PutEventLog (AGESA_ERROR, MEM_ERROR_NO_ADDRESS_MAPPING, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, DimmID, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + } + } //if (MemTCheckBankAddr3 (Value8, &i) + } + // For ranks that need to be excluded, the loading of this rank should be considered + // in timing, so need to set CsPresent before setting CsTestFail + if ((CSSpdCSE != 0) || (CSExclude != 0)) { + if (!NBPtr->MemPtr->ErrorHandling (MCTPtr, NBPtr->Dct, (CSSpdCSE | CSExclude), &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + } + + // If there are no chip selects, we have an error situation. + if (DCTPtr->Timings.CsPresent == 0) { + PutEventLog (AGESA_ERROR, MEM_ERROR_NO_CHIPSELECT, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + } + + NBPtr->SetBitField (NBPtr, BFDramBankAddrReg, BankAddrReg); + + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns the low bit that will be swapped to enable CS interleaving + * + * @param[in] BankEnc - AddrMap Bank encoding from F2x80 + * @param[in] *LowBit - pointer to low bit + * @param[in] *HiBit - pointer hight bit + * + */ + +VOID +MemTGetCSIntLvAddr3 ( + IN UINT8 BankEnc, + OUT UINT8 *LowBit, + OUT UINT8 *HiBit + ) +{ + CONST UINT8 ArrCodesLo[] = {0, 8, 8, 0, 0, 8, 9, 8, 9, 9, 8, 9}; + CONST UINT8 ArrCodesHi[] = {0, 20, 21, 0, 0, 22, 22, 23, 23, 24, 24, 25}; + ASSERT (BankEnc < GET_SIZE_OF (ArrCodesLo)); + ASSERT (BankEnc < GET_SIZE_OF (ArrCodesHi)); + // return ArrCodes[BankEnc]; + *LowBit = ArrCodesLo[BankEnc]; + *HiBit = ArrCodesHi[BankEnc]; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines if the checksum is correct + * + * @param[in] *SPDPtr - Pointer to SPD data + * + * @return TRUE - CRC check passes + * @return FALSE - CRC check fails + */ + +BOOLEAN +STATIC +MemTCRCCheck3 ( + IN OUT UINT8 *SPDPtr + ) +{ + UINT16 Crc; + INT16 i; + INT16 j; + INT16 Count; + + if (SPDPtr[SPD_TYPE] == JED_DDR3SDRAM) { + Count = (SPDPtr[SPD_BYTE_USED] & 0x80) ? 117 : 126; + Crc = 0; + for (j = 0; j < Count; j++) { + Crc = Crc ^ ((UINT16)SPDPtr[j] << 8); + for (i = 0; i < 8; i++) { + if (Crc & 0x8000) { + Crc = (Crc << 1) ^ 0x1021; + } else { + Crc = (Crc << 1); + } + } + } + if (*(UINT16 *) (SPDPtr + 126) == Crc) { + return TRUE; + } + } + + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns the CAS latency of the current frequency (DCTPtr->Timings.Speed). + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return CAS Latency + */ + +UINT8 +STATIC +MemTSPDGetTCL3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 *SpdBufferPtr; + UINT8 CLdesired; + UINT8 CLactual; + UINT8 Dimm; + UINT8 Channel; + UINT16 CASLat; + UINT16 Mask16; + INT32 MTB_ps; + INT32 FTB_ps; + INT32 TAAmin_ps; + INT32 TCKproposed_ps; + INT32 Value32; + BOOLEAN CltFail; + MEM_NB_BLOCK *NBPtr; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + + NBPtr = TechPtr->NBPtr; + DCTPtr = NBPtr->DCTPtr; + + CASLat = 0xFFFF; + TAAmin_ps = 0; + CltFail = FALSE; + + for (Channel = 0; Channel < NBPtr->ChannelCount; Channel++) { + NBPtr->SwitchChannel (NBPtr, Channel); + ChannelPtr = NBPtr->ChannelPtr; + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) { + if ((ChannelPtr->ChDimmValid & ((UINT8)1 << Dimm)) != 0) { + MemTGetDimmSpdBuffer3 (TechPtr, &SpdBufferPtr, Dimm); + + // Step 1: Determine the common set of supported CAS Latency + // values for all modules on the memory Channel using the CAS + // Latencies Supported in SPD bytes 14 and 15. + // + CASLat &= ((UINT16)SpdBufferPtr[SPD_CASHI] << 8) | SpdBufferPtr[SPD_CASLO]; + + // Step 2: Determine tAAmin(all) which is the largest tAAmin + // value for all modules on the memory Channel (SPD byte 16). + // + MTB_ps = ((INT32) SpdBufferPtr[SPD_DIVIDENT] * 1000) / SpdBufferPtr[SPD_DIVISOR]; + FTB_ps = (SpdBufferPtr[SPD_FTB] >> 4) / (SpdBufferPtr[SPD_FTB] & 0xF); + Value32 = (MTB_ps * SpdBufferPtr[SPD_TAA]) + (FTB_ps * (INT8) SpdBufferPtr[SPD_TAA_FTB]) ; + if (TAAmin_ps < Value32) { + TAAmin_ps = Value32; + } + + // Step 3: Determine tCKmin(all) which is the largest tCKmin + // value for all modules on the memory Channel (SPD byte 12). + // * This step has been done in SPDGetTargetSpeed + } + } + } + + TCKproposed_ps = 1000500 / DCTPtr->Timings.Speed; + + // Step 4: For a proposed tCK value (tCKproposed) between tCKmin(all) and tCKmax, + // determine the desired CAS Latency. If tCKproposed is not a standard JEDEC + // value (2.5, 1.875, 1.5, or 1.25 ns) then tCKproposed must be adjusted to the + // next lower standard tCK value for calculating CLdesired. + // CLdesired = ceiling ( tAAmin(all) / tCKproposed ) + // where tAAmin is defined in Byte 16. The ceiling function requires that the + // quotient be rounded up always. + // + CLdesired = (UINT8) ((TAAmin_ps + TCKproposed_ps - 1) / TCKproposed_ps); + + // Step 5: Choose an actual CAS Latency (CLactual) that is greater than or equal + // to CLdesired and is supported by all modules on the memory Channel as + // determined in step 1. If no such value exists, choose a higher tCKproposed + // value and repeat steps 4 and 5 until a solution is found. + // + CLactual = 4; + for (Mask16 = 1; Mask16 < 0x8000; Mask16 <<= 1) { + if (CASLat & Mask16) { + if (CLdesired <= CLactual) { + break; + } + } + CLactual++; + } + if (Mask16 == 0x8000) { + CltFail = TRUE; + } + + // Step 6: Once the calculation of CLactual is completed, the BIOS must also + // verify that this CAS Latency value does not exceed tAAmax, which is 20 ns + // for all DDR3 speed grades, by multiplying CLactual times tCKproposed. If + // not, choose a lower CL value and repeat steps 5 and 6 until a solution is found. + // + if ((TCKproposed_ps * CLactual) > 20000) { + CltFail = TRUE; + } + + if (!CltFail) { + DCTPtr->Timings.CasL = CLactual; + } else { + // Fail to find supported Tcl, use 6 clocks since it is required for all DDR3 speed bin. + DCTPtr->Timings.CasL = 6; + } + + return DCTPtr->Timings.CasL; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns the encoded value of bank address. + * + * @param[in] Encode - RRRBCC, where CC is the number of Columns minus 9, + * RRR is the number of Rows minus 12, and B is the number of banks + * minus 3. + * @param[out] *Index - index in bank address table + * @return TRUE - encoded value is found. + * FALSE - encoded value is not found. + */ + +BOOLEAN +STATIC +MemTCheckBankAddr3 ( + IN UINT8 Encode, + OUT UINT8 *Index + ) +{ + UINT8 i; + CONST UINT8 TabBankAddr[] = { + 0x3F, 0x01, 0x09, 0x3F, 0x3F, 0x11, + 0x0A, 0x19, 0x12, 0x1A, 0x21, 0x22 + }; + + for (i = 0; i < GET_SIZE_OF (TabBankAddr); i++) { + if (Encode == TabBankAddr[i]) { + *Index = i; + return TRUE; + } + } + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns a pointer to the SPD Buffer of a specific dimm on + * the current channel. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] **SpdBuffer - Pointer to a pointer to a UINT8 Buffer + * @param[in] Dimm - Dimm number + * + * + * @return BOOLEAN - Value of DimmPresent + * TRUE = Dimm is present, pointer is valid + * FALSE = Dimm is not present, pointer has not been modified. + */ + +BOOLEAN +MemTGetDimmSpdBuffer3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT UINT8 **SpdBuffer, + IN UINT8 Dimm + ) +{ + CH_DEF_STRUCT *ChannelPtr; + SPD_DEF_STRUCT *SPDPtr; + BOOLEAN DimmPresent; + + DimmPresent = FALSE; + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + ASSERT (Dimm < (sizeof (ChannelPtr->DimmSpdPtr) / sizeof (ChannelPtr->DimmSpdPtr[0]))) + SPDPtr = ChannelPtr->DimmSpdPtr[Dimm]; + + + if (SPDPtr != NULL) { + DimmPresent = SPDPtr->DimmPresent; + if (DimmPresent) { + *SpdBuffer = SPDPtr->Data; + } + } + return DimmPresent; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.h new file mode 100644 index 0000000000..bf13c7f13c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mtspd3.h @@ -0,0 +1,180 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtspd3.h + * + * Technology SPD support for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 85961 $ @e \$Date: 2013-01-14 19:58:20 -0600 (Mon, 14 Jan 2013) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MTSPD3_H_ +#define _MTSPD3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*=============================================================================== + * Jedec DDR III + *=============================================================================== + */ +#define SPD_BYTE_USED 0 +#define SPD_TYPE 2 /* SPD byte read location */ +#define JED_DDR_SDRAM 7 /* Jedec defined bit field */ +#define JED_DDR2_SDRAM 8 /* Jedec defined bit field */ +#define JED_DDR3SDRAM 0xB /* Jedec defined bit field */ + +#define SPD_DIMM_TYPE 3 +#define SPD_ATTRIB 21 +#define JED_DIF_CK_MSK 0x20 /* Differential Clock Input */ +#define JED_RDIMM 1 +#define JED_MINIRDIMM 5 +#define JED_UDIMM 2 +#define JED_SODIMM 3 +#define JED_LRDIMM 0xB +#define JED_72B_SOUDIMM 8 +#define JED_UNDEFINED 0 /* Undefined value */ + +#define SPD_L_BANKS 4 /* [7:4] number of [logical] banks on each device */ +#define SPD_DENSITY 4 /* bit 3:0 */ +#define SPD_ROW_SZ 5 /* bit 5:3 */ +#define SPD_COL_SZ 5 /* bit 2:0 */ +#define SPD_RANKS 7 /* bit 5:3 */ +#define SPD_DEV_WIDTH 7 /* bit 2:0 */ +#define SPD_ECCBITS 8 /* bit 4:3 */ +#define JED_ECC 8 +#define SPD_RAWCARD 62 /* bit 2:0 */ +#define SPD_ADDRMAP 63 /* bit 0 */ + +#define SPD_CTLWRD03 70 /* bit 7:4 */ +#define SPD_CTLWRD04 71 /* bit 3:0 */ +#define SPD_CTLWRD05 71 /* bit 7:4 */ + +#define SPD_FTB 9 + +#define SPD_DIVIDENT 10 +#define SPD_DIVISOR 11 + +#define SPD_TCK 12 +#define SPD_CASLO 14 +#define SPD_CASHI 15 +#define SPD_TAA 16 + +#define SPD_TRP 20 +#define SPD_TRRD 19 +#define SPD_TRCD 18 +#define SPD_TRAS 22 +#define SPD_TWR 17 +#define SPD_TWTR 26 +#define SPD_TRTP 27 +#define SPD_TRC 23 +#define SPD_UPPER_TRC 21 /* bit 7:4 */ +#define SPD_UPPER_TRAS 21 /* bit 3:0 */ +#define SPD_TFAW 29 +#define SPD_UPPER_TFAW 28 /* bit 3:0 */ + +#define SPD_TCK_FTB 34 +#define SPD_TAA_FTB 35 +#define SPD_TRCD_FTB 36 +#define SPD_TRP_FTB 37 +#define SPD_TRC_FTB 38 + +#define SPD_TRFC_LO 24 +#define SPD_TRFC_HI 25 + +/*----------------------------- + * Jedec DDR II related equates + *----------------------------- + */ + +#define CL_DEF 4 /* Default value for failsafe operation. 4=CL 6.0 T */ +#define T_DEF 4 /* Default value for failsafe operation. 4=2.5ns (cycle time) */ + +#define BIAS_TRTP_T 4 +#define BIAS_TRCD_T 5 +#define BIAS_TRAS_T 15 +#define BIAS_TRC_T 11 +#define BIAS_TRRD_T 4 +#define BIAS_TWR_T 4 +#define BIAS_TRP_T 5 +#define BIAS_TWTR_T 4 +#define BIAS_TFAW_T 14 + +#define MIN_TRTP_T 4 +#define MAX_TRTP_T 7 +#define MIN_TRCD_T 5 +#define MAX_TRCD_T 12 +#define MIN_TRAS_T 15 +#define MAX_TRAS_T 30 +#define MIN_TRC_T 11 +#define MAX_TRC_T 42 +#define MIN_TRRD_T 4 +#define MAX_TRRD_T 7 +#define MIN_TWR_T 5 +#define MAX_TWR_T 12 +#define MIN_TRP_T 5 +#define MAX_TRP_T 12 +#define MIN_TWTR_T 4 +#define MAX_TWTR_T 7 +#define MIN_TFAW_T 16 +#define MAX_TFAW_T 32 + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + + +#endif /* _MTSPD3_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttecc3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttecc3.c new file mode 100644 index 0000000000..abd7965c6e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttecc3.c @@ -0,0 +1,163 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttecc3.c + * + * Technology ECC byte support for registered DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_DDR3_MTTECC3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the DQS ECC timings for registered DDR3 + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTSetDQSEccTmgsRDdr3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 Dct; + UINT8 Dimm; + UINT8 i; + UINT8 *WrDqsDly; + UINT16 *RcvEnDly; + UINT8 *RdDqsDly; + UINT8 *WrDatDly; + UINT8 EccByte; + INT16 TempValue; + + MEM_NB_BLOCK *NBPtr; + CH_DEF_STRUCT *ChannelPtr; + + EccByte = TechPtr->MaxByteLanes (); + NBPtr = TechPtr->NBPtr; + + if (NBPtr->MCTPtr->NodeMemSize) { + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + ChannelPtr = NBPtr->ChannelPtr; + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) { + if (NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16)3 << (Dimm * 2))) { + i = Dimm * TechPtr->DlyTableWidth (); + WrDqsDly = &ChannelPtr->WrDqsDlys[i]; + RcvEnDly = &ChannelPtr->RcvEnDlys[i]; + RdDqsDly = &ChannelPtr->RdDqsDlys[i]; + WrDatDly = &ChannelPtr->WrDatDlys[i]; + // Receiver DQS Enable: + // Receiver DQS enable for ECC bytelane = Receiver DQS enable for bytelane 3 - + // [write DQS for bytelane 3 - write DQS for ECC] + + TempValue = (INT16) RcvEnDly[3] - (INT16) (WrDqsDly[3] - WrDqsDly[EccByte]); + if (TempValue < 0) { + TempValue = 0; + } + RcvEnDly[EccByte] = (UINT16) TempValue; + + // Read DQS: + // Read DQS for ECC bytelane = read DQS of byte lane 3 + // + RdDqsDly[EccByte] = RdDqsDly[3]; + + // Write Data: + // Write Data for ECC bytelane = Write DQS for ECC + + // [write data for bytelane 3 - Write DQS for bytelane 3] + TempValue = (INT16) (WrDqsDly[EccByte] + (INT8) (WrDatDly[3] - WrDqsDly[3])); + if (TempValue < 0) { + TempValue = 0; + } + WrDatDly[EccByte] = (UINT8) TempValue; + + NBPtr->SetTrainDly (NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Dimm, EccByte), RcvEnDly[EccByte]); + NBPtr->SetTrainDly (NBPtr, AccessRdDqsDly, DIMM_BYTE_ACCESS (Dimm, EccByte), RdDqsDly[EccByte]); + NBPtr->SetTrainDly (NBPtr, AccessWrDatDly, DIMM_BYTE_ACCESS (Dimm, EccByte), WrDatDly[EccByte]); + } + } + } + } + } + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} \ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttwl3.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttwl3.c new file mode 100644 index 0000000000..361b56a896 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/DDR3/mttwl3.c @@ -0,0 +1,718 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttwl3.c + * + * Technology Phy assisted write levelization for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech/DDR3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mp.h" +#include "mtsdi3.h" +#include "mtlrdimm3.h" +#include "merrhdl.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_DDR3_MTTWL3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +extern MEM_PSC_FLOW_BLOCK* memPlatSpecFlowArray[]; + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +STATIC +MemTWriteLevelizationHw3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Pass + ); + +VOID +STATIC +MemTWLPerDimmHw3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dimm, + IN UINT8 Pass + ); + +VOID +STATIC +MemTPrepareDIMMs3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 TargetDIMM, + IN BOOLEAN Wl + ); + +VOID +STATIC +MemTProcConfig3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dimm, + IN UINT8 Pass + ); + +VOID +STATIC +MemTBeginWLTrain3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dimm + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes first pass of Phy assisted write levelization + * for a specific node (DDR800). + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTWriteLevelizationHw3Pass1 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + return MemTWriteLevelizationHw3 (TechPtr, 1); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes second pass of Phy assisted write levelization + * for a specific node (DDR1066 and above). + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTWriteLevelizationHw3Pass2 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + // If current speed is higher than start-up speed, do second pass of WL + if (TechPtr->NBPtr->DCTPtr->Timings.Speed > TechPtr->NBPtr->StartupSpeed) { + return MemTWriteLevelizationHw3 (TechPtr, 2); + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function prepares for Phy assisted training. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTPreparePhyAssistedTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + // Disable auto refresh by configuring F2x[1, 0]8C[DisAutoRefresh] = 1. + TechPtr->NBPtr->BrdcstSet (TechPtr->NBPtr, BFDisAutoRefresh, 1); + // Disable ZQ calibration short command by configuring F2x[1, 0]94[ZqcsInterval] = 00b. + TechPtr->NBPtr->BrdcstSet (TechPtr->NBPtr, BFZqcsInterval, 0); + // Attempt to get the seeds value from PSC tables for WL and RxEn pass1 training if applicable. + if (!TechPtr->NBPtr->PsPtr->MemPGetPass1Seeds (TechPtr->NBPtr)) { + ASSERT (FALSE); + } + + return (BOOLEAN) (TechPtr->NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function revert to normal settings when exiting from Phy assisted training. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTExitPhyAssistedTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + NBPtr = TechPtr->NBPtr; + + // 13.Program F2x[1, 0]8C[DisAutoRefresh] = 0. + NBPtr->BrdcstSet (NBPtr, BFDisAutoRefresh, 0); + // 14.Program F2x[1, 0]94[ZqcsInterval] to the proper interval for the current memory configuration. + NBPtr->BrdcstSet (NBPtr, BFZqcsInterval, 2); + NBPtr->FamilySpecificHook[ExitPhyAssistedTraining] (NBPtr, NBPtr); + + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executed hardware based write levelization for a specific die + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Pass - Pass number (1 (400Mhz) or 2 (>400Mhz)) + * + * @pre Auto refresh and ZQCL must be disabled + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +STATIC +MemTWriteLevelizationHw3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Pass + ) +{ + MEM_NB_BLOCK *NBPtr; + DCT_STRUCT *DCTPtr; + UINT8 Dct; + UINT8 ChipSel; + + NBPtr = TechPtr->NBPtr; + + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart write leveling\n"); + AGESA_TESTPOINT (TpProcMemWriteLevelizationTraining, &(NBPtr->MemPtr->StdHeader)); + // Begin DQS Write timing training + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + DCTPtr = NBPtr->DCTPtr; + + TechPtr->WLCriticalDelay = 0x00; + + //training for each Dimm/CS + for (ChipSel = 0; ChipSel < NBPtr->CsPerChannel; ChipSel = ChipSel + NBPtr->CsPerDelay) { + if ((DCTPtr->Timings.CsEnabled & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSel)) != 0) { + if (!(NBPtr->MCTPtr->Status[SbLrdimms]) || ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0)) { + IDS_HDT_CONSOLE (MEM_STATUS, "\t\tCS %d\n", ChipSel); + MemTWLPerDimmHw3 (TechPtr, (ChipSel / NBPtr->CsPerDelay), Pass); + } + } + } + + NBPtr->FamilySpecificHook[CalcWrDqDqsEarly] (NBPtr, NULL); + } + IDS_HDT_CONSOLE (MEM_FLOW, "End write leveling\n\n"); + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes per DIMM write levelization + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Dimm - DIMM to be trained + * @param[in] Pass - Pass number (1 (400Mhz) or 2 (>400Mhz)) + * + */ + +VOID +STATIC +MemTWLPerDimmHw3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dimm, + IN UINT8 Pass + ) +{ + MEM_DATA_STRUCT *MemPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + + ASSERT (Dimm < (NBPtr->CsPerChannel / NBPtr->CsPerDelay)); + + // 1. A. Specify the target Dimm that is to be trained by programming + // F2x[1, 0]9C_x08[TrDimmSel]. + NBPtr->SetBitField (NBPtr, BFTrDimmSel, Dimm); + + TechPtr->TargetDIMM = Dimm; + NBPtr->FamilySpecificHook[InitPerNibbleTrn] (NBPtr, NULL); + for (TechPtr->TrnNibble = NIBBLE_0; TechPtr->TrnNibble <= (NBPtr->FamilySpecificHook[TrainWlPerNibble] (NBPtr, &Dimm)? NIBBLE_0 : NIBBLE_1); TechPtr->TrnNibble++) { + // 2. Prepare the DIMMs for write levelization using DDR3-defined + // MR commands. + MemTPrepareDIMMs3 (TechPtr, Dimm, TRUE); + + // 3. After the DIMMs are configured, BIOS waits 40 MEMCLKs to + // satisfy DDR3-defined internal DRAM timing. + NBPtr->WaitXMemClks (NBPtr, 40); + + // 4. Configure the processor's DDR phy for write levelization training: + MemTProcConfig3 (TechPtr, Dimm, Pass); + + // 5. Begin write levelization training + MemTBeginWLTrain3 (TechPtr, Dimm); + } + // 7. Program the target Dimm back to normal operation + MemTPrepareDIMMs3 (TechPtr, Dimm, FALSE); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function prepares the DIMMS for Write Levelization + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] TargetDIMM - DIMM to be trained + * @param[in] Wl - Indicates if WL mode should be enabled + * + */ + +VOID +STATIC +MemTPrepareDIMMs3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 TargetDIMM, + IN BOOLEAN Wl + ) +{ + MEM_NB_BLOCK *NBPtr; + UINT8 ChipSel; + + NBPtr = TechPtr->NBPtr; + + AGESA_TESTPOINT (TpProcMemWlPrepDimms, &(NBPtr->MemPtr->StdHeader)); + ASSERT (TargetDIMM < (NBPtr->CsPerChannel / NBPtr->CsPerDelay)); + TechPtr->TargetDIMM = TargetDIMM; + if (!(TechPtr->TechnologySpecificHook[WlTrainingPrepareLrdimm] (TechPtr, &Wl))) { + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) { + if ((NBPtr->DCTPtr->Timings.CsPresent & ((UINT16)1 << ChipSel)) != 0) { + NBPtr->SetBitField (NBPtr, BFMrsChipSel, ChipSel); + // Set MR1 to F2x7C[MrsAddress], F2x7C[MrsBank]=1 + MemTEMRS13 (TechPtr, Wl, TargetDIMM); + NBPtr->SendMrsCmd (NBPtr); + // Set MR2 to F2x7C[MrsAddress], F2x7C[MrsBank]=1 + MemTEMRS23 (TechPtr); + // Send command + NBPtr->SendMrsCmd (NBPtr); + } + } + if (Wl) { + // Program WrLvOdt for the Target DIMM (or CS) + NBPtr->SetBitField (NBPtr, BFWrLvOdt, NBPtr->ChannelPtr->PhyWLODT[TargetDIMM]); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs seed values for Write Levelization + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Dimm - DIMM to be trained + * @param[in] Pass - Pass for WL training (1 - 400Mhz or 2 - >400Mhz) + * + */ + +VOID +STATIC +MemTProcConfig3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dimm, + IN UINT8 Pass + ) +{ + DIE_STRUCT *MCTPtr; + CH_DEF_STRUCT *ChannelPtr; + MEM_NB_BLOCK *NBPtr; + UINT16 WrDqsDly; + // Memclk Delay incurred by register. + UINT8 MemClkRegDly; + UINT8 ByteLane; + UINT8 DefaultSeed; + UINT8 CurrentSeed; + UINT8 *Seed; + UINT8 RCW2; + UINT16 Speed; + INT16 WrDqsBias; + + NBPtr = TechPtr->NBPtr; + MCTPtr = NBPtr->MCTPtr; + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + + AGESA_TESTPOINT (TpProcMemWlConfigDimms, &(NBPtr->MemPtr->StdHeader)); + RCW2 = ChannelPtr->CtrlWrd02[Dimm]; + Speed = TechPtr->NBPtr->DCTPtr->Timings.Speed; + + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSeeds: "); + // Program an initialization Value to registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52 to set + // the gross and fine delay for all the byte lane fields. If the target frequency is different than 400MHz, + // BIOS must execute two training passes for each Dimm. For pass 1 at a 400MHz MEMCLK frequency, + // use an initial total delay value. + if (Pass == 1) { + // + // Get the default value of seed + // + if (MCTPtr->Status[SbRegistered]) { + // + // RDIMM + // + if (Speed == DDR667_FREQUENCY) { + DefaultSeed = ((RCW2 & BIT0) == 0) ? 0x3B : 0x4B; + } else { + DefaultSeed = ((RCW2 & BIT0) == 0) ? 0x41 : 0x51; + } + } else if (ChannelPtr->SODimmPresent != 0) { + // + // SODIMMM + // + DefaultSeed = 0x12; + } else if (MCTPtr->Status[SbLrdimms]) { + // + // LRDIMM + // + DefaultSeed = 0xF7; + } else { + // + // UDIMMM + // + DefaultSeed = 0x1A; + } + + NBPtr->FamilySpecificHook[OverrideWLSeed] (NBPtr, &DefaultSeed); + ASSERT (Speed >= DDR667_FREQUENCY); + + // Get platform override seed + Seed = (UINT8 *) FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_WL_SEED, MCTPtr->SocketId, ChannelPtr->ChannelID, Dimm, + &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); + for (ByteLane = 0; ByteLane < TechPtr->DlyTableWidth (); ByteLane++) { + // This includes ECC as byte 8 + CurrentSeed = ((Seed != NULL) ? Seed[ByteLane] : DefaultSeed); + ChannelPtr->WrDqsDlys[Dimm * TechPtr->DlyTableWidth () + ByteLane] = CurrentSeed; + + if (NBPtr->IsSupported[WLSeedAdjust]) { + if ((CurrentSeed & 0x20) != 0) { + // If (SeedGross is odd) then SeedPreGross = 1 + CurrentSeed = (CurrentSeed & 0x1F) | 0x20; + } else { + // If (SeedGross is even) then SeedPreGross = 2 + CurrentSeed = (CurrentSeed & 0x1F) | 0x40; + } + } + + NBPtr->SetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), CurrentSeed); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", CurrentSeed); + } + } else { + //10.Multiply the previously saved delay values in Pass 1, step #5 by (target frequency)/400 to find + //the gross and fine delay initialization values at the target frequency. Use these values as the initial + //seed values when executing Pass 2, step #4. + for (ByteLane = 0; ByteLane < TechPtr->DlyTableWidth (); ByteLane++) { + // This includes ECC as byte 8 + WrDqsDly = ChannelPtr->WrDqsDlys[Dimm * TechPtr->DlyTableWidth () + ByteLane]; + TechPtr->Bytelane = ByteLane; + NBPtr->FamilySpecificHook[TrainWlPerNibbleSeed] (NBPtr, &WrDqsDly); + + if (MCTPtr->Status[SbRegistered]) { + // + // For Registered Dimms + // + MemClkRegDly = ((RCW2 & BIT0) == 0) ? 0x20 : 0x30; + } else { + // + // Unbuffered Dimms and LRDIMMs + // + MemClkRegDly = 0; + } + // + // Recover any adjustmen to delay for WrDqDqsEarly + // + WrDqsBias = 0; + NBPtr->FamilySpecificHook[AdjustWrDqsBeforeSeedScaling] (NBPtr, &WrDqsBias); + + // Scale WrDqsDly to the next speed + WrDqsDly = (UINT16) (MemClkRegDly + ((((INT32) WrDqsDly - MemClkRegDly - WrDqsBias) * Speed) / TechPtr->PrevSpeed)); + + ChannelPtr->WrDqsDlys[Dimm * TechPtr->DlyTableWidth () + ByteLane] = (UINT8) WrDqsDly; + + if (NBPtr->IsSupported[WLSeedAdjust]) { + if ((WrDqsDly & 0x20) != 0) { + // If (SeedGross is odd) then SeedPreGross = 1 + WrDqsDly = (WrDqsDly & 0x1F) | 0x20; + } else { + // If (SeedGross is even) then SeedPreGross = 2 + WrDqsDly = (WrDqsDly & 0x1F) | 0x40; + } + } + NBPtr->SetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), WrDqsDly); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", WrDqsDly); + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function begins WL training for a specific DIMM + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Dimm - DIMM to be trained + * + */ + +VOID +STATIC +MemTBeginWLTrain3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dimm + ) +{ + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + MEM_NB_BLOCK *NBPtr; + UINT8 ByteLane; + UINT8 Seed; + UINT8 Delay; + INT16 Delay16; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + MCTPtr = NBPtr->MCTPtr; + + AGESA_TESTPOINT (TpProcMemWlTrainTargetDimm, &(MemPtr->StdHeader)); + // Assert ODT pins for write leveling + NBPtr->SetBitField (NBPtr, BFWrLvOdtEn, 1); + + // Wait 10 MEMCLKs to allow for ODT signal settling. + NBPtr->WaitXMemClks (NBPtr, 10); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tWrtLvTrEn = 1\n"); + // Program F2x[1, 0]9C_x08[WrtLlTrEn]=1. + NBPtr->SetBitField (NBPtr, BFWrtLvTrEn, 1); + + // Wait 200 MEMCLKs. + NBPtr->WaitXMemClks (NBPtr, 200); + + // Program F2x[1, 0]9C_x08[WrtLlTrEn]=0. + NBPtr->SetBitField (NBPtr, BFWrtLvTrEn, 0); + + // Read from registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52 to get the gross and fine Delay settings + // for the target Dimm and save these values. + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t PRE: "); + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + // This includes ECC as byte 8 + Seed = NBPtr->ChannelPtr->WrDqsDlys[(Dimm * TechPtr->DlyTableWidth ()) + ByteLane]; + Delay = (UINT8)NBPtr->GetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (Dimm, ByteLane)); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Delay); + + TechPtr->Bytelane = ByteLane; + TechPtr->TargetDIMM = Dimm; + NBPtr->FamilySpecificHook[TrainWlPerNibbleAdjustWLDly] (NBPtr, &Delay); + + if (NBPtr->IsSupported[WLSeedAdjust]) { + // Recover WrDqsGrossDly: + // WrDqsGrossDly = SeedGross + PhRecGrossDlyByte - SeedPreGross + if ((Seed & 0x20) != 0) { + // If (SeedGross is odd) then SeedPreGross = 1 + if ((NBPtr->IsSupported[WLNegativeDelay]) && ((Seed & 0x80) != 0)) { + // If the seed was negative, save the most negative delay in WLCriticalDelay + TechPtr->WLCriticalDelay = MIN (TechPtr->WLCriticalDelay, (INT16)Delay - 0x40); + Delay -= 0x40; + } else { + Delay += (Seed & 0xE0) - 0x20; + } + } else { + // If (SeedGross is even) then SeedPreGross = 2 + if (((Seed & 0xE0) == 0) && (Delay < 0x40)) { + // If SeedGross is 0 and PhRecGrossDlyByte is less than SeedPreGross, + // we have a negative result and need to program the delay to 0 + if (NBPtr->IsSupported[WLNegativeDelay]) { + // + // Save the lowest negative delay value across all Dimms and Bytelanes + // + TechPtr->WLCriticalDelay = MIN (TechPtr->WLCriticalDelay, (INT16)Delay - 0x40); + Delay -= 0x40; + } else { + Delay = 0; + } + } else { + if (NBPtr->GetBitField (NBPtr, BFWrDqDqsEarly) != 0) { + Delay = Delay + (Seed & 0xE0); + Delay16 = Delay - 0x40; + Delay = (UINT8)Delay16; + TechPtr->WLCriticalDelay = MIN (TechPtr->WLCriticalDelay, Delay16); + } else { + Delay += (Seed & 0xE0) - 0x40; + } + } + } + } else if (((Seed >> 5) == 0) && ((Delay >> 5) == 3)) { + IDS_OPTION_HOOK (IDS_CHECK_NEGATIVE_WL, &Delay, &(TechPtr->NBPtr->MemPtr->StdHeader)); + // If seed has gross delay of 0 and PRE has gross delay of 3, + // then round the total delay of TxDqs to 0. + Delay = 0; + } + + if ((!NBPtr->IsSupported[WLNegativeDelay]) && ((Delay > (Seed + 0x20)) || (Seed > (Delay + 0x20)))) { + // + // If PRE comes back with more than Seed +/- 0x20, then this is an + // unexpected condition. Log the condition. + // + PutEventLog (AGESA_ERROR, MEM_ERROR_WL_PRE_OUT_OF_RANGE, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, ((Seed << 8) + Delay), &NBPtr->MemPtr->StdHeader); + } + NBPtr->SetTrainDly (NBPtr, AccessWrDqsDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), Delay); + NBPtr->ChannelPtr->WrDqsDlys[(Dimm * TechPtr->DlyTableWidth ()) + ByteLane] = Delay; + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\tWrDqs: "); + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", NBPtr->ChannelPtr->WrDqsDlys[(Dimm * TechPtr->DlyTableWidth ()) + ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\n"); + ); + + // Disable write leveling ODT pins + NBPtr->SetBitField (NBPtr, BFWrLvOdtEn, 0); + + // Wait 10 MEMCLKs to allow for ODT signal settling. + NBPtr->WaitXMemClks (NBPtr, 10); + +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs register after Phy assisted training is finish. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTExitPhyAssistedTrainingClient3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + UINT8 Dct; + UINT8 ChipSel; + NBPtr = TechPtr->NBPtr; + + NBPtr->FamilySpecificHook[ReEnablePhyComp] (NBPtr, NBPtr); + NBPtr->BrdcstSet (NBPtr, BFRxPtrInitReq, 1); + NBPtr->PollBitField (NBPtr, BFRxPtrInitReq, 0, PCI_ACCESS_TIMEOUT, TRUE); + NBPtr->BrdcstSet (NBPtr, BFDisDllShutdownSR, 1); + NBPtr->BrdcstSet (NBPtr, BFEnterSelfRef, 1); + NBPtr->PollBitField (NBPtr, BFEnterSelfRef, 0, PCI_ACCESS_TIMEOUT, TRUE); + IDS_HDT_CONSOLE (MEM_FLOW, "\tMemClkAlign = 2\n"); + NBPtr->BrdcstSet (NBPtr, BFDbeGskMemClkAlignMode, 2); + NBPtr->BrdcstSet (NBPtr, BFExitSelfRef, 1); + NBPtr->PollBitField (NBPtr, BFExitSelfRef, 0, PCI_ACCESS_TIMEOUT, TRUE); + if (NBPtr->IsSupported[SetDllShutDown]) { + NBPtr->BrdcstSet (NBPtr, BFDisDllShutdownSR, 0); + } + + // Calculate Max Latency for both channels to prepare for position training + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + if (TechPtr->FindMaxDlyForMaxRdLat (TechPtr, &ChipSel)) { + NBPtr->SetMaxLatency (NBPtr, TechPtr->MaxDlyForMaxRdLat); + } + } + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mt.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mt.c new file mode 100644 index 0000000000..45e00d31f7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mt.c @@ -0,0 +1,262 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mt.c + * + * Common Technology file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "amdlib.h" +#include "mport.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemTDefaultTechnologyHook ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT VOID *OptParam + ); +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is the default return for non-training technology features + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + */ +BOOLEAN +MemTFeatDef ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the TestFail bit for all CS that fail training. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + */ +VOID +MemTMarkTrainFail ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + UINT8 Dct; + UINT8 ChipSel; + + NBPtr = TechPtr->NBPtr; + for (Dct = 0; Dct < NBPtr->DctCount; Dct ++) { + NBPtr->SwitchDCT (NBPtr, Dct); + NBPtr->DCTPtr->Timings.CsEnabled &= ~NBPtr->DCTPtr->Timings.CsTrainFail; + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel ++) { + if ((NBPtr->DCTPtr->Timings.CsTrainFail & ((UINT16)1 << ChipSel)) != 0) { + NBPtr->SetBitField (NBPtr, (BFCSBaseAddr0Reg + ChipSel), (UINT32)1 << BFTestFail); + } + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the initial controller environment before training. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTBeginTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + S_UINT64 SMsr; + MEM_DATA_STRUCT *MemPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + + LibAmdReadCpuReg (CR4_REG, &TechPtr->CR4reg); + LibAmdWriteCpuReg (CR4_REG, TechPtr->CR4reg | ((UINT32)1 << 9)); // enable SSE2 + + LibAmdMsrRead (HWCR, (UINT64 *) (&SMsr), &MemPtr->StdHeader); // HWCR + TechPtr->HwcrLo = SMsr.lo; + SMsr.lo |= 0x00020000; // turn on HWCR.wrap32dis + SMsr.lo &= 0xFFFF7FFF; // turn off HWCR.SSEDIS + LibAmdMsrWrite (HWCR, (UINT64 *) (&SMsr), &MemPtr->StdHeader); + + TechPtr->DramEcc = (UINT8) NBPtr->GetBitField (NBPtr, BFDramEccEn); + NBPtr->SetBitField (NBPtr, BFDramEccEn, 0); // Disable ECC +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the final controller environment after training. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTEndTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + S_UINT64 SMsr; + MEM_DATA_STRUCT *MemPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + + LibAmdWriteCpuReg (CR4_REG, TechPtr->CR4reg); + + LibAmdMsrRead (HWCR, (UINT64 *)&SMsr, &MemPtr->StdHeader); + SMsr.lo = TechPtr->HwcrLo; + LibAmdMsrWrite (HWCR, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + NBPtr->SetBitField (NBPtr, BFDramEccEn, TechPtr->DramEcc); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets all the bytelanes/nibbles to the same delay value + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Dly - Delay value to set + * + */ + +VOID +MemTSetDQSDelayAllCSR ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dly + ) +{ + UINT8 i; + UINT8 MaxBytelanes; + MaxBytelanes = (TechPtr->NBPtr->MCTPtr->Status[SbEccDimms] && TechPtr->NBPtr->IsSupported[EccByteTraining]) ? 9 : 8; + + for (i = 0; i < MaxBytelanes; i++) { + TechPtr->SetDQSDelayCSR (TechPtr, i, Dly); + } + TechPtr->NBPtr->FamilySpecificHook[RegAccessFence] (TechPtr->NBPtr, NULL); +} +/*----------------------------------------------------------------------------- + * + * + * This function is used to intialize common technology functions + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * ---------------------------------------------------------------------------- + */ +VOID +MemTCommonTechInit ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 i; + for (i = 0; i < NumberOfTechHooks; i++) { + TechPtr->TechnologySpecificHook[i] = MemTDefaultTechnologyHook; + } +} +/*----------------------------------------------------------------------------- + * + * + * This function is an empty function used to intialize TechnologySpecificHook array + * + * @param[in,out] *TechPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return FALSE - always + * ---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemTDefaultTechnologyHook ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT VOID *OptParam + ) +{ + return FALSE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mthdi.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mthdi.c new file mode 100644 index 0000000000..3831b16db8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mthdi.c @@ -0,0 +1,124 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mthdi.c + * + * Common technology hardware dram init support functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTHDI_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initiates Hardware based dram initialization for both DCTs + * at the same time. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTDramInitHw ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 Dct; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + + NBPtr->BrdcstSet (NBPtr, BFInitDram, 1); + // Phy fence training + AGESA_TESTPOINT (TpProcMemPhyFenceTraining, &(NBPtr->MemPtr->StdHeader)); + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->PhyFenceTraining (NBPtr); + } + } +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.c new file mode 100644 index 0000000000..01e63f854e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.c @@ -0,0 +1,906 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttEdgeDetect.c + * + * DQS R/W position training utilizing Data Eye Edge Detection for optimization + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + + + +#include "AGESA.h" +#include "amdlib.h" +#include "AdvancedApi.h" +#include "GeneralServices.h" +#include "Ids.h" +#include "heapManager.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mport.h" +#include "mttEdgeDetect.h" +#include "OptionMemory.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTEDGEDETECT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + +#define LAST_DELAY (-128) +#define INC_DELAY 1 +#define DEC_DELAY 0 + + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/** + * Sweep Table For Byte Training without insertion delay + * +*/ +DQS_POS_SWEEP_TABLE SweepTableByte[] = +{ + // Begin End Inc/Dec Step EndResult Edge + { 0x00, 0x1F, INC_DELAY, 4, 0xFFFF, LEFT_EDGE}, /// For Left Edge, start from 0 and Increment to 0x1F by 4 until all PASS + { LAST_DELAY, 0x00, DEC_DELAY, -1, 0xFE00, LEFT_EDGE}, /// Then go back down to 0x00 by 1 until all FAIL + { 0x1F, 0x00, DEC_DELAY, -4, 0xFFFF, RIGHT_EDGE}, /// For Right Edge, start from 0x1F down to 0 until all PASS. + { LAST_DELAY, 0x1F, INC_DELAY, 1, 0xFE00, RIGHT_EDGE} /// Then go back up by 1 until all FAIL. +}; +/** + * Sweep Table For Byte Training with insertion delay + * +*/ +DQS_POS_SWEEP_TABLE InsSweepTableByte[] = +{ + // Begin End Inc/Dec Step EndResult Edge + { 0x00, -0x20, DEC_DELAY, -4, 0xFE00, LEFT_EDGE}, /// For Left Edge, start from 0 and Decrement to -0x20 by -4 until all FAIL + { LAST_DELAY, 0x1F, INC_DELAY, 1, 0xFFFF, LEFT_EDGE}, /// Then go back up to 0x1F by 1 until all PASS + { 0x1F, 0x00, DEC_DELAY, -4, 0xFFFF, RIGHT_EDGE}, /// For Right Edge, start from 0x1F down to 0 until all PASS. + { LAST_DELAY, 0x1F, INC_DELAY, 1, 0xFE00, RIGHT_EDGE} /// Then go back up by 1 until all FAIL. +}; + +BOOLEAN +STATIC +MemTTrainDQSRdWrEdgeDetect ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +STATIC +MemTInitTestPatternAddress ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT SWEEP_INFO *SweepPtr + ); + +BOOLEAN +STATIC +MemTContinueSweep ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT SWEEP_INFO *SweepPtr + ); + +BOOLEAN +STATIC +MemTSetNextDelay ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT SWEEP_INFO *SweepPtr + ); + +UINT8 +STATIC +MemTScaleDelayVal ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN INT8 Delay + ); + +BOOLEAN +STATIC +MemTDataEyeSave ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT SWEEP_INFO *SweepPtr, + IN UINT8 ByteLane + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern MEM_FEAT_TRAIN_SEQ memTrainSequenceDDR3[]; +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes DQS position training for all a Memory channel using + * the Edge Detection algorithm. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +BOOLEAN +MemTTrainDQSEdgeDetectSw ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + BOOLEAN Status; + + Status = FALSE; + NBPtr = TechPtr->NBPtr; + TechPtr->TrainingType = TRN_DQS_POSITION; + // + // Initialize the Pattern + // + if (AGESA_SUCCESS == NBPtr->TrainingPatternInit (NBPtr)) { + // + // Setup hardware training engine (if applicable) + // + NBPtr->FamilySpecificHook[SetupHwTrainingEngine] (NBPtr, &TechPtr->TrainingType); + // + // Start Edge Detection + // + Status |= MemTTrainDQSRdWrEdgeDetect (TechPtr); + // + // Finalize the Pattern + // + Status &= (AGESA_SUCCESS == NBPtr->TrainingPatternFinalize (NBPtr)); + } + return Status; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This Executes Read DQS and Write Data Position training on a chip select pair + * using the Edge Detection algorithm. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + + */ + +BOOLEAN +STATIC +MemTTrainDQSRdWrEdgeDetect ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + MEM_DATA_STRUCT *MemPtr; + MEM_NB_BLOCK *NBPtr; + UINT8 WrDqDelay; + UINT8 Dct; + UINT8 ChipSel; + UINT8 i; + BOOLEAN Status; + UINT8 TimesFail; + UINT8 TimesRetrain; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + TimesRetrain = DEFAULT_TRAINING_TIMES; + IDS_OPTION_HOOK (IDS_MEM_RETRAIN_TIMES, &TimesRetrain, &MemPtr->StdHeader); + // + // Set environment settings before training + // + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart Read/Write Data Eye Edge Detection.\n"); + MemTBeginTraining (TechPtr); + // + // Do Rd DQS /Wr Data Position training for all Dcts/Chipselects + // + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + // + // Chip Select Loop + // + TechPtr->RestartChipSel = -1; + for (ChipSel = 0; ChipSel < NBPtr->CsPerChannel; ChipSel = ChipSel + NBPtr->CsPerDelay ) { + // + // Init Bit Error Masks + // + LibAmdMemFill (&NBPtr->ChannelPtr->FailingBitMask[ (ChipSel * MAX_BYTELANES_PER_CHANNEL) ], + 0xFF, + (MAX_BYTELANES_PER_CHANNEL * NBPtr->CsPerDelay), + &MemPtr->StdHeader); + if ( (NBPtr->MCTPtr->Status[SbLrdimms]) ? ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0) : + ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) != 0) ) { + + TechPtr->ChipSel = ChipSel; + IDS_HDT_CONSOLE (MEM_STATUS, "\t\tCS %d\n", ChipSel); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tIncrease WrDat, Train RdDqs:\n"); + + TechPtr->DqsRdWrPosSaved = 0; + // + // Use a list of Approximate Write Data delay values and train Read DQS Position for + // each until a valid Data eye is found. + // + Status = FALSE; + TimesFail = 0; + NBPtr->FamilySpecificHook[InitializeRxEnSeedlessTraining] (NBPtr, NBPtr); + ERROR_HANDLE_RETRAIN_BEGIN (TimesFail, TimesRetrain) { + i = 0; + while (NBPtr->GetApproximateWriteDatDelay (NBPtr, i, &WrDqDelay)) { + TechPtr->SmallDqsPosWindow = FALSE; + // + // Set Write Delay approximation + // + TechPtr->Direction = DQS_WRITE_DIR; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\tWrite Delay: %02x", WrDqDelay); + MemTSetDQSDelayAllCSR (TechPtr, WrDqDelay); + // + // Attempt Read Training + // + TechPtr->Direction = DQS_READ_DIR; + Status = memTrainSequenceDDR3[NBPtr->TrainingSequenceIndex].MemTechFeatBlock->RdPosTraining (TechPtr); + if (Status) { + // + // If Read DQS Training was successful, Train Write Data (DQ) Position + // + TechPtr->DqsRdWrPosSaved = 0; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\tTrain WrDat:\n\n"); + TechPtr->Direction = DQS_WRITE_DIR; + if (NBPtr->FamilySpecificHook[BeforeWrDatTrn] (NBPtr, &ChipSel)) { + Status = MemTTrainDQSEdgeDetect (TechPtr); + } + break; + } + i++; + } + ERROR_HANDLE_RETRAIN_END ((Status == FALSE), TimesFail) + } + + // + // If we went through the table, Fail. + // + if (Status == FALSE) { + // On training failure, check and record whether training fails due to small window or no window + if (TechPtr->SmallDqsPosWindow) { + NBPtr->MCTPtr->ErrStatus[EsbSmallDqs] = TRUE; + } else { + NBPtr->MCTPtr->ErrStatus[EsbNoDqsPos] = TRUE; + } + + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + if (TechPtr->Direction == DQS_READ_DIR) { + PutEventLog (AGESA_ERROR, MEM_ERROR_NO_DQS_POS_RD_WINDOW, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + } else { + PutEventLog (AGESA_ERROR, MEM_ERROR_NO_DQS_POS_WR_WINDOW, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + } + NBPtr->DCTPtr->Timings.CsTrainFail |= (UINT16)1 << ChipSel; + // If the even chip select failed training always fail the odd, if present. + if (((ChipSel & 0x01) == 0) && (NBPtr->CsPerDelay == 2)) { + if (NBPtr->DCTPtr->Timings.CsPresent & ((UINT16)1 << (ChipSel + 1))) { + NBPtr->DCTPtr->Timings.CsTrainFail |= (UINT16)1 << (ChipSel + 1); + } + } + if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, NBPtr->DCTPtr->Timings.CsTrainFail, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + } + } else { + // + // Clear Bit Error Masks if these CS will not be trained. + // + LibAmdMemFill (&NBPtr->ChannelPtr->FailingBitMask[ (ChipSel * MAX_BYTELANES_PER_CHANNEL) ], + 0x00, + (MAX_BYTELANES_PER_CHANNEL * NBPtr->CsPerDelay), + &NBPtr->MemPtr->StdHeader); + } + } + } + // + // Restore environment settings after training + // + MemTEndTraining (TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "End Read/Write Data Eye Edge Detection\n\n"); + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes DQS position training for both read and write, using + * the Edge Detection Algorithm. This method searches for the beginning and end + * of the Data Eye with out scanning every DSQ delay value. The following is a + * detailed description of the algorithm: + * + * Four-Stage Data Eye Sweep + * + * -Search starts at Delay value of 0. + * -Search left in steps of 4/32UI looking for all Byte lanes Passing. Left from zero rolls over to a negative value. + * -Negative values are translated to the high end of the delay range, but using Insertion delay comparison. + * -For each passing byte lane, freeze delay at first passing value, but set mask so next steps will not compare for byte lanes that previously passed + * -Switch to search right in steps of 1/32UI looking for fail. + * -For each lane, starting delay for 1/32 sweep right is first passing delay from 4/32 sweep left. + * -For each failing byte lane, freeze delay at first failing value, but set mask so next steps will not compare for byte lanes that previously failed + * -Search right until all byte lanes have failed + * -For each lane, right edge used by BIOS will be first failing delay value minus 1/32 + + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - All bytelanes pass + * @return FALSE - Some bytelanes fail +*/ +BOOLEAN +MemTTrainDQSEdgeDetect ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + DIE_STRUCT *MCTPtr; + DQS_POS_SWEEP_TABLE *SweepTablePtr; + UINT8 SweepTableSize; + SWEEP_INFO SweepData; + BOOLEAN Status; + UINT16 CurrentResult; + UINT16 AlignedResult; + UINT16 OffsetResult; + UINT8 StageIndex; + UINT8 CsIndex; + UINT8 i; + + Status = TRUE; + // + // Initialize Object Pointers + // + NBPtr = TechPtr->NBPtr; + MCTPtr = NBPtr->MCTPtr; + // + // Initialize stack variables + // + LibAmdMemFill (&SweepData, 0, sizeof (SWEEP_INFO), &NBPtr->MemPtr->StdHeader); + // + /// Get Pointer to Sweep Table + // + if (TechPtr->Direction == DQS_READ_DIR) { + SweepTablePtr = InsSweepTableByte; + SweepTableSize = GET_SIZE_OF (InsSweepTableByte); + } else { + SweepTablePtr = SweepTableByte; + SweepTableSize = GET_SIZE_OF (SweepTableByte); + } + + // + /// Set up the test Pattern, exit if no Memory + // + if (MemTInitTestPatternAddress (TechPtr, &SweepData) == FALSE) { + LibAmdMemFill (&NBPtr->ChannelPtr->FailingBitMask[ (TechPtr->ChipSel * MAX_BYTELANES_PER_CHANNEL) ], + 0, + (MAX_BYTELANES_PER_CHANNEL * NBPtr->CsPerDelay), + &NBPtr->MemPtr->StdHeader); + return FALSE; + } + // + // Clear Error Flag + // + SweepData.Error = FALSE; + NBPtr->FamilySpecificHook[InitialzeRxEnSeedlessByteLaneError] (NBPtr, NBPtr); + // + /// Process Sweep table, using entries from the table to determine Starting and Ending Delays + /// as well as the Step size and criteria for evaluating whether the correct result is found. + /// + /// Delay values at this level are an abstract range of values which gets scaled to the actual value + /// before it is written to the hardware. This allows NB specific code to handle the scaling as a + /// function of frequency or other conditions. + // + for (StageIndex = 0; (StageIndex < SweepTableSize) && (SweepData.Error == FALSE); StageIndex++) { + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSTAGE: %d\t", StageIndex); + // + /// Initialize SweepData variables + // + SweepData.BeginDelay = SweepTablePtr->BeginDelay; + SweepData.EndDelay = SweepTablePtr->EndDelay; + SweepData.Step = 0; /// Step Value will be 0 to start. + SweepData.EndResult = SweepTablePtr->EndResult; + if (!(MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining])) { + SweepData.EndResult |= 0x0100; + } + SweepData.Edge = SweepTablePtr->MinMax; + SweepData.InsertionDelayMsk = 0; + SweepData.ResultFound = 0x0000; + // + // Set Training Delays Pointer. + // + if (TechPtr->Direction == DQS_READ_DIR) { + SweepData.TrnDelays = (INT8 *) ((SweepData.Edge == RIGHT_EDGE) ? NBPtr->ChannelPtr->RdDqsMaxDlys : NBPtr->ChannelPtr->RdDqsMinDlys); + } else { + SweepData.TrnDelays = (INT8 *) ((SweepData.Edge == RIGHT_EDGE) ? NBPtr->ChannelPtr->WrDatMaxDlys : NBPtr->ChannelPtr->WrDatMinDlys); + }; + // + /// Set initial TrnDelay Values if necessary + // + IDS_HDT_CONSOLE (MEM_FLOW, "Sweeping %s DQS, %s from ", (TechPtr->Direction == DQS_READ_DIR) ?"Read":"Write", (SweepTablePtr->ScanDir == INC_DELAY) ? "incrementing":"decrementing"); + if (SweepData.BeginDelay != LAST_DELAY) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x", (UINT16) MemTScaleDelayVal (TechPtr, SweepData.BeginDelay)); + for (i = 0; i < ((MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8); i++) { + SweepData.TrnDelays[i] = SweepData.BeginDelay; + } + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "Current Delay"); + SweepData.Step = SweepTablePtr->Step; + } + IDS_HDT_CONSOLE (MEM_FLOW, " by %02x, until all bytelanes %s.\n\n", (UINT16) MemTScaleDelayVal (TechPtr, ABS (SweepTablePtr->Step)), (SweepData.EndResult == 0xFFFF)?"PASS":"FAIL"); + + //------------------------------------------------------------------- + // Sweep DQS Delays + // MemTContinueSweep function returns false to break out of loop. + // There are no other breaks out of this loop. + //------------------------------------------------------------------- + while (MemTContinueSweep (TechPtr, &SweepData)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tByte Lane : 08 07 06 05 04 03 02 01 00\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tDQS Delays : %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[8]), + (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[7]), (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[6]), + (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[5]), (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[4]), + (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[3]), (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[2]), + (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[1]), (UINT16) MemTScaleDelayVal (TechPtr, SweepData.TrnDelays[0]) + ); + // + /// Set Step Value + // + SweepData.Step = SweepTablePtr->Step; + CurrentResult = 0xFFFF; + // + /// Chip Select Loop: Test the Pattern for all populated CS that are controlled by the current delay registers + // + for (CsIndex = 0; CsIndex < NBPtr->CsPerDelay ; CsIndex++, TechPtr->ChipSel++) { + ASSERT (CsIndex < MAX_CS_PER_CHANNEL); + ASSERT (TechPtr->ChipSel < MAX_CS_PER_CHANNEL); + if (SweepData.CsAddrValid[CsIndex] == TRUE) { + // + /// If this is a Write Dqs sweep, Write the pattern now. + // + if (TechPtr->Direction == DQS_WRITE_DIR) { + NBPtr->WritePattern (NBPtr, SweepData.TestAddrRJ16[CsIndex], TechPtr->PatternBufPtr, TechPtr->PatternLength); + } + // + /// Read the Pattern Back + // + NBPtr->ReadPattern (NBPtr, TechPtr->TestBufPtr, SweepData.TestAddrRJ16[CsIndex], TechPtr->PatternLength); + // + /// Compare the Pattern and Merge the results using InsertionDelayMsk + // + AlignedResult = NBPtr->CompareTestPattern (NBPtr, TechPtr->TestBufPtr, TechPtr->PatternBufPtr, TechPtr->PatternLength * 64); + CurrentResult &= AlignedResult | SweepData.InsertionDelayMsk; + if (SweepData.InsertionDelayMsk != 0) { + OffsetResult = NBPtr->InsDlyCompareTestPattern (NBPtr, TechPtr->TestBufPtr, TechPtr->PatternBufPtr, TechPtr->PatternLength * 64); + CurrentResult &= (OffsetResult | (~SweepData.InsertionDelayMsk)); + } + // + /// Flush the Test Pattern + // + NBPtr->FlushPattern (NBPtr, SweepData.TestAddrRJ16[CsIndex], TechPtr->PatternLength); + NBPtr->FamilySpecificHook[ResetRxFifoPtr] (NBPtr, NBPtr); + } + } /// End Chip Select Loop + TechPtr->ChipSel = TechPtr->ChipSel - CsIndex; + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tResult : %c %c %c %c %c %c %c %c %c \n", + (SweepData.ResultFound & ((UINT16) 1 << (8))) ? ' ':(CurrentResult & ((UINT16) 1 << (8))) ? 'P':'.', + (SweepData.ResultFound & ((UINT16) 1 << (7))) ? ' ':(CurrentResult & ((UINT16) 1 << (7))) ? 'P':'.', + (SweepData.ResultFound & ((UINT16) 1 << (6))) ? ' ':(CurrentResult & ((UINT16) 1 << (6))) ? 'P':'.', + (SweepData.ResultFound & ((UINT16) 1 << (5))) ? ' ':(CurrentResult & ((UINT16) 1 << (5))) ? 'P':'.', + (SweepData.ResultFound & ((UINT16) 1 << (4))) ? ' ':(CurrentResult & ((UINT16) 1 << (4))) ? 'P':'.', + (SweepData.ResultFound & ((UINT16) 1 << (3))) ? ' ':(CurrentResult & ((UINT16) 1 << (3))) ? 'P':'.', + (SweepData.ResultFound & ((UINT16) 1 << (2))) ? ' ':(CurrentResult & ((UINT16) 1 << (2))) ? 'P':'.', + (SweepData.ResultFound & ((UINT16) 1 << (1))) ? ' ':(CurrentResult & ((UINT16) 1 << (1))) ? 'P':'.', + (SweepData.ResultFound & ((UINT16) 1 << (0))) ? ' ':(CurrentResult & ((UINT16) 1 << (0))) ? 'P':'.' + ); + // + /// Merge current result into cumulative result and make it positive. + // + SweepData.ResultFound |= ~(CurrentResult ^ SweepData.EndResult); + + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tResultFound : %c %c %c %c %c %c %c %c %c \n\n", + (SweepData.ResultFound & ((UINT16) 1 << (8))) ? 'Y':' ', + (SweepData.ResultFound & ((UINT16) 1 << (7))) ? 'Y':' ', + (SweepData.ResultFound & ((UINT16) 1 << (6))) ? 'Y':' ', + (SweepData.ResultFound & ((UINT16) 1 << (5))) ? 'Y':' ', + (SweepData.ResultFound & ((UINT16) 1 << (4))) ? 'Y':' ', + (SweepData.ResultFound & ((UINT16) 1 << (3))) ? 'Y':' ', + (SweepData.ResultFound & ((UINT16) 1 << (2))) ? 'Y':' ', + (SweepData.ResultFound & ((UINT16) 1 << (1))) ? 'Y':' ', + (SweepData.ResultFound & ((UINT16) 1 << (0))) ? 'Y':' ' + ); + } /// End of Delay Sweep + // + /// Place Final delay values at last passing delay. + // + if (SweepData.ResultFound == 0xFFFF) { + if ( ABS (SweepData.Step) == 1) { + for (i = 0; i < ((MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8) ; i++) { + if ((SweepData.EndResult & ((UINT16) (1 << i))) == 0) { + SweepData.TrnDelays[i] = SweepData.TrnDelays[i] - SweepData.Step; + } + } + } + } + // + // Update Pointer to Sweep Table + // + SweepTablePtr++; + }///End of Edge Detect loop + // + /// If No Errors are detected, Calculate Data Eye Width and Center + // + if (SweepData.Error == FALSE) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tData Eye Results:\n\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tByte Left Right\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tLane Edge Edge Width Center\n"); + for (i = 0; i < ((MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8) ; i++) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t %0d", i); + TechPtr->Bytelane = i; + if (!MemTDataEyeSave (TechPtr, &SweepData, i)) { + break; + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + if (SweepData.Error == TRUE) { + Status = FALSE; + } + } + } else { + Status = FALSE; + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t--DATA EYE NOT FOUND--\n\n"); + NBPtr->FamilySpecificHook[TrackRxEnSeedlessRdWrNoWindBLError] (NBPtr, &SweepData); + } + return Status; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Initialize the Test Pattern Address for two chip selects and, if this + * is a Write Data Eye, write the initial test pattern. + * + * Test Address is stored in the Sweep info struct. If Memory is not present + * then return with False. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] *SweepPtr - Pointer to SWEEP_INFO structure. + * + * @return BOOLEAN + * TRUE - Memory is present + * FALSE - No memory present on this Chip Select pair. + * +** + */ +BOOLEAN +STATIC +MemTInitTestPatternAddress ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT SWEEP_INFO *SweepPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + UINT8 ChipSel; + UINT8 CsIndex; + BOOLEAN BanksPresent; + + NBPtr = TechPtr->NBPtr; + BanksPresent = FALSE; + ChipSel = TechPtr->ChipSel; + for (CsIndex = 0; CsIndex < NBPtr->CsPerDelay; ChipSel++, CsIndex++, TechPtr->ChipSel++) { + ASSERT (CsIndex < MAX_CS_PER_CHANNEL); + ASSERT (ChipSel < MAX_CS_PER_CHANNEL); + ASSERT (TechPtr->ChipSel < MAX_CS_PER_CHANNEL); + // + /// If memory is present on this cs, get the test addr + // + if (NBPtr->GetSysAddr (NBPtr, ChipSel, &(SweepPtr->TestAddrRJ16[CsIndex]))) { + if (!(NBPtr->MCTPtr->Status[SbLrdimms]) || ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0)) { + BanksPresent = TRUE; + SweepPtr->CsAddrValid[CsIndex] = TRUE; + // + /// If this is a Read Dqs sweep, Write the pattern now. + // + if (TechPtr->Direction == DQS_READ_DIR) { + IDS_HDT_CONSOLE (MEM_FLOW, "\tTestAddr: %x0000\n", SweepPtr->TestAddrRJ16[CsIndex]); + NBPtr->WritePattern (NBPtr, SweepPtr->TestAddrRJ16[CsIndex], TechPtr->PatternBufPtr, TechPtr->PatternLength); + } + } + } else { + SweepPtr->CsAddrValid[CsIndex] = FALSE; + } + } /// End Chip Select Loop + TechPtr->ChipSel = TechPtr->ChipSel - CsIndex; + // + /// return FALSE if no ChipSelects present. + // + return BanksPresent; +} + +/* -----------------------------------------------------------------------------*/ +/** + * Test Conditions for exiting the training loop, set the next delay value, + * and return status + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] *SweepPtr - Pointer to SWEEP_INFO structure. + * + * @return BOOLEAN + * TRUE - Continue to test with next delay setting + * FALSE - Exit training loop. Either the result has been found or + * end of delay range has been reached. +*/ +BOOLEAN +STATIC +MemTContinueSweep ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT SWEEP_INFO *SweepPtr + ) +{ + BOOLEAN Status; + Status = FALSE; + if (SweepPtr->ResultFound != 0xFFFF) { + Status = MemTSetNextDelay (TechPtr, SweepPtr); + } + TechPtr->NBPtr->FamilySpecificHook[RegAccessFence] (TechPtr->NBPtr, NULL); + return Status; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the next delay value for each bytelane that needs to + * be advanced. It checks the bounds of the delay to see if we are at the + * end of the range. If we are to close to advance a whole step value, but + * not at the boundary, then we set the delay to the boundary. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] *SweepPtr - Pointer to SWEEP_INFO structure. + * + */ + +BOOLEAN +STATIC +MemTSetNextDelay ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT SWEEP_INFO *SweepPtr + ) +{ + DIE_STRUCT *MCTPtr; + UINT8 i; + + MCTPtr = TechPtr->NBPtr->MCTPtr; + // + ///< Loop through bytelanes + // + for (i = 0; i < ((MCTPtr->Status[SbEccDimms] && TechPtr->NBPtr->IsSupported[EccByteTraining]) ? 9 : 8) ; i++) { + // + /// Skip Bytelanes that have already reached the desired result + // + if ( (SweepPtr->ResultFound & ((UINT16)1 << i)) == 0) { + // + /// If a bytelane has reached the end, flag an error and exit + // + if (SweepPtr->TrnDelays[i] == SweepPtr->EndDelay) { + if ((SweepPtr->EndResult & ((UINT16) (1 << i))) != 0) { + MCTPtr->ErrStatus[EsbNoDqsPos] = TRUE; + SweepPtr->Error = TRUE; + } + return FALSE; + } + // + /// If the Current delay value is less than a step away from EndDelay, + // + if ( ABS (SweepPtr->EndDelay - SweepPtr->TrnDelays[i]) < ABS (SweepPtr->Step)) { + /// set to EndDelay. + // + SweepPtr->TrnDelays[i] = SweepPtr->EndDelay; + } else { + // + /// Otherwise, add the step value to it + SweepPtr->TrnDelays[i] = SweepPtr->TrnDelays[i] + SweepPtr->Step; + } + // + /// Set InsertionDelayMsk bit if Delay < 0 for this bytelane + // + if (SweepPtr->TrnDelays[i] < 0) { + SweepPtr->InsertionDelayMsk |= ((UINT16) 1 << i); + } else { + SweepPtr->InsertionDelayMsk &= ~((UINT16) 1 << i); + } + // + /// Write the scaled value to the Delay Register + // + TechPtr->SetDQSDelayCSR (TechPtr, i, MemTScaleDelayVal (TechPtr, SweepPtr->TrnDelays[i])); + } + } + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function accepts a delay value in 32nd of a UI and converts it to an + * actual register value, taking into consideration NB type, rd/wr, + * and frequency. + * + * Delay = (Min + (Delay * ( (Max - Min) / TRN_DELAY_MAX) )) & Mask + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Delay - INT8 of delay value; + * + * @return UINT8 of the adjusted delay value +*/ +UINT8 +STATIC +MemTScaleDelayVal ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN INT8 Delay + ) +{ + MEM_NB_BLOCK *NBPtr; + TRN_DLY_PARMS Parms; + TRN_DLY_TYPE DelayType; + UINT8 NewDelay; + INT8 Factor; + INT8 ScaledDelay; + + NBPtr = TechPtr->NBPtr; + // + // Determine Delay Type, Get Delay Parameters, and return scaled Delay value + // + DelayType = (TechPtr->Direction == DQS_WRITE_DIR) ? AccessWrDatDly : AccessRdDqsDly; + NBPtr->GetTrainDlyParms (NBPtr, DelayType, &Parms); + Factor = ((Parms.Max - Parms.Min) / TRN_DELAY_MAX); + ScaledDelay = Delay * Factor; + NewDelay = (Parms.Min + ScaledDelay) & Parms.Mask; + return NewDelay; +} + + + + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates the Center of the Data eye for the specified byte lane + * and stores its DQS Delay value for reference. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] *SweepPtr - Pointer to SWEEP_INFO structure. + * @param[in] ByteLane - Bytelane number being targeted + * + */ +BOOLEAN +STATIC +MemTDataEyeSave ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT SWEEP_INFO *SweepPtr, + IN UINT8 ByteLane + ) +{ + MEM_NB_BLOCK *NBPtr; + UINT8 EyeCenter; + UINT8 DlyMin; + UINT8 DlyMax; + UINT8 EyeWidth; + UINT8 Dimm; + CH_DEF_STRUCT *ChanPtr; + + NBPtr = TechPtr->NBPtr; + ChanPtr = NBPtr->ChannelPtr; + + ASSERT (ByteLane < ((NBPtr->MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8)); + // + // Calculate Data Eye edges, Width, and Center in real terms. + // + if (TechPtr->Direction == DQS_READ_DIR) { + DlyMin = MemTScaleDelayVal (TechPtr, ChanPtr->RdDqsMinDlys[ByteLane]); + DlyMax = MemTScaleDelayVal (TechPtr, ChanPtr->RdDqsMaxDlys[ByteLane]); + EyeWidth = MemTScaleDelayVal (TechPtr, (ChanPtr->RdDqsMaxDlys[ByteLane] - ChanPtr->RdDqsMinDlys[ByteLane])); + EyeCenter = MemTScaleDelayVal (TechPtr, ((ChanPtr->RdDqsMinDlys[ByteLane] + ChanPtr->RdDqsMaxDlys[ByteLane] + 1) / 2)); + if (!NBPtr->FamilySpecificHook[RdDqsDlyRestartChk] (NBPtr, &EyeCenter)) { + return FALSE; + } + ChanPtr->RdDqsMinDlys[ByteLane] = DlyMin; + ChanPtr->RdDqsMaxDlys[ByteLane] = DlyMax; + NBPtr->FamilySpecificHook[ForceRdDqsPhaseB] (NBPtr, &EyeCenter); + } else { + DlyMin = MemTScaleDelayVal (TechPtr, ChanPtr->WrDatMinDlys[ByteLane]); + DlyMax = MemTScaleDelayVal (TechPtr, ChanPtr->WrDatMaxDlys[ByteLane]); + EyeWidth = MemTScaleDelayVal (TechPtr, (ChanPtr->WrDatMaxDlys[ByteLane] - ChanPtr->WrDatMinDlys[ByteLane])); + EyeCenter = MemTScaleDelayVal (TechPtr, ((ChanPtr->WrDatMinDlys[ByteLane] + ChanPtr->WrDatMaxDlys[ByteLane] + 1) / 2)); + ChanPtr->WrDatMinDlys[ByteLane] = DlyMin; + ChanPtr->WrDatMaxDlys[ByteLane] = DlyMax; + } + // + // Flag error for small window. + // + if (EyeWidth < MemTScaleDelayVal (TechPtr, NBPtr->MinDataEyeWidth (NBPtr))) { + TechPtr->SmallDqsPosWindow = TRUE; + SweepPtr->Error = TRUE; + NBPtr->FamilySpecificHook[TrackRxEnSeedlessRdWrSmallWindBLError] (NBPtr, NULL); + } + + IDS_HDT_CONSOLE (MEM_FLOW, " %02x %02x %02x %02x", DlyMin, DlyMax, EyeWidth, EyeCenter); + + TechPtr->SetDQSDelayCSR (TechPtr, ByteLane, EyeCenter); + if (!SweepPtr->Error) { + TechPtr->DqsRdWrPosSaved |= (UINT8)1 << ByteLane; + } + TechPtr->DqsRdWrPosSaved |= 0xFE00; + + Dimm = (TechPtr->ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane; + if (TechPtr->Direction == DQS_READ_DIR) { + ChanPtr->RdDqsDlys[Dimm] = EyeCenter; + } else { + ChanPtr->WrDatDlys[Dimm] = EyeCenter + ChanPtr->WrDqsDlys[Dimm]; + } + + return TRUE; +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.h new file mode 100644 index 0000000000..113f864055 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttEdgeDetect.h @@ -0,0 +1,117 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttEdgeDetect.h + * + * Technology Common Training Header file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MTTEDGEDETECT_H_ +#define _MTTEDGEDETECT_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + + +#define SCAN_LEFT 0 ///< Scan Down +#define SCAN_RIGHT 1 ///< Scan Up +#define LEFT_EDGE 0 ///< searching for the left edge +#define RIGHT_EDGE 1 ///< searching for the right edge + +#define SweepStages 4 +#define TRN_DELAY_MAX 31 ///< Max Virtual delay value for DQS Position Training + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/** + * Sweep Table Structure. ROM based table defining parameters for DQS position + * training delay sweep. +*/ +typedef struct { + INT8 BeginDelay; ///< Starting Delay Value + INT8 EndDelay; ///< Ending Delay Value + BOOLEAN ScanDir; ///< Scan Direction. 0 = down, 1 = up + INT8 Step; ///< Amount to increment delay value + UINT16 EndResult; ///< Result value to stop sweeping (to compare with failure mask) + BOOLEAN MinMax; ///< Flag indicating lower (left edge) or higher(right edge) +} DQS_POS_SWEEP_TABLE; + +/** + * Sweep Information Struct - Used to track data through the DQS Delay Sweep + * +*/ +typedef struct _SWEEP_INFO { + BOOLEAN Error; ///< Indicates an Error has been found + UINT32 TestAddrRJ16[MAX_CS_PER_CHANNEL]; ///< System address of chipselects RJ 16 bits (Addr[47:16]) + BOOLEAN CsAddrValid[MAX_CS_PER_CHANNEL]; ///< Indicates which chipselects to test + INT8 BeginDelay; ///< Beginning Delay value (Virtual) + INT8 EndDelay; ///< Ending Delay value (Virtual) + INT8 Step; ///< Amount to Inc or Dec Virtual Delay value + BOOLEAN Edge; ///< Left or right edge (0 = LEFT, 1= RIGHT) + UINT16 EndResult; ///< Result value that will stop a Dqs Sweep + UINT16 InsertionDelayMsk; ///< Mask of Byte Lanes that should use ins. dly. comparison + UINT16 LaneMsk; ///< Mask indicating byte lanes to update + UINT16 ResultFound; ///< Mask indicating byte lanes where desired result was found on a sweep + INT8 *TrnDelays; ///< Delay Values for each byte (Virtual). Points into the delay values +} SWEEP_INFO; ///< stored in the CH_DEF_STRUCT. + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + + + +#endif /* _MTTEDGEDETECT_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DEyeRimSearch.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DEyeRimSearch.c new file mode 100644 index 0000000000..a568f9ec68 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DEyeRimSearch.c @@ -0,0 +1,996 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttRdDqs2DEyeRimmSearch.c + * + * RD DQS 2 Dimentional Training using Eye Rim Sampling + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "AdvancedApi.h" +#include "GeneralServices.h" +#include "Ids.h" +#include "heapManager.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mport.h" +#include "merrhdl.h" +#include "Filecode.h" +#include "OptionMemory.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTRDDQS2DEYERIMSEARCH_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +BOOLEAN +MemTInitializeEyeRimSearch ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemTEyeFill ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +CheckSaveResAtEdge ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN INT8 xdir + ); + +UINT8 +DetermineSavedState ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ); + +UINT8 +GetPassFailValue ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ); + +VOID +SetPassFailValue ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN UINT8 result + ); + +VOID +SetSavedState ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN UINT8 result + ); + +INT8 MemTGet1DTrainedEyeCenter ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane + ); + +BOOLEAN +CheckForFail ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ); + +BOOLEAN +AllocateSaveLaneStorage ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +INT8 +xlateY ( + IN INT8 y + ); + +BOOLEAN +ClearSampledPassResults ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +/* -----------------------------------------------------------------------------*/ +/** + * + * Initialize Eye Rim Search + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE + */ +BOOLEAN +MemTInitializeEyeRimSearch ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 lane; + UINT8 vref; + MEM_2D_ENTRY *Data; + MEM_2D_RIM_ENTRY *RimData; + Data = TechPtr->Local2DData; + RimData = TechPtr->SavedData; + // + // Set Boundaries + // + RimData->xMax = Data->MaxRdDqsSweep - 1; + RimData->yMax = (TechPtr->NBPtr->TotalMaxVrefRange / 2) - 1; + RimData->xMin = RimData->xMax * -1; + RimData->yMin = RimData->yMax * -1; + + RimData->ParallelSampling = EYERIM_PARALLEL_SAMPLING; + RimData->BroadcastDelays = EYERIM_BROADCAST_DELAYS; + RimData->Dirs[0] = 1; + RimData->Dirs[1] = -1; + + RimData->SampleCount = 0; + RimData->VrefUpdates = 0; + RimData->RdDqsDlyUpdates = 0; + for (lane = 0; lane < MemT2DGetMaxLanes (TechPtr); lane ++ ) { + for ( vref = 0; vref < TechPtr->NBPtr->TotalMaxVrefRange; vref ++ ) { + // 00b = state not saved + // 01b = state saved + RimData->LaneSaved[lane].Vref[vref].PosRdDqsDly = 0; + RimData->LaneSaved[lane].Vref[vref].NegRdDqsDly = 0; + // 00b = Fail + // 01b = Pass + Data->Lane[lane].Vref[vref].PosRdDqsDly = 0; + Data->Lane[lane].Vref[vref].NegRdDqsDly = 0; + } + } + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * This function collects data for Eye Rim Search + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ +BOOLEAN +MemT2DRdDQSEyeRimSearch ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 lane; + UINT8 j; + UINT8 k; + INT8 ydir; + INT8 xdir; + INT8 xi; + INT8 yi; + INT8 x; + INT8 y; + INT8 xmax; + INT8 ymax; + INT8 xmin; + INT8 ymin; + INT8 xo; + INT8 xt; + INT8 yo; + INT8 yt; + UINT8 slane; + UINT8 result; + INT8 states[2]; + UINT8 InitialCS; + UINT8 ChipSel; + UINT8 Aggr; + UINT8 SeedCount; + UINT32 InPhaseResult; + UINT32 PhaseResult180; + UINT32 Result; + MEM_2D_ENTRY *Data; + MEM_2D_RIM_ENTRY RimData; + MEM_NB_BLOCK *NBPtr; + RD_DQS_2D *VrefPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + NBPtr = TechPtr->NBPtr; + Data = TechPtr->Local2DData; + + //if (AllocateSaveLaneStorage(TechPtr)) { + // return FALSE; + //} + // Allocate Storage for Rim Search + AllocHeapParams.RequestedBufferSize = MemT2DGetMaxLanes (TechPtr) * TechPtr->NBPtr->TotalMaxVrefRange * sizeof (RD_DQS_2D); + AllocHeapParams.BufferHandle = AMD_MEM_2D_RDQS_RIM_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &TechPtr->NBPtr->MemPtr->StdHeader) == AGESA_SUCCESS) { + VrefPtr = (RD_DQS_2D *) AllocHeapParams.BufferPtr; + } else { + SetMemError (AGESA_FATAL, TechPtr->NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_2D, 0, 0, 0, 0, &TechPtr->NBPtr->MemPtr->StdHeader); + return FALSE; + } + for (lane = 0; lane < MemT2DGetMaxLanes (TechPtr); lane++) { + RimData.LaneSaved[lane].Vref = &VrefPtr[lane * TechPtr->NBPtr->TotalMaxVrefRange]; + } + TechPtr->SavedData = &RimData; + MemTInitializeEyeRimSearch (TechPtr); + MemT2DProgramIntExtVrefSelect (TechPtr); + InitialCS = TechPtr->ChipSel; + NBPtr->FamilySpecificHook[Adjust2DPhaseMaskBasedOnEcc] (NBPtr, &NBPtr); + NBPtr->InitializeRdDqs2dVictimContinuousWrites (NBPtr); + // + // EnableDisable continuous writes on the agressor channels + // + IDS_HDT_CONSOLE (MEM_FLOW,"\n\tEye Rim Search, ParallelSampling: %c, BroadcastDelays: %c \n", (RimData.ParallelSampling == TRUE) ? 'Y' : 'N', (RimData.BroadcastDelays == TRUE) ? 'Y' : 'N'); + + for (Aggr = 0; Aggr < (NBPtr->MaxAggressorDimms[(NBPtr->Dct + 1) & 1] > 0 ? NBPtr->MaxAggressorDimms[(NBPtr->Dct + 1) & 1] : 1) ; Aggr += (NBPtr->IsSupported[PerDimmAggressors2D] ? 2 : NBPtr->CsPerDelay) ) { + ClearSampledPassResults (TechPtr); + // + // Enable continuous writes on the aggressors + // + NBPtr->AgressorContinuousWrites (NBPtr, Aggr, TRUE); + for (ChipSel = InitialCS; ChipSel < (InitialCS + NBPtr->CsPerDelay); ChipSel++) { + xmax = RimData.xMax; + xmin = RimData.xMin; + ymax = RimData.yMax; + ymin = RimData.yMin; + if ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) != 0) { + TechPtr->ChipSel = ChipSel; + for (lane = 0; lane < MemT2DGetMaxLanes (TechPtr); lane ++ ) { + // + // Two loops to handle each quadrant from the trained point + // + for ( j = 0; j < 2; j++) { + ydir = RimData.Dirs[j]; + for ( k = 0; k < 2; k++) { + xdir = RimData.Dirs[k]; + // + // Sample Loops - stay w/n the defined quadrant + // assume xmax = -1 * xmin, ymax = -1 * ymin + // initial point must always pass + // end point - boundary or two consecutive fails along the y-axis + // + // Initial dx, dy step state + // Starting dy at 8 to reduce samples necessary searching for the eye height + states[0] = 0; + states[1] = 8; + // xi and yi are inital trained points, assumed to be inside the eye + // These set the coordinate syst em for the quadrants + xi = MemTGet1DTrainedEyeCenter (TechPtr, lane); + yi = 0; // Initial center is always at Vref nominal + x = xi; + y = yi; + while ( + ((xdir > 0 && x >= xi && x <= xmax) || + (xdir < 0 && x <= xi && x >= xmin)) && + ((ydir > 0 && y >= yi && y <= ymax) || + (ydir < 0 && y <= yi && y >= ymin)) && + !(y == yi && (xdir * (xi - x) >= 2) && + CheckSaveResAtEdge (TechPtr, lane, y, x, xdir)) + ) { + // + // Decide if result is already sampled, or need to take the sample + // + if (0 == DetermineSavedState (TechPtr, lane, y, x)) { + RimData.SampleCount++; + // + // Result for this point is not in the cache, sample it + // + for (slane = 0; slane < MemT2DGetMaxLanes (TechPtr); slane ++ ) { + if (!RimData.ParallelSampling && ( slane != lane)) { + continue; + } + // + // Calculate the relative offset from the initial trained position for this lane + // + xo = MemTGet1DTrainedEyeCenter (TechPtr, slane); + yo = 0; + xt = xo + (x - xi); + yt = yo + (y - yi); + if (xt > xmax || xt < xmin || yt > ymax || yt < ymin) { + continue; + } + // + // Update the vref and lane delays (yt, xt) + // + if (slane == lane) { + // + // For processors w/ a single Vref per channel, only set Vref once + // + if ( NBPtr->Vref != xlateY (yt)) { + // + // If not already set + // + TechPtr->SavedData->VrefUpdates++; + NBPtr->Vref = xlateY (yt); + MemT2DProgramVref (TechPtr, xlateY (yt)); + } + } + if (RimData.BroadcastDelays) { + // When BroadcastDelays, only set RdDqs once + if (slane == lane) { + // + // If current lane + // + if ( NBPtr->RdDqsDly != (UINT8) (xt & RimData.xMax)) { + // + // If the not already set + // Account for rollover. + // + TechPtr->SavedData->RdDqsDlyUpdates++; + NBPtr->RdDqsDly = (UINT8) (xt & RimData.xMax); + MemT2DPrograRdDQSDly (TechPtr, (UINT8) (xt & RimData.xMax)); + } + } + } else { + // + /// @todo: Set individual lanes + // + } + } + // + // Perform Memory RW test + // + InPhaseResult = 0; + PhaseResult180 = 0; + NBPtr->InitializeRdDqs2dVictimChipSelContinuousWrites (NBPtr); + for (SeedCount = 0; SeedCount < NBPtr->MaxSeedCount; SeedCount++) { + // + // Begin continuous reads and writes on the victim channels + // + NBPtr->StartRdDqs2dVictimContinuousWrites (NBPtr, SeedCount); + // + // Occasionally check if all trained lanes have already failed + // + if ((NBPtr->MaxSeedCount < 4) || ((SeedCount % (NBPtr->MaxSeedCount / 4)) == 0)) { + InPhaseResult |= NBPtr->InPhaseCompareRdDqs2DPattern (NBPtr, TechPtr->TestBufPtr, TechPtr->PatternBufPtr, TechPtr->PatternLength * 64); + PhaseResult180 |= NBPtr->Phase180CompareRdDqs2DPattern (NBPtr, TechPtr->TestBufPtr, TechPtr->PatternBufPtr, TechPtr->PatternLength * 64); + if (((InPhaseResult & NBPtr->PhaseLaneMask) == NBPtr->PhaseLaneMask) && ((PhaseResult180& NBPtr->PhaseLaneMask) == NBPtr->PhaseLaneMask)) { + break; + } + } + } + // + // Obtain the results + // + for (slane = 0; slane < MemT2DGetMaxLanes (TechPtr); slane ++ ) { + if (!RimData.ParallelSampling && (slane != lane)) { + continue; + } + // + // Calculate the relative offset from legacy trained + // + xo = MemTGet1DTrainedEyeCenter (TechPtr, RimData.BroadcastDelays?lane:slane); + yo = 0; + xt = xo + (x - xi); + yt = yo + (y - yi); + if (xt > xmax || xt < xmin || yt > ymax || yt < ymin) { + continue; + } + // + // In this example, data{}{}{} = 1 is a Fail, 0 is a Pass + // In-Phase Results + // + if (CheckForFail (TechPtr, slane, yt, xt)) { + // + // Don't overwrite a fail + // + if (xt > 0) { + if ((TechPtr->NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // x8, so combine "Nibble X" and "Nibble X+1" results + Result = (InPhaseResult >> (slane * 2)) & 0x03; + } else { + // x4, so use "Nibble" results + Result = (InPhaseResult >> slane) & 0x01; + } + SetPassFailValue (TechPtr, slane, yt, xt, (UINT8) (Result & 0x0F)); + SetSavedState (TechPtr, slane, yt, xt, (UINT8) (Result & 0x0F)); + } else { + if ((TechPtr->NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // x8, so combine "Nibble X" and "Nibble X+1" results + Result = (PhaseResult180 >> (slane * 2)) & 0x03; + } else { + // x4, so use "Nibble" results + Result = (PhaseResult180 >> slane) & 0x01; + } + SetPassFailValue (TechPtr, slane, yt, xt, (UINT8) (Result & 0x0F)); + SetSavedState (TechPtr, slane, yt, xt, (UINT8) (Result & 0x0F)); + } + } + } + } + // Decide the next sample point based on the result of the current lane + result = GetPassFailValue (TechPtr, lane, y, x); + InPhaseResult = 0; + PhaseResult180 = 0; + // States && comments are relative to the ++ Quadrant + if (result == 3) { + // Current Pass + if (states[0] > 0 || states[1] > 0) { + if (states[1] > 1 && y * ydir <= ymax - states[1]) { + // Current Pass, Continue searching up by leaps + states[0] = 0; + } else if (states[1] > 1 && y * ydir <= ymax - 4) { + // Current Pass, Continue searching up by leaps + states[0] = 0; + states[1] = 4; + } else if (states[1] > 1 && y * ydir <= ymax - 2) { + // Current Pass, Continue searching up by leaps + states[0] = 0; + states[1] = 2; + } else if (y * ydir <= ymax - 1) { + // Current Pass, Continue searching up by one + states[0] = 0; + states[1] = 1; + } else if (y * ydir == ymax) { + // Current Pass and at the top edge, Move right + states[0] = 1; + states[1] = 0; + } else { + ASSERT (FALSE); + } + } else { + // Move right one + states[0] = 1; + states[1] = 0; + } + } else if (result == 2) { + // Current Fail + if (states[0] > 0) { + // Search down and left + states[0] = -1; + states[1] = -1; + } else if (states[1] > 1 || states[1] < 0) { + // Search down + states[0] = 0; + states[1] = -1; + } else if (states[1] == 1) { + // Move down and right + states[0] = 1; + states[1] = -1; + } else { + ASSERT (FALSE); + } + } else { + ASSERT (FALSE); + } + // Update the coordinates based on the new state and quadrant direction + x += xdir * states[0]; + y += ydir * states[1]; + } + } + } + } + } + } + // + // Disable continuous writes on the agressor channels + // + NBPtr->AgressorContinuousWrites (NBPtr, Aggr, FALSE); + } + IDS_HDT_CONSOLE (MEM_FLOW,"\n\tSampleCount:%d",TechPtr->SavedData->SampleCount); + IDS_HDT_CONSOLE (MEM_FLOW,"\t\tVref Updates:%d",TechPtr->SavedData->VrefUpdates); + IDS_HDT_CONSOLE (MEM_FLOW,"\t\tRdDqs Dly Updates:%d\n",TechPtr->SavedData->RdDqsDlyUpdates); + // + // Finilazing Victim Continuous writes + // + NBPtr->FinalizeRdDqs2dVictimContinuousWrites (NBPtr); + TechPtr->ChipSel = InitialCS; + // + // Fill eye based on Rim Search results + // + MemTEyeFill (TechPtr); + // + // Display the results the completed eye + // + MemT2DRdDqsDisplaySearch (TechPtr, Data); + // + // Restore environment settings after training + // + if (HeapDeallocateBuffer (AMD_MEM_2D_RDQS_RIM_HANDLE, &TechPtr->NBPtr->MemPtr->StdHeader) != AGESA_SUCCESS) { + SetMemError (AGESA_FATAL, TechPtr->NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_DEALLOCATE_FOR_2D, 0, 0, 0, 0, &TechPtr->NBPtr->MemPtr->StdHeader); + } + return TRUE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * Fill the data eye + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return + */ +VOID +MemTEyeFill ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + INT8 x; + INT8 y; + UINT8 lane; + UINT8 result; + INT8 yLastPass; + UINT8 xMax; + UINT8 yMax; + UINT8 xMin; + UINT8 yMin; + BOOLEAN FirstPassFound; + + xMax = TechPtr->SavedData->xMax; + yMax = TechPtr->SavedData->yMax; + xMin = TechPtr->SavedData->xMin; + yMin = TechPtr->SavedData->yMin; + for (lane = 0; lane < MemT2DGetMaxLanes (TechPtr); lane++) { + for (x = xMin ; x <= xMax ; x++) { + FirstPassFound = FALSE; + yLastPass = yMin; + // + // Scan for the last passing value + // + for (y = yMax ; y >= yLastPass ; y--) { + result = GetPassFailValue (TechPtr, lane, y, x); + if (result == 0) { + // + // Not Saved, Mark it as FAIL. (Should already be cleared) + // + } else if (result == 2) { + // + // FAIL, so Mark as FAIL (Do nothing) + // + } else if (result == 3) { + // + // PASS, Mark it and save y value (This will end the loop) + // + SetPassFailValue (TechPtr, lane, y, x, result); + yLastPass = y; + } else { + ASSERT (FALSE); + } + } + // + // Scan for the first pass, the fill until the last pass + // + for (y = yMin ; y < yLastPass ; y++) { + result = GetPassFailValue (TechPtr, lane, y, x); + if (result == 0) { + // + // Not Saved, if we've already found a first Passing value, mark it as a PASS + // otherwise, mark it as FAIL. (Should already be cleared) + // + if (FirstPassFound == TRUE) { + SetPassFailValue (TechPtr, lane, y, x, result); + } + } else if (result == 2) { + // + // FAIL, so Mark as FAIL (Do nothing) + // + } else if (result == 3) { + // + // PASS, Mark it and set FirstPassFound + // + SetPassFailValue (TechPtr, lane, y, x, result); + FirstPassFound = TRUE; + } else { + ASSERT (FALSE); + } + } // y Loop + } //x Loop + } // Lane Loop +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Get the 1D trained center + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] lane - current lane + * + * @return + */ +INT8 +MemTGet1DTrainedEyeCenter ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane + ) +{ + if ((TechPtr->NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // Program Byte based for x8 and x16 + return (INT8)TechPtr->NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * MAX_DELAYS + lane]; + } else { + return (INT8)TechPtr->NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * MAX_DELAYS + (lane >> 1)]; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Determine if the saved value is at or close to the edge + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *lane - current lane + * @param[in] y - vref value + * @param[in] x - RdDqs value + * @param[in] xdir - x-direction + * + * @return TRUE - close to edge, FALSE - not close to edge + */ +BOOLEAN +CheckSaveResAtEdge ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN INT8 xdir + ) +{ + if (x > 0) { + if (((TechPtr->Local2DData->Lane[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax) + (-1 * xdir))) & 0x1) == 0) { + if (((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax) + (-1 * xdir))) & 0x1) == 1) { + if (((TechPtr->Local2DData->Lane[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax) + (-2 * xdir))) & 0x1) == 0) { + if (((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax) + (-2 * xdir))) & 0x1) == 1) { + return TRUE; + } else { + return FALSE; + } + } else { + return FALSE; + } + } else { + return FALSE; + } + } else { + return FALSE; + } + } else { + if (((TechPtr->Local2DData->Lane[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax) + (-1 * xdir))) & 0x1) == 0) { + if (((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax) + (-1 * xdir))) & 0x1) == 1) { + if (((TechPtr->Local2DData->Lane[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax) + (-2 * xdir))) & 0x1) == 0) { + if (((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax) + (-2 * xdir))) & 0x1) == 1) { + return TRUE; + } else { + return FALSE; + } + } else { + return FALSE; + } + } else { + return FALSE; + } + } else { + return FALSE; + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * determine if a BL has been saved + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] lane - current lane + * @param[in] y - vref value + * @param[in] x - RdDqs value + * + * @return 1 - value saved, 0 - value not saved + */ +UINT8 +DetermineSavedState ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ) +{ + if (x > 0) { + return (UINT8) (TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1); + } else { + return (UINT8) (TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1); + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Determine if a failure has occured + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] lane - current lane + * @param[in] y - vref value + * @param[in] x - RdDqs value + * + * @return 2 - Fail, 3 - Pass + */ +BOOLEAN +CheckForFail ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ) +{ + if (x > 0) { + if ((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1) == 0) { + // value not saved, so it is not fail + return TRUE; + } else { + // value saved, so examine result + if ((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1) == 0) { + // result = fail + return FALSE; + } else { + // result = pass + return TRUE; + } + } + } else { + if ((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1) == 0) { + // value not saved, so it is not fail + return TRUE; + } else { + // value saved, so examine result + if ((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1) == 0) { + // result = fail + return FALSE; + } else { + // result = pass + return TRUE; + } + } + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Get pass fail state of lane + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] lane - current lane + * @param[in] y - vref value + * @param[in] x - RdDqs value + * + * @return 0 - Value not saved, 2 - Fail, 3 - Pass + */ +UINT8 +GetPassFailValue ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x + ) +{ + if (x > 0) { + if ((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1) == 0) { + // value not saved + return 0; + } else { + // value saved, so return pass/fail + return ((TechPtr->Local2DData->Lane[lane].Vref[xlateY (y)].PosRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1) == 0) ? 2 : 3; + } + } else { + if ((TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1) == 0) { + // value not saved + return 0; + } else { + // value saved, so return pass/fail + return ((TechPtr->Local2DData->Lane[lane].Vref[xlateY (y)].NegRdDqsDly >> (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax)) & 0x1) == 0) ? 2 : 3; + } + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Set the Pass/Fail state of lane + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *lane - current lane + * @param[in] y - vref value + * @param[in] x - RdDqs value + * @param[in] result - result value + * + * @return Saved Value + */ +VOID +SetPassFailValue ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN UINT8 result + ) +{ + if (x > 0) { + TechPtr->Local2DData->Lane[lane].Vref[xlateY (y)].PosRdDqsDly |= (result == 0) ? (1 << (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax))) : 0; + } else { + TechPtr->Local2DData->Lane[lane].Vref[xlateY (y)].NegRdDqsDly |= (result == 0) ? (1 << (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax))) : 0; + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Set the save state of lane + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *lane - current lane + * @param[in] y - vref value + * @param[in] x - RdDqs value + * @param[in] result - result value + * + * @return Saved Value + */ +VOID +SetSavedState ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 lane, + IN INT8 y, + IN INT8 x, + IN UINT8 result + ) +{ + if (x > 0) { + TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].PosRdDqsDly |= (1 << (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax))); + } else { + TechPtr->SavedData->LaneSaved[lane].Vref[xlateY (y)].NegRdDqsDly |= (1 << (TechPtr->SavedData->xMax - (x & TechPtr->SavedData->xMax))); + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * Allocate data storage + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return FALSE - No Errors occurred + * @return TRUE - Errors occurred + */ +BOOLEAN +AllocateSaveLaneStorage ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + RD_DQS_2D *VrefPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + UINT8 Lane; + + AllocHeapParams.RequestedBufferSize = MemT2DGetMaxLanes (TechPtr) * TechPtr->NBPtr->TotalMaxVrefRange * sizeof (RD_DQS_2D); + AllocHeapParams.BufferHandle = AMD_MEM_2D_RDQS_RIM_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &TechPtr->NBPtr->MemPtr->StdHeader) == AGESA_SUCCESS) { + VrefPtr = (RD_DQS_2D *) AllocHeapParams.BufferPtr; + } else { + SetMemError (AGESA_FATAL, TechPtr->NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_2D, 0, 0, 0, 0, &TechPtr->NBPtr->MemPtr->StdHeader); + return TRUE; + } + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + TechPtr->SavedData->LaneSaved[Lane].Vref = &VrefPtr[Lane * TechPtr->NBPtr->TotalMaxVrefRange]; + } + return FALSE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Translate Vref into a positive, linear value that can be used as an + * array index. + * + * @param[in] y - vref value + * + * @return Saved Value + */ +INT8 +xlateY ( + IN INT8 y + ) +{ + ASSERT ( y > -0x10); + ASSERT ( y < 0x10); + return (y + 0xF) & 0x1F; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Re-walking the eye rim for each aggressor combination, which invalidates previous Passes + * in the sample array. Previous Fails in the sample array remain valid. Knowledge of previous Fails + * and speeds sampling for the subsequent walks, esp. when used in conjunction w/ ParallelSampling + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE + */ +BOOLEAN +ClearSampledPassResults ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 lane; + UINT8 vref; + MEM_2D_ENTRY *Data; + MEM_2D_RIM_ENTRY *RimData; + Data = TechPtr->Local2DData; + RimData = TechPtr->SavedData; + for (lane = 0; lane < MemT2DGetMaxLanes (TechPtr); lane ++ ) { + for ( vref = 0; vref < TechPtr->NBPtr->TotalMaxVrefRange; vref ++ ) { + RimData->LaneSaved[lane].Vref[vref].PosRdDqsDly &= ~(Data->Lane[lane].Vref[vref].PosRdDqsDly); + Data->Lane[lane].Vref[vref].PosRdDqsDly = 0; + RimData->LaneSaved[lane].Vref[vref].NegRdDqsDly &= ~(Data->Lane[lane].Vref[vref].NegRdDqsDly); + Data->Lane[lane].Vref[vref].NegRdDqsDly = 0; + } + } + return TRUE; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DTraining.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DTraining.c new file mode 100644 index 0000000000..0fc13f92d8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttRdDqs2DTraining.c @@ -0,0 +1,1185 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttRdDqs2DTraining.c + * + * RD DQS 2 dimentional training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + + + +#include "AGESA.h" +#include "amdlib.h" +#include "AdvancedApi.h" +#include "GeneralServices.h" +#include "Ids.h" +#include "heapManager.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "mport.h" +#include "merrhdl.h" +#include "Filecode.h" +#include "OptionMemory.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTRDDQS2DTRAINING_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */ +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemT2DRdDQSProcessConvolution ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + extern MEM_PSC_FLOW_BLOCK* memPlatSpecFlowArray[]; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes 2D training for Rd DQS + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ + +BOOLEAN +MemTAmdRdDqs2DTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + MEM_DATA_STRUCT *MemPtr; + UINT8 Dct; + UINT8 ChipSel; + MEM_2D_ENTRY Data; + UINT8 Lane; + UINT8 Vref; + BOOLEAN Status; + BOOLEAN DCT_x4Present; + UINT8 MaxLanes; + PSO_TABLE *PsoTable; + RD_DQS_2D *VrefPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + AGESA_TESTPOINT (TpProcMem2dRdDqsTraining, &(MemPtr->StdHeader)); + PsoTable = MemPtr->ParameterListPtr->PlatformMemoryConfiguration; + // + // Set environment settings before training + // + IDS_HDT_CONSOLE (MEM_STATUS, "\n\nStart RD DQS 2D training.\n\n"); + MemTBeginTraining (TechPtr); + // + // Allocate heap for the 2D RdDqs/Vref Data structure + // + DCT_x4Present = FALSE; + // Check DCTs for x4 DIMMs + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->ChannelPtr->DimmNibbleAccess != 0) { + DCT_x4Present = TRUE; + break; + } + } + + NBPtr->SwitchDCT (NBPtr, 0); + // If DCT0 or DCT1 have x4 DIMMs, additonal allocate space + if (DCT_x4Present == TRUE) { + // Per Nibble + MaxLanes = TechPtr->NBPtr->MCTPtr->Status[SbEccDimms] ? 18 : 16; + } else { + // Per Byte + MaxLanes = TechPtr->NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8; + } + MaxLanes = 8; /// @todo Family specific hook + AllocHeapParams.RequestedBufferSize = MaxLanes * NBPtr->TotalMaxVrefRange * sizeof (RD_DQS_2D); + AllocHeapParams.BufferHandle = AMD_MEM_2D_RDQS_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) == AGESA_SUCCESS) { + VrefPtr = (RD_DQS_2D *) AllocHeapParams.BufferPtr; + } else { + SetMemError (AGESA_FATAL, NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_2D, 0, 0, 0, 0, &MemPtr->StdHeader); + return TRUE; + } + for (Lane = 0; Lane < MaxLanes; Lane++) { + Data.Lane[Lane].Vref = &VrefPtr[Lane * NBPtr->TotalMaxVrefRange]; + } + // + // Setup hardware training engine + // + TechPtr->Direction = DQS_READ_DIR; + TechPtr->TrainingType = TRN_DQS_POSITION; + NBPtr->FamilySpecificHook[SetupHwTrainingEngine] (NBPtr, &TechPtr->TrainingType); + + Data.Vnom = NBPtr->TotalMaxVrefRange / 2; // Set Nominal Vref + Data.MaxRdDqsSweep = NBPtr->TotalRdDQSDlyRange / 2; // Set Nominal Vref + ASSERT (NBPtr->TotalRdDQSDlyRange <= MAX_RD_DQS_ENTRIES); + // + // Execute 2d Rd DQS training for all Dcts/Chipselects + // + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + Status = FALSE; + if (MemTCheck2DTrainingPerConfig (TechPtr)) { + for (ChipSel = 0; ChipSel < NBPtr->CsPerChannel; ChipSel = ChipSel + NBPtr->CsPerDelay ) { + if ( (NBPtr->MCTPtr->Status[SbLrdimms]) ? ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0) : + ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) != 0) ) { + //Initialize storage + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + for (Vref = 0; Vref < NBPtr->TotalMaxVrefRange; Vref++) { + Data.Lane[Lane].Vref[Vref].PosRdDqsDly = 0; + Data.Lane[Lane].Vref[Vref].NegRdDqsDly = 0; + } + } + TechPtr->ChipSel = ChipSel; + IDS_HDT_CONSOLE (MEM_FLOW,"\tChip Select: %02x \n", TechPtr->ChipSel); + // + // 1. Sample the data eyes for each channel: + // + TechPtr->Local2DData = &Data; + if (TechPtr->NBPtr->MemN2DRdDQSDataCollection (NBPtr)) { + // + // 2. Process the array of results with a diamond convolution mask, summing the number passing sample points. + // + // Determine Diamond Mask Height + if (MemT2DRdDQSHeight (TechPtr, &Data)) { + // Apply Mask + if (MemT2DRdDQSApplyMask (TechPtr, &Data)) { + // Convolution + if (MemT2DRdDQSProcessConvolution (TechPtr, &Data)) { + // + // 3. Program the final DQS delay values. + // + if (MemT2DRdDQSPrograMaxRdDQSDly (TechPtr, &Data)) { + // + // Find the Smallest Positive or Negative Margin for current CS + // + if (MemT2DRdDQSFindCsVrefMargin (TechPtr, &Data)) { + Status = TRUE; + // + // DATAEYE - Allocate Temp storage for Generate Composite Eyes, + // Save composite eye for CS Pair into Allocated Storage. + TechPtr->TechnologySpecificHook[DataEyeSaveCompositeEyes] (TechPtr, &Data); + } + } + } + } + } + } + if (Status == FALSE) { + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + PutEventLog (AGESA_ERROR, MEM_ERROR_2D_DQS_ERROR, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + } + } // Chipselect + } // End of ChipSel for loop. + + // + // DATAEYE - Compress Eyes, Deallocate temp storage. Allocate memory for compressed eyes, + // copy eyes to new struct, fixup pointers. + // + TechPtr->TechnologySpecificHook[DataEyeCompressEyes] (TechPtr, &Data); + // + // Find the Max and Min Vref values for each DCT + // + if (Status == TRUE) { + if (MemT2DRdDQSFinalVrefMargin (TechPtr, &Data)) { + // + // Program the Max Vref value + // + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tProgramming Final Vref for channel\n\n"); + MemT2DProgramVref (TechPtr, NBPtr->ChannelPtr->MaxVref); + Status = TRUE; + } else { + SetMemError (AGESA_ERROR, NBPtr->MCTPtr); + PutEventLog (AGESA_ERROR, MEM_ERROR_2D_DQS_VREF_MARGIN_ERROR, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + } + } + } + } + // + // Restore environment settings after training + // + if (HeapDeallocateBuffer (AMD_MEM_2D_RDQS_HANDLE, &MemPtr->StdHeader) != AGESA_SUCCESS) { + SetMemError (AGESA_FATAL, NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_DEALLOCATE_FOR_2D, 0, 0, 0, 0, &MemPtr->StdHeader); + } + IDS_HDT_CONSOLE (MEM_STATUS, "\tEnd\n"); + MemTEndTraining (TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\nEnd RD DQS 2D training\n\n"); + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines the maximum number of lanes to program 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - Configuration valid + * FALSE - Configuration invalid + */ +BOOLEAN +MemTCheck2DTrainingPerConfig ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 i; + if (TechPtr->NBPtr->RefPtr->ForceTrainMode == FORCE_TRAIN_AUTO) { + i = 0; + while (memPlatSpecFlowArray[i] != NULL) { + if ((memPlatSpecFlowArray[i])->S2D (TechPtr->NBPtr, (memPlatSpecFlowArray[i])->EntryOfTables)) { + return TRUE; + } + i++; + } + } + return FALSE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines the maximum number of lanes to program 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - Max Number of Lanes + */ +UINT8 +MemT2DGetMaxLanes ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 MaxLanes; + if ((TechPtr->NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) != 0) { + // Per Nibble + MaxLanes = TechPtr->NBPtr->MCTPtr->Status[SbEccDimms] ? 18 : 16; + } else { + // Per Byte + MaxLanes = TechPtr->NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8; + } + MaxLanes = 8; + return MaxLanes; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs Vref to internal or external control for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ +VOID +MemT2DProgramIntExtVrefSelect ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFVrefSel, (TechPtr->NBPtr->RefPtr->ExternalVrefCtl ? 0x0000 : 0x0001)); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs Vref for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Vref - Vref value + * + */ +VOID +MemT2DProgramVref ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Vref + ) +{ + ID_INFO CallOutIdInfo; + CallOutIdInfo.IdField.SocketId = TechPtr->NBPtr->MCTPtr->SocketId; + CallOutIdInfo.IdField.ModuleId = TechPtr->NBPtr->MCTPtr->DieId; + if (TechPtr->NBPtr->RefPtr->ExternalVrefCtl == FALSE) { + // + // Internal vref control + /// @todo : Separate Family-Specific Funtionality + // + // + // This is 1/2 VrefDAC value Sign bit is shifted into place. + // + ASSERT (Vref < 32); + if (Vref < 15) { + Vref = (31 - Vref) << 1; + } else { + Vref = (Vref - 15) << 1; + } + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFVrefDAC, Vref << 2); + } else { + // External vref control + AGESA_TESTPOINT (TpProcMemBefore2dTrainExtVrefChange, &(TechPtr->NBPtr->MemPtr->StdHeader)); + TechPtr->NBPtr->MemPtr->ParameterListPtr->ExternalVrefValue = Vref; + IDS_HDT_CONSOLE (MEM_FLOW, "\n2D training External Vref callout \n"); + // + /// @todo: Implement UEFI DXE Callout for AgesaExternal2dTrainVrefChange before uncommenting this + // + // AgesaExternal2dTrainVrefChange ((UINTN) CallOutIdInfo.IdInformation, TechPtr->NBPtr->MemPtr); + AGESA_TESTPOINT (TpProcMemAfter2dTrainExtVrefChange, &(TechPtr->NBPtr->MemPtr->StdHeader)); + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs RdDQS for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] RdDQSDly - RdDqs value + * + */ +VOID +MemT2DPrograRdDQSDly ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 RdDQSDly + ) +{ + UINT32 RdDqsTime; + // Program BL registers for both nibble (x4) and bytes (x8, x16) + RdDqsTime = 0; + RdDqsTime = (RdDQSDly & 0x1F) << 8; + RdDqsTime = RdDqsTime | (RdDQSDly & 0x1F); + if ((TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) == 0) { + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFDataByteRxDqsDLLDimm0Broadcast, RdDqsTime); + } else if ((TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) == 1) { + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFDataByteRxDqsDLLDimm1Broadcast, RdDqsTime); + } else if ((TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) == 2) { + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFDataByteRxDqsDLLDimm2Broadcast, RdDqsTime); + } else if ((TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) == 3) { + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFDataByteRxDqsDLLDimm3Broadcast, RdDqsTime); + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function stores data for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * @param[in] *InPhaseResult[] - Array of inphase results + * @param[in] *PhaseResult180[] - Array of Phase 180 results + * + * @return TRUE - No Errors occurred + */ +VOID +StoreResult ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data, + IN UINT32 InPhaseResult[], + IN UINT32 PhaseResult180[] + ) +{ + UINT8 Lane; + UINT8 Vref; + UINT8 RdDqsDly; + UINT32 Result; + UINT32 Result180; + UINT8 Index; + Vref = TechPtr->NBPtr->Vref; + RdDqsDly = TechPtr->NBPtr->RdDqsDly; + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + for (RdDqsDly = 0; RdDqsDly < Data->MaxRdDqsSweep; RdDqsDly++) { + if ((TechPtr->NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // x8, so combine "Nibble X" and "Nibble X+1" results + Index = Lane * 2; + Result = (InPhaseResult[RdDqsDly] >> Index) & 0x03; + Result180 = (PhaseResult180[RdDqsDly] >> Index) & 0x03; + } else { + // x4, so use "Nibble" results + Result = (InPhaseResult[RdDqsDly] >> Lane) & 0x01; + Result180 = (PhaseResult180[RdDqsDly] >> Lane) & 0x01; + } + Data->Lane[Lane].Vref[Vref].PosRdDqsDly |= (Result == 0) ? (1 << (Data->MaxRdDqsSweep - 1 - RdDqsDly)) : 0; + Data->Lane[Lane].Vref[Vref].NegRdDqsDly |= (Result180 == 0) ? (1 << (Data->MaxRdDqsSweep - 1 - RdDqsDly)) : 0; + } + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines the height of data for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ +BOOLEAN +MemT2DRdDQSHeight ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ) +{ + UINT8 Lane; + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + Data->Lane[Lane].HalfDiamondHeight = 0x0F; + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t Lane: "); + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Lane); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tHeight: "); + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", (2*(Data->Lane[Lane].HalfDiamondHeight) + 1)); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + ); + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets the width for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return width + */ +UINT8 +MemGet2dRdDQSWidth ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ) +{ + return TechPtr->NBPtr->DiamondWidthRd; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets the step height for the dimond mask for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * @param[in] Vref - current Vref value + * @param[in] Lane - current Lane + * + * @return TRUE - Step found and value should be updated + * FALSE - Step not found and value should not be updated + */ +BOOLEAN +MemCheck2dRdDQSDiamondMaskStep ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data, + IN UINT8 Vref, + IN UINT8 Lane + ) +{ + UINT8 M; + UINT8 VrefVal; + UINT8 width; + UINT8 i; + BOOLEAN status; + // m = -1 * height/width + // (y-b)/m = x + status = FALSE; + if (Vref > (Data->Vnom - 1)) { + VrefVal = (Vref + 1) - Data->Vnom; + } else { + VrefVal = Vref; + } + width = (MemGet2dRdDQSWidth (TechPtr, Data) - 1) / 2; + M = Data->Lane[Lane].HalfDiamondHeight / width; + i = 1; + while (i <= Data->Lane[Lane].HalfDiamondHeight) { + i = i + M; + if (VrefVal == i) { + status = TRUE; + } + } + return status; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function applies a mask fo 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ +BOOLEAN +MemT2DRdDQSApplyMask ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ) +{ + UINT8 RdDqsDly; + UINT8 Lane; + UINT8 Height; + UINT8 Width; + UINT32 PosNegData; + UINT8 Vref; + UINT8 count; + UINT8 Dly; + UINT8 endWidth; + UINT8 startWidth; + UINT8 origEndWidth; + UINT8 origStartWidth; + UINT8 maxOverLapWidth; + UINT8 startOverLapWidth; + BOOLEAN maxHeightExceeded; + BOOLEAN negVrefComplete; + BOOLEAN PosRdDqsToNegRdDqs; + BOOLEAN NegRdDqsToPosRdDqs; + MEM_NB_BLOCK *NBPtr; + NBPtr = TechPtr->NBPtr; + // + // Initialize Convolution + // + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + for (RdDqsDly = 0; RdDqsDly < NBPtr->TotalRdDQSDlyRange; RdDqsDly++) { + Data->Lane[Lane].Convolution[RdDqsDly] = 0; + NBPtr->FamilySpecificHook[Adjust2DDelayStepSize] (NBPtr, &RdDqsDly); + } + } + endWidth = 0; + startWidth = 0; + origEndWidth = 0; + origStartWidth = 0; + startOverLapWidth = 0; + maxOverLapWidth = 0; + maxHeightExceeded = FALSE; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tDetermining Width"); + // + // Get the Width of Diamond + // + Width = MemGet2dRdDQSWidth (TechPtr, Data); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\tWidth: %02x\n", Width); + ASSERT (Width != 0); + + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tExecuting convolution function\n"); + // + // Perform the convolution by sweeping the mask function centered at nominal Vref. Results in a one + // dimensional array with FOM values at each delay for each lane. Choose the delay setting at the peak + // FOM value. + // + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + Height = Data->Lane[Lane].HalfDiamondHeight; + ASSERT (Height < Data->Vnom); + // + // RdDqsDly is divided around "Data->MaxRdDqsSweep" into positive and negative directions + // Positive direction -> RdDqsDly = 0 to (Data->MaxRdDqsSweep - 1) + // Negative direction -> RdDqsDly = Data->MaxRdDqsSweep to (NBPtr->TotalRdDQSDlyRange - 1) + // + for (RdDqsDly = 0; RdDqsDly < NBPtr->TotalRdDQSDlyRange; RdDqsDly++) { + // Vref loop is divided around "Data->Vnom - 1" into positive and negative directions + // Negative direction -> Vref = 0 ("Data->Vnom - 1") to Height("Data->Vnom - 1" - Height) + // Positive direction -> Vref = "Data->Vnom" to Height("Data->Vnom" + Height) + // + negVrefComplete = FALSE; + PosRdDqsToNegRdDqs = FALSE; + NegRdDqsToPosRdDqs = FALSE; + for (Vref = 0; Vref < (NBPtr->TotalMaxVrefRange - 1); Vref++) { + // Initial negative direction where Vref = 0 ("Data->Vnom - 1"), so we need to set + // initial startWidth and endWidth for +/- RdDqs + // + // Create common delay based on +/- RdDqs + if (RdDqsDly > (Data->MaxRdDqsSweep - 1)) { + Dly = RdDqsDly - Data->MaxRdDqsSweep; + } else { + Dly = RdDqsDly; + } + if (Vref == 0 ) { + // Initialize -Vref + maxHeightExceeded = FALSE; // reset for start of -Vref + // Case 1: if +RdDqs - Check for lower bound (Width/2 > RdDqs > 0) + // : if -RdDqs - Check for lower bound (Width/2 + Data->MaxRdDqsSweep > RdDqs > Data->MaxRdDqsSweep) + if (Dly < Width / 2) { + endWidth = Dly + Width / 2 + 1; + startWidth = 0; + } else if ((Dly + Width / 2) > (Data->MaxRdDqsSweep - 1)) { + // Case 2: if +RdDqs - Check for upper bound ((Data->MaxRdDqsSweep - 1) < RdDqs < ((Data->MaxRdDqsSweep - 1) - Width/2)) + // : if -RdDqs - Check for lower bound ((DatNBPtra->TotalRdDQSDlyRange - 1) < RdDqs < ((NBPtr->TotalRdDQSDlyRange - 1) - Width/2)) + endWidth = Data->MaxRdDqsSweep; + startWidth = Dly - Width / 2; + } else { + // Set the initial "startWidth" and "endWidth" for +/- RdDqs + endWidth = Dly + Width / 2 + 1; + startWidth = Dly - Width / 2; + } + origEndWidth = endWidth; + origStartWidth = startWidth; + } else if (Vref == Data->Vnom) { + // Initialize +Vref + endWidth = origEndWidth; + startWidth = origStartWidth; + maxHeightExceeded = FALSE; // reset for start of +Vref + negVrefComplete = TRUE; + } else if ((Vref > (Data->Vnom + Height)) && negVrefComplete == TRUE) { + break; //switch to next RdDqs Dly if height exceeded for +vref and -vref complete + } else { + if (startWidth >= endWidth) { + if (RdDqsDly == (NBPtr->TotalRdDQSDlyRange - 1)) { + // Special condition for end of -RdDqs range + startWidth = Data->MaxRdDqsSweep - 1; + endWidth = Data->MaxRdDqsSweep; + } else { + // Width = 0, but Height not reached, + startWidth = Dly; + endWidth = Dly + 1; + } + } else { + // Check for Case 1 and Case 2 above + if ((RdDqsDly + Width / 2) > (NBPtr->TotalRdDQSDlyRange - 1)) { + endWidth = origEndWidth; + } + } + maxHeightExceeded = FALSE; + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + if (Lane == 0) { + if (RdDqsDly == (Data->MaxRdDqsSweep - (Width / 2)) ) { + Data->DiamondLeft[Vref] = startWidth; + Data->DiamondRight[Vref] = endWidth - 1; + } + } + ); + // + // Determine the correct RdDqs (+/-) and Vref (+/-)direction + // + if (maxHeightExceeded == FALSE) { + if (RdDqsDly < Data->MaxRdDqsSweep) { + if (Vref > (Data->Vnom - 1)) { + PosNegData = Data->Lane[Lane].Vref[Vref].PosRdDqsDly; // +RdDqs Dly, +Vref + } else { + PosNegData = Data->Lane[Lane].Vref[(Data->Vnom - 1) - Vref].PosRdDqsDly; // +RdDqs Dly, -Vref + } + } else { + if (Vref > (Data->Vnom - 1)) { + PosNegData = Data->Lane[Lane].Vref[Vref].NegRdDqsDly; // -RdDqs Dly, +Vref + } else { + PosNegData = Data->Lane[Lane].Vref[(Data->Vnom - 1) - Vref].NegRdDqsDly; // -RdDqs Dly, -Vref + } + } + // + // Case 1: Non-overlap condition: + // Count the number of passes from "startWidth" to "endWidth" + // + for (count = startWidth; count < endWidth; count++) { + Data->Lane[Lane].Convolution[RdDqsDly] = (UINT8) ((PosNegData >> count) & 0x1) + Data->Lane[Lane].Convolution[RdDqsDly]; + } + // Case 2: Overlay between +RdDqs and -RdDqs starting from +RdDqs + // Count the number of passes from "startWidth" to "endWidth" + // + if ((RdDqsDly <= (Data->MaxRdDqsSweep - 1) && (RdDqsDly > ((Data->MaxRdDqsSweep - 1) - Width / 2)))) { + startOverLapWidth = 0; + if (Vref == 0 || Vref == Data->Vnom) { + maxOverLapWidth = (RdDqsDly + Width / 2) - (Data->MaxRdDqsSweep - 1); // Initial overlap max width size + } else if (maxOverLapWidth == 0) { + maxOverLapWidth = startOverLapWidth; // Stop counting after overlap region complete + } + // Ensure that +/- vref is set correctly + if (Vref > (Data->Vnom - 1)) { + PosNegData = Data->Lane[Lane].Vref[Vref].NegRdDqsDly; + } else { + PosNegData = Data->Lane[Lane].Vref[(Data->Vnom - 1) - Vref].NegRdDqsDly; + } + // Need to count the number of passes when range extends from Pos RdDqs to Neg RdDqs + for (count = startOverLapWidth; count < maxOverLapWidth; count++) { + Data->Lane[Lane].Convolution[RdDqsDly] = (UINT8) ((PosNegData >> count) & 0x1) + Data->Lane[Lane].Convolution[RdDqsDly]; + } + if (maxOverLapWidth > 0) { + if (MemCheck2dRdDQSDiamondMaskStep (TechPtr, Data, Vref, Lane) || (Vref == 1) || (Vref == Data->Vnom)) { + maxOverLapWidth--; // Reduce overlap width outside of diamond mask + } + PosRdDqsToNegRdDqs = TRUE; + } + } + if (((RdDqsDly - Data->MaxRdDqsSweep) < Width / 2) && (RdDqsDly > (Data->MaxRdDqsSweep - 1))) { + // + // Case 3: Overlay between -RdDqs and +RdDqs starting from -RdDqs + // Count the number of passes from "startWidth" to "endWidth" + // + maxOverLapWidth = Data->MaxRdDqsSweep; + if (Vref == 0 || Vref == Data->Vnom) { + startOverLapWidth = RdDqsDly - Width / 2; // Initial overlap start point + } else if (startOverLapWidth > maxOverLapWidth) { + maxOverLapWidth = maxOverLapWidth - 1; // Continue to count until MaxHeight excceded + } + // Ensure that vref + or - is set correctly + if (Vref > (Data->Vnom - 1)) { + PosNegData = Data->Lane[Lane].Vref[Vref].PosRdDqsDly; + } else { + PosNegData = Data->Lane[Lane].Vref[(Data->Vnom - 1) - Vref].PosRdDqsDly; + } + // Need to count the number of passes when range extends from Pos RdDqs to Neg RdDqs + for (count = startOverLapWidth; count < maxOverLapWidth; count++) { + Data->Lane[Lane].Convolution[RdDqsDly] = (UINT8) ((PosNegData >> count) & 0x1) + Data->Lane[Lane].Convolution[RdDqsDly]; + } + if (startOverLapWidth < maxOverLapWidth) { + if (MemCheck2dRdDQSDiamondMaskStep (TechPtr, Data, Vref, Lane) || (Vref == 1) || (Vref == Data->Vnom)) { + startOverLapWidth++; // Reduce overlap width outside of diamond mask + } + NegRdDqsToPosRdDqs = TRUE; + } + } + } + if (MemCheck2dRdDQSDiamondMaskStep (TechPtr, Data, Vref, Lane) || (Vref == 1) || (Vref == Data->Vnom)) { + if (PosRdDqsToNegRdDqs) { + startWidth++; + endWidth = Data->MaxRdDqsSweep; + PosRdDqsToNegRdDqs = FALSE; + } else if (NegRdDqsToPosRdDqs) { + startWidth = 0; + endWidth--; + NegRdDqsToPosRdDqs = FALSE; + } else { + startWidth++; + endWidth--; + } + } + NBPtr->FamilySpecificHook[Adjust2DVrefStepSize] (NBPtr, &Vref); + } + NBPtr->FamilySpecificHook[Adjust2DDelayStepSize] (NBPtr, &RdDqsDly); + } + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t Diamond Shape: \n"); + for (Vref = 0; Vref < (NBPtr->TotalMaxVrefRange - 1); Vref++) { + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + for (RdDqsDly = (Data->MaxRdDqsSweep - Width); RdDqsDly < Data->MaxRdDqsSweep; RdDqsDly++) { + if (Vref < (Data->Vnom - 1)) { + if (RdDqsDly == Data->DiamondLeft[(NBPtr->TotalMaxVrefRange - 2) - Vref]) { + IDS_HDT_CONSOLE (MEM_FLOW, " | "); + } else if (RdDqsDly == Data->DiamondRight[(NBPtr->TotalMaxVrefRange - 2) - Vref]) { + IDS_HDT_CONSOLE (MEM_FLOW, " | -> Width = %02x", (Data->DiamondRight[(NBPtr->TotalMaxVrefRange - 2) - Vref]) - (Data->DiamondLeft[(NBPtr->TotalMaxVrefRange - 2) - Vref])); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " "); + } + } else { + if (RdDqsDly == Data->DiamondLeft[Vref - (Data->Vnom - 1)]) { + IDS_HDT_CONSOLE (MEM_FLOW, " | "); + } else if (RdDqsDly == Data->DiamondRight[Vref - (Data->Vnom - 1)]) { + IDS_HDT_CONSOLE (MEM_FLOW, " | -> Width = %02x", (Data->DiamondRight[Vref - (Data->Vnom - 1)]) - (Data->DiamondLeft[Vref - (Data->Vnom - 1)])); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " "); + } + } + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t Convolution results after processing raw data:\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t Delay: "); + for (RdDqsDly = 0; RdDqsDly < NBPtr->TotalRdDQSDlyRange; RdDqsDly++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %02x ", RdDqsDly <= (Data->MaxRdDqsSweep - 1) ? (Data->MaxRdDqsSweep - 1) - RdDqsDly : (NBPtr->TotalRdDQSDlyRange - 1) - RdDqsDly); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tLane: %02x\n", Lane); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tConv: "); + for (RdDqsDly = 0; RdDqsDly < NBPtr->TotalRdDQSDlyRange; RdDqsDly++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", Data->Lane[Lane].Convolution[RdDqsDly]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + ); + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function Examines the convolution function and determines the Max RDqs for + * 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ + +BOOLEAN +MemT2DRdDQSProcessConvolution ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ) +{ + UINT8 RdDqsDly; + UINT8 Lane; + UINT16 MaxFOM; + UINT8 MaxRange; + UINT8 CurrRange; + MEM_NB_BLOCK *NBPtr; + BOOLEAN status; + + NBPtr = TechPtr->NBPtr; + status = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tDetermining MaxRdDqs based on Convolution function\n"); + // Determine the MaxRdDqs Dly for the convolution function + // - Choose the delay setting at the peak FOM value. + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + // Find largest value as MaxFOM + MaxFOM = 0; + for (RdDqsDly = 0; RdDqsDly < NBPtr->TotalRdDQSDlyRange; RdDqsDly++) { + if (Data->Lane[Lane].Convolution[RdDqsDly] > MaxFOM) { + MaxFOM = Data->Lane[Lane].Convolution[RdDqsDly]; + } + } + status = MaxFOM > 0 ? TRUE : FALSE; // It is an error if all convolution points are zero + + // Then find the midpoint of the largest consecutive window w/ that MaxFOM + // In cases of an even number of consecutive points w/ that MaxFOM exists, + // choose the midpoint to the right + // All things being equal, favor the right side of a bi-modal eye + // Stressful SSO patterns shift the eye right! + MaxRange = 0; + CurrRange = 0; + for (RdDqsDly = 0; (MaxFOM > 0) && RdDqsDly < NBPtr->TotalRdDQSDlyRange; RdDqsDly++) { + if (Data->Lane[Lane].Convolution[RdDqsDly] == MaxFOM) { + CurrRange++; + if (CurrRange >= MaxRange) { + Data->Lane[Lane].MaxRdDqs = RdDqsDly - ((CurrRange - 1) / 2); + MaxRange = CurrRange; + } + } else { + CurrRange = 0; + } + } + + if (Data->Lane[Lane].MaxRdDqs > Data->MaxRdDqsSweep) { + status = FALSE; // Error + } + // Set Actual register value + if (Data->Lane[Lane].MaxRdDqs < Data->MaxRdDqsSweep) { + Data->Lane[Lane].MaxRdDqs = (Data->MaxRdDqsSweep - 1) - Data->Lane[Lane].MaxRdDqs; + } else { + status = FALSE; // Error + } + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t Lane: "); + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Lane); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tMaxRdDqs: "); + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Data->Lane[Lane].MaxRdDqs); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + ); + + if (status == FALSE) { + SetMemError (AGESA_FATAL, NBPtr->MCTPtr); + PutEventLog (AGESA_FATAL, MEM_ERROR_INVALID_2D_RDDQS_VALUE, 0, 0, 0, 0, &TechPtr->NBPtr->MemPtr->StdHeader); + } + return status; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the Max RDqs for 2D RdDQS training from convolution + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ +BOOLEAN +MemT2DRdDQSPrograMaxRdDQSDly ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ) +{ + UINT8 Lane; + UINT8 LaneHighRdDqs2dDlys; + UINT8 LaneLowRdDqs2dDlys; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tProgramming MaxRdDysDly per Lane\n\n"); + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + if ((TechPtr->NBPtr->ChannelPtr->DimmNibbleAccess & (1 << (TechPtr->ChipSel >> 1))) == 0) { + // Program Byte based for x8 and x16 + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRdDqsDly, DIMM_BYTE_ACCESS ((TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay), Lane), (UINT16)Data->Lane[Lane].MaxRdDqs); + TechPtr->NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * MAX_DELAYS + Lane] = Data->Lane[Lane].MaxRdDqs; + } else { + // Program nibble based x4, so use "Nibble" + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRdDqs2dDly, DIMM_NBBL_ACCESS ((TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay), Lane), (UINT16)Data->Lane[Lane].MaxRdDqs); + TechPtr->NBPtr->ChannelPtr->RdDqs2dDlys[(TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * MAX_NUMBER_LANES + Lane] = Data->Lane[Lane].MaxRdDqs; + // For each pair of nibbles (high (Odd Nibble) and Low (Even nibble)), find the largest and use that as the RdDqsDly value + if ((Lane & 0x1) == 0) { + LaneHighRdDqs2dDlys = Data->Lane[Lane + 1].MaxRdDqs; + LaneLowRdDqs2dDlys = Data->Lane[Lane].MaxRdDqs; + if (LaneHighRdDqs2dDlys > LaneLowRdDqs2dDlys) { + TechPtr->NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * MAX_DELAYS + (Lane >> 1)] = LaneHighRdDqs2dDlys; + } else { + TechPtr->NBPtr->ChannelPtr->RdDqsDlys[(TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * MAX_DELAYS + (Lane >> 1)] = LaneLowRdDqs2dDlys; + } + } + TechPtr->NBPtr->DctCachePtr->Is2Dx4 = TRUE; + } + } + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the Positive and negative Vref Margin for the current CS + * for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ +BOOLEAN +MemT2DRdDQSFindCsVrefMargin ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ) +{ + UINT8 SmallestMaxVrefNeg; + UINT8 Lane; + UINT8 RdDqsDly; + UINT8 Vref; + UINT8 MaxVrefPositive; + UINT8 MaxVrefNegative; + UINT8 SmallestMaxVrefPos; + UINT32 PosNegData; + SmallestMaxVrefPos = 0xFF; + SmallestMaxVrefNeg = 0; + MaxVrefPositive = 0; + MaxVrefNegative = 0xFF; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFinding Smallest Max Positive and Negative Vref\n\n"); + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + RdDqsDly = (Data->MaxRdDqsSweep - 1) - Data->Lane[Lane].MaxRdDqs; + for (Vref = 0; Vref < (Data->Vnom - 1); Vref++) { + // Neg Vref - (searching from top of array down) + PosNegData = Data->Lane[Lane].Vref[Vref].PosRdDqsDly; + if ((UINT8) ((PosNegData >> RdDqsDly) & 0x1) == 1) { + MaxVrefNegative = Vref; + break; + } + TechPtr->NBPtr->FamilySpecificHook[Adjust2DVrefStepSize] (TechPtr->NBPtr, &Vref); + } + for (Vref = (Data->Vnom - 1); Vref < (TechPtr->NBPtr->TotalMaxVrefRange - 1); Vref++) { + // Pos Vref - (searching from Vnom + 1 of array down) + PosNegData = Data->Lane[Lane].Vref[Vref].PosRdDqsDly; + if ((UINT8) ((PosNegData >> RdDqsDly) & 0x1) == 0) { + // Convert to register setting + MaxVrefPositive = Vref - 1;// - Data->Vnom; + break; + } else { + // If Vref = 1F passes, then smallest Vref = 0x1F + if (Vref == ((TechPtr->NBPtr->TotalMaxVrefRange - 1) - 1)) { + MaxVrefPositive = 0x1E; + break; + } + } + TechPtr->NBPtr->FamilySpecificHook[Adjust2DVrefStepSize] (TechPtr->NBPtr, &Vref); + } + if (MaxVrefPositive < SmallestMaxVrefPos) { + // Find the smallest Max Pos Vref + SmallestMaxVrefPos = MaxVrefPositive; + } + if (MaxVrefNegative > SmallestMaxVrefNeg) { + // Find the largest Max Neg Vref + SmallestMaxVrefNeg = MaxVrefNegative; + } + } + if (SmallestMaxVrefPos != (Data->Vnom - 2)) { + Data->SmallestPosMaxVrefperCS[TechPtr->ChipSel] = SmallestMaxVrefPos - Data->Vnom + 1; + } else { + Data->SmallestPosMaxVrefperCS[TechPtr->ChipSel] = 0; + } + Data->SmallestNegMaxVrefperCS[TechPtr->ChipSel] = (Data->Vnom - 1) - SmallestMaxVrefNeg; + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "Smallest Max Positive Vref Offset from V-Nom for ChipSel %02x = + %02x\n", TechPtr->ChipSel, Data->SmallestPosMaxVrefperCS[TechPtr->ChipSel]); + if (Data->SmallestPosMaxVrefperCS[TechPtr->ChipSel] == 0) { + IDS_HDT_CONSOLE (MEM_FLOW, "Smallest Max Negative Vref Offset from V-Nom for ChipSel %02x = 00\n"); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "Smallest Max Negative Vref Offset from V-Nom for ChipSel %02x = - %02x\n", TechPtr->ChipSel, Data->SmallestNegMaxVrefperCS[TechPtr->ChipSel]); + } + ); + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the final Vref Margin for 2D RdDQS training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return TRUE - No Errors occurred + * @return FALSE - Errors occurred + */ +BOOLEAN +MemT2DRdDQSFinalVrefMargin ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ) +{ + UINT8 ChipSel; + UINT8 SmallestMaxPosVref; + UINT8 SmallestMaxNegVref; + UINT8 OffsetFromVref; + UINT8 MaxRegVref; + SmallestMaxNegVref = 0x7F; + SmallestMaxPosVref = 0x7F; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tFinding Final Vref for channel\n\n"); + for (ChipSel = 0; ChipSel < TechPtr->NBPtr->CsPerChannel; ChipSel = ChipSel + TechPtr->NBPtr->CsPerDelay ) { + if ( (TechPtr->NBPtr->MCTPtr->Status[SbLrdimms]) ? ((TechPtr->NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0) : + ((TechPtr->NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) 1 << ChipSel)) != 0) ) { + if (Data->SmallestPosMaxVrefperCS[ChipSel] < SmallestMaxPosVref) { + SmallestMaxPosVref = Data->SmallestPosMaxVrefperCS[ChipSel]; + } + if (Data->SmallestNegMaxVrefperCS[ChipSel] < SmallestMaxNegVref) { + SmallestMaxNegVref = Data->SmallestNegMaxVrefperCS[ChipSel]; + } + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "Final Max Vref Offset From Vnom ="); + if (SmallestMaxPosVref > SmallestMaxNegVref) { + OffsetFromVref = (SmallestMaxPosVref - SmallestMaxNegVref) / 2; + if (OffsetFromVref != 0) { + IDS_HDT_CONSOLE (MEM_FLOW, " + "); + } + TechPtr->NBPtr->ChannelPtr->MaxVref = (Data->Vnom - 1) + OffsetFromVref; + } else { + OffsetFromVref = (SmallestMaxNegVref - SmallestMaxPosVref) / 2; + if (OffsetFromVref != 0) { + IDS_HDT_CONSOLE (MEM_FLOW, " - "); + } + TechPtr->NBPtr->ChannelPtr->MaxVref = (Data->Vnom - 1) - OffsetFromVref; + } + IDS_HDT_CONSOLE (MEM_FLOW, "%02x \n", OffsetFromVref); + MaxRegVref = TechPtr->NBPtr->ChannelPtr->MaxVref; + if (MaxRegVref <= ((TechPtr->NBPtr->TotalMaxVrefRange / 2) - 1)) { + MaxRegVref = (TechPtr->NBPtr->TotalMaxVrefRange - 1) - MaxRegVref; + } else { + MaxRegVref = MaxRegVref - (TechPtr->NBPtr->TotalMaxVrefRange / 2 - 1); + } + /// @todo: Need Family specific hook for MaxRegVref + MaxRegVref = ((MaxRegVref * 2) & 0x3F); + IDS_HDT_CONSOLE (MEM_FLOW, "Actual Max Vref programmed = %02x \n", MaxRegVref); + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function displays ther results of the 2D search + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *Data - Pointer to Result data structure + * + * @return + */ +VOID +MemT2DRdDqsDisplaySearch ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ) +{ + IDS_HDT_CONSOLE_DEBUG_CODE ( + UINT8 Lane; + INT8 Vref; + // Display data collected + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDisplaying Data collected\n\n"); + for (Lane = 0; Lane < MemT2DGetMaxLanes (TechPtr); Lane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tLane: %02x\n", Lane); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t Vref NegRdDqs PosRdDqs\n"); + for (Vref = TechPtr->NBPtr->TotalMaxVrefRange - 2; Vref >= 0; Vref--) { + if (Vref < (Data->Vnom - 1)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t - "); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", ((Data->Vnom -1) - Vref)); + } else if (Vref == (Data->Vnom - 1)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t 00 "); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t + "); + IDS_HDT_CONSOLE (MEM_FLOW, "%02x ", Vref - (Data->Vnom - 1)); + } + IDS_HDT_CONSOLE (MEM_FLOW, "%08x", TechPtr->Local2DData->Lane[Lane].Vref[Vref].NegRdDqsDly); // debug + IDS_HDT_CONSOLE (MEM_FLOW, "%08x \n", TechPtr->Local2DData->Lane[Lane].Vref[Vref].PosRdDqsDly); //debug + TechPtr->NBPtr->FamilySpecificHook[Adjust2DVrefStepSize] (TechPtr->NBPtr, &Vref); + } + } + ) +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttdimbt.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttdimbt.c new file mode 100644 index 0000000000..97ca08d04f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttdimbt.c @@ -0,0 +1,1478 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttdimmbt.c + * + * Technology Dimm Based Training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "GeneralServices.h" +#include "heapManager.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTDIMBT_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemTInitDqsPos4RcvrEnByte ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +STATIC +MemTSetRcvrEnDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly + ); + +VOID +STATIC +MemTLoadRcvrEnDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver + ); + +BOOLEAN +STATIC +MemTSaveRcvrEnDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly, + IN UINT16 CmpResultRank0, + IN UINT16 CmpResultRank1 + ); + +VOID +STATIC +MemTResetDctWrPtrByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver + ); + +UINT16 +STATIC +MemTCompare1ClPatternByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[] + ); + +VOID +STATIC +MemTSkipChipSelPass1Byte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT UINT8 *ChipSelPtr + ); + +VOID +STATIC +MemTSkipChipSelPass2Byte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT UINT8 *ChipSelPtr + ); + +UINT8 +STATIC +MemTMaxByteLanesByte ( VOID ); + +UINT8 +STATIC +MemTDlyTableWidthByte ( VOID ); + +VOID +STATIC +MemTSetDqsDelayCsrByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 ByteLane, + IN UINT8 Dly + ); + +VOID +STATIC +MemTDqsWindowSaveByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 ByteLane, + IN UINT8 DlyMin, + IN UINT8 DlyMax + ); + +BOOLEAN +STATIC +MemTFindMaxRcvrEnDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + OUT UINT8 *ChipSel + ); + +UINT16 +STATIC +MemTCompare1ClPatternOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT8 Side, + IN UINT8 Receiver, + IN BOOLEAN Side1En + ); + +VOID +STATIC +MemTLoadRcvrEnDlyOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver + ); + +VOID +STATIC +MemTSetRcvrEnDlyOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly + ); + +VOID +STATIC +MemTLoadInitialRcvEnDlyOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver + ); + +UINT8 +STATIC +MemTFindMinMaxGrossDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN TRN_DLY_TYPE TrnDlyType, + IN BOOLEAN IfMax + ); +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function enables byte based training if called + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +MemTDimmByteTrainInit ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 Dct; + UINT8 Channel; + UINT8 DctCount; + UINT8 ChannelCount; + DIE_STRUCT *MCTPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MCTPtr = NBPtr->MCTPtr; + + ASSERT ((NBPtr->CsPerDelay == 1) || (NBPtr->CsPerDelay == 2)); + + TechPtr->InitDQSPos4RcvrEn = MemTInitDqsPos4RcvrEnByte; + TechPtr->SetRcvrEnDly = MemTSetRcvrEnDlyByte; + TechPtr->LoadRcvrEnDly = MemTLoadRcvrEnDlyByte; + TechPtr->SaveRcvrEnDly = MemTSaveRcvrEnDlyByte; + TechPtr->SaveRcvrEnDlyFilter = MemTSaveRcvrEnDlyByteFilterOpt; + TechPtr->ResetDCTWrPtr = MemTResetDctWrPtrByte; + TechPtr->Compare1ClPattern = MemTCompare1ClPatternByte; + TechPtr->SkipChipSelPass1 = MemTSkipChipSelPass1Byte; + TechPtr->SkipChipSelPass2 = MemTSkipChipSelPass2Byte; + TechPtr->MaxByteLanes = MemTMaxByteLanesByte; + TechPtr->DlyTableWidth = MemTDlyTableWidthByte; + TechPtr->SetDQSDelayCSR = MemTSetDqsDelayCsrByte; + TechPtr->DQSWindowSave = MemTDqsWindowSaveByte; + TechPtr->FindMaxDlyForMaxRdLat = MemTFindMaxRcvrEnDlyByte; + TechPtr->Compare1ClPatternOpt = MemTCompare1ClPatternOptByte; + TechPtr->LoadRcvrEnDlyOpt = MemTLoadRcvrEnDlyOptByte; + TechPtr->SetRcvrEnDlyOpt = MemTSetRcvrEnDlyOptByte; + TechPtr->InitializeVariablesOpt = MemTInitializeVariablesOptByte; + TechPtr->GetMaxValueOpt = MemTGetMaxValueOptByte; + TechPtr->SetSweepErrorOpt = MemTSetSweepErrorOptByte; + TechPtr->CheckRcvrEnDlyLimitOpt = MemTCheckRcvrEnDlyLimitOptByte; + TechPtr->LoadInitialRcvrEnDlyOpt = MemTLoadInitialRcvEnDlyOptByte; + TechPtr->GetMinMaxGrossDly = MemTFindMinMaxGrossDlyByte; + // Dynamically allocate buffers for storing trained timings. + DctCount = MCTPtr->DctCount; + ChannelCount = MCTPtr->DctData[0].ChannelCount; + AllocHeapParams.RequestedBufferSize = ((DctCount * ChannelCount) * + ((MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES) + + (MAX_DELAYS * MAX_CS_PER_CHANNEL * NUMBER_OF_FAILURE_MASK_TABLES) + + (MAX_DIMMS * MAX_NUMBER_LANES) + ) + ); + + if (NBPtr->MemPstateStage == MEMORY_PSTATE_1ST_STAGE) { + AllocHeapParams.RequestedBufferSize *= 2; + } + + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_TRN_DATA_HANDLE, MCTPtr->NodeId, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &NBPtr->MemPtr->StdHeader) == AGESA_SUCCESS) { + for (Dct = 0; Dct < DctCount; Dct++) { + for (Channel = 0; Channel < ChannelCount; Channel++) { + MCTPtr->DctData[Dct].ChData[Channel].RowCount = MAX_DIMMS; + MCTPtr->DctData[Dct].ChData[Channel].ColumnCount = MAX_DELAYS; + + MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2; + MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].RdDqsDlys = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].WrDatDlys = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].RdDqs2dDlys = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_NUMBER_LANES); + MCTPtr->DctData[Dct].ChData[Channel].RdDqsMinDlys = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].RdDqsMaxDlys = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].WrDatMinDlys = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].WrDatMaxDlys = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].FailingBitMask = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_CS_PER_CHANNEL * MAX_DELAYS); + if (NBPtr->MemPstateStage == MEMORY_PSTATE_1ST_STAGE) { + MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlysMemPs1 = (UINT16 *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2; + MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlysMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].RdDqsDlysMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].WrDatDlysMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].RdDqs2dDlysMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_NUMBER_LANES); + MCTPtr->DctData[Dct].ChData[Channel].RdDqsMinDlysMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].RdDqsMaxDlysMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].WrDatMinDlysMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].WrDatMaxDlysMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + MCTPtr->DctData[Dct].ChData[Channel].FailingBitMaskMemPs1 = AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_CS_PER_CHANNEL * MAX_DELAYS); + + } + } + } + } else { + PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_DYN_STORING_OF_TRAINED_TIMINGS, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_FATAL, MCTPtr); + ASSERT(FALSE); // Could not dynamically allocate buffers for storing trained timings + } +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the DQS Positions in preparation for Receiver Enable Training. + * Write Position is no delay, Read Position is 1/2 Memclock delay + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + */ + +VOID +STATIC +MemTInitDqsPos4RcvrEnByte ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 Dimm; + UINT8 ByteLane; + UINT8 WrDqs; + + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) { + for (ByteLane = 0; ByteLane < MAX_DELAYS; ByteLane++) { + WrDqs = TechPtr->NBPtr->ChannelPtr->WrDqsDlys[(Dimm * MAX_DELAYS) + ByteLane]; + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessWrDatDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), WrDqs); + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRdDqsDly, DIMM_BYTE_ACCESS (Dimm, ByteLane), 0x3F); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs DqsRcvEnDly to additional index for DQS receiver enabled training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Current Chip select value + * @param[in] RcvEnDly - receiver enable delay to be saved + */ + +VOID +STATIC +MemTSetRcvrEnDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly + ) +{ + UINT8 ByteLane; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + for (ByteLane = 0; ByteLane < MAX_BYTELANES; ByteLane++) { + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Receiver >> 1, ByteLane), RcvEnDly); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function loads the DqsRcvEnDly from saved data and program to additional index + * for DQS receiver enabled training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Current Chip select value + * + */ + +VOID +STATIC +MemTLoadRcvrEnDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver + ) +{ + UINT8 i; + UINT8 Dimm; + UINT16 Saved; + CH_DEF_STRUCT *ChannelPtr; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + + Dimm = Receiver >> 1; + Saved = TechPtr->DqsRcvEnSaved; + for (i = 0; i < MAX_BYTELANES; i++) { + if (Saved & 1) { + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Receiver >> 1, i), + ChannelPtr->RcvEnDlys[Dimm * MAX_DELAYS + i]); + } + Saved >>= 1; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function saves passing DqsRcvEnDly values to the stack + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Current Chip select value + * @param[in] RcvEnDly - receiver enable delay to be saved + * @param[in] CmpResultRank0 - compare result for Rank 0 + * @param[in] CmpResultRank1 - compare result for Rank 1 + * + * @return TRUE - All bytelanes pass + * @return FALSE - Some bytelanes fail + */ + +BOOLEAN +STATIC +MemTSaveRcvrEnDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly, + IN UINT16 CmpResultRank0, + IN UINT16 CmpResultRank1 + ) +{ + UINT8 i; + UINT8 Passed; + UINT8 Saved; + UINT8 Mask; + UINT8 Dimm; + CH_DEF_STRUCT *ChannelPtr; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + + Passed = (UINT8) ((CmpResultRank0 & CmpResultRank1) & 0xFF); + + Saved = (UINT8) (TechPtr->DqsRcvEnSaved & Passed); //@attention - false passes filter (subject to be replaced with a better solution) + Dimm = Receiver >> 1; + Mask = 1; + for (i = 0; i < MAX_BYTELANES; i++) { + if (Passed & Mask) { + if (!(Saved & Mask)) { + ChannelPtr->RcvEnDlys[Dimm * MAX_DELAYS + i] = RcvEnDly + 0x20; // @attention -1 pass only + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tBL %d = %02x", i, RcvEnDly + 0x20); + } + Saved |= Mask; + } + Mask <<= 1; + } + TechPtr->DqsRcvEnSaved = Saved; + + if (Saved == 0xFF) { + return TRUE; + } else { + return FALSE; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function performs a filtering functionality and saves passing DqsRcvEnDly + * values to the stack + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Current Chip select value + * @param[in] RcvEnDly - receiver enable delay to be saved + * @param[in] CmpResultRank0 - compare result for Rank 0 + * @param[in] CmpResultRank1 - compare result for Rank 1 + * + * @return TRUE - All bytelanes pass + * @return FALSE - Some bytelanes fail + */ + +BOOLEAN +MemTSaveRcvrEnDlyByteFilter ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly, + IN UINT16 CmpResultRank0, + IN UINT16 CmpResultRank1 + ) +{ + UINT8 i; + UINT8 Passed; + UINT8 Saved; + UINT8 Mask; + UINT8 Dimm; + UINT8 MaxFilterDly; + CH_DEF_STRUCT *ChannelPtr; + MEM_DCT_CACHE *DctCachePtr; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + DctCachePtr = TechPtr->NBPtr->DctCachePtr; + + MaxFilterDly = TechPtr->MaxFilterDly; + Passed = (UINT8) ((CmpResultRank0 & CmpResultRank1) & 0xFF); + + Dimm = Receiver >> 1; + Saved = (UINT8) TechPtr->DqsRcvEnSaved; + Mask = 1; + for (i = 0; i < MAX_BYTELANES; i++) { + if ((Passed & Mask) != 0) { + DctCachePtr->RcvEnDlyCounts [i] += 1; + if ((Saved & Mask) == 0) { + ChannelPtr->RcvEnDlys[Dimm * MAX_DELAYS + i] = RcvEnDly + 0x20; + Saved |= Mask; + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tBL %d = %02x", i, RcvEnDly + 0x20); + } + } else { + if (DctCachePtr->RcvEnDlyCounts [i] <= MaxFilterDly) { + DctCachePtr->RcvEnDlyCounts [i] = 0; + Saved &= ~Mask; + } + } + Mask <<= 1; + } + + //----------------------- + TechPtr->DqsRcvEnSaved = (UINT16) Saved; + + Saved = 0; + for (i = 0; i < MAX_BYTELANES; i++) { + if (DctCachePtr->RcvEnDlyCounts [i] >= MaxFilterDly) { + Saved |= (UINT8) 1 << i; + } + } + + if (Saved == 0xFF) { + return TRUE; + } else { + return FALSE; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function compares test pattern with data in buffer and return a pass/fail bitmap + * for 8 Bytes + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * + * @return PASS - Bit map of results of comparison + */ + +UINT16 +STATIC +MemTCompare1ClPatternByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[] + ) +{ + UINT16 i; + UINT16 j; + UINT16 Pass; + DIE_STRUCT *MCTPtr; + + MCTPtr = TechPtr->NBPtr->MCTPtr; + if (MCTPtr->GangedMode && MCTPtr->Dct) { + j = 8; + } else { + j = 0; + } + + Pass = 0xFFFF; + IDS_HDT_CONSOLE (MEM_FLOW, " -"); + for (i = 0; i < 8; i++) { + if (Buffer[j] != Pattern[j]) { + // if bytelane n fails + Pass &= ~((UINT16)1 << (j % 8)); // clear bit n + } + IDS_HDT_CONSOLE (MEM_FLOW, " %c", (Buffer[j] == Pattern[j]) ? 'P' : '.'); + j++; + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t -"); + for (i = 0, j -= 8; i < 8; i++, j++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %02x", Buffer[j]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t -"); + for (i = 0, j -= 8; i < 8; i++, j++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %02x", Pattern[j]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\n"); + ); + + return Pass; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * The function resets the DCT input buffer write pointer. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Chip select + * + */ + +VOID +STATIC +MemTResetDctWrPtrByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver + ) +{ + UINT8 i; + UINT16 RcvEnDly; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + for (i = 0; i < MAX_BYTELANES; i++) { + RcvEnDly = (UINT16) TechPtr->NBPtr->GetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Receiver / 2, i)); + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Receiver / 2, i), RcvEnDly); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function skips odd chip select if training at 800MT or above. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] *ChipSelPtr - Pointer to variable contains Chip select index + * + */ + +VOID +STATIC +MemTSkipChipSelPass1Byte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT UINT8 *ChipSelPtr + ) +{ + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + // if the even chip select failed training, need to set CsTrainFail for odd chip select if present. + if (NBPtr->DCTPtr->Timings.CsPresent & ((UINT16)1 << ((*ChipSelPtr) + 1))) { + if (NBPtr->DCTPtr->Timings.CsTrainFail & ((UINT16)1 << *ChipSelPtr)) { + NBPtr->DCTPtr->Timings.CsTrainFail |= (UINT16)1 << ((*ChipSelPtr) + 1); + if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, NBPtr->DCTPtr->Timings.CsTrainFail, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + } + } + } + (*ChipSelPtr)++; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * MemTSkipChipSelPass2Byte: + * + * This function skips odd chip select if training at 800MT or above. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] *ChipSelPtr - Pointer to variable contains Chip select index + * + */ + +VOID +STATIC +MemTSkipChipSelPass2Byte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT UINT8 *ChipSelPtr + ) +{ + if (*ChipSelPtr & 1) { + *ChipSelPtr = MAX_CS_PER_CHANNEL; // skip all successions + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines the maximum number of byte lanes + * + * @return Max number of Bytelanes + */ + +UINT8 +STATIC +MemTMaxByteLanesByte ( VOID ) +{ + return MAX_BYTELANES; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines the width of the delay tables (eg. RcvEnDlys, WrDqsDlys,...) + * + * @return Delay table width in bytes + */ + +UINT8 +STATIC +MemTDlyTableWidthByte ( VOID ) +{ + return MAX_DELAYS; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function writes the Delay value to a certain byte lane + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] ByteLane - Bytelane number being targeted + * @param[in] Dly - Delay value + * + */ + +VOID +STATIC +MemTSetDqsDelayCsrByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 ByteLane, + IN UINT8 Dly + ) +{ + UINT8 Reg; + UINT8 Dimm; + + ASSERT (ByteLane <= MAX_BYTELANES); + + if (!(TechPtr->DqsRdWrPosSaved & ((UINT8)1 << ByteLane))) { + Dimm = TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay; + + if (TechPtr->Direction == DQS_WRITE_DIR) { + Dly = Dly + ((UINT8) TechPtr->NBPtr->ChannelPtr->WrDqsDlys[(Dimm * MAX_DELAYS) + ByteLane]); + Reg = AccessWrDatDly; + } else { + Reg = AccessRdDqsDly; + } + + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, Reg, DIMM_BYTE_ACCESS (Dimm, ByteLane), Dly); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the trained DQS delay for the specified byte lane + * and stores its DQS window for reference. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] ByteLane - Bytelane number being targeted + * @param[in] DlyMin - Minimum delay value + * @param[in] DlyMax- Maximum delay value + * + */ + +VOID +STATIC +MemTDqsWindowSaveByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 ByteLane, + IN UINT8 DlyMin, + IN UINT8 DlyMax + ) +{ + UINT8 DqsDelay; + UINT8 Dimm; + CH_DEF_STRUCT *ChanPtr; + + ASSERT (ByteLane <= MAX_BYTELANES); + ChanPtr = TechPtr->NBPtr->ChannelPtr; + + DqsDelay = ((DlyMin + DlyMax + 1) / 2) & 0x3F; + MemTSetDqsDelayCsrByte (TechPtr, ByteLane, DqsDelay); + TechPtr->DqsRdWrPosSaved |= (UINT8)1 << ByteLane; + TechPtr->DqsRdWrPosSaved |= 0xFF00; + + Dimm = (TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * MAX_DELAYS + ByteLane; + if (TechPtr->Direction == DQS_READ_DIR) { + ChanPtr->RdDqsDlys[Dimm] = DqsDelay; + } else { + ChanPtr->WrDatDlys[Dimm] = DqsDelay + ChanPtr->WrDqsDlys[Dimm]; + } + + if (TechPtr->Direction == DQS_READ_DIR) { + ChanPtr->RdDqsMinDlys[ByteLane] = DlyMin; + ChanPtr->RdDqsMaxDlys[ByteLane] = DlyMax; + } else { + ChanPtr->WrDatMinDlys[ByteLane] = DlyMin; + ChanPtr->WrDatMaxDlys[ByteLane] = DlyMax; + } + +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the DIMM that has the largest receiver enable delay. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[out] *ChipSel - Pointer to the Chip select that has the largest receiver enable delay. + * + * @return TRUE - A chip select can be found. + * @return FALSE - A chip select cannot be found. + */ + +BOOLEAN +STATIC +MemTFindMaxRcvrEnDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + OUT UINT8 *ChipSel + ) +{ + UINT8 ChipSelect; + UINT8 ByteLane; + UINT16 RcvEnDly; + UINT16 MaxDly; + UINT8 MaxDlyCs; + BOOLEAN RetVal; + + MEM_NB_BLOCK *NBPtr; + CH_DEF_STRUCT *ChannelPtr; + + NBPtr = TechPtr->NBPtr; + ChannelPtr = NBPtr->ChannelPtr; + + RetVal = FALSE; + MaxDly = 0; + MaxDlyCs = 0; + for (ChipSelect = 0; ChipSelect < NBPtr->CsPerChannel; ChipSelect = ChipSelect + NBPtr->CsPerDelay) { + if ((NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSelect)) != 0) { + if ((NBPtr->DCTPtr->Timings.CsTrainFail & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSelect)) == 0) { + // Only choose the dimm that does not fail training + for (ByteLane = 0; ByteLane < ((NBPtr->MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8); ByteLane++) { + RcvEnDly = ChannelPtr->RcvEnDlys[ChipSelect / NBPtr->CsPerDelay * MAX_DELAYS + ByteLane]; + if (RcvEnDly > MaxDly) { + MaxDly = RcvEnDly; + MaxDlyCs = ChipSelect; + RetVal = TRUE; + } + } + } + } + } + + if (NBPtr->MCTPtr->Status[Sb128bitmode] != 0) { + //The RcvrEnDlys of DCT1 DIMMs should also be considered while ganging. + NBPtr->SwitchDCT (NBPtr, 1); + ChannelPtr = NBPtr->ChannelPtr; + for (ChipSelect = 0; ChipSelect < NBPtr->CsPerChannel; ChipSelect = ChipSelect + NBPtr->CsPerDelay) { + for (ByteLane = 0; ByteLane < ((NBPtr->MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8); ByteLane++) { + RcvEnDly = ChannelPtr->RcvEnDlys[ChipSelect / NBPtr->CsPerDelay * MAX_DELAYS + ByteLane]; + if (RcvEnDly > MaxDly) { + MaxDly = RcvEnDly; + MaxDlyCs = ChipSelect; + } + } + } + NBPtr->SwitchDCT (NBPtr, 0); + } + + TechPtr->MaxDlyForMaxRdLat = MaxDly; + *ChipSel = MaxDlyCs; + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the DIMM that has the largest receiver enable delay + Read DQS Delay. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[out] *ChipSel - Pointer to the Chip select that has the largest receiver enable delay + * + Read DQS Delay. + * + * @return TRUE - A chip select can be found. + * @return FALSE - A chip select cannot be found. + */ + +BOOLEAN +MemTFindMaxRcvrEnDlyRdDqsDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + OUT UINT8 *ChipSel + ) +{ + UINT8 ChipSelect; + UINT8 ByteLane; + UINT16 RcvEnDly; + UINT16 RdDqsDly; + UINT16 TotalDly; + UINT16 MaxDly; + UINT8 MaxDlyCs; + BOOLEAN RetVal; + + MEM_NB_BLOCK *NBPtr; + CH_DEF_STRUCT *ChannelPtr; + + NBPtr = TechPtr->NBPtr; + ChannelPtr = NBPtr->ChannelPtr; + + RetVal = FALSE; + MaxDly = 0; + MaxDlyCs = 0; + for (ChipSelect = 0; ChipSelect < NBPtr->CsPerChannel; ChipSelect = ChipSelect + NBPtr->CsPerDelay) { + if ((NBPtr->DCTPtr->Timings.CsTrainFail & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSelect)) == 0) { + // Only choose the dimm that does not fail training + for (ByteLane = 0; ByteLane < MAX_BYTELANES; ByteLane++) { + RcvEnDly = ChannelPtr->RcvEnDlys[ChipSelect / NBPtr->CsPerDelay * MAX_DELAYS + ByteLane]; + // Before Dqs Position Training, this value is 0. So the maximum value for + // RdDqsDly needs to be added later when calculating the MaxRdLatency value + // after RcvEnDly training but before DQS Position Training. + RdDqsDly = ChannelPtr->RdDqsDlys[ChipSelect / NBPtr->CsPerDelay * MAX_DELAYS + ByteLane]; + TotalDly = RcvEnDly + (RdDqsDly >> 1); + if (TotalDly > MaxDly) { + MaxDly = TotalDly; + MaxDlyCs = ChipSelect; + RetVal = TRUE; + } + } + } + } + + TechPtr->MaxDlyForMaxRdLat = MaxDly; + *ChipSel = MaxDlyCs; + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the DIMM that has the largest receiver enable delay + Read DQS Delay for UNB + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[out] *ChipSel - Pointer to the Chip select that has the largest receiver enable delay + * + Read DQS Delay. + * + * @return TRUE - A chip select can be found. + * @return FALSE - A chip select cannot be found. + */ + +BOOLEAN +MemTFindMaxRcvrEnDlyRdDqsDlyByteUnb ( + IN OUT MEM_TECH_BLOCK *TechPtr, + OUT UINT8 *ChipSel + ) +{ + UINT8 ChipSelect; + UINT8 ByteLane; + UINT16 RcvEnDly; + UINT16 RdDqsDly; + UINT16 TotalDly; + UINT16 MaxDly; + UINT8 MaxDlyCs; + BOOLEAN RetVal; + UINT16 *RcvEnDlyPtr; + UINT8 *RdDqsDlyPtr; + + MEM_NB_BLOCK *NBPtr; + CH_DEF_STRUCT *ChannelPtr; + + NBPtr = TechPtr->NBPtr; + ChannelPtr = NBPtr->ChannelPtr; + RcvEnDlyPtr = ChannelPtr->RcvEnDlys; + RdDqsDlyPtr = ChannelPtr->RdDqsDlys; + if (NBPtr->MemPstate == MEMORY_PSTATE1) { + RcvEnDlyPtr = ChannelPtr->RcvEnDlysMemPs1; + RdDqsDlyPtr = ChannelPtr->RdDqsDlysMemPs1; + } + + RetVal = FALSE; + MaxDly = 0; + MaxDlyCs = 0; + for (ChipSelect = 0; ChipSelect < NBPtr->CsPerChannel; ChipSelect = ChipSelect + NBPtr->CsPerDelay) { + if ((NBPtr->DCTPtr->Timings.CsTrainFail & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSelect)) == 0) { + // Only choose the dimm that does not fail training + for (ByteLane = 0; ByteLane < MAX_BYTELANES; ByteLane++) { + RcvEnDly = RcvEnDlyPtr[ChipSelect / NBPtr->CsPerDelay * MAX_DELAYS + ByteLane]; + // Before Dqs Position Training, this value is 0. So the maximum value for + // RdDqsDly needs to be added later when calculating the MaxRdLatency value + // after RcvEnDly training but before DQS Position Training. + RdDqsDly = RdDqsDlyPtr[ChipSelect / NBPtr->CsPerDelay * MAX_DELAYS + ByteLane]; + TotalDly = RcvEnDly + ((NBPtr->IsSupported[SwitchRdDqsDlyForMaxRdLatency] && NBPtr->RdDqsDlyForMaxRdLat != 0) ? NBPtr->RdDqsDlyForMaxRdLat: RdDqsDly); + if (TotalDly > MaxDly) { + MaxDly = TotalDly; + MaxDlyCs = ChipSelect; + RetVal = TRUE; + } + } + } + } + + TechPtr->MaxDlyForMaxRdLat = MaxDly; + *ChipSel = MaxDlyCs; + return RetVal; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the minimum or maximum gross dly among all the bytes. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] TrnDlyType - Target Dly type + * @param[in] IfMax - If this is for maximum value or minimum + * + * @return minimum gross dly + */ +UINT8 +STATIC +MemTFindMinMaxGrossDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN TRN_DLY_TYPE TrnDlyType, + IN BOOLEAN IfMax + ) +{ + UINT8 ChipSelect; + UINT8 ByteLane; + UINT16 CsEnabled; + UINT8 MinMaxGrossDly; + UINT8 TrnDly; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + CsEnabled = NBPtr->DCTPtr->Timings.CsEnabled; + MinMaxGrossDly = IfMax ? 0 : 0xFF; + + for (ChipSelect = 0; ChipSelect < NBPtr->CsPerChannel; ChipSelect = ChipSelect + NBPtr->CsPerDelay) { + if ((CsEnabled & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSelect)) != 0) { + for (ByteLane = 0; ByteLane < ((NBPtr->MCTPtr->Status[SbEccDimms] && NBPtr->IsSupported[EccByteTraining]) ? 9 : 8); ByteLane++) { + TrnDly = (UINT8) (GetTrainDlyFromHeapNb (NBPtr, TrnDlyType, DIMM_BYTE_ACCESS (ChipSelect / NBPtr->CsPerDelay, ByteLane)) >> 5); + if ((IfMax && (TrnDly > MinMaxGrossDly)) || (!IfMax && (TrnDly < MinMaxGrossDly))) { + MinMaxGrossDly = TrnDly; + } + } + } + } + + return MinMaxGrossDly; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function compares test pattern with data in buffer and return a pass/fail bitmap + * for 8 Bytes for optimized receiver enable training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * @param[in] Side - current side being targeted + * @param[in] Receiver - Current receiver value + * @param[in] Side1En - Indicates if the second side of the DIMM is being used + * @return PASS - Bit map of results of comparison + */ + +UINT16 +STATIC +MemTCompare1ClPatternOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT8 Side, + IN UINT8 Receiver, + IN BOOLEAN Side1En + ) +{ + UINT16 i; + UINT16 j; + UINT16 Pass; + DIE_STRUCT *MCTPtr; + CH_DEF_STRUCT *ChannelPtr; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + MCTPtr = TechPtr->NBPtr->MCTPtr; + + if (MCTPtr->GangedMode && MCTPtr->Dct) { + j = 8; + } else { + j = 0; + } + + Pass = 0xFFFF; + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tDelay[BL] -"); + for (i = 0; i < 8; i++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %02x", TechPtr->RcvrEnDlyOpt[i] & 0xFF); + if (Buffer[j] != Pattern[j]) { + // if bytelane n fails + Pass &= ~((UINT16)1 << (j % 8)); // clear bit n + TechPtr->DqsRcvEnFirstPassValOpt[i] = 0; + TechPtr->GetFirstPassValOpt[i] = FALSE; + TechPtr->IncBy1ForNextCountOpt[i] = FALSE; + TechPtr->DqsRcvEnSavedOpt[i] = FALSE; + if (TechPtr->FilterStatusOpt[i] != DONE_FILTER) { + if (Side == ((Side1En ? 4 : 2) - 1)) { + TechPtr->RcvrEnDlyOpt[i] += FILTER_FIRST_STAGE_COUNT; + } + } + } else { + if (TechPtr->FilterSidePassCountOpt[i] == ((Side1En ? 4 : 2) - 1)) { + //Only apply filter if all sides have passed + if (TechPtr->FilterStatusOpt[i] != DONE_FILTER) { + if (TechPtr->GetFirstPassValOpt[i] == FALSE) { + // This is the first Pass, mark the start of filter check + TechPtr->DqsRcvEnFirstPassValOpt[i] = TechPtr->RcvrEnDlyOpt[i]; + TechPtr->GetFirstPassValOpt[i] = TRUE; + TechPtr->IncBy1ForNextCountOpt[i] = FALSE; + TechPtr->RcvrEnDlyOpt[i]++; + } else { + if ((TechPtr->RcvrEnDlyOpt[i] - TechPtr->DqsRcvEnFirstPassValOpt[i]) < FILTER_WINDOW_SIZE) { + if (TechPtr->IncBy1ForNextCountOpt[i] == FALSE) { + TechPtr->RcvrEnDlyOpt[i] += FILTER_SECOND_STAGE_COUNT; + TechPtr->IncBy1ForNextCountOpt[i] = TRUE; + } else { + TechPtr->RcvrEnDlyOpt[i]++; + TechPtr->IncBy1ForNextCountOpt[i] = FALSE; + } + } else { + // End sweep and add offset to first pass + TechPtr->MaxRcvrEnDlyBlOpt[i] = TechPtr->DqsRcvEnFirstPassValOpt[i]; + TechPtr->RcvrEnDlyOpt[i] = TechPtr->DqsRcvEnFirstPassValOpt[i] + FILTER_OFFSET_VALUE; + TechPtr->FilterStatusOpt[i] = DONE_FILTER; + TechPtr->FilterCountOpt++; + } + } + } else { + TechPtr->FilterSidePassCountOpt[i]++; + } + } else { + if (TechPtr->GetFirstPassValOpt[i] == FALSE) { + if (Side == ((Side1En ? 4 : 2) - 1)) { + TechPtr->RcvrEnDlyOpt[i] += FILTER_FIRST_STAGE_COUNT; + } + } + TechPtr->FilterSidePassCountOpt[i]++; + } + TechPtr->DqsRcvEnSavedOpt[i] = TRUE; + ChannelPtr->RcvEnDlys[(Receiver >> 1) * MAX_DELAYS + i] = TechPtr->RcvrEnDlyOpt[i]; + } + if (Side == ((Side1En ? 4 : 2) - 1)) { + TechPtr->FilterSidePassCountOpt[i] = 0; + } + if (TechPtr->RcvrEnDlyOpt[i] >= TechPtr->RcvrEnDlyLimitOpt[i]) { + TechPtr->FilterCountOpt++; + } + + j++; + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\tPass/Fail -"); + for (i = 0, j -= 8; i < 8; i++, j++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %c", (Buffer[j] == Pattern[j]) ? 'P' : '.'); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t Measured -"); + for (i = 0, j -= 8; i < 8; i++, j++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %02x", Buffer[j]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t Expected -"); + for (i = 0, j -= 8; i < 8; i++, j++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %02x", Pattern[j]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\n"); + ); + + return Pass; +} +/*----------------------------------------------------------------------------- + * + * This function initializes variables for optimized training. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * ---------------------------------------------------------------------------- + */ +VOID +MemTInitializeVariablesOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 ByteLane; + for (ByteLane = 0; ByteLane < MAX_BYTELANES_PER_CHANNEL; ByteLane++) { + TechPtr->RcvrEnDlyLimitOpt[ByteLane] = FILTER_MAX_REC_EN_DLY_VALUE; // @attention - limit depends on proc type + TechPtr->DqsRcvEnSavedOpt[ByteLane] = FALSE; + TechPtr->RcvrEnDlyOpt[ByteLane] = FILTER_NEW_RECEIVER_START_VALUE; + TechPtr->GetFirstPassValOpt[ByteLane] = FALSE; + TechPtr->DqsRcvEnFirstPassValOpt[ByteLane] = 0; + TechPtr->RevertPassValOpt[ByteLane] = FALSE; + TechPtr->MaxRcvrEnDlyBlOpt[ByteLane] = 0; + TechPtr->FilterStatusOpt[ByteLane] = START_FILTER; + TechPtr->FilterCountOpt = 0; + TechPtr->FilterSidePassCountOpt[ByteLane] = 0; + TechPtr->IncBy1ForNextCountOpt[ByteLane] = FALSE; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function loads the DqsRcvEnDly from saved data and program to additional index + * for optimized DQS receiver enabled training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Current Chip select value + * + */ + +VOID +STATIC +MemTLoadRcvrEnDlyOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver + ) +{ + UINT8 i; + UINT8 Dimm; + CH_DEF_STRUCT *ChannelPtr; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + + Dimm = Receiver >> 1; + for (i = 0; i < 8; i++) { + if (TechPtr->DqsRcvEnSavedOpt[i]) { + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Receiver >> 1, i), + ChannelPtr->RcvEnDlys[Dimm * MAX_DELAYS + i]); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs DqsRcvEnDly to additional index for DQS receiver enabled training + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Current Chip select value + * @param[in] RcvEnDly - receiver enable delay to be saved + */ + +VOID +STATIC +MemTSetRcvrEnDlyOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly + ) +{ + UINT8 ByteLane; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + + for (ByteLane = 0; ByteLane < 8; ByteLane++) { + if (TechPtr->FilterStatusOpt[ByteLane] != DONE_FILTER) { + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (Receiver >> 1, ByteLane), TechPtr->RcvrEnDlyOpt[ByteLane]); + } + } +} +/*----------------------------------------------------------------------------- + * + * This sets any Errors generated from Dly sweep + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] DCT - current DCT + * @param[in] Receiver - current receiver + * + * @return FALSE - Fatal error occurs. + * @return TRUE - No fatal error occurs. + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemTSetSweepErrorOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT8 Dct, + IN BOOLEAN ErrorCheck + ) +{ + UINT8 ByteLane; + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + MCTPtr = NBPtr->MCTPtr; + DCTPtr = NBPtr->DCTPtr; + for (ByteLane = 0; ByteLane < MAX_BYTELANES_PER_CHANNEL; ByteLane++) { + if (TechPtr->RcvrEnDlyOpt[ByteLane] == TechPtr->RcvrEnDlyLimitOpt[ByteLane]) { + // no passing window + if (ErrorCheck) { + return FALSE; + } + PutEventLog (AGESA_ERROR, MEM_ERROR_RCVR_EN_NO_PASSING_WINDOW, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, ByteLane, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + } + if (TechPtr->RcvrEnDlyOpt[ByteLane] > (TechPtr->RcvrEnDlyLimitOpt[ByteLane] - 1)) { + // passing window too narrow, too far delayed + if (ErrorCheck) { + return FALSE; + } + PutEventLog (AGESA_ERROR, MEM_ERROR_RCVR_EN_VALUE_TOO_LARGE, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, ByteLane, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + DCTPtr->Timings.CsTrainFail |= (UINT16) (3 << Receiver) & DCTPtr->Timings.CsPresent; + MCTPtr->ChannelTrainFail |= (UINT32)1 << Dct; + if (!NBPtr->MemPtr->ErrorHandling (MCTPtr, NBPtr->Dct, DCTPtr->Timings.CsTrainFail, &MemPtr->StdHeader)) { + ASSERT (FALSE); + return FALSE; + } + } + } + return TRUE; +} + +/*----------------------------------------------------------------------------- + * + * This function determines the maximum receiver delay value + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @retval MaxRcvrValue - Maximum receiver delay value for all bytelanes + * ---------------------------------------------------------------------------- + */ + +UINT16 +MemTGetMaxValueOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 ByteLane; + UINT16 MaxRcvrValue; + MaxRcvrValue = 0; + for (ByteLane = 0; ByteLane < MAX_BYTELANES_PER_CHANNEL; ByteLane++) { + if (TechPtr->MaxRcvrEnDlyBlOpt[ByteLane] > MaxRcvrValue) { + MaxRcvrValue = TechPtr->MaxRcvrEnDlyBlOpt[ByteLane]; + } + } + MaxRcvrValue += FILTER_OFFSET_VALUE; + return MaxRcvrValue; +} +/*----------------------------------------------------------------------------- + * + * This function determines if the sweep loop should complete. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @retval TRUE - All bytelanes pass + * FALSE - Some bytelanes fail + * ---------------------------------------------------------------------------- + */ + +BOOLEAN +MemTCheckRcvrEnDlyLimitOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + if (TechPtr->FilterCountOpt >= (UINT16)MAX_CS_PER_CHANNEL) { + return TRUE; + } else { + return FALSE; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function load the result of write levelization training into RcvrEnDlyOpt, + * using it as the initial value for Receiver DQS training. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Current Chip select value + */ +VOID +STATIC +MemTLoadInitialRcvEnDlyOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver + ) +{ + UINT8 ByteLane; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + for (ByteLane = 0; ByteLane < MAX_BYTELANES_PER_CHANNEL; ByteLane++) { + TechPtr->RcvrEnDlyOpt[ByteLane] = NBPtr->ChannelPtr->WrDqsDlys[((Receiver >> 1) * TechPtr->DlyTableWidth ()) + ByteLane]; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function finds the DIMM that has the largest receiver enable delay that are trained by PMU + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[out] *ChipSel - Pointer to the Chip select that has the largest receiver enable delay + * + Read DQS Delay. + * + * @return TRUE - A chip select can be found. + * @return FALSE - A chip select cannot be found. + */ + +BOOLEAN +MemTFindMaxRcvrEnDlyTrainedByPmuByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + OUT UINT8 *ChipSel + ) +{ + UINT8 ChipSelect; + BOOLEAN RetVal; + UINT16 MaxDly; + UINT8 MaxDlyCs; + + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + + RetVal = FALSE; + MaxDly = 0; + MaxDlyCs = 0; + for (ChipSelect = 0; ChipSelect < NBPtr->CsPerChannel; ChipSelect = ChipSelect + NBPtr->CsPerDelay) { + /// @todo Fix this when BKDG has updated algorithm + if ((NBPtr->DCTPtr->Timings.CsPresent & ((UINT16) ((NBPtr->CsPerDelay == 2)? 3 : 1) << ChipSelect)) != 0) { + MaxDly = 0; + MaxDlyCs = ChipSelect; + RetVal = TRUE; + } + } + + TechPtr->MaxDlyForMaxRdLat = MaxDly; + *ChipSel = MaxDlyCs; + return RetVal; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttecc.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttecc.c new file mode 100644 index 0000000000..054a274702 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttecc.c @@ -0,0 +1,225 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttecc.c + * + * Technology ECC byte support + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTECC_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemTCalcDQSEccTmg ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dimm, + IN UINT8 Type, + IN OUT VOID *DlyArray + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the DQS ECC timings + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTSetDQSEccTmgs ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 Dct; + UINT8 Dimm; + UINT8 i; + + MEM_NB_BLOCK *NBPtr; + CH_DEF_STRUCT *ChannelPtr; + + NBPtr = TechPtr->NBPtr; + if (NBPtr->MCTPtr->NodeMemSize) { + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + ChannelPtr = NBPtr->ChannelPtr; + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) { + if (NBPtr->DCTPtr->Timings.CsEnabled & ((UINT16)1 << (Dimm * 2))) { + i = Dimm * TechPtr->DlyTableWidth (); + MemTCalcDQSEccTmg (TechPtr, Dimm, AccessRcvEnDly, &ChannelPtr->RcvEnDlys[i]); + MemTCalcDQSEccTmg (TechPtr, Dimm, AccessRdDqsDly, &ChannelPtr->RdDqsDlys[i]); + MemTCalcDQSEccTmg (TechPtr, Dimm, AccessWrDatDly, &ChannelPtr->WrDatDlys[i]); + } + } + } + } + } + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates the DQS ECC timings + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Dimm - Dimm number + * @param[in] Type - Type of DQS timing + * @param[in,out] *DlyArray - Pointer to the array of delays per this Dimm + * + */ + +VOID +STATIC +MemTCalcDQSEccTmg ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dimm, + IN UINT8 Type, + IN OUT VOID *DlyArray + ) +{ + UINT8 i; + UINT8 j; + UINT8 Scale; + UINT8 EccByte; + UINT16 ByteiDly; + UINT16 BytejDly; + UINT16 EccDly; + UINT8 *WrDqsDly; + MEM_NB_BLOCK *NBPtr; + CH_DEF_STRUCT *ChannelPtr; + + NBPtr = TechPtr->NBPtr; + ChannelPtr = NBPtr->ChannelPtr; + + EccByte = TechPtr->MaxByteLanes (); + i = (UINT8) (ChannelPtr->DctEccDqsLike & 0xFF); + j = (UINT8) (ChannelPtr->DctEccDqsLike >> 8); + Scale = ChannelPtr->DctEccDqsScale; + WrDqsDly = &ChannelPtr->WrDqsDlys[Dimm * TechPtr->DlyTableWidth ()]; + + if (Type == AccessRcvEnDly) { + ByteiDly = ((UINT16 *) DlyArray)[i]; + BytejDly = ((UINT16 *) DlyArray)[j]; + } else { + ByteiDly = ((UINT8 *) DlyArray)[i]; + BytejDly = ((UINT8 *) DlyArray)[j]; + } + + // + // For WrDatDly, Subtract TxDqs Delay to get + // TxDq-TxDqs Delta, which is what should be averaged. + // + if (Type == AccessWrDatDly) { + ByteiDly = ByteiDly - WrDqsDly[i]; + BytejDly = BytejDly - WrDqsDly[j]; + } + + if (BytejDly > ByteiDly) { + EccDly = ByteiDly + (UINT8) (((UINT16) (BytejDly - ByteiDly) * Scale + 0x77) / 0xFF); + // Round up --^ + } else { + EccDly = BytejDly + (UINT8) (((UINT16) (ByteiDly - BytejDly) * (0xFF - Scale) + 0x77) / 0xFF); + // Round up --^ + } + + if (Type == AccessRcvEnDly) { + ((UINT16 *) DlyArray)[EccByte] = EccDly; + } else { + ((UINT8 *) DlyArray)[EccByte] = (UINT8) EccDly; + } + + // + // For WrDatDly, Add back the TxDqs value for ECC bytelane + // + if (Type == AccessWrDatDly) { + EccDly = EccDly + WrDqsDly[EccByte]; + } + + NBPtr->SetTrainDly (NBPtr, Type, DIMM_BYTE_ACCESS (Dimm, EccByte), EccDly); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mtthrc.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mtthrc.c new file mode 100644 index 0000000000..58ba34a616 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mtthrc.c @@ -0,0 +1,312 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtthrc.c + * + * Phy assisted DQS receiver enable training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTHRC_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define TpProcMemRcvrSetSeed TpProcMemRcvrSetDelay +#define TpProcMemRcvrInitPRE TpProcMemRcvrStartSweep +#define TpProcMemRcvrBackToBackRead TpProcMemRcvrTestPattern + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemTProgramRcvrEnDly ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 ChipSel, + IN UINT8 Pass + ); + +BOOLEAN +STATIC +MemTDqsTrainRcvrEnHw ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Pass + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern UINT16 T1minToFreq[]; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes first pass of Phy assisted receiver enable training + * for current node at DDR800 and below. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @pre Auto refresh and ZQCL must be disabled + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemTDqsTrainRcvrEnHwPass1 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + return MemTDqsTrainRcvrEnHw (TechPtr, 1); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes second pass of Phy assisted receiver enable training + * for current node at DDR1066 and above. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @pre Auto refresh and ZQCL must be disabled + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +MemTDqsTrainRcvrEnHwPass2 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + // If current speed is higher than start-up speed, do second pass of WL + if (TechPtr->NBPtr->DCTPtr->Timings.Speed > TechPtr->NBPtr->StartupSpeed) { + return MemTDqsTrainRcvrEnHw (TechPtr, 2); + } + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes Phy assisted receiver enable training for current node. + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Pass - Pass of the receiver training + * + * @pre Auto refresh and ZQCL must be disabled + * + */ +BOOLEAN +STATIC +MemTDqsTrainRcvrEnHw ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Pass + ) +{ + MEM_NB_BLOCK *NBPtr; + UINT32 TestAddrRJ16; + UINT8 Dct; + UINT8 ChipSel; + NBPtr = TechPtr->NBPtr; + + TechPtr->TrainingType = TRN_RCVR_ENABLE; + + AGESA_TESTPOINT (TpProcMemReceiverEnableTraining , &(NBPtr->MemPtr->StdHeader)); + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart HW RxEn training\n"); + + // Set environment settings before training + MemTBeginTraining (TechPtr); + // + // Setup hardware training engine (if applicable) + // + NBPtr->FamilySpecificHook[SetupHwTrainingEngine] (NBPtr, &TechPtr->TrainingType); + + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + //training for each rank + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; (NBPtr->MCTPtr->Status[SbLrdimms])? ChipSel += 2: ChipSel++) { + if (NBPtr->GetSysAddr (NBPtr, ChipSel, &TestAddrRJ16)) { + if (!(NBPtr->MCTPtr->Status[SbLrdimms]) || ((NBPtr->ChannelPtr->LrDimmPresent & ((UINT8) 1 << (ChipSel >> 1))) != 0)) { + // 1.Prepare the DIMMs for training + NBPtr->SetBitField (NBPtr, BFTrDimmSel, ChipSel / NBPtr->CsPerDelay); + + TechPtr->ChipSel = ChipSel; + TechPtr->Pass = Pass; + NBPtr->FamilySpecificHook[InitPerNibbleTrn] (NBPtr, NULL); + for (TechPtr->TrnNibble = NIBBLE_0; TechPtr->TrnNibble <= (NBPtr->FamilySpecificHook[TrainRxEnPerNibble] (NBPtr, &ChipSel)? NIBBLE_0 : NIBBLE_1); TechPtr->TrnNibble++) { + // 2.Prepare the phy for DQS receiver enable training. + IDS_HDT_CONSOLE (MEM_STATUS, "\t\tCS %d\n", ChipSel); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tTestAddr %x0000\n", TestAddrRJ16); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + + AGESA_TESTPOINT (TpProcMemRcvrSetSeed, &(NBPtr->MemPtr->StdHeader)); + NBPtr->MemNPrepareRcvrEnDlySeed (NBPtr); + + NBPtr->FamilySpecificHook[SetMaxRdLatBasedOnSeededRxEnDly] (NBPtr, NULL); + + AGESA_TESTPOINT (TpProcMemRcvrInitPRE, &(NBPtr->MemPtr->StdHeader)); + // 3.BIOS initiates the phy assisted receiver enable training + NBPtr->SetBitField (NBPtr, BFDqsRcvTrEn, 1); + + // 4.BIOS begins sending out of back-to-back reads to create + // a continuous stream of DQS edges on the DDR interface + AGESA_TESTPOINT (TpProcMemRcvrBackToBackRead, &(NBPtr->MemPtr->StdHeader)); + NBPtr->GenHwRcvEnReads (NBPtr, TestAddrRJ16); + + // 7.Program [DqsRcvTrEn]=0 to stop the DQS receive enable training. + NBPtr->SetBitField (NBPtr, BFDqsRcvTrEn, 0); + + // 8.Get the gross and fine delay values. + // 9.Calculate the corresponding final delay values + MemTProgramRcvrEnDly (TechPtr, ChipSel, Pass); + } + } + } + } + } + // Restore environment settings after training + MemTEndTraining (TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "End HW RxEn training\n\n"); + + return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates final RcvrEnDly for each rank + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] ChipSel - Rank to be trained + * @param[in] Pass - Pass of the receiver training + * + */ +VOID +STATIC +MemTProgramRcvrEnDly ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 ChipSel, + IN UINT8 Pass + ) +{ + MEM_NB_BLOCK *NBPtr; + CH_DEF_STRUCT *ChannelPtr; + UINT8 ByteLane; + UINT16 RcvEnDly; + UINT16 CsPairRcvEnDly; + UINT16 RankRcvEnDly[9]; + NBPtr = TechPtr->NBPtr; + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t PRE: "); + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8) ; ByteLane++) { + RcvEnDly = (UINT8) NBPtr->GetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (ChipSel / NBPtr->CsPerDelay, ByteLane)); + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", RcvEnDly); + + RcvEnDly = RcvEnDly + TechPtr->DiffSeedGrossSeedPreGross[ByteLane]; + + // Add 1 UI to get to the midpoint of preamble + RcvEnDly += 0x20; + TechPtr->Bytelane = ByteLane; + RankRcvEnDly[ByteLane] = RcvEnDly; + if (NBPtr->FamilySpecificHook[TrainRxEnAdjustDlyPerNibble] (NBPtr, &RcvEnDly)) { + if (((ChipSel & 1) == 1) && (NBPtr->CsPerDelay == 2)) { + // For each rank pair on a dual-rank DIMM, compute the average value of the total delays saved during the + // training of each rank and program the result in D18F2x[1,0]9C_x0000_00[24:10][DqsRcvEnGrossDelay, + // DqsRcvEnFineDelay]. + CsPairRcvEnDly = ChannelPtr->RcvEnDlys[(ChipSel >> 1) * TechPtr->DlyTableWidth () + ByteLane]; + RcvEnDly = (CsPairRcvEnDly + RcvEnDly + 1) / 2; + } + } + ChannelPtr->RcvEnDlys[(ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane] = RcvEnDly; + NBPtr->SetTrainDly (NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS ((ChipSel / NBPtr->CsPerDelay), ByteLane), RcvEnDly); + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t RxEn: "); + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", RankRcvEnDly[ByteLane]); + } + if (NBPtr->FamilySpecificHook[TrainRxEnGetAvgDlyPerNibble] (NBPtr, NULL)) { + if (((ChipSel & 1) == 1) && (NBPtr->CsPerDelay == 2)) { + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t Avg: "); + for (ByteLane = 0; ByteLane < (NBPtr->MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", ChannelPtr->RcvEnDlys[(ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane]); + } + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\n"); + ) +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mtthrcSeedTrain.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mtthrcSeedTrain.c new file mode 100644 index 0000000000..ce295acc80 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mtthrcSeedTrain.c @@ -0,0 +1,623 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mtthrcSt.c + * + * Phy assisted DQS receiver enable seedless training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mttEdgeDetect.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTHRCSEEDTRAIN_FILECODE +/*---------------------------------------------------------------------------- +3 * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemTRdPosRxEnSeedSetDly3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT UINT16 RcvEnDly, + IN OUT UINT8 ByteLane + ); + +VOID +STATIC +MemTRdPosRxEnSeedCheckRxEndly3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/*----------------------------------------------------------------------------- + * + * + * This function checks each bytelane for no window error. + * + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemTTrackRxEnSeedlessRdWrNoWindBLError ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT VOID *OptParam + ) +{ + UINT8 i; + SWEEP_INFO SweepData; + SweepData = *(SWEEP_INFO*)OptParam; + for (i = 0; i < ((TechPtr->NBPtr->MCTPtr->Status[SbEccDimms] && TechPtr->NBPtr->IsSupported[EccByteTraining]) ? 9 : 8) ; i++) { + // + /// Skip Bytelanes that have already reached the desired result + // + if ((SweepData.ResultFound & ((UINT16)1 << i)) == 0) { + if (SweepData.TrnDelays[i] == SweepData.EndDelay) { + if ((SweepData.EndResult & ((UINT16) (1 << i))) != 0) { + TechPtr->ByteLaneError[i] = TRUE; + } else { + TechPtr->ByteLaneError[i] = FALSE; + } + } + } + } + return TRUE; +} +/*----------------------------------------------------------------------------- + * + * + * This function checks each bytelane for small window error. + * + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] OptParam - Optional parameter(Unused) + * + * @return TRUE + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemTTrackRxEnSeedlessRdWrSmallWindBLError ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT VOID *OptParam + ) +{ + TechPtr->ByteLaneError[TechPtr->Bytelane] = TRUE; + return TRUE; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the RxEn delay + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in,out] *RcvEnDly - Receiver Enable Delay + * @param[in,out] *ByteLane - Bytelane + * +*/ +VOID +STATIC +MemTRdPosRxEnSeedSetDly3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT UINT16 RcvEnDly, + IN OUT UINT8 ByteLane + ) +{ + TechPtr->NBPtr->ChannelPtr->RcvEnDlys[(TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane] = RcvEnDly; + TechPtr->NBPtr->SetTrainDly (TechPtr->NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS ((TechPtr->ChipSel / TechPtr->NBPtr->CsPerDelay), ByteLane), RcvEnDly); + TechPtr->NBPtr->FamilySpecificHook[ResetRxFifoPtr] (TechPtr->NBPtr, TechPtr->NBPtr); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines if the currert RxEn delay settings have failed + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * +*/ +VOID +STATIC +MemTRdPosRxEnSeedCheckRxEndly3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 MaxDlyDimm; + TechPtr->FindMaxDlyForMaxRdLat (TechPtr, &MaxDlyDimm); + TechPtr->NBPtr->SetMaxLatency (TechPtr->NBPtr, TechPtr->MaxDlyForMaxRdLat); + TechPtr->DqsRdWrPosSaved = 0; + MemTTrainDQSEdgeDetect (TechPtr); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes RdDQS training and if fails adjusts the RxEn Gross results for + * each bytelane + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - All bytelanes pass + * @return FALSE - Some bytelanes fail +*/ +BOOLEAN +MemTRdPosWithRxEnDlySeeds3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 ByteLane; + UINT16 PassTestRxEnDly[MAX_BYTELANES_PER_CHANNEL + 1]; + UINT16 FailTestRxEnDly[MAX_BYTELANES_PER_CHANNEL + 1]; + UINT16 FinalRxEnCycle[MAX_BYTELANES_PER_CHANNEL + 1]; + UINT16 RxOrig[MAX_BYTELANES_PER_CHANNEL]; + UINT8 i; + UINT8 j; + UINT8 NumBLWithTargetFound; + UINT8 MaxByteLanes; + INT16 RxEn; + BOOLEAN status; + BOOLEAN EsbNoDqsPosSave; + BOOLEAN OutOfRange[MAX_BYTELANES_PER_CHANNEL]; + BOOLEAN ByteLanePass[MAX_BYTELANES_PER_CHANNEL]; + BOOLEAN ByteLaneFail[MAX_BYTELANES_PER_CHANNEL]; + BOOLEAN RxEnMemClkTested[MAX_BYTELANES_PER_CHANNEL][MAX_POS_RX_EN_SEED_GROSS_RANGE]; + BOOLEAN RxEnMemClkSt[MAX_BYTELANES_PER_CHANNEL][MAX_POS_RX_EN_SEED_GROSS_RANGE]; + BOOLEAN RxEnDlyTargetFound[MAX_BYTELANES_PER_CHANNEL]; + BOOLEAN DlyWrittenToReg[MAX_BYTELANES_PER_CHANNEL]; + UINT16 RxEnDlyTargetValue[MAX_BYTELANES_PER_CHANNEL]; + UINT8 AllByteLanesOutOfRange; + UINT8 AllByteLanesSaved; + UINT8 TotalByteLanesCheckedForSaved; + UINT8 MemClkCycle; + MEM_NB_BLOCK *NBPtr; + CH_DEF_STRUCT *ChannelPtr; + NBPtr = TechPtr->NBPtr; + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + NumBLWithTargetFound = 0; + status = FALSE; + EsbNoDqsPosSave = TechPtr->NBPtr->MCTPtr->ErrStatus[EsbNoDqsPos]; + NBPtr->RdDqsDlyRetrnStat = RDDQSDLY_RTN_SUSPEND; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\nStart HW RxEn Seedless training\n\n"); + // 1. Program D18F2x9C_x0D0F_0[F,8:0]30_dct[1:0][BlockRxDqsLock] = 1. + NBPtr->SetBitField (NBPtr, BFBlockRxDqsLock, 0x0100); + IDS_HDT_CONSOLE (MEM_FLOW, "\tChip Select: %02x \n", TechPtr->ChipSel); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\t\tRxEn Orig: "); + // + // Start sweep loops for RxEn Seedless Training + // + MaxByteLanes = (TechPtr->NBPtr->MCTPtr->Status[SbEccDimms] && TechPtr->NBPtr->IsSupported[EccByteTraining]) ? 9 : 8; //dmach + // + //Initialialize BL variables + // + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + OutOfRange[ByteLane] = FALSE; + ByteLanePass[ByteLane] = FALSE; + ByteLaneFail[ByteLane] = FALSE; + // 2. RxEnOrig = D18F2x9C_x0000_00[2A:10]_dct[1:0][DqsRcvEnGrossDelay, DqsRcvEnFineDelay] result + // from 2.10.6.8.2 [Phy Assisted DQS Receiver Enable Training] + RxOrig[ByteLane] = TechPtr->RxOrig[ByteLane]; // Original RxEn Dly based on PRE results + RxEnDlyTargetFound[ByteLane] = FALSE; + RxEnDlyTargetValue[ByteLane] = 0; + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", RxOrig[ByteLane]); + for (i = 0; i < MAX_POS_RX_EN_SEED_GROSS_RANGE; i++) { + RxEnMemClkTested[ByteLane][i] = FALSE; + } + } + // Start MemClk delay sweep + for (i = 0; i < MAX_POS_RX_EN_SEED_GROSS_RANGE; i++) { + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\ti: %02x\n", i); + // Start direction sweep (0, - Positive, 1 - negative) + for (j = 0; j < MAX_POS_RX_EN_SEED_GROSS_DIR; j++) { + // Edge detect may run twice to see Pass to fail transition + // It is not run if the value are already saved + // Fail test is only done if pass is found + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tj: %02x\n", j); + // Reset Bytelane Flags for next sweep + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + ByteLaneFail[ByteLane] = FALSE; + ByteLanePass[ByteLane] = FALSE; + OutOfRange[ByteLane] = FALSE; + } + if (i == 0 && j == 1) { + continue; // Since i & j are the same skip + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t Target BL Found: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", ((RxEnDlyTargetFound[ByteLane] == TRUE) ? 'Y' : 'N')); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t Target BL Value: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", RxEnDlyTargetValue[ByteLane]); + } + ); + // + // Find the RxEn Delay for the Pass condition in the Pass to Fail transition + // "PassTestRxEnDly" + // + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t Setting PassTestRxEnDly\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t PassTestRxEnDly: "); + PassTestRxEnDly[ByteLane] = RxOrig[ByteLane]; + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (RxEnDlyTargetFound[ByteLane] == FALSE) { + // Calculate "PassTestRxEnDly" from current "RxEnDly" + // 3. RxEnOffset = MOD(RxEnOrig + 0x10, 0x40) + RxEn = (j == 0) ? ((INT16)RxOrig[ByteLane] + 0x10 + (0x40*i)) : ((INT16)RxOrig[ByteLane] + 0x10 - (0x40*i)); + // Check if RxEnDly is in a valid range + if ((RxEn >= NBPtr->MinRxEnSeedGross) && (RxEn <= NBPtr->MaxRxEnSeedTotal)) { + PassTestRxEnDly[ByteLane] = (UINT16)RxEn; + // 4. For each DqsRcvEn value beginning from RxEnOffset incrementing by 1 MEMCLK: + // A. Program D18F2x9C_x0000_00[2A:10]_dct[1:0][DqsRcvEnGrossDelay, DqsRcvEnFineDelay] with + // the current value. + MemTRdPosRxEnSeedSetDly3 (TechPtr, PassTestRxEnDly[ByteLane], ByteLane); + OutOfRange[ByteLane] = FALSE; + } else { + OutOfRange[ByteLane] = TRUE; + } + } else { + PassTestRxEnDly[ByteLane] = RxEnDlyTargetValue[ByteLane]; + } + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", PassTestRxEnDly[ByteLane]); + } + // Check if all BLs out of Range at "PassTestRxEnDly" + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t OutOfRange: "); + AllByteLanesOutOfRange = 0; + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (OutOfRange[ByteLane]) { + AllByteLanesOutOfRange++; + } + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", (OutOfRange[ByteLane] == TRUE) ? 'Y' : 'N'); + } + if (AllByteLanesOutOfRange == MaxByteLanes) { + continue; // All BLs out of range, so skip + } + // Check if all BLs saved Results at "PassTestRxEnDly" + AllByteLanesSaved = 0; + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + MemClkCycle = (UINT8) (PassTestRxEnDly[ByteLane] >> 5); + if (RxEnDlyTargetFound[ByteLane] == FALSE) { + if (!RxEnMemClkTested[ByteLane][MemClkCycle]) { + AllByteLanesSaved++; + } + } + } + // Check if "RxEnDlyValueForPassCond" passed + if (AllByteLanesSaved != 0) { + // At least one BL has not been saved, so check if "PassTestRxEnDly" passed + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t Checking if PassTestRxEnDly Passes?\n\n"); + // 4B. Perform 2.10.6.8.5 [DQS Position Training]. + // Record the result for the current DqsRcvEn setting as a pass or fail depending if a data eye is found. + MemTRdPosRxEnSeedCheckRxEndly3 (TechPtr); + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t Err Status: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", (TechPtr->ByteLaneError[ByteLane] == TRUE) ? 'F' : 'P'); + } + ); + } else { + // All BLs saved, so use saved results for "PassTestRxEnDly" + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tAll BLs Saved at PassTestRxEnDly\n"); + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t Save Err Stat: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + MemClkCycle = (UINT8) (PassTestRxEnDly[ByteLane] >> 5); + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", ((RxEnMemClkSt[ByteLane][MemClkCycle] == TRUE) ? 'F' : 'P')); + } + ); + } + // Update Saved values for "PassTestRxEnDly" + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (RxEnDlyTargetFound[ByteLane] == FALSE) { + if (OutOfRange[ByteLane] == FALSE) { + MemClkCycle = (UINT8) (PassTestRxEnDly[ByteLane] >> 5); + if (!RxEnMemClkTested[ByteLane][MemClkCycle]) { + RxEnMemClkTested[ByteLane][MemClkCycle] = TRUE; + RxEnMemClkSt[ByteLane][MemClkCycle] = TechPtr->ByteLaneError[ByteLane]; + } + } + } + } + // + // Find the RxEn Delay for the Fail condition in the Pass to Fail transition + // "FailTestRxEnDly" + // + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + DlyWrittenToReg[ByteLane] = FALSE; + } + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + FailTestRxEnDly[ByteLane] = PassTestRxEnDly[ByteLane] + 0x40; + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t FailTestRxEnDly: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", FailTestRxEnDly[ByteLane]); + } + ); + // Check if all BLs Saved Results at FailTestRxEnDly + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tSetting FailTestRxEnDly"); + AllByteLanesSaved = 0; + TotalByteLanesCheckedForSaved = 0; + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (RxEnDlyTargetFound[ByteLane] == FALSE) { + MemClkCycle = (UINT8) (FailTestRxEnDly[ByteLane] >> 5); + // Check if RxEnDly + 40 is valid + if ((FailTestRxEnDly[ByteLane] >= NBPtr->MinRxEnSeedGross) && (FailTestRxEnDly[ByteLane] <= NBPtr->MaxRxEnSeedTotal)) { + if (RxEnMemClkTested[ByteLane][MemClkCycle]) { + AllByteLanesSaved++; + } + OutOfRange[ByteLane] = FALSE; + } else { + OutOfRange[ByteLane] = TRUE; + } + TotalByteLanesCheckedForSaved++; + } + } + // Check if all BLs out of Range condition at FailTestRxEnDly + AllByteLanesOutOfRange = 0; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t OutOfRange: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (OutOfRange[ByteLane]) { + AllByteLanesOutOfRange++; + } + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", (OutOfRange[ByteLane] == TRUE) ? 'Y' : 'N'); + } + if (AllByteLanesOutOfRange == MaxByteLanes) { + continue; // All BLs out of range, so skip + } + // Setting FailTestRxEnDly for any BL that was not saved + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t FailTestRxEnDly: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (RxEnDlyTargetFound[ByteLane] == FALSE) { + MemClkCycle = (UINT8) (PassTestRxEnDly[ByteLane] >> 5); + // Check if New RxEnDly has Passed + if ((RxEnMemClkTested[ByteLane][MemClkCycle] ? RxEnMemClkSt[ByteLane][MemClkCycle] : TechPtr->ByteLaneError[ByteLane]) == FALSE) { + if (OutOfRange[ByteLane] == FALSE) { + // BL has passed at "New RxEnDly", so check if "New RxEnDly" + 0x40 fails + MemClkCycle = (UINT8) (FailTestRxEnDly[ByteLane] >> 5); + if (!RxEnMemClkTested[ByteLane][MemClkCycle]) { + // Only Set Delays for ByteLanes that have not been already tested + MemTRdPosRxEnSeedSetDly3 (TechPtr, FailTestRxEnDly[ByteLane], ByteLane); + DlyWrittenToReg[ByteLane] = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'Y'); + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'N'); + } + ByteLanePass[ByteLane] = TRUE; + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'O'); + } + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'F'); + } + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'N'); + } + } + // Check if BLs that passed at PassTestRxEnDly fail at FailTestRxEnDly + if (AllByteLanesSaved != TotalByteLanesCheckedForSaved) { + // At least one BL has not been saved, so check if FailTestRxEnDly passed + IDS_HDT_CONSOLE (MEM_FLOW, "\n\n\t\t Checking if FailTestRxEnDly Fails?\n"); + MemTRdPosRxEnSeedCheckRxEndly3 (TechPtr); + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t Err Status: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", (TechPtr->ByteLaneError[ByteLane] == TRUE) ? 'F' : 'P'); + } + ); + } else { + // All BLs saved, so use saved results for FailTestRxEnDly + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\tAll BLs Saved at PassTestRxEnDly\n"); + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\t Byte: 00 01 02 03 04 05 06 07 ECC\n"); + IDS_HDT_CONSOLE (MEM_FLOW, "\t Save Err Stat: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + MemClkCycle = (UINT8) (FailTestRxEnDly[ByteLane] >> 5); + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", (RxEnMemClkSt[ByteLane][MemClkCycle] == TRUE) ? 'F' : 'P'); + } + ); + } + // + // If BL failes at "FailTestRxEnDly" set FinalRxEnCycle + // + // Setting FinalRxEnCycle for any BL that Failed at FailTestRxEnDly + IDS_HDT_CONSOLE (MEM_FLOW, "\n Set FinalRxEnCycle: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (RxEnDlyTargetFound[ByteLane] == FALSE) { + MemClkCycle = (UINT8) (FailTestRxEnDly[ByteLane] >> 5); + if (RxEnMemClkTested[ByteLane][MemClkCycle] ? RxEnMemClkSt[ByteLane][MemClkCycle] == TRUE : (TechPtr->ByteLaneError[ByteLane] && DlyWrittenToReg[ByteLane])) { + FinalRxEnCycle[ByteLane] = PassTestRxEnDly[ByteLane] - 0x10; + if (((UINT16) FinalRxEnCycle[ByteLane] >= NBPtr->MinRxEnSeedGross) && ((UINT16) FinalRxEnCycle[ByteLane] <= NBPtr->MaxRxEnSeedTotal)) { + // Since FailTestRxEnDly, we can set FinalRxEnCycle + MemTRdPosRxEnSeedSetDly3 (TechPtr, (UINT16) FinalRxEnCycle[ByteLane], ByteLane); + ByteLaneFail[ByteLane] = TRUE; + OutOfRange[ByteLane] = FALSE; + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'Y'); + } else { + OutOfRange[ByteLane] = TRUE; + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'N'); + } + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'F'); + OutOfRange[ByteLane] = FALSE; + } + } else { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", 'Y'); + } + } + // Update Saved values for FailTestRxEnDly + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (RxEnDlyTargetFound[ByteLane] == FALSE) { + if (OutOfRange[ByteLane] == FALSE) { + MemClkCycle = (UINT8) (FailTestRxEnDly[ByteLane] >> 5); + if (!RxEnMemClkTested[ByteLane][MemClkCycle] && DlyWrittenToReg[ByteLane]) { + RxEnMemClkTested[ByteLane][MemClkCycle] = TRUE; + RxEnMemClkSt[ByteLane][MemClkCycle] = TechPtr->ByteLaneError[ByteLane]; + } + } + } + } + // Check for out of Range condition + AllByteLanesOutOfRange = 0; + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t OutOfRange: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (OutOfRange[ByteLane]) { + AllByteLanesOutOfRange++; + } + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", (OutOfRange[ByteLane] == TRUE) ? 'Y' : 'N'); + } + if (AllByteLanesOutOfRange == MaxByteLanes) { + continue; // All BLs out of range so skip + } + IDS_HDT_CONSOLE_DEBUG_CODE ( + IDS_HDT_CONSOLE (MEM_FLOW, "\n FinalRxEnCycle: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", (UINT16) FinalRxEnCycle[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n ByteLaneFail: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", (ByteLaneFail[ByteLane] == TRUE) ? 'Y' : 'N'); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n ByteLanePass: "); + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, " %c ", (ByteLanePass[ByteLane] == TRUE) ? 'Y' : 'N'); + } + ); + // + // Check for exit condition + // PassTestRxEnDly = Pass and FailTestRxEnDly[ByteLane] = Fail + // If found, use "FinalRxEnCycle" as final RxEnDly value + // + // 5. Process the array of results and determine a pass-to-fail transition. + NumBLWithTargetFound = 0; + for (ByteLane = 0; ByteLane < MaxByteLanes; ByteLane++) { + if (RxEnDlyTargetFound[ByteLane] == FALSE) { + // Check if the current BL has found its target + if (ByteLanePass[ByteLane] == TRUE && ByteLaneFail[ByteLane] == TRUE) { + RxEnDlyTargetFound[ByteLane] = TRUE; + NumBLWithTargetFound++; + RxEnDlyTargetValue[ByteLane] = FinalRxEnCycle[ByteLane]; + } else { + RxEnDlyTargetFound[ByteLane] = FALSE; + } + } else { + // BL has already failed and passed, so increment both flags + NumBLWithTargetFound++; + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + // Check for exit condition + if (NumBLWithTargetFound == MaxByteLanes) { + // Exit condition found, so setting new RDQS based on RxEn-0x10 \n\n + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t Setting new RDQS based on FinalRxEnCycle \n\n"); + // 5 A. DqsRcvEnCycle = the total delay value of the pass result. + // B. Program D18F2x9C_x0000_00[2A:10]_dct[1:0][DqsRcvEnGrossDelay, DqsRcvEnFineDelay] = + // DqsRcvEnCycle - 0x10. + NBPtr->RdDqsDlyRetrnStat = RDDQSDLY_RTN_NEEDED; + MemTRdPosRxEnSeedCheckRxEndly3 (TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + status = TRUE; + break; + } else { + status = FALSE; + } + } + // Check for exit condition + if (NumBLWithTargetFound == MaxByteLanes) { + status = TRUE; + break; + } else { + status = FALSE; + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + TechPtr->NBPtr->MCTPtr->ErrStatus[EsbNoDqsPos] = EsbNoDqsPosSave; + if (i == MAX_POS_RX_EN_SEED_GROSS_RANGE) { + TechPtr->NBPtr->MCTPtr->ErrStatus[EsbNoDqsPos] = TRUE; + } + + // 6. Program D18F2x9C_x0D0F_0[F,8:0]30_dct[1:0][BlockRxDqsLock] = 0. + NBPtr->SetBitField (NBPtr, BFBlockRxDqsLock, 0); + IDS_HDT_CONSOLE (MEM_FLOW, "\nEnd HW RxEn Seedless training\n\n"); + return status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttml.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttml.c new file mode 100644 index 0000000000..450d03fbf6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttml.c @@ -0,0 +1,263 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttml.c + * + * Technology Max Latency Training support + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "merrhdl.h" +#include "GeneralServices.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTML_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function trains Max latency for all dies + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTTrainMaxLatency ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT32 TestAddrRJ16; + UINT8 Dct; + UINT8 ChipSel; + UINT8 *PatternBufPtr; + UINT8 *TestBufferPtr; + UINT8 CurrentNbPstate; + UINT16 CalcMaxLatDly; + UINT16 MaxLatDly; + UINT16 MaxLatLimit; + UINT16 Margin; + UINT16 CurTest; + UINT16 _CL_; + UINT8 TimesFail; + UINT8 TimesRetrain; + UINT16 i; + + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MCTPtr = NBPtr->MCTPtr; + MemPtr = NBPtr->MemPtr; + TechPtr->TrainingType = TRN_MAX_READ_LATENCY; + TimesRetrain = DEFAULT_TRAINING_TIMES; + IDS_OPTION_HOOK (IDS_MEM_RETRAIN_TIMES, &TimesRetrain, &MemPtr->StdHeader); + + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart MaxRdLat training\n"); + // Set environment settings before training + AGESA_TESTPOINT (TpProcMemMaxRdLatencyTraining, &(MemPtr->StdHeader)); + + MemTBeginTraining (TechPtr); + // + // Initialize the Training Pattern + // + if (AGESA_SUCCESS != NBPtr->TrainingPatternInit (NBPtr)) { + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); + } + TechPtr->PatternLength = (MCTPtr->Status[Sb128bitmode]) ? 6 : 3; + // + // Setup hardware training engine (if applicable) + // + NBPtr->FamilySpecificHook[SetupHwTrainingEngine] (NBPtr, &TechPtr->TrainingType); + // + // Adjust RdDqsDly used for MaxRdLatency calculation + // + NBPtr->FamilySpecificHook[AdjustRdDqsDlyForMaxRdLat] (NBPtr, NULL); + + MaxLatDly = 0; + _CL_ = TechPtr->PatternLength; + PatternBufPtr = TechPtr->PatternBufPtr; + TestBufferPtr = TechPtr->TestBufPtr; + // + // Begin max latency training + // + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + if (MCTPtr->Status[Sb128bitmode] && (Dct != 0)) { + break; + } + + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + + if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { + if (TechPtr->FindMaxDlyForMaxRdLat (TechPtr, &ChipSel)) { + TechPtr->ChipSel = ChipSel; + if (NBPtr->GetSysAddr (NBPtr, ChipSel, &TestAddrRJ16)) { + IDS_HDT_CONSOLE (MEM_STATUS, "\t\tCS %d\n", ChipSel); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tWrite to address: %04x0000\n", TestAddrRJ16); + + // Write the test patterns + AGESA_TESTPOINT (TpProcMemMaxRdLatWritePattern, &(MemPtr->StdHeader)); + NBPtr->WritePattern (NBPtr, TestAddrRJ16, PatternBufPtr, _CL_); + + // Sweep max latency delays + NBPtr->getMaxLatParams (NBPtr, TechPtr->MaxDlyForMaxRdLat, &CalcMaxLatDly, &MaxLatLimit, &Margin); + AGESA_TESTPOINT (TpProcMemMaxRdLatStartSweep, &(MemPtr->StdHeader)); + + TimesFail = 0; + ERROR_HANDLE_RETRAIN_BEGIN (TimesFail, TimesRetrain) + { + MaxLatDly = CalcMaxLatDly; + for (i = 0; i < (MaxLatLimit - CalcMaxLatDly); i++) { + NBPtr->SetBitField (NBPtr, BFMaxLatency, MaxLatDly); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tDly %3x", MaxLatDly); + TechPtr->ResetDCTWrPtr (TechPtr, 6); + + AGESA_TESTPOINT (TpProcMemMaxRdLatReadPattern, &(MemPtr->StdHeader)); + NBPtr->ReadPattern (NBPtr, TestBufferPtr, TestAddrRJ16, _CL_); + AGESA_TESTPOINT (TpProcMemMaxRdLatTestPattern, &(MemPtr->StdHeader)); + CurTest = NBPtr->CompareTestPattern (NBPtr, TestBufferPtr, PatternBufPtr, _CL_ * 64); + NBPtr->FlushPattern (NBPtr, TestAddrRJ16, _CL_); + + if (NBPtr->IsSupported[ReverseMaxRdLatTrain]) { + // Reverse training decrements MaxLatDly whenever the test passes + // and uses the last passing MaxLatDly as left edge + if (CurTest == 0xFFFF) { + IDS_HDT_CONSOLE (MEM_FLOW, " P"); + if (MaxLatDly == 0) { + break; + } else { + MaxLatDly--; + } + } + } else { + // Traditional training increments MaxLatDly until the test passes + // and uses it as left edge + if (CurTest == 0xFFFF) { + IDS_HDT_CONSOLE (MEM_FLOW, " P"); + break; + } else { + MaxLatDly++; + } + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } // End of delay sweep + ERROR_HANDLE_RETRAIN_END ((MaxLatDly >= MaxLatLimit), TimesFail) + } + + AGESA_TESTPOINT (TpProcMemMaxRdLatSetDelay, &(MemPtr->StdHeader)); + + if (MaxLatDly >= MaxLatLimit) { + PutEventLog (AGESA_ERROR, MEM_ERROR_MAX_LAT_NO_WINDOW, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + NBPtr->DCTPtr->Timings.CsTrainFail |= NBPtr->DCTPtr->Timings.CsPresent; + MCTPtr->ChannelTrainFail |= (UINT32)1 << Dct; + if (!NBPtr->MemPtr->ErrorHandling (MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + return FALSE; + } + } else { + NBPtr->FamilySpecificHook[AddlMaxRdLatTrain] (NBPtr, &TestAddrRJ16); + + MaxLatDly = MaxLatDly + Margin; + if (NBPtr->IsSupported[ReverseMaxRdLatTrain]) { + MaxLatDly++; // Add 1 to get back to the last passing value + } + // Set final delays + CurrentNbPstate = (UINT8) MemNGetBitFieldNb (NBPtr, BFCurNbPstate); + ASSERT (CurrentNbPstate <= 3); + NBPtr->ChannelPtr->DctMaxRdLat [CurrentNbPstate] = MaxLatDly; + NBPtr->SetBitField (NBPtr, BFMaxLatency, MaxLatDly); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tFinal MaxRdLat: %03x\n", MaxLatDly); + + } + } + } + } + } + + // Restore environment settings after training + MemTEndTraining (TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "End MaxRdLat training\n\n"); + // + // Finalize the Pattern + // + NBPtr->TrainingPatternFinalize (NBPtr); + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttoptsrc.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttoptsrc.c new file mode 100644 index 0000000000..8114730d09 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttoptsrc.c @@ -0,0 +1,425 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttoptsrc.c + * + * New Technology Software based DQS receiver enable training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTOPTSRC_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +STATIC +MemTDqsTrainOptRcvrEnSw ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Pass + ); + +BOOLEAN +MemTNewRevTrainingSupport ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + return TRUE; +} + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes first pass of receiver enable training for all dies + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTTrainOptRcvrEnSwPass1 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + return MemTDqsTrainOptRcvrEnSw (TechPtr, 1); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes receiver enable training for a specific die + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Pass - Pass of the receiver training + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +STATIC +MemTDqsTrainOptRcvrEnSw ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Pass + ) +{ + _16BYTE_ALIGN UINT8 PatternBuffer[6 * 64]; + UINT8 TestBuffer[256]; + UINT8 *PatternBufPtr[6]; + UINT8 *TempPtr; + UINT32 TestAddrRJ16[4]; + UINT32 TempAddrRJ16; + UINT32 RealAddr; + UINT16 CurTest[4]; + UINT8 Dct; + UINT8 Receiver; + UINT8 i; + UINT8 TimesFail; + UINT8 TimesRetrain; + UINT16 RcvrEnDly; + UINT16 MaxRcvrEnDly; + UINT16 RcvrEnDlyLimit; + UINT16 MaxDelayCha; + BOOLEAN IsDualRank; + BOOLEAN S0En; + BOOLEAN S1En; + + + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + MCTPtr = NBPtr->MCTPtr; + TechPtr->TrainingType = TRN_RCVR_ENABLE; + + + TempAddrRJ16 = 0; + TempPtr = NULL; + MaxDelayCha = 0; + TimesRetrain = DEFAULT_TRAINING_TIMES; + IDS_OPTION_HOOK (IDS_MEM_RETRAIN_TIMES, &TimesRetrain, &MemPtr->StdHeader); + + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart Optimized SW RxEn training\n"); + // Set environment settings before training + MemTBeginTraining (TechPtr); + + PatternBufPtr[0] = PatternBufPtr[2] = PatternBuffer; + // These two patterns used for first Test Address + MemUFillTrainPattern (TestPattern0, PatternBufPtr[0], 64); + // Second Cacheline used for Dummy Read is the inverse of + // the first so that is is not mistaken for the real read + MemUFillTrainPattern (TestPattern1, PatternBufPtr[0] + 64, 64); + PatternBufPtr[1] = PatternBufPtr[3] = PatternBufPtr[0] + 128; + // These two patterns used for second Test Address + MemUFillTrainPattern (TestPattern1, PatternBufPtr[1], 64); + // Second Cacheline used for Dummy Read is the inverse of + // the first so that is is not mistaken for the real read + MemUFillTrainPattern (TestPattern0, PatternBufPtr[1] + 64, 64); + + // Fill pattern for flush after every sweep + PatternBufPtr[4] = PatternBufPtr[0] + 256; + MemUFillTrainPattern (TestPattern3, PatternBufPtr[4], 64); + + // Fill pattern for initial dummy read + PatternBufPtr[5] = PatternBufPtr[0] + 320; + MemUFillTrainPattern (TestPattern4, PatternBufPtr[5], 64); + + + // Begin receiver enable training + AGESA_TESTPOINT (TpProcMemReceiverEnableTraining, &(MemPtr->StdHeader)); + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + DCTPtr = NBPtr->DCTPtr; + + // Set training bit + NBPtr->SetBitField (NBPtr, BFDqsRcvEnTrain, 1); + + // Relax Max Latency before training + NBPtr->SetMaxLatency (NBPtr, 0xFFFF); + + if (Pass == FIRST_PASS) { + TechPtr->InitDQSPos4RcvrEn (TechPtr); + } + + // there are four receiver pairs, loosely associated with chipselects. + Receiver = DCTPtr->Timings.CsEnabled ? 0 : 8; + for (; Receiver < 8; Receiver += 2) { + S0En = NBPtr->GetSysAddr (NBPtr, Receiver, &TestAddrRJ16[0]); + S1En = NBPtr->GetSysAddr (NBPtr, Receiver + 1, &TestAddrRJ16[2]); + if (S0En) { + TestAddrRJ16[1] = TestAddrRJ16[0] + BIGPAGE_X8_RJ16; + } + if (S1En) { + TestAddrRJ16[3] = TestAddrRJ16[2] + BIGPAGE_X8_RJ16; + } + if (S0En && S1En) { + IsDualRank = TRUE; + } else { + IsDualRank = FALSE; + } + if (S0En || S1En) { + IDS_HDT_CONSOLE (MEM_STATUS, "\t\tCS %d\n", Receiver); + + RcvrEnDlyLimit = 0x1FF; // @attention - limit depends on proc type + TechPtr->DqsRcvEnSaved = 0; + RcvrEnDly = RcvrEnDlyLimit; + RealAddr = 0; + + TechPtr->GetFirstPassVal = FALSE; + TechPtr->DqsRcvEnFirstPassVal = 0; + TechPtr->RevertPassVal = FALSE; + TechPtr->InitializeVariablesOpt (TechPtr); + + // Write the test patterns + AGESA_TESTPOINT (TpProcMemRcvrWritePattern, &(MemPtr->StdHeader)); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tWrite to addresses: "); + for (i = (S0En ? 0 : 2); i < (S1En ? 4 : 2); i++) { + RealAddr = MemUSetUpperFSbase (TestAddrRJ16[i], MemPtr); + // One cacheline of data to be tested and one of dummy data + MemUWriteCachelines (RealAddr, PatternBufPtr[i], 2); + // This is dummy data with a different pattern used for the first dummy read. + MemUWriteCachelines (RealAddr + 128, PatternBufPtr[5], 1); + IDS_HDT_CONSOLE (MEM_FLOW, " %04x0000 ", TestAddrRJ16[i]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + + // Sweep receiver enable delays + AGESA_TESTPOINT (TpProcMemRcvrStartSweep, &(MemPtr->StdHeader)); + TimesFail = 0; + ERROR_HANDLE_RETRAIN_BEGIN (TimesFail, TimesRetrain) + { + TechPtr->LoadInitialRcvrEnDlyOpt (TechPtr, Receiver); + while (!TechPtr->CheckRcvrEnDlyLimitOpt (TechPtr)) { + AGESA_TESTPOINT (TpProcMemRcvrSetDelay, &(MemPtr->StdHeader)); + TechPtr->SetRcvrEnDlyOpt (TechPtr, Receiver, RcvrEnDly); + // Read and compare the first beat of data + for (i = (S0En ? 0 : 2); i < (S1En ? 4 : 2); i++) { + AGESA_TESTPOINT (TpProcMemRcvrReadPattern, &(MemPtr->StdHeader)); + RealAddr = MemUSetUpperFSbase (TestAddrRJ16[i], MemPtr); + // + // Issue dummy cacheline reads + // + MemUReadCachelines (TestBuffer + 128, RealAddr + 128, 1); + MemUReadCachelines (TestBuffer, RealAddr, 1); + MemUProcIOClFlush (TestAddrRJ16[i], 2, MemPtr); + // + // Perform actual read which will be compared + // + MemUReadCachelines (TestBuffer + 64, RealAddr + 64, 1); + AGESA_TESTPOINT (TpProcMemRcvrTestPattern, &(MemPtr->StdHeader)); + CurTest[i] = TechPtr->Compare1ClPatternOpt (TechPtr, TestBuffer + 64 , PatternBufPtr[i] + 64, i, Receiver, S1En); + // Due to speculative execution during MemUReadCachelines, we must + // flush one more cache line than we read. + MemUProcIOClFlush (TestAddrRJ16[i], 4, MemPtr); + TechPtr->ResetDCTWrPtr (TechPtr, Receiver); + + // + // Swap the test pointers such that even and odd steps alternate. + // + if ((i % 2) == 0) { + TempPtr = PatternBufPtr[i]; + PatternBufPtr[i] = PatternBufPtr[i + 1]; + + TempAddrRJ16 = TestAddrRJ16[i]; + TestAddrRJ16[i] = TestAddrRJ16[i + 1]; + } else { + PatternBufPtr[i] = TempPtr; + TestAddrRJ16[i] = TempAddrRJ16; + } + } + } // End of delay sweep + ERROR_HANDLE_RETRAIN_END (!TechPtr->SetSweepErrorOpt (TechPtr, Receiver, Dct, TRUE), TimesFail) + } + + if (!TechPtr->SetSweepErrorOpt (TechPtr, Receiver, Dct, FALSE)) { + return FALSE; + } + + TechPtr->LoadRcvrEnDlyOpt (TechPtr, Receiver); // set final delays + // + // Flush AA and 55 patterns by reading a dummy pattern to fill in FIFO + // + // Aquire a new FSBase, based on the last test address that we stored. + RealAddr = MemUSetUpperFSbase (TempAddrRJ16, MemPtr); + ASSERT (RealAddr != 0); + MemUWriteCachelines (RealAddr, PatternBufPtr[4], 1); + MemUWriteCachelines (RealAddr + 64, PatternBufPtr[4], 1); + MemUReadCachelines (TestBuffer, RealAddr, 2); + // Due to speculative execution during MemUReadCachelines, we must + // flush one more cache line than we read. + MemUProcIOClFlush (TempAddrRJ16, 3, MemPtr); + } + } // End while Receiver < 8 + + // Clear training bit when done + NBPtr->SetBitField (NBPtr, BFDqsRcvEnTrain, 0); + + // Set Max Latency for both channels + MaxRcvrEnDly = TechPtr->GetMaxValueOpt (TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMaxRcvrEnDly: %03x\n", MaxRcvrEnDly); + if (MCTPtr->GangedMode) { + if (Dct == 0) { + MaxDelayCha = MaxRcvrEnDly; + } else if (MaxRcvrEnDly > MaxDelayCha) { + NBPtr->SwitchDCT (NBPtr, 0); + NBPtr->SetMaxLatency (NBPtr, MaxRcvrEnDly); + } + } else { + NBPtr->SetMaxLatency (NBPtr, MaxRcvrEnDly); + } + TechPtr->ResetDCTWrPtr (TechPtr, 6); + } + + // Restore environment settings after training + MemTEndTraining (TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "End Optimized SW RxEn training\n\n"); + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + +/*----------------------------------------------------------------------------- + * + * This function saves passing DqsRcvEnDly values to the stack + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Receiver - Current Chip select value + * @param[in] RcvEnDly - receiver enable delay to be saved + * @param[in] cmpResultRank0 - compare result for Rank 0 + * @param[in] cmpResultRank0 - compare result for Rank 1 + * + * @retval TRUE - All bytelanes pass + * FALSE - Some bytelanes fail + * ---------------------------------------------------------------------------- + */ + +BOOLEAN +MemTSaveRcvrEnDlyByteFilterOpt ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly, + IN UINT16 CmpResultRank0, + IN UINT16 CmpResultRank1 + ) +{ + UINT8 i; + UINT8 Passed; + UINT8 Dimm; + CH_DEF_STRUCT *ChannelPtr; + + ASSERT (Receiver < MAX_CS_PER_CHANNEL); + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + + Passed = (UINT8) ((CmpResultRank0 & CmpResultRank1) & 0xFF); + + Dimm = Receiver >> 1; + + if (TechPtr->GetFirstPassVal && (RcvEnDly - TechPtr->DqsRcvEnFirstPassVal) >= 0x30) { + for (i = 0; i < 8; i++) { + ChannelPtr->RcvEnDlys[Dimm * TechPtr->DlyTableWidth () + i] = TechPtr->DqsRcvEnFirstPassVal + NEW_RECEIVER_FINAL_OFFSETVALUE; + } + TechPtr->DqsRcvEnSaved = 0xFF; + } + + if (Passed == 0xFF) { + if (!TechPtr->GetFirstPassVal) { + TechPtr->DqsRcvEnFirstPassVal = RcvEnDly; + TechPtr->GetFirstPassVal = TRUE; + } + return TRUE; + } else { + TechPtr->DqsRcvEnFirstPassVal = 0; + + // We have got first passing value, but later, we meet with glitch + if (TechPtr->GetFirstPassVal) { + TechPtr->DqsRcvEnFirstPassVal = 0xFF; + TechPtr->GetFirstPassVal = FALSE; + } + return FALSE; + } +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttsrc.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttsrc.c new file mode 100644 index 0000000000..7fcf6d0d96 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Tech/mttsrc.c @@ -0,0 +1,345 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mttsrc.c + * + * Technology Software based DQS receiver enable training + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Tech) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "mt.h" +#include "GeneralServices.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_TECH_MTTSRC_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +STATIC +MemTDqsTrainRcvrEnSw ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Pass + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes first pass of receiver enable training for all dies + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ + +BOOLEAN +MemTTrainRcvrEnSwPass1 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + return MemTDqsTrainRcvrEnSw (TechPtr, 1); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function executes receiver enable training for a specific die + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * @param[in] Pass - Pass of the receiver training + * + * @return TRUE - No fatal error occurs. + * @return FALSE - Fatal error occurs. + */ +BOOLEAN +STATIC +MemTDqsTrainRcvrEnSw ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Pass + ) +{ + _16BYTE_ALIGN UINT8 PatternBuffer[3 * 64]; + UINT8 TestBuffer[120]; + UINT8 *PatternBufPtr[4]; + UINT8 *TempPtr; + UINT32 TestAddrRJ16[4]; + UINT32 TempAddrRJ16; + UINT32 RealAddr; + UINT16 CurTest[4]; + UINT8 Dct; + UINT8 Receiver; + UINT8 i; + UINT8 TimesFail; + UINT8 TimesRetrain; + UINT16 RcvrEnDly; + UINT16 MaxRcvrEnDly; + UINT16 RcvrEnDlyLimit; + UINT16 MaxDelayCha; + BOOLEAN IsDualRank; + BOOLEAN S0En; + BOOLEAN S1En; + UINT8 MaxFilterDly; + + MEM_DATA_STRUCT *MemPtr; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + MEM_NB_BLOCK *NBPtr; + + NBPtr = TechPtr->NBPtr; + MemPtr = NBPtr->MemPtr; + MCTPtr = NBPtr->MCTPtr; + TechPtr->TrainingType = TRN_RCVR_ENABLE; + + + TempAddrRJ16 = 0; + TempPtr = NULL; + MaxDelayCha = 0; + MaxFilterDly = TechPtr->MaxFilterDly; + RcvrEnDlyLimit = NBPtr->RcvrEnDlyLimit; + TimesRetrain = DEFAULT_TRAINING_TIMES; + IDS_OPTION_HOOK (IDS_MEM_RETRAIN_TIMES, &TimesRetrain, &MemPtr->StdHeader); + + IDS_HDT_CONSOLE (MEM_STATUS, "\nStart SW RxEn training\n"); + // Set environment settings before training + MemTBeginTraining (TechPtr); + + PatternBufPtr[0] = PatternBufPtr[2] = PatternBuffer; + MemUFillTrainPattern (TestPattern0, PatternBufPtr[0], 64); + PatternBufPtr[1] = PatternBufPtr[3] = PatternBufPtr[0] + 128; + MemUFillTrainPattern (TestPattern1, PatternBufPtr[1], 64); + + // Begin receiver enable training + AGESA_TESTPOINT (TpProcMemReceiverEnableTraining, &(MemPtr->StdHeader)); + MaxRcvrEnDly = 0; + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct); + NBPtr->SwitchDCT (NBPtr, Dct); + DCTPtr = NBPtr->DCTPtr; + + // Set training bit + NBPtr->SetBitField (NBPtr, BFDqsRcvEnTrain, 1); + + // Relax Max Latency before training + NBPtr->SetMaxLatency (NBPtr, 0xFFFF); + + if (Pass == FIRST_PASS) { + TechPtr->InitDQSPos4RcvrEn (TechPtr); + } + + // there are four receiver pairs, loosely associated with chipselects. + Receiver = DCTPtr->Timings.CsEnabled ? 0 : 8; + for (; Receiver < 8; Receiver += 2) { + TechPtr->DqsRcvEnSaved = 0; + RcvrEnDly = RcvrEnDlyLimit; + S0En = NBPtr->GetSysAddr (NBPtr, Receiver, &TestAddrRJ16[0]); + S1En = NBPtr->GetSysAddr (NBPtr, Receiver + 1, &TestAddrRJ16[2]); + if (S0En) { + TestAddrRJ16[1] = TestAddrRJ16[0] + BIGPAGE_X8_RJ16; + } + if (S1En) { + TestAddrRJ16[3] = TestAddrRJ16[2] + BIGPAGE_X8_RJ16; + } + if (S0En && S1En) { + IsDualRank = TRUE; + } else { + IsDualRank = FALSE; + } + + if (S0En || S1En) { + IDS_HDT_CONSOLE (MEM_STATUS, "\t\tCS %d\n", Receiver); + + // Write the test patterns + AGESA_TESTPOINT (TpProcMemRcvrWritePattern, &(MemPtr->StdHeader)); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tWrite to addresses: "); + for (i = (S0En ? 0 : 2); i < (S1En ? 4 : 2); i++) { + RealAddr = MemUSetUpperFSbase (TestAddrRJ16[i], MemPtr); + MemUWriteCachelines (RealAddr, PatternBufPtr[i], 1); + IDS_HDT_CONSOLE (MEM_FLOW, " %04x0000 ", TestAddrRJ16[i]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + + // Initialize RcvrEnDly value and other DCT stored values + // MCTPtr->DqsRcvEnPass = Pass ? 0xFF : 0; + + // Sweep receiver enable delays + AGESA_TESTPOINT (TpProcMemRcvrStartSweep, &(MemPtr->StdHeader)); + TimesFail = 0; + ERROR_HANDLE_RETRAIN_BEGIN (TimesFail, TimesRetrain) + { + for (RcvrEnDly = 0; RcvrEnDly < RcvrEnDlyLimit; RcvrEnDly++) { + AGESA_TESTPOINT (TpProcMemRcvrSetDelay, &(MemPtr->StdHeader)); + TechPtr->SetRcvrEnDly (TechPtr, Receiver, RcvrEnDly); + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tDly %3x", RcvrEnDly); + + // Read and compare the first beat of data + for (i = (S0En ? 0 : 2); i < (S1En ? 4 : 2); i++) { + AGESA_TESTPOINT (TpProcMemRcvrReadPattern, &(MemPtr->StdHeader)); + RealAddr = MemUSetUpperFSbase (TestAddrRJ16[i], MemPtr); + MemUReadCachelines (TestBuffer, RealAddr, 1); + AGESA_TESTPOINT (TpProcMemRcvrTestPattern, &(MemPtr->StdHeader)); + CurTest[i] = TechPtr->Compare1ClPattern (TechPtr, TestBuffer, PatternBufPtr[i]); + // Due to speculative execution during MemUReadCachelines, we must + // flush one more cache line than we read. + MemUProcIOClFlush (TestAddrRJ16[i], 2, MemPtr); + TechPtr->ResetDCTWrPtr (TechPtr, Receiver); + + // + // Swap the test pointers such that even and odd steps alternate. + // + if ((i % 2) == 0) { + TempPtr = PatternBufPtr[i]; + PatternBufPtr[i] = PatternBufPtr[i + 1]; + + TempAddrRJ16 = TestAddrRJ16[i]; + TestAddrRJ16[i] = TestAddrRJ16[i + 1]; + } else { + PatternBufPtr[i] = TempPtr; + TestAddrRJ16[i] = TempAddrRJ16; + } + } + + if (TechPtr->SaveRcvrEnDly (TechPtr, Receiver, RcvrEnDly, S0En ? (CurTest[0] & CurTest[1]) : 0xFFFF, S1En ? (CurTest[2] & CurTest[3]) : 0xFFFF)) { + // if all bytelanes pass + if (MaxRcvrEnDly < (RcvrEnDly - MaxFilterDly)) { + MaxRcvrEnDly = RcvrEnDly - MaxFilterDly; + } + break; + } + } // End of delay sweep + ERROR_HANDLE_RETRAIN_END ((RcvrEnDly > (RcvrEnDlyLimit - 1)), TimesFail) + } + + if (RcvrEnDly == RcvrEnDlyLimit) { + // no passing window + PutEventLog (AGESA_ERROR, MEM_ERROR_RCVR_EN_NO_PASSING_WINDOW_EQUAL_LIMIT, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + } + + if (RcvrEnDly > (RcvrEnDlyLimit - 1)) { + // passing window too narrow, too far delayed + PutEventLog (AGESA_ERROR, MEM_ERROR_RCVR_EN_VALUE_TOO_LARGE_LIMIT_LESS_ONE, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader); + SetMemError (AGESA_ERROR, MCTPtr); + DCTPtr->Timings.CsTrainFail |= DCTPtr->Timings.CsPresent & (UINT16) (3 << Receiver); + MCTPtr->ChannelTrainFail |= (UINT32)1 << Dct; + if (!NBPtr->MemPtr->ErrorHandling (MCTPtr, NBPtr->Dct, DCTPtr->Timings.CsTrainFail, &NBPtr->MemPtr->StdHeader)) { + ASSERT (FALSE); + return FALSE; + } + } + } + + TechPtr->LoadRcvrEnDly (TechPtr, Receiver); // set final delays + } // End while Receiver < 8 + + // Clear training bit when done + NBPtr->SetBitField (NBPtr, BFDqsRcvEnTrain, 0); + + // Set Max Latency for both channels + MaxRcvrEnDly += 0x20; // @attention - + IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMaxRcvrEnDly: %03x\n", MaxRcvrEnDly); + if (MCTPtr->GangedMode) { + if (Dct == 0) { + MaxDelayCha = MaxRcvrEnDly; + } else if (MaxRcvrEnDly > MaxDelayCha) { + NBPtr->SwitchDCT (NBPtr, 0); + NBPtr->SetMaxLatency (NBPtr, MaxRcvrEnDly); + } + } else { + NBPtr->SetMaxLatency (NBPtr, MaxRcvrEnDly); + } + TechPtr->ResetDCTWrPtr (TechPtr, 6); + } + + // Restore environment settings after training + MemTEndTraining (TechPtr); + IDS_HDT_CONSOLE (MEM_FLOW, "End SW RxEn training\n\n"); + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/ma.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/ma.h new file mode 100644 index 0000000000..31bba312ba --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/ma.h @@ -0,0 +1,162 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * ma.h + * + * ARDK common header file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _MA_H_ +#define _MA_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + + +#define MAX_CS_PER_CHANNEL 8 ///< Max CS per channel +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/** MARDK Structure*/ +typedef struct { + UINT16 Speed; ///< Dram speed in MHz + UINT8 Loads; ///< Number of Data Loads + UINT32 AddrTmg; ///< Address Timing value + UINT32 Odc; ///< Output Driver Compensation Value +} PSCFG_ENTRY; + +/** MARDK Structure*/ +typedef struct { + UINT16 Speed; ///< Dram speed in MHz + UINT8 Loads; ///< Number of Data Loads + UINT32 AddrTmg; ///< Address Timing value + UINT32 Odc; ///< Output Driver Compensation Value + UINT8 Dimms; ///< Number of Dimms +} ADV_PSCFG_ENTRY; + +/** MARDK Structure for RDIMMs*/ +typedef struct { + UINT16 Speed; ///< Dram speed in MHz + UINT16 DIMMRankType; ///< Bitmap of Ranks //Bit0-3:DIMM0(1:SR, 2:DR, 4:QR, 0:No Dimm, 0xF:Any), Bit4-7:DIMM1, Bit8-11:DIMM2, Bit12-16:DIMM3 + UINT32 AddrTmg; ///< Address Timing value + UINT16 RC2RC8; ///< RC2 and RC8 value //High byte: 1st pair value, Low byte: 2nd pair value + UINT8 Dimms; ///< Number of Dimms +} ADV_R_PSCFG_ENTRY; + +/** MARDK Structure*/ +typedef struct { + UINT16 DIMMRankType; ///< Bitmap of Ranks //Bit0-3:DIMM0(1:SR, 2:DR, 4:QR, 0:No Dimm, 0xF:Any), Bit4-7:DIMM1, Bit8-11:DIMM2, Bit12-16:DIMM3 + UINT32 PhyRODTCSLow; ///< Fn2_9C 180 + UINT32 PhyRODTCSHigh; ///< Fn2_9C 181 + UINT32 PhyWODTCSLow; ///< Fn2_9C 182 + UINT32 PhyWODTCSHigh; ///< Fn2_9C 183 + UINT8 Dimms; ///< Number of Dimms +} ADV_PSCFG_ODT_ENTRY; + +/** MARDK Structure for Write Levelization ODT*/ +typedef struct { + UINT16 DIMMRankType; ///< Bitmap of Ranks //Bit0-3:DIMM0(1:SR, 2:DR, 4:QR, 0:No Dimm, 0xF:Any), Bit4-7:DIMM1, Bit8-11:DIMM2, Bit12-16:DIMM3 + UINT8 PhyWrLvOdt[MAX_CS_PER_CHANNEL / 2]; ///< WrLvOdt (Fn2_9C_0x08[11:8]) Value for each Dimm + UINT8 Dimms; ///< Number of Dimms +} ADV_R_PSCFG_WL_ODT_ENTRY; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +AGESA_STATUS +MemAGetPsCfgDef ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ); + +UINT16 +MemAGetPsRankType ( + IN CH_DEF_STRUCT *CurrentChannel + ); + +AGESA_STATUS +MemRecNGetPsCfgDef ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ); + +UINT16 +MemRecNGetPsRankType ( + IN CH_DEF_STRUCT *CurrentChannel + ); + +AGESA_STATUS +MemRecNGetPsCfgUDIMM3Nb ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ); + +AGESA_STATUS +MemRecNGetPsCfgSODIMM3Nb ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ); + +AGESA_STATUS +MemRecNGetPsCfgRDIMM3Nb ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ); + +#endif /* _MA_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/merrhdl.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/merrhdl.h new file mode 100644 index 0000000000..43f8db6a88 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/merrhdl.h @@ -0,0 +1,103 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mmerrhdl.h + * + * main error handling + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MMERRHDL_H_ +#define _MMERRHDL_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define EXCLUDE_ALL_DCT 0xFF +#define EXCLUDE_ALL_CHIPSEL 0xFF + +/// default times of training +#define DEFAULT_TRAINING_TIMES 1 + +/// number of us to wait in parallel training +#define PARALLEL_TRAINING_TIMEOUT 60000000 + +/// number of us to wait in PCI space access +#define PCI_ACCESS_TIMEOUT 10000000 +/// number of us to wait in special PCI space access which takes much longer than others +#define SPECIAL_PCI_ACCESS_TIMEOUT 20000000 + +/// Beginning of retrain handling, must be ended with the ending of the handling +#define ERROR_HANDLE_RETRAIN_BEGIN(counter, limit) while (counter < limit) + +/// Ending of retrain handling +#define ERROR_HANDLE_RETRAIN_END(condition, counter) \ +if (condition) { \ + counter ++; \ +} else { \ + break; \ +} + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemErrHandle ( + IN DIE_STRUCT *MCTPtr, + IN UINT8 DCT, + IN UINT16 ChipSelMask, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif /* _MMERRHDL_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfParallelTraining.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfParallelTraining.h new file mode 100644 index 0000000000..312407980d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfParallelTraining.h @@ -0,0 +1,113 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfParallelTraining.h + * + * Header file for the parallel training feature + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + +#ifndef _MFPARALLELTRAINING_H_ +#define _MFPARALLELTRAINING_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +typedef BOOLEAN (*REMOTE_NBBLOCK_CONSTRUCTOR) ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN DIE_STRUCT *MCTPtr, + IN MEM_FEAT_BLOCK_NB *FeatPtr +); + +///< This structure defines the environment on the AP for parallel training +typedef struct _REMOTE_TRAINING_ENV { + IN OUT AMD_CONFIG_PARAMS StdHeader; ///< Config pointer of BSP + IN OUT AGESA_STATUS (*GetPlatformCfg[MAX_PLATFORM_TYPES]) (struct _MEM_DATA_STRUCT *MemData, UINT8 SocketID, CH_DEF_STRUCT *CurrentChannel); ///< look-up platform info + IN OUT BOOLEAN (*ErrorHandling)(struct _DIE_STRUCT *MCTPtr, UINT8 DCT, UINT16 ChipSelMask, AMD_CONFIG_PARAMS *StdHeader); ///< Error Handling + IN REMOTE_NBBLOCK_CONSTRUCTOR NBBlockCtor; ///< NB Block constructor + IN MEM_FEAT_BLOCK_NB *FeatPtr; ///< Feature block pointer + IN UINT8 *TableBasedAlterations; ///< Point to an array of data bytes describing desired modifications to register settings + IN PSO_TABLE *PlatformMemoryConfiguration; ///< Point to platform config table + IN UINT32 HoleBase; ///< Used for Memtyping + IN UINT32 UmaSize; ///< Used for Memtyping + IN UINT16 BottomIo; ///< Used for Memtyping + IN UINT32 SysLimit; ///< Used for Memtyping + IN UINT8 BspSocket; ///< Socket number of BSP + IN UINT8 BspCore; ///< Core number of BSP + IN DIE_STRUCT DieStruct; ///< Remote copy of Die Struct +} REMOTE_TRAINING_ENV; + +///< This structure defines Die information +typedef struct _DIE_INFO { + IN OUT UINT8 Socket; ///< Socket number + IN OUT UINT8 Core; ///< Core number + IN OUT BOOLEAN Training; ///< Training Flag, 1 = Training has been started on this core +} DIE_INFO; + + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemFParallelTraining ( + IN OUT REMOTE_TRAINING_ENV *EnvPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +#endif /* _MFPARALLELTRAINING_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfStandardTraining.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfStandardTraining.h new file mode 100644 index 0000000000..a8e076a07a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfStandardTraining.h @@ -0,0 +1,81 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfStandardTraining.h + * + * Feature implementation of standard function which performs memory training + * from the BSP only + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + +#ifndef _MFSTANDARDTRAINING_H_ +#define _MFSTANDARDTRAINING_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemFStandardTraining ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +#endif /* _MFSTANDARDTRAINING_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfmemclr.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfmemclr.h new file mode 100644 index 0000000000..4babfa341d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfmemclr.h @@ -0,0 +1,83 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfmemclr.h + * + * Feature Functions For Memory Clear Operation + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MFMEMCLR_H_ +#define _MFMEMCLR_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +BOOLEAN +MemFMctMemClr_Init ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemFMctMemClr_Sync ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +#endif /* _MFMEMCLR_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfs3.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfs3.h new file mode 100644 index 0000000000..4b30237912 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mfs3.h @@ -0,0 +1,335 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mfS3.h + * + * S3 resume memory related functions. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Feat/S3) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _MFS3_H_ +#define _MFS3_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define PRESELFREF 0 +#define POSTSELFREF 1 +#define DCT0 0 +#define DCT1 1 +#define DCT0_MASK 0x1 +#define DCT1_MASK 0x2 +#define DCT0_NBPSTATE_SUPPORT_MASK 0x4 +#define DCT1_NBPSTATE_SUPPORT_MASK 0x8 +#define DCT0_DDR3_MASK 0x10 +#define DCT1_DDR3_MASK 0x20 +#define NODE_WITHOUT_DIMM_MASK 0x80 +#define DCT0_ANY_DIMM_MASK 0x55 +#define DCT1_ANY_DIMM_MASK 0xAA +#define ANY_DIMM_MASK 0xFF + +#define DCT_PHY_FLAG 0 +#define DCT_EXTRA_FLAG 1 +#define SET_S3_SPECIAL_OFFSET(AccessType, Dct, Offset) ((AccessType << 11) | (Dct << 10) | Offset) + +#define RESTORE_TRAINING_MODE 1 +#define CAPSULE_REBOOT_MODE 2 +#define S3_RESUME_MODE 4 +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ +/// struct for all the descriptor for pre exit self refresh and post exit self refresh +typedef struct _DESCRIPTOR_GROUP { + PCI_DEVICE_DESCRIPTOR PCIDevice[2]; ///< PCI device descriptor + CONDITIONAL_PCI_DEVICE_DESCRIPTOR CPCIDevice[2]; ///< Conditional PCI device descriptor + MSR_DEVICE_DESCRIPTOR MSRDevice[2]; ///< MSR device descriptor + CONDITIONAL_MSR_DEVICE_DESCRIPTOR CMSRDevice[2]; ///< Conditional MSR device descriptor +} DESCRIPTOR_GROUP; + +/// Northbridge block to be used in S3 resume and save. +typedef struct _S3_MEM_NB_BLOCK { + UINT8 MemS3SpecialCaseHeapSize; ///< Heap size for the special case register heap. + struct _MEM_NB_BLOCK *NBPtr; ///< Pointer to the north bridge block. + VOID (*MemS3ExitSelfRefReg) (MEM_NB_BLOCK *NBPtr, AMD_CONFIG_PARAMS *StdHeaderPtr); ///< S3 Exit self refresh register + VOID (*MemS3GetConPCIMask) (MEM_NB_BLOCK *NBPtr, DESCRIPTOR_GROUP *DescriptPtr); ///< Get conditional mask for PCI register setting + VOID (*MemS3GetConMSRMask) (MEM_NB_BLOCK *NBPtr, DESCRIPTOR_GROUP *DescriptPtr); ///< Get conditional mask for MSR register setting + UINT16 (*MemS3GetRegLstPtr) (MEM_NB_BLOCK *NBPtr, DESCRIPTOR_GROUP *DescriptPtr); ///< Get register list pointer for both PCI and MSR register + BOOLEAN (*MemS3Resume) (struct _S3_MEM_NB_BLOCK *S3NBPtr, UINT8 NodeID);///< Exit Self Refresh + VOID (*MemS3RestoreScrub) (MEM_NB_BLOCK *NBPtr, UINT8 NodeID);///< Restore scrubber base + AGESA_STATUS (*MemS3GetDeviceRegLst) (UINT32 ReigsterLstID, VOID **RegisterHeader); ///< Get register list for a device +} S3_MEM_NB_BLOCK; + +/// Header for heap space to store the special case register. +typedef struct _S3_SPECIAL_CASE_HEAP_HEADER { + UINT8 Node; ///< Node ID for the the header + UINT8 Offset; ///< Offset for the target node +} S3_SPECIAL_CASE_HEAP_HEADER; + +/// Flag for hob data save and restore +typedef enum _MEM_HOB_DATA_TYPE { + S3_UMA_SIZE, ///< UMA size + S3_UMA_BASE, ///< UMA base + S3_UMA_MODE, ///< UMA mode + S3_SUB_4G_CACHE_TOP, ///< Sub 4G Cache Top + S3_SYSLIMIT, ///< System limit + S3_UMA_ATTRIBUTE, ///< UMA attribute + S3_VDDIO ///< VDDIO +} MEM_HOB_DATA_TYPE; + +/// Header for heap space to store reduced memory internal data +typedef struct _REDUCED_MEM_BLOCK_HEAP_HEADER { + UINT16 Version; ///< Version of header + UINT8 NumNodes; ///< Number of reduced NB blocks in the list +} REDUCED_MEM_BLOCK_HEAP_HEADER; + +/// Reduced NB Block to store data during memory context save/restore +typedef struct _REDUCED_NB_BLOCK { + UINT32 NodeMemSize; ///< Base[47:16], total DRAM size controlled by both DCT0 and DCT1 of this Node. + UINT32 NodeSysBase; ///< System base of this node + UINT8 NumDcts; ///< Number of reduced DCT blocks in the list +} REDUCED_NB_BLOCK; + +/// Reduced DCT Block to store data during memory context save/restore +typedef struct _REDUCED_DCT_BLOCK { + UINT8 Dct; ///< Dct Number + UINT32 DctMemSize; ///< Base[47:16], total DRAM size controlled by this DCT. + UINT8 EnabledChipSels; ///< Number of enabled chip selects on current DCT + UINT8 BankAddrMap; ///< Bank Address Mapping + BOOLEAN BkIntDis; ///< Bank interleave requested but not enabled on current DCT +} REDUCED_DCT_BLOCK; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +AmdMemS3Resume ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +MemS3ResumeInitNB ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +MemS3Deallocate ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +MemFS3GetPciDeviceRegisterList ( + IN PCI_DEVICE_DESCRIPTOR *Device, + OUT PCI_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +MemFS3GetCPciDeviceRegisterList ( + IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device, + OUT CPCI_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +MemFS3GetMsrDeviceRegisterList ( + IN MSR_DEVICE_DESCRIPTOR *Device, + OUT MSR_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +MemFS3GetCMsrDeviceRegisterList ( + IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, + OUT CMSR_REGISTER_BLOCK_HEADER **RegisterHdr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +MemFS3GetDeviceList ( + IN OUT DEVICE_BLOCK_HEADER **DeviceBlockHdrPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +MemFS3Wait10ns ( + IN UINT32 Count, + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +BOOLEAN +MemNS3ResumeUNb ( + IN OUT S3_MEM_NB_BLOCK *S3NBPtr, + IN UINT8 NodeID + ); + +VOID +MemNS3GetBitFieldNb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3SetBitFieldNb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3RestoreScrubNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Node + ); + +AGESA_STATUS +MemS3InitNB ( + IN OUT S3_MEM_NB_BLOCK **S3NBPtr, + IN OUT MEM_DATA_STRUCT **MemPtr, + IN OUT MEM_MAIN_DATA_BLOCK *mmData, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +MemNS3SetPreDriverCalUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +BOOLEAN +MemNS3DctCfgSelectUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *Dct + ); + +VOID +MemNS3GetNBPStateDepRegUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3SetNBPStateDepRegUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3SaveNBRegisterUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3RestoreNBRegisterUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3SetMemClkFreqValUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3ChangeMemPStateContextNb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3ForceNBP0Unb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNS3ReleaseNBPSUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNSaveHobDataUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); + +VOID +MemNRestoreHobDataUnb ( + IN ACCESS_WIDTH AccessWidth, + IN PCI_ADDR Address, + IN OUT VOID *Value, + IN OUT VOID *ConfigPtr + ); +#endif //_MFS3_H_ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mftds.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mftds.h new file mode 100644 index 0000000000..e830bfbf82 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mftds.h @@ -0,0 +1,80 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mftds.h + * + * Memory Controller + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + + +#ifndef _MFTDS_H_ +#define _MFTDS_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +VOID +MemFInitTableDrive ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 time + ); +#endif /* _MFTDS_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mm.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mm.h new file mode 100644 index 0000000000..bdb759e975 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mm.h @@ -0,0 +1,1500 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mm.h + * + * Common main functions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 86704 $ @e \$Date: 2013-01-24 17:29:29 -0600 (Thu, 24 Jan 2013) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MM_H_ +#define _MM_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +#define ALLOC_SOCKET_STRUCT_HANDLE 0 +#define ALLOC_DIE_STRUCT_HANDLE 1 +#define ALLOC_DCT_STRUCT_HANDLE 2 +#define ALLOC_CHL_STRUCT_HANDLE 3 +#define ALLOC_PLATFORM_PTR_HANDLE 4 +#define ALLOC_FORM_FACTOR_HANDLE 5 +#define ALLOC_TRN_DATA_HANDLE 6 +#define ALLOC_DIMM_DATA_HANDLE 7 +#define ALLOC_PAR_TRN_HANDLE 8 +#define ALLOC_NB_REG_TABLE 9 +#define ALLOC_DEVICE_INFO 10 +#define ALLOC_DATAEYES_HANDLE 11 + +#define GENERATE_MEM_HANDLE(type, x, y, z) (\ + AMD_MEM_MISC_HANDLES_START + (((type) << 18) + ((x) << 12) + ((y) << 6) + (z)) \ +) + +/// Heap handle for each supported family's NB register table +typedef enum { + NbRegTabDR, ///< Heap handle for DR NB register table + NbRegTabDA, ///< Heap handle for DA NB register table + NbRegTabC32, ///< Heap handle for C32 NB register table + NbRegTabHY, ///< Heap handle for HY NB register table + NbRegTabKR, ///< Heap handle for KR NB register table + NbRegTabLN, ///< Heap handle for LN NB register table + NbRegTabON, ///< Heap handle for ON NB register table + NbRegTabOR, ///< Heap handle for OR NB register table + NbRegTabTN, ///< Heap handle for TN NB register table + NbRegTabKV, ///< Heap handle for KV NB register table + NbRegTabKB, ///< Heap handle for KB NB register table + NbRegTabBK, ///< Heap handle for BK NB register table + NbRegTabML, ///< Heap handle for ML NB register table + NumberOfNbRegTables ///< Number of families that have NB register tables +} NB_REG_TAB_HANDLE; + +#define VOLT1_5_ENCODED_VAL 0 +#define VOLT1_35_ENCODED_VAL 1 +#define VOLT1_25_ENCODED_VAL 2 +#define CONVERT_VDDIO_TO_ENCODED(VddIo) (\ + (VddIo == VOLT1_5) ? VOLT1_5_ENCODED_VAL : ((VddIo == VOLT1_35) ? VOLT1_35_ENCODED_VAL : ((VddIo == VOLT1_25) ? VOLT1_25_ENCODED_VAL : 0xFF)) \ +) +#define CONVERT_ENCODED_TO_VDDIO(EncodedVal) (\ + (EncodedVal == VOLT1_5_ENCODED_VAL) ? VOLT1_5 : ((EncodedVal == VOLT1_35_ENCODED_VAL) ? VOLT1_35 : ((EncodedVal == VOLT1_25_ENCODED_VAL) ? VOLT1_25 : VOLT_UNSUPPORTED)) \ +) +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/// Bit field names used in memory initialization +typedef enum { + BFDevVendorIDReg, ///< Bit field DevVendorIDReg + BFNodeID, ///< Bit field NodeID + BFNodeCnt, ///< Bit field NodeCnt + + BFDramBaseReg0, ///< Bit field DramBaseReg0 + BFDramBaseReg1, ///< Bit field DramBaseReg1 + BFDramBaseReg2, ///< Bit field DramBaseReg2 + BFDramBaseReg3, ///< Bit field DramBaseReg3 + BFDramBaseReg4, ///< Bit field DramBaseReg4 + BFDramBaseReg5, ///< Bit field DramBaseReg5 + BFDramBaseReg6, ///< Bit field DramBaseReg6 + BFDramBaseReg7, ///< Bit field DramBaseReg7 + + BFDramLimitReg0, ///< Bit field DramLimitReg0 + BFDramLimitReg1, ///< Bit field DramLimitReg1 + BFDramLimitReg2, ///< Bit field DramLimitReg2 + BFDramLimitReg3, ///< Bit field DramLimitReg3 + BFDramLimitReg4, ///< Bit field DramLimitReg4 + BFDramLimitReg5, ///< Bit field DramLimitReg5 + BFDramLimitReg6, ///< Bit field DramLimitReg6 + BFDramLimitReg7, ///< Bit field DramLimitReg7 + + BFDramBaseHiReg0, ///< Bit field DramBaseHiReg0 + BFDramBaseHiReg1, ///< Bit field DramBaseHiReg1 + BFDramBaseHiReg2, ///< Bit field DramBaseHiReg2 + BFDramBaseHiReg3, ///< Bit field DramBaseHiReg3 + BFDramBaseHiReg4, ///< Bit field DramBaseHiReg4 + BFDramBaseHiReg5, ///< Bit field DramBaseHiReg5 + BFDramBaseHiReg6, ///< Bit field DramBaseHiReg6 + BFDramBaseHiReg7, ///< Bit field DramBaseHiReg7 + + BFDramLimitHiReg0, ///< Bit field DramLimitHiReg0 + BFDramLimitHiReg1, ///< Bit field DramLimitHiReg1 + BFDramLimitHiReg2, ///< Bit field DramLimitHiReg2 + BFDramLimitHiReg3, ///< Bit field DramLimitHiReg3 + BFDramLimitHiReg4, ///< Bit field DramLimitHiReg4 + BFDramLimitHiReg5, ///< Bit field DramLimitHiReg5 + BFDramLimitHiReg6, ///< Bit field DramLimitHiReg6 + BFDramLimitHiReg7, ///< Bit field DramLimitHiReg7 + + BFDramHoleAddrReg, ///< Bit field DramHoleAddrReg + + BFDramRngRE0, ///< Bit field DramBaseReg0 RE + BFDramRngRE1, ///< Bit field DramBaseReg1 RE + BFDramRngRE2, ///< Bit field DramBaseReg2 RE + BFDramRngRE3, ///< Bit field DramBaseReg3 RE + BFDramRngRE4, ///< Bit field DramBaseReg4 RE + BFDramRngRE5, ///< Bit field DramBaseReg5 RE + BFDramRngRE6, ///< Bit field DramBaseReg6 RE + BFDramRngRE7, ///< Bit field DramBaseReg7 RE + + BFDramRngWE0, ///< Bit field DramBaseReg0 WE + BFDramRngWE1, ///< Bit field DramBaseReg1 WE + BFDramRngWE2, ///< Bit field DramBaseReg2 WE + BFDramRngWE3, ///< Bit field DramBaseReg3 WE + BFDramRngWE4, ///< Bit field DramBaseReg4 WE + BFDramRngWE5, ///< Bit field DramBaseReg5 WE + BFDramRngWE6, ///< Bit field DramBaseReg6 WE + BFDramRngWE7, ///< Bit field DramBaseReg7 WE + + BFDramRngDstNode0, ///< Bit field Dram Range0 DstNode + BFDramRngDstNode1, ///< Bit field Dram Range1 DstNode + BFDramRngDstNode2, ///< Bit field Dram Range2 DstNode + BFDramRngDstNode3, ///< Bit field Dram Range3 DstNode + BFDramRngDstNode4, ///< Bit field Dram Range4 DstNode + BFDramRngDstNode5, ///< Bit field Dram Range5 DstNode + BFDramRngDstNode6, ///< Bit field Dram Range6 DstNode + BFDramRngDstNode7, ///< Bit field Dram Range7 DstNode + + BFCSBaseAddr0Reg, ///< Bit field CSBaseAddr0Reg + BFCSBaseAddr1Reg, ///< Bit field CSBaseAddr1Reg + BFCSBaseAddr2Reg, ///< Bit field CSBaseAddr2Reg + BFCSBaseAddr3Reg, ///< Bit field CSBaseAddr3Reg + BFCSBaseAddr4Reg, ///< Bit field CSBaseAddr4Reg + BFCSBaseAddr5Reg, ///< Bit field CSBaseAddr5Reg + BFCSBaseAddr6Reg, ///< Bit field CSBaseAddr6Reg + BFCSBaseAddr7Reg, ///< Bit field CSBaseAddr7Reg + + BFCSMask0Reg, ///< Bit field CSMask0Reg + BFCSMask1Reg, ///< Bit field CSMask1Reg + BFCSMask2Reg, ///< Bit field CSMask2Reg + BFCSMask3Reg, ///< Bit field CSMask3Reg + + BFRankDef0, ///< Bit field RankDef 0 + BFRankDef1, ///< Bit field RankDef 1 + BFRankDef2, ///< Bit field RankDef 2 + BFRankDef3, ///< Bit field RankDef 3 + + BFDramControlReg, ///< Bit field DramControlReg + BFDramInitRegReg, ///< Bit field DramInitRegReg + BFDramBankAddrReg, ///< Bit field DramBankAddrReg + BFDramMRSReg, ///< Bit field DramMRSReg + BFDramTimingLoReg, ///< Bit field DramTimingLoReg + BFDramTimingHiReg, ///< Bit field DramTimingHiReg + BFDramConfigLoReg, ///< Bit field DramConfigLoReg + BFDramConfigHiReg, ///< Bit field DramConfigHiReg + BFDctAddlOffsetReg, ///< Bit field DctAddlOffsetReg + BFDctAddlDataReg, ///< Bit field DctAddlDataReg + BFDctAccessDone, ///< Bit field DctAccessDone + BFDctAccessError, ///< Bit field DctAccessError + BFDctExtraOffsetReg, ///< Bit field DctExtraOffsetReg + BFDctExtraDataReg, ///< Bit field DctExtraDataReg + BFDctExtraAccessDone, ///< Bit field DctExtraAccessDone + BFDramConfigMiscReg, ///< Bit field DramConfigMiscReg + BFDramCtrlMiscReg2, ///< Bit field DramCtrlMiscReg2 + BFMctCfgHiReg, ///< Bit field MctCfgHiReg + BFTrcBufAdrPtrHi, ///< Bit field BFTrcBufAdrPtr + BFTrcBufDramLimitHi, ///< Bit field BFTrcBufDramLimit + BFTrcBufDramBaseHi, ///< Bit field BFTrcBufDramBase + BFMctCfgLoReg, ///< Bit field MctCfgLoReg + BFExtMctCfgLoReg, ///< Bit field ExtMctCfgLoReg + BFExtMctCfgHiReg, ///< Bit field ExtMctCfgHiReg + BFDcqBwThrotWm, ///< Bit field DcqBwThrotWm + BFPrefFiveConf, ///< Bit field PrefFiveConf + BFPrefFourConf, ///< Bit field PrefFourConf + BFDcqBwThrotWm1, ///< Bit field DcqBwThrotWm1 + BFDcqBwThrotWm2, ///< Bit field DcqBwThrotWm2 + + BFCSMapCKE, ///< Bit field CSMapCKE + BFTrdrdBan, ///< Bit field TrdrdBan + BFTzqcs, ///< Bit field Tzqcs + BFTzqoper, ///< Bit field Tzqoper + + BFDramHoleBase, ///< Bit field DramHoleBase + BFDramHoleOffset, ///< Bit field DramHoleOffset + BFDramMemHoistValid, ///< Bit field DramMemHoistValid + BFDramHtHoleValid, ///< Bit field BFDramHtHoleValid + BFDramHoleValid, ///< Bit field DramHoleValid + BFDramBaseAddr, ///< Bit field DramBaseAddr + BFDramIntlvSel, ///< Bit field DramIntlvSel + BFDramLimitAddr, ///< Bit field DramLimitAddr + BFDramCtrlBaseReg0, ///< Bit field DramCtrlBaseReg0 + BFLgcyMmioHoleEn0, ///< Bit field LgcyMmioHoleEn0 + BFDramCtrlLimitReg0, ///< Bit field DramCtrlLimitReg0 + BFDramIntlvEn, ///< Bit field DramIntlvEn + BFMemPsSel, ///< Bit field MemPsSel + BFDctCfgSel, ///< Bit field DctCfgSel + BFRcvParErr, ///< Bit field RcvParErr + + BFDctBaseReg0, ///< Bit field DctBaseReg0 + BFDctBaseReg1, ///< Bit field DctBaseReg1 + BFDctBaseReg2, ///< Bit field DctBaseReg2 + BFDctBaseReg3, ///< Bit field DctBaseReg3 + + BFDctLimitReg0, ///< Bit field DctLimitReg0 + BFDctLimitReg1, ///< Bit field DctLimitReg1 + BFDctLimitReg2, ///< Bit field DctLimitReg2 + BFDctLimitReg3, ///< Bit field DctLimitReg3 + + BFDctHighAddressOffsetReg0, ///< Bit field DctHighAddressOffsetReg0 + BFDctHighAddressOffsetReg1, ///< Bit field DctHighAddressOffsetReg1 + BFDctHighAddressOffsetReg2, ///< Bit field DctHighAddressOffsetReg2 + BFDctHighAddressOffsetReg3, ///< Bit field DctHighAddressOffsetReg3 + + BFDctTriChannelInterleaveReg0, ///< Bit field DctTriChannelInterleaveReg0 + BFDctTriChannelInterleaveReg1, ///< Bit field DctTriChannelInterleaveReg1 + BFDctTriChannelInterleaveReg2, ///< Bit field DctTriChannelInterleaveReg2 + BFDctTriChannelInterleaveReg3, ///< Bit field DctTriChannelInterleaveReg3 + BFDctTriChannelInterleaveReg4, ///< Bit field DctTriChannelInterleaveReg4 + BFDctTriChannelInterleaveReg5, ///< Bit field DctTriChannelInterleaveReg5 + BFDctTriChannelInterleaveReg6, ///< Bit field DctTriChannelInterleaveReg6 + BFDctTriChannelInterleaveReg7, ///< Bit field DctTriChannelInterleaveReg7 + + BF3DStackHeight0, ///< Bit field 3DStackHeight0 + BF3DStackHeight1, ///< Bit field 3DStackHeight1 + BF3DStackHeight2, ///< Bit field 3DStackHeight2 + BF3DStackHeight3, ///< Bit field 3DStackHeight3 + + BFIdleCycLowLimit, ///< Bit field IdleCycLowLimit + BFIdleCycLimit, ///< Bit field IdleCycLimit + BFPendRefPayback, ///< Bit field PendRefPayback + BFProcOdtDis, ///< Bit field ProcOdtDis + + + + BFMcaNbCtlReg, ///< Bit field McaNbCtlReg + BFDramEccEn, ///< Bit field DramEccEn + BFSyncOnUcEccEn, ///< Bit field SyncOnUcEccEn + BFEccSymbolSize, ///< Bit field EccSymbolSize + BFMcaNbStatusLoReg, ///< Bit field McaNbStatusLoReg + BFMcaNbStatusHiReg, ///< Bit field McaNbStatusHiReg + BFDramScrub, ///< Bit field DramScrub + BFL2Scrub, ///< Bit field L2Scrub + BFDcacheScrub, ///< Bit field DcacheScrub + BFL3Scrub, ///< Bit field L3Scrub + BFScrubReDirEn, ///< Bit field ScrubReDirEn + BFScrubAddrLoReg, ///< Bit field ScrubAddrLoReg + BFScrubAddrHiReg, ///< Bit field ScrubAddrHiReg + BFDisDramScrub, ///< Bit field DisDramScrub + BFC1ClkDivisor, ///< Bit field C1ClkDivisor + BFDisDatMsk, ///< Bit field DisDatMsk + BFNbFid, ///< Bit field NbFid + BFMTC1eEn, ///< Bit field MTC1eEn + BFL3Capable, ///< Bit field L3Capable + BFDisableL3, ///< Bit field DisableL3 + BFEnhMemProtCap, ///< Bit field EnhMemProtCap + BFNbPsForceReq, ///< Bit field NbPsForceReq + BFNbPsCtrlDis, ///< Bit field NbPsCtrlDis + BFNbPsCap, ///< Bit field NbPsCap + + BFNonSPDHi, ///< Bit field NonSPDHi + BFRdPtrInit, ///< Bit field RdPtrInit + BFAltVidC3MemClkTriEn, ///< Bit field AltVidC3MemClkTriEn + BFDqsRcvEnTrain, ///< Bit field DqsRcvEnTrain + BFEarlyArbEn, ///< Bit field EarlyArbEn + BFMaxLatency, ///< Bit field either MaxRdLat or MaxAsyncLat + + BFMrsAddress, ///< Bit field MrsAddress + BFMrsBank, ///< Bit field MrsBank + BFMrsChipSel, ///< Bit field MrsChipSel + BFSendPchgAll, ///< Bit field SendPchgAll + BFSendAutoRefresh, ///< Bit field SendAutoRefresh + BFSendMrsCmd, ///< Bit field SendMrsCmd + BFDeassertMemRstX, ///< Bit field DeassertMemRstX + BFAssertCke, ///< Bit field AssertCke + BFSendZQCmd, ///< Bit field SendZQCmd + BFSendCtrlWord, ///< Bit field SendCtrlWord + BFEnDramInit, ///< Bit field EnDramInit + BFMrsLevel, ///< Bit field MrsLevel + BFMrsQoff, ///< Bit field MrsQoff + BFMrsAddressHi, ///< Bit field MrsAddress [17:13] + + BFBurstCtrl, ///< Bit field BurstCtrl + BFDrvImpCtrl, ///< Bit field DrvImpCtrl + BFDramTerm_DDR3, ///< Bit field DramTerm_DDR3 + BFDramTermDyn, ///< Bit field DramTermDyn + BFQoff, ///< Bit field Qoff + BFASR, ///< Bit field ASR + BFSRT, ///< Bit field SRT + BFTcwl, ///< Bit field Tcwl + BFPchgPDModeSel, ///< Bit field PchgPDModeSel + BFLowPowerDefault, ///< Bit field LowPowerDefault + + BFTwrDDR3, ///< Bit field TwrDDR3 + BFTcl, ///< Bit field Tcl + BFTrcd, ///< Bit field Trcd + BFTrp, ///< Bit field Trp + BFTrtp, ///< Bit field Trtp + BFTras, ///< Bit field Tras + BFTrc, ///< Bit field Trc + BFTwr, ///< Bit field Twr + BFTrrd, ///< Bit field Trrd + BFMemClkDis, ///< Bit field MemClkDis + BFDramTiming0, ///< Bit field BFDramTiming0 + BFDramTiming1, ///< Bit field BFDramTiming1 + BFDramTiming2, ///< Bit field BFDramTiming2 + BFDramTiming3, ///< Bit field BFDramTiming3 + BFDramTiming4, ///< Bit field BFDramTiming4 + BFDramTiming5, ///< Bit field BFDramTiming5 + BFDramTiming6, ///< Bit field BFDramTiming6 + BFDramTiming10, ///< Bit field BFDramTiming10 + BFDramNBP0, ///< Bit field BFDramNBP0 + + BFNonSPD, ///< Bit field NonSPD + BFTrwtWB, ///< Bit field TrwtWB + BFTrwtTO, ///< Bit field TrwtTO + BFTwtr, ///< Bit field Twtr + BFTwrrd, ///< Bit field Twrrd + BFTwrrdHi, ///< Bit field TwrrdHi + BFTwrwr, ///< Bit field Twrwr + BFTwrwrHi, ///< Bit field TwrwrHi + BFTrdrdSD, ///< Bit field TrdrdSD + BFTwrwrSD, ///< Bit field TwrwrSD + BFTwrrdSD, ///< Bit field TwrrdSD + BFTmod, ///< Bit field Tmod + BFTmrd, ///< Bit field Tmrd + BFRdOdtTrnOnDly, ///< Bit field RdOdtTrnOnDly + BFRdOdtOnDuration, ///< Bit field RdOdtOnDuration + BFWrOdtTrnOnDly, ///< Bit field WrOdtTrnOnDly + BFWrOdtOnDuration, ///< Bit field WrOdtOnDuration + BFPrtlChPDDynDly, ///< Bit field PrtlChPDDynDly + + BFAggrPDDelay, ///< Bit field AggrPDDelay + BFPchgPDEnDelay, ///< Bit field PchgPDEnDelay + + BFTrdrd, ///< Bit field Trdrd + BFTrdrdHi, ///< Bit field TrdrdHi + BFTref, ///< Bit field Tref + BFDisAutoRefresh, ///< Bit field DisAutoRefresh + BFTrfc0, ///< Bit field Trfc0 + BFTrfc1, ///< Bit field Trfc1 + BFTrfc2, ///< Bit field Trfc2 + BFTrfc3, ///< Bit field Trfc3 + + BFInitDram, ///< Bit field InitDram + BFExitSelfRef, ///< Bit field ExitSelfRef + BFDramTerm, ///< Bit field DramTerm + BFParEn, ///< Bit field ParEn + BFBurstLength32, ///< Bit field BurstLength32 + BFWidth128, ///< Bit field Width128 + BFX4Dimm, ///< Bit field X4Dimm + BFDimmEccEn, ///< Bit field DimmEccEn + BFUnBuffDimm, ///< Bit field UnBuffDimm + BFEnterSelfRef, ///< Bit field EnterSelfRef + BFDynPageCloseEn, ///< Bit field DynPageCloseEn + BFIdleCycInit, ///< Bit field IdleCycInit + BFFreqChgInProg, ///< Bit field FreqChgInProg + BFForceAutoPchg, ///< Bit field ForceAutoPchg + BFStagRefEn, ///< Bit field StagRefEn + BFPendRefPaybackS3En, ///< Bit field PendRefPaybackS3En + BFEnDispAutoPrecharge, ///< Bit field EnDispAutoPrecharge + BFDisDllShutdownSR, ///< Bit field DisDllShutdownSR + BFDisSscClkGateData, ///< Bit field DisSscClkGateData + BFDisSscClkGateCmdAddr, ///< Bit field DisSscClkGateCmdAddr + BFDisSimulRdWr, ///< Bit field DisSimulRdWr + + BFMemClkFreq, ///< Bit field MemClkFreq + BFMemClkFreqVal, ///< Bit field MemClkFreqVal + BFDdr3Mode, ///< Bit field Ddr3Mode + BFLegacyBiosMode, ///< Bit field LegacyBiosMode + BFZqcsInterval, ///< Bit field ZqcsInterval + BFRDqsEn, ///< Bit field RDqsEn + BFDisDramInterface, ///< Bit field DisDramInterface + BFPowerDownEn, ///< Bit field PowerDownEn + BFPowerDownMode, ///< Bit field PowerDownMode + BFFourRankSoDimm, ///< Bit field FourRankSoDimm + BFDcqArbBypassEn, ///< Bit field DcqArbBypassEn + BFFourRankRDimm, ///< Bit field FourRankRDimm + BFSlowAccessMode, ///< Bit field SlowAccessMode + BFBankSwizzleMode, ///< Bit field BankSwizzleMode + BFDcqBypassMax, ///< Bit field DcqBypassMax + BFFourActWindow, ///< Bit field FourActWindow + BFDphyMemPsSelEn, ///< Bit field BFDphyMemPsSelEn + + BFODTSEn, ///< Bit field ODTSEn + BFCmdThrottleMode, ///< Bit field CmdThrottleMode + BFBwCapEn, ///< Bit field BwCapEn + + BFDdr3FourSocketCh, ///< Bit field Ddr3FourSocketCh + BFSubMemclkRegDly, ///< Bit field SubMemclkRegDly + BFOdtSwizzle, ///< Bit field OdtSwizzle + BFProgOdtEn, ///< Bit field ProgOdtEn + BFCtrlWordCS, ///< Bit field CtrlWordCS + BFRefChCmdMgtDis, ///< Bit field RefChCmdMgtDis + BFFastSelfRefEntryDis, ///< Bit field FastSelfRefEntryDis + BFPrtlChPDEnhEn, ///< Bit field PrtlChPDEnhEn + BFAggrPDEn, ///< Bit field AggrPDEn + BFDataTxFifoWrDly, ///< Bit field DataTxFifoWrDly + BFWrDqDqsEarly, ///< Bit field WrDqDqsEarly + BFCSMux45, ///< Bit field CSMux45 + BFCSMux67, ///< Bit field CSMux67 + BFLrDimmMrsCtrl, ///< Bit field LrDimmMrsCtrl + BFExtendedParityEn, ///< Bit field ExtendedParityEn + BFLrDimmEnhRefEn, ///< Bit field LrDimmEnhRefEn + BFCSTimingMux67, ///< Bit field CSTimingMux67 + BFLrDimmErrOutMonEn, ///< Bit field LrDimmErrOutMonEn + + BFIntLvRgnSwapEn, ///< Bit field IntLvRgnSwapEn + BFIntLvRgnBaseAddr, ///< Bit field IntLvRgnBaseAddr + BFIntLvRgnLmtAddr, ///< Bit field IntLvRgnLmtAddr + BFIntLvRgnSize, ///< Bit field IntLvRgnSize + + BFDctSelHiRngEn, ///< Bit field DctSelHiRngEn + BFDctSelHi, ///< Bit field DctSelHi + BFDctSelIntLvEn, ///< Bit field DctSelIntLvEn + BFMemClrInit, ///< Bit field MemClrInit + BFDctGangEn, ///< Bit field DctGangEn + BFDctDatIntLv, ///< Bit field DctDatIntLv + BFDctSelIntLvAddr, ///< Bit field DctSelIntLvAddr + BFDctSelIntLvAddrHi, ///< Bit field DctSelIntLvAddrHi + BFParallelMemClrEn, ///< Bit field ParallelMemClrEn + BFDramEnabled, ///< Bit field DramEnabled + BFMemClrBusy, ///< Bit field MemClrBusy + BFMemCleared, ///< Bit field MemCleared + BFDctSelBaseAddr, ///< Bit field DctSelBaseAddr + BFDctSelBaseOffset, ///< Bit field DctSelBaseOffset + BFBankSwapAddr8En, ///< Bit field DctSelBankSwap + + BFAdapPrefMissRatio, ///< Bit field AdapPrefMissRatio + BFAdapPrefPosStep, ///< Bit field AdapPrefPosStep + BFAdapPrefNegStep, ///< Bit field AdapPrefNegStep + BFCohPrefPrbLmt, ///< Bit field CohPrefPrbLmt + + BFFlushWrOnS3StpGnt, ///< Bit field FlushWrOnS3StpGnt + + BFPrefDramTrainDone, ///< Bit field PrefDramTrainDone + BFWrDramTrainMode, ///< Bit field WrDramTrainMode + BFMctPrefReqLimit, ///< Bit field MctPrefReqLimit + BFPrefDramTrainMode, ///< Bit field PrefDramTrainMode + BFDctWrLimit, ///< Bit field DctWrLimit + BFMctWrLimit, ///< Bit field MctWrLimit + BFDramTrainPdbDis, ///< Bit field DramTrainPdbDis + BFTrainLength, ///< Bit field TrainLength + BFRdTrainGo, ///< Bit field RdTrainGo + BFWrTrainGo, ///< Bit field WrTrainGo + BFWrTrainAdrPtrLo, ///< Bit field WrTrainAdrPtrLo + BFWrTrainAdrPtrHi, ///< Bit field WrTrainAdrPtrHi + BFWrTrainBufAddr, ///< Bit field WrTrainBufAddr + BFWrTrainBufDat, ///< Bit field WrTrainBufDat + BFFlushWr, ///< Bit field FlushWr + BFFlushWrOnStpGnt, ///< Bit field FlushWrOnStpGnt + BFPrefCpuDis, ///< Bit field PrefCpuDis + BFPrefIoDis, ///< Bit field PrefIoDis + BFTrainCmpSts, ///< Bit field TrainCmpSts + BFTrainCmpSts2, ///< Bit field TrainCmpSts2 + BFTcbModeEn, ///< Bit field TcbModeEn + BFTraceModeEn, ///< Bit field TraceModeEn + + BFAddrCmdDrvStren, ///< Bit field AddrCmdDrvStren + BFDataDrvStren, ///< Bit field DataDrvStren + BFCkeDrvStren, ///< Bit field CkeDrvStren + BFCsOdtDrvStren, ///< Bit field CsOdtDrvStren + BFClkDrvStren, ///< Bit field ClkDrvStren + BFDqsDrvStren, ///< Bit field DqsDrvStren + BFProcOdt, ///< Bit field ProcOdt + BFODCControl, ///< Bit field ODCControl + BFAddrTmgControl, ///< Bit field AddrTmgControl + BFAddrCmdFineDelay, ///< Bit field AddrCmdFineDelay + + BFWrtLvTrEn, ///< Bit field WrtLvTrEn + BFWrtLvTrMode, ///< Bit field WrtLvTrMode + BFPhyFenceTrEn, ///< Bit field PhyFenceTrEn + BFTrDimmSel, ///< Bit field TrDimmSel + BFTrNibbleSel, ///< Bit field TrNibbleSel + BFFenceTrSel, ///< Bit field FenceTrSel + BFWrLvOdt, ///< Bit field WrLvOdt + BFWrLvOdtEn, ///< Bit field WrLvOdtEn + BFDqsRcvTrEn, ///< Bit field DqsRcvTrEn + BFDisAutoComp, ///< Bit field DisAutoComp + BFWrtLvErr, ///< Bit field WrtLvErr + BFODTAssertionCtl, ///< Bit field ODTAssertionCtl + BFNibbleTrainModeEn, ///< Bit field NibbleTrainModeEn + BFRankTrainModeEn, ///< Bit field RankTrainModeEn + BFPllMult, ///< Bit field PllMult + BFPllDiv, ///< Bit field PllDiv + BFDramPhyCtlReg, ///< Bit field Dram Phy Control Register + + BFDramPhyStatusReg, ///< Bit field DramPhyStatusReg + + BFD3Cmp2PCal, ///< Bit field D3Cmp2PCal + BFD3Cmp2NCal, ///< Bit field D3Cmp2NCal + BFD3Cmp1PCal, ///< Bit field D3Cmp1PCal + BFD3Cmp1NCal, ///< Bit field D3Cmp1NCal + BFD3Cmp0PCal, ///< Bit field D3Cmp0PCal + BFD3Cmp0NCal, ///< Bit field D3Cmp0NCal + + BFPhyFence, ///< Bit field PhyFence + BFODTTri, ///< Bit field ODTTri + BFCKETri, ///< Bit field CKETri + BFChipSelTri, ///< Bit field ChipSelTri + BFPhyRODTCSLow, ///< Bit field PhyRODTCSLow + BFPhyRODTCSHigh, ///< Bit field PhyRODTCSHigh + BFPhyWODTCSLow, ///< Bit field PhyWODTCSLow + BFPhyWODTCSHigh, ///< Bit field PhyWODTCSHigh + BFUSPLLCtlAll, ///< Bit field USPLLCtlAll + BFDSPLLCtlAll, ///< Bit field DSPLLCtlAll + BFUSNibbleAlignEn, ///< Bit field USNibbleAlignEn + BFChnLinitClkEn, ///< Bit field ChnLinitClkEn + + BFTSLinkSelect, ///< Bit field TSLinkSelect + BFTS2BitLockEn, ///< Bit field TS2BitLockEn + BFTS2En, ///< Bit field TS2En + BFTS1En, ///< Bit field TS1En + BFTS0LinkStarEn, ///< Bit field TS0LinkStarEn + BFTS0En, ///< Bit field TS0En + + BFLinkTrainData, ///< Bit field LinkTrainData + + BFRstRxFifoPtrs, ///< Bit field RstRxFifoPtrs + BFRxFifoPtrInit, ///< Bit field RxFifoPtrInit + BFRstTxFifoPtrs, ///< Bit field RstTxFifoPtrs + BFTxFifoPtrInit, ///< Bit field TxFifoPtrInit + + BFLpbkCount, ///< Bit field LpbkCount + BFLpbkMap, ///< Bit field LpbkMap + BFSendLpbkMaintCmd, ///< Bit field SendLpbkMaintCmd + BFLpbkData, ///< Bit field LpbkData + + BFMbRdPtrEn, ///< Bit field MbRdPtrEn + BFLnkLpBkLat, ///< Bit field LnkLpBkLat + BFLpbkRndTripLatDone, ///< Bit field LpbkRndTripLatDone + BFLnkLatTrainEn, ///< Bit field LnkLatTrainEn + + BFDsPhyReset, ///< Bit field DsPhyReset + BFLinkReset, ///< Bit field LinkReset + + BFPllLockTime, ///< Bit field PllLockTime + BFPllRegWaitTime, ///< Bit field PllRegWaitTime + BFNclkFreqDone, ///< Bit field NclkFreqDone + BFNbPs0NclkDiv, ///< Bit field NbPs0NclkDiv + BFNbPs1NclkDiv, ///< Bit field NbPs1NclkDiv + BFNbPsCsrAccSel, ///< Bit field NbPsCsrAccSel + BFNbPsDbgEn, ///< Bit field NbPsDbgEn + BFNclkRampWithDllRelock, ///< Bit field NclkRampWithDllRelock + + BFOnLineSpareControl, ///< Bit field OnLineSpareControl + BFDdrMaxRate, ///< Bit field DdrMaxRate + + BFPhyDctCfgSelMode, ///< Bit field PhyDctCfgSelMode + BFNbPstateDis, ///< Bit field NbPstateDis + BFNbPsSel, ///< Bit field NbPsSel + BFNbPstateCtlReg, ///< Bit field NB Pstate Control register + BFSwNbPstateLoDis, ///< Bit field SwNbPstateLoDis + BFNbPstateLo, ///< Bit field NbPstateLo + BFNbPstateHi, ///< Bit field NbPstateHi + BFNbPstateMaxVal, ///< Bit field NbPstateMaxVal + BFCurNbPstate, ///< Bit field NbCurNbPstate + + BFC6Base, ///< Bit field C6Base + BFC6DramLock, ///< Bit field C6DramLock + BFCC6SaveEn, ///< Bit field CC6SaveEn + BFCoreStateSaveDestNode, ///< Bit field CoreStateSaveDestNode + + BFRxPtrInitReq, ///< Bit field RxPtrInitReq + BFAddrCmdTriEn, ///< Bit field AddrCmdTriEn + BFForceCasToSlot0, ///< Bit field ForceCasToSlot0 + BFDisCutThroughMode, ///< Bit field DisCutThroughMode + BFDbeSkidBufDis, ///< Bit field DbeSkidBufDis + BFDbeGskMemClkAlignMode, ///< Bit field DbeGskMemClkAlignMode + BFEnCpuSerRdBehindNpIoWr, ///< Bit field EnCpuSerRdBehindNpIoWr + BFDRAMPhyDLLControl, ///< Bit field DRAMPhyDLLControl + BFRxDLLWakeupTime, ///< Bit field RxDllWakeupTime + BFRxCPUpdPeriod, ///< Bit field RxCPUpdPeriod + BFRxMaxDurDllNoLock, ///< Bit field RxMaxDurDllNoLock + BFTxDLLWakeupTime, ///< Bit field TxDllWakeupTime + BFTxCPUpdPeriod, ///< Bit field TxCPUpdPeriod + BFTxMaxDurDllNoLock, ///< Bit field TxMaxDurDllNoLock + BFEnRxPadStandby, ///< Bit field EnRxPadStandby + BFMaxSkipErrTrain, ///< Bit field MaxSkipErrTrain + BFSlotSel, ///< Bit field SlotSel + BFSlot1ExtraClkEn, ///< Bit field Slot1ExtraClkEn + BFPtrInitReq, ///< Bit field PtrInitReq + BFDccPgSsBusDis, ///< Bit field DccPgSsBusDis + BFGsyncDis, ///< Bit field GsyncDis + BFChanVal, ///< Bit field ChanVal + BFDctCfgBcEn, ///< Bit field DctCfgBcEn + + BFMemTempHot, ///< Bit field MemTempHot + BFDoubleTrefRateEn, ///< Bit field DoubleTrefRateEn + + BFAcpiPwrStsCtrlHi, ///< Bit field BFAcpiPwrStsCtrlHi + BFDramSrHysEn, ///< Bit field BFDramSrHysEn + BFDramSrHys, ///< Bit field BFDramSrHys + BFMemTriStateEn, ///< Bit field BFMemTriStateEn + BFDramSrEn, ///< Bit field BFDramSrEn + + BFDeassertCke, ///< Bit field BFDeassertCke + BFFourRankRDimm0, ///< Bit field BFFourRankRDimm0 + BFFourRankRDimm1, ///< Bit field BFFourRankRDimm1 + BFTwrwrSdSc, ///< Bit field BFTwrwrSdSc + BFTwrwrSdDc, ///< Bit field BFTwrwrSdDc + BFTwrwrDd, ///< Bit field BFTwrwrDd + BFTrdrdSdSc, ///< Bit field BFTrdrdSdSc + BFTrdrdSdDc, ///< Bit field BFTrdrdSdDc + BFTrdrdDd, ///< Bit field BFTrdrdDd + BFTstag0, ///< Bit field BFTstag0 + BFTstag1, ///< Bit field BFTstag1 + BFTstag2, ///< Bit field BFTstag2 + BFTstag3, ///< Bit field BFTstag3 + + BFDataPatGenSel, ///< Bit field DataPatGenSel + BFActPchgGenEn, ///< Bit field ActPchgGenEn + BFShmooRdDqsDly, ///< Bit field ShmooRdDqsDly + + BFReverseLoopbackEn, ///< Bit field BFReverseLoopbackEn + BFCmdSendInProg, ///< Bit field CmdSendInProg + BFSendCmd, ///< Bit field SendCmd + BFTestStatus, ///< Bit field TestStatus + BFCmdTgt, ///< Bit field CmdTgt + BFCmdType, ///< Bit field CmdType + BFStopOnErr, ///< Bit field StopOnErr + BFResetAllErr, ///< Bit field ResetAllErr + BFCmdTestEnable, ///< Bit field CmdTestEnable + BFTgtChipSelectA, ///< Bit field TgtChipSelectA + BFTgtBankA, ///< Bit field TgtBankA + BFTgtAddressHiA, ///< Bit field TgtAddressHiA + BFTgtAddressA, ///< Bit field TgtAddressA + BFTgtChipSelectB, ///< Bit field TgtChipSelectB + BFTgtBankB, ///< Bit field TgtBankB + BFTgtAddressHiB, ///< Bit field TgtAddressHiB + BFTgtAddressB, ///< Bit field TgtAddressB + BFBubbleCnt2, ///< Bit field BubbleCnt2 + BFBubbleCnt, ///< Bit field BubbleCnt + BFCmdStreamLen, ///< Bit field CmdStreamLen + BFCmdCount, ///< Bit field CmdCount + BFErrDqNum, ///< Bit field ErrDQNum + BFErrCnt, ///< Bit field ErrCnt + BFNibbleErrSts, ///< Bit field NibbleErrSts + BFNibbleErr180Sts, ///< Bit field NibbleErr180Sts + BFDataPrbsSeed, ///< Bit field DataPrbsSeed + BFDramDqMaskLow, ///< Bit field DramDqMaskLow + BFDramDqMaskHigh, ///< Bit field DramDqMaskHigh + BFDramEccMask, ///< Bit field DramEccMask + BFDQPatOvrEn0, ///< Bit field DQPatOvrEn0 + BFDQPatOvrEn1, ///< Bit field DQPatOvrEn1 + BFXorPatOvr, ///< Bit field XorPatOvr + BFPatOvrVal, ///< Bit field PatOvrVal + BFEccPatOvrEn, ///< Bit field EccPatOvrEn + BFSendActCmd, ///< Bit field SendActCmd + BFSendPchgCmd, ///< Bit field SendPchgCmd + BFCmdChipSelect, ///< Bit field CmdChipSelect + BFCmdBank, ///< Bit field CmdBank + BFCmdAddress, ///< Bit field CmdAddress + BFErrBeatNum, ///< Bit Field ErrBeatNum + BFErrCmdNum, ///< Bit field BFErrCmdNum + BFDQErrLow, ///< Bit field DQSErrLow + BFDQErrHigh, ///< Bit field DQSErrHigh + BFEccErr, ///< Bit field EccErr + BFFastMstateDis, ///< Bit field FastMstateDis + BFDramUserDataPattern0, ///< Bit field DramUserDataPattern0 + BFDramUserDataPattern1, ///< Bit field DramUserDataPattern1 + BFDramUserDataPattern2, ///< Bit field DramUserDataPattern2 + BFDramUserDataPattern3, ///< Bit field DramUserDataPattern3 + BFActPchgSeq, ///< Bit field ActPchgSeq + BFActPchgCmdMin, ///< Bit field ActPchgCmdMin + BFDramCommandReg4, ///< Bit field DramCommandReg4 + BFDramCommandReg5, ///< Bit field DramCommandReg5 + BFNibbleErrStsSel, ///< Bit field NibbleErrStsSel + BFErrStsDly, ///< Bit field ErrStsDly + BFErrStsDly180, ///< Bit field ErrStsDly180 + + /* Bit fields for workarounds */ + BFErr263, ///< Bit field Err263 + BFErr350, ///< Bit field Err350 + BFErr322I, ///< Bit field Err322I + BFErr322II, ///< Bit field Err322II + BFErratum468WorkaroundNotRequired, ///< Bit field Erratum468WorkaroundNotRequired + + /* Bit fields for Phy */ + BFEccDLLConf, ///< Bit field EccDLLConf + BFProcOdtAdv, ///< Bit field ProcOdtAdv + BFEccDLLPwrDnConf, ///< Bit field EccDLLPwrDnConf + BFDataCtlPipePclkGateEn, ///< Bit field DataCtlPipePclkGateEn + BFPchgPdPclkGateEn, ///< Bit field PchgPdPclkGateEn + BFTxPclkGateEn, ///< Bit field TxPclkGateEn + BFPhyPLLLockTime, ///< Bit field PhyPLLLockTime + BFPhyDLLLockTime, ///< Bit field PhyDLLLockTime + BFSkewMemClk, ///< Bit field SkewMemClk + BFPhyDLLControl, ///< Bit field BFPhyDLLControl + BFPhy0x0D080F0C, ///< Bit field BFPhy0x0D080F0C + BFPhy0x0D080F10, ///< Bit field BFPhy0x0D080F10 + BFPhy0x0D080F11, ///< Bit field BFPhy0x0D080F11 + BFPhy0x0D088F30, ///< Bit field BFPhy0x0D088F30 + BFPhy0x0D08C030, ///< Bit field BFPhy0x0D08C030 + BFPhy0x0D082F30, ///< Bit field BFPhy0x0D082F30 + BFDiffTimingEn, ///< Bit Field DiffTimingEn + BFFence, ///< Bit Field Fence + BFDelay, ///< Bit Field Delay + BFFenceValue, ///< Bit Field FenceValue + + BFTxP, ///< Bit Field TxP + BFTxN, ///< Bit Field TxN + BFPhy0x0D0F0F0B, ///< Bit Field BFPhy0x0D0F0F0B + BFPhy0x0D0F0F07, ///< Bit Field BFPhy0x0D0F0F07 + BFPhy0x0D0F0F03, ///< Bit Field BFPhy0x0D0F0F03 + + BFPhy0x0D040F3E, ///< Bit field BFPhy0x0D040F3E + BFPhy0x0D042F3E, ///< Bit field BFPhy0x0D042F3E + BFPhy0x0D048F3E, ///< Bit field BFPhy0x0D048F3E + BFPhy0x0D04DF3E, ///< Bit field BFPhy0x0D04DF3E + + BFPhyClkDllFine0, ///< Bit field ClkDllFineDly 0 + BFPhyClkDllFine1, ///< Bit field ClkDllFineDly 1 + + BFPhyClkConfig0, ///< Bit field ClkConfig0 + BFPhyClkConfig1, ///< Bit field ClkConfig1 + BFPhyClkConfig2, ///< Bit field ClkConfig2 + BFPhyClkConfig3, ///< Bit field ClkConfig3 + + BFPhy0x0D0F0F13, ///< Bit field BFPhy0x0D0F0F13 + BFPhy0x0D0F0F13Bit0to7, ///< Bit field BFPhy0x0D0F0F13Bit0to7 + BFPhy0x0D0F0830, ///< Bit field BFPhy0x0D0F0830 + BFPhy0x0D07812F, ///< Bit field BFPhy0x0D0F8108 + + BFDataRxVioLvl, ///< Bit field DataRxVioLvl + BFClkRxVioLvl, ///< Bit field ClkRxVioLvl + BFCmdRxVioLvl, ///< Bit field CmdRxVioLvl + BFAddrRxVioLvl, ///< Bit field AddrRxVioLvl + BFCmpVioLvl, ///< Bit field CmpVioLvl + BFCsrComparator, ///< Bit field CsrComparator + BFAlwaysEnDllClks, ///< Bit field AlwaysEnDllClks + BFPhy0x0D0FE00A, ///< Bit field Phy0x0D0FE00A + BFPllPdMode, ///< Bit fields SelCsrPllPdMode and CsrPhySrPllPdMode + + BFDataFence2, ///< Bit field DataFence2 + BFClkFence2, ///< Bit field ClkFence2 + BFCmdFence2, ///< Bit field CmdFence2 + BFAddrFence2, ///< Bit field AddrFence2 + + BFDataByteDMConf, ///< Bit field DataByteDMConf + + BFAddrCmdTri, ///< Bit field BFAddrCmdTri + BFLowPowerDrvStrengthEn, ///< Bit field BFLowPowerDrvStrengthEn + BFLevel, ///< Bit field Level + + BFDbeGskFifoNumerator, ///< Bit field DbeGskFifoNumerator + BFDbeGskFifoDenominator, ///< Bit field DbeGskFifoDenominator + BFDataTxFifoSchedDlyNegSlot0, ///< Bit field DataTxFifoSchedDlyNegSlot0 + BFDataTxFifoSchedDlyNegSlot1, ///< Bit field DataTxFifoSchedDlyNegSlot1 + BFDataTxFifoSchedDlySlot0, ///< Bit field DataTxFifoSchedDlySlot0 + BFDataTxFifoSchedDlySlot1, ///< Bit field DataTxFifoSchedDlySlot1 + + BFDisablePredriverCal, ///< Bit field DisablePredriverCal + BFDataByteTxPreDriverCal, ///< Bit field DataByteTxPreDriverCal + BFPOdtOff, ///< Bit field POdtOff + BFDataByteTxPreDriverCal2Pad1, ///< Bit field DataByteTxPreDriverCal2Pad1 + BFDataByteTxPreDriverCal2Pad2, ///< Bit field DataByteTxPreDriverCal2Pad2 + BFCmdAddr0TxPreDriverCal2Pad1, ///< Bit field CmdAddr0TxPreDriverCal2Pad1 + BFCmdAddr0TxPreDriverCal2Pad2, ///< Bit field CmdAddr0TxPreDriverCal2Pad2 + BFCmdAddr1TxPreDriverCal2Pad1, ///< Bit field CmdAddr1TxPreDriverCal2Pad1 + BFCmdAddr1TxPreDriverCal2Pad2, ///< Bit field CmdAddr1TxPreDriverCal2Pad2 + BFAddrTxPreDriverCal2Pad1, ///< Bit field AddrTxPreDriverCal2Pad1 + BFAddrTxPreDriverCal2Pad2, ///< Bit field AddrTxPreDriverCal2Pad2 + BFAddrTxPreDriverCal2Pad3, ///< Bit field AddrTxPreDriverCal2Pad3 + BFAddrTxPreDriverCal2Pad4, ///< Bit field AddrTxPreDriverCal2Pad4 + BFCmdAddr0TxPreDriverCalPad0, ///< Bit field CmdAddr0TxPreDriverCalPad0 + BFCmdAddr1TxPreDriverCalPad0, ///< Bit field CmdAddr1TxPreDriverCalPad0 + BFAddrTxPreDriverCalPad0, ///< Bit field AddrTxPreDriverCalPad0 + BFClock0TxPreDriverCalPad0, ///< Bit field Clock0TxPreDriverCalPad0 + BFClock1TxPreDriverCalPad0, ///< Bit field Clock1TxPreDriverCalPad0 + BFClock2TxPreDriverCalPad0, ///< Bit field Clock2TxPreDriverCalPad0 + BFPNOdtCal, ///< Bit field P/NOdtCal + BFPNDrvCal, ///< Bit field P/NDrvCal + BFCalVal, ///< Bit field CalVal + BFPStateToAccess, ///< Bit field PStateToAccess + + BFTxp, ///< Bit field Txp + BFTxpdll, ///< Bit field Txpdll + BFDramPwrMngm1Reg, ///< Bit field DRAM Power Management 1 register + BFL3ScrbRedirDis, ///< Bit field L3ScrbRedirDis + BFDQOdt03, ///< Bit field DQ Odt 0-3 + BFDQOdt47, ///< Bit field DQ Odt 4-7 + BFTriDM, ///< Bit field TriDM + + BFTcksrx, ///< Bit field Tcksrx + BFTcksre, ///< Bit field Tcksre + BFTckesr, ///< Bit field Tckesr + BFTpd, ///< Bit field Tpd + + BFFixedErrataSkipPorFreqCap, ///< Bit field FixedErrataSkipPorFreqCap + BFPerRankTimingEn, ///< Bit field PerRankTimingEn + BFMemPhyPllPdMode, ///< Bit field MemPhyPllPdMode + BFBankSwap, ///< Bit field BankSwap + BFBwCapCmdThrottleMode, ///< Bit field BwCapCmdThrottleMode + BFRxChMntClkEn, ///< Bit field RxChMntClkEn + BFBlockRxDqsLock, ///< Bit field BlockRxDqsLock + BFRxSsbMntClkEn, ///< Bit field RxSsbMntClkEn + BFPhyPSMasterChannel, ///< Bit field PhyPSMasterChannel + + BFObsrvVrefSel, ///< Bit field BFObsrvVrefSel + BFVrefSel, ///< Bit field VrefSel + BFVrefDAC, ///< Bit field VrefDAC + BFDataByteRxDqsDLLDimm0Lane0, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 0 + BFDataByteRxDqsDLLDimm0Lane1, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 1 + BFDataByteRxDqsDLLDimm0Lane2, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 2 + BFDataByteRxDqsDLLDimm0Lane3, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 3 + BFDataByteRxDqsDLLDimm0Lane4, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 4 + BFDataByteRxDqsDLLDimm0Lane5, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 5 + BFDataByteRxDqsDLLDimm0Lane6, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 6 + BFDataByteRxDqsDLLDimm0Lane7, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 7 + BFDataByteRxDqsDLLDimm0Lane8, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 8 + BFDataByteRxDqsDLLDimm0Lane9, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 9 + BFDataByteRxDqsDLLDimm0LaneA, ///< Bit field DataByteRxDqsDLL DIMM0 Lane A + BFDataByteRxDqsDLLDimm0LaneB, ///< Bit field DataByteRxDqsDLL DIMM0 Lane B + BFDataByteRxDqsDLLDimm0LaneC, ///< Bit field DataByteRxDqsDLL DIMM0 Lane C + BFDataByteRxDqsDLLDimm0LaneD, ///< Bit field DataByteRxDqsDLL DIMM0 Lane D + BFDataByteRxDqsDLLDimm0LaneE, ///< Bit field DataByteRxDqsDLL DIMM0 Lane E + BFDataByteRxDqsDLLDimm0LaneF, ///< Bit field DataByteRxDqsDLL DIMM0 Lane F + BFDataByteRxDqsDLLDimm0Lane10, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 10 + BFDataByteRxDqsDLLDimm0Lane11, ///< Bit field DataByteRxDqsDLL DIMM0 Lane 11 + BFDataByteRxDqsDLLDimm0Broadcast, ///< Bit field DataByteRxDqsDLL DIMM0 Broadcast + BFDataByteRxDqsDLLDimm1Lane0, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 0 + BFDataByteRxDqsDLLDimm1Lane1, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 1 + BFDataByteRxDqsDLLDimm1Lane2, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 2 + BFDataByteRxDqsDLLDimm1Lane3, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 3 + BFDataByteRxDqsDLLDimm1Lane4, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 4 + BFDataByteRxDqsDLLDimm1Lane5, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 5 + BFDataByteRxDqsDLLDimm1Lane6, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 6 + BFDataByteRxDqsDLLDimm1Lane7, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 7 + BFDataByteRxDqsDLLDimm1Lane8, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 8 + BFDataByteRxDqsDLLDimm1Lane9, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 9 + BFDataByteRxDqsDLLDimm1LaneA, ///< Bit field DataByteRxDqsDLL DIMM1 Lane A + BFDataByteRxDqsDLLDimm1LaneB, ///< Bit field DataByteRxDqsDLL DIMM1 Lane B + BFDataByteRxDqsDLLDimm1LaneC, ///< Bit field DataByteRxDqsDLL DIMM1 Lane C + BFDataByteRxDqsDLLDimm1LaneD, ///< Bit field DataByteRxDqsDLL DIMM1 Lane D + BFDataByteRxDqsDLLDimm1LaneE, ///< Bit field DataByteRxDqsDLL DIMM1 Lane E + BFDataByteRxDqsDLLDimm1LaneF, ///< Bit field DataByteRxDqsDLL DIMM1 Lane F + BFDataByteRxDqsDLLDimm1Lane10, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 10 + BFDataByteRxDqsDLLDimm1Lane11, ///< Bit field DataByteRxDqsDLL DIMM1 Lane 11 + BFDataByteRxDqsDLLDimm1Broadcast, ///< Bit field DataByteRxDqsDLL DIMM1 Broadcast + BFDataByteRxDqsDLLDimm2Lane0, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 0 + BFDataByteRxDqsDLLDimm2Lane1, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 1 + BFDataByteRxDqsDLLDimm2Lane2, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 2 + BFDataByteRxDqsDLLDimm2Lane3, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 3 + BFDataByteRxDqsDLLDimm2Lane4, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 4 + BFDataByteRxDqsDLLDimm2Lane5, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 5 + BFDataByteRxDqsDLLDimm2Lane6, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 6 + BFDataByteRxDqsDLLDimm2Lane7, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 7 + BFDataByteRxDqsDLLDimm2Lane8, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 8 + BFDataByteRxDqsDLLDimm2Lane9, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 9 + BFDataByteRxDqsDLLDimm2LaneA, ///< Bit field DataByteRxDqsDLL DIMM2 Lane A + BFDataByteRxDqsDLLDimm2LaneB, ///< Bit field DataByteRxDqsDLL DIMM2 Lane B + BFDataByteRxDqsDLLDimm2LaneC, ///< Bit field DataByteRxDqsDLL DIMM2 Lane C + BFDataByteRxDqsDLLDimm2LaneD, ///< Bit field DataByteRxDqsDLL DIMM2 Lane D + BFDataByteRxDqsDLLDimm2LaneE, ///< Bit field DataByteRxDqsDLL DIMM2 Lane E + BFDataByteRxDqsDLLDimm2LaneF, ///< Bit field DataByteRxDqsDLL DIMM2 Lane F + BFDataByteRxDqsDLLDimm2Lane10, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 10 + BFDataByteRxDqsDLLDimm2Lane11, ///< Bit field DataByteRxDqsDLL DIMM2 Lane 11 + BFDataByteRxDqsDLLDimm2Broadcast, ///< Bit field DataByteRxDqsDLL DIMM2 Broadcast + BFDataByteRxDqsDLLDimm3Lane0, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 0 + BFDataByteRxDqsDLLDimm3Lane1, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 1 + BFDataByteRxDqsDLLDimm3Lane2, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 2 + BFDataByteRxDqsDLLDimm3Lane3, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 3 + BFDataByteRxDqsDLLDimm3Lane4, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 4 + BFDataByteRxDqsDLLDimm3Lane5, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 5 + BFDataByteRxDqsDLLDimm3Lane6, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 6 + BFDataByteRxDqsDLLDimm3Lane7, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 7 + BFDataByteRxDqsDLLDimm3Lane8, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 8 + BFDataByteRxDqsDLLDimm3Lane9, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 9 + BFDataByteRxDqsDLLDimm3LaneA, ///< Bit field DataByteRxDqsDLL DIMM3 Lane A + BFDataByteRxDqsDLLDimm3LaneB, ///< Bit field DataByteRxDqsDLL DIMM3 Lane B + BFDataByteRxDqsDLLDimm3LaneC, ///< Bit field DataByteRxDqsDLL DIMM3 Lane C + BFDataByteRxDqsDLLDimm3LaneD, ///< Bit field DataByteRxDqsDLL DIMM3 Lane D + BFDataByteRxDqsDLLDimm3LaneE, ///< Bit field DataByteRxDqsDLL DIMM3 Lane E + BFDataByteRxDqsDLLDimm3LaneF, ///< Bit field DataByteRxDqsDLL DIMM3 Lane F + BFDataByteRxDqsDLLDimm3Lane10, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 10 + BFDataByteRxDqsDLLDimm3Lane11, ///< Bit field DataByteRxDqsDLL DIMM3 Lane 11 + BFDataByteRxDqsDLLDimm3Broadcast, ///< Bit field DataByteRxDqsDLL DIMM3 Broadcast + BFDataByteDllPowerMgnByte0, ///< Bit field DataByteDllPowerManagement for Byte 0 + BFDataByteDllPowerMgnByte1, ///< Bit field DataByteDllPowerManagement for Byte 1 + BFDataByteDllPowerMgnByte2, ///< Bit field DataByteDllPowerManagement for Byte 2 + BFDataByteDllPowerMgnByte3, ///< Bit field DataByteDllPowerManagement for Byte 3 + BFDataByteDllPowerMgnByte4, ///< Bit field DataByteDllPowerManagement for Byte 4 + BFDataByteDllPowerMgnByte5, ///< Bit field DataByteDllPowerManagement for Byte 5 + BFDataByteDllPowerMgnByte6, ///< Bit field DataByteDllPowerManagement for Byte 6 + BFDataByteDllPowerMgnByte7, ///< Bit field DataByteDllPowerManagement for Byte 7 + BFDataByteDllPowerMgnByte8, ///< Bit field DataByteDllPowerManagement for Byte ECC + BFDataByteDllPowerMgnByteAll, ///< Bit field DataByteDllPowerManagement for all bytes + BFIoSkewMode, ///< Bit field for IoSkewMode + BFLfsrRollOver, ///< Bit field for LfsrRollOver + BFM1MemClkFreq, ///< Bit field M1MemClkFreq + BFRate, ///< Bit field Rate + BFFence2, ///< Bit field Fence2 + BFReducedLoop, ///< Bit field ReducedLoop + + BFNbVid0, ///< Bit field NbVid for NB Pstate 0 + BFNbVid0Hi, ///< Bit field 7th bit of NbVid for NB Pstate 0 + BFNbVid1, ///< Bit field NbVid for NB Pstate 1 + BFNbVid1Hi, ///< Bit field 7th bit of NbVid for NB Pstate 1 + BFNbVid2, ///< Bit field NbVid for NB Pstate 2 + BFNbVid2Hi, ///< Bit field 7th bit of NbVid for NB Pstate 2 + BFNbVid3, ///< Bit field NbVid for NB Pstate 3 + BFNbVid3Hi, ///< Bit field 7th bit of NbVid for NB Pstate 3 + + BFMemPstate0, ///< Bit field MemPstate for NB Pstate 0 + BFMemPstate1, ///< Bit field MemPstate for NB Pstate 1 + BFMemPstate2, ///< Bit field MemPstate for NB Pstate 2 + BFMemPstate3, ///< Bit field MemPstate for NB Pstate 3 + BFMemPstateDis, ///< Bit field MemPstateDis + BFMultiNodeCpu, ///< Bit field for MultiNodeCpu( MCM capability) + + BFRxBypass3rd4thStg, ///< Bit field RxBypass3rd4thStg + BFRx4thStgEn, ///< Bit field Rx4thStgEn + BFDllCSRBiasTrim, ///< Bit feild DllCSRBiasTrim + BFRxDqInsDly, ///< Bit feild RxDqInsDly + BFDllNoLock, ///< Bit field DllNoLock + BFEnSplitDctLimits, ///< Bit field EnSplitDctLimits + BFEnSplitMctDatBuffers, ///< Bit field EnSplitMctDatBuffers + BFGmcTokenLimit, ///< Bit fieid GmcTokenLimit + BFMctTokenLimit, ///< Bit field MctTokenLimit + BFGmcToDctControl1, ///< Bit field GmcToDctControl1 + BFDllCSRBisaTrimDByte, ///< Bit field DllCSRBisaTrimDByte + BFDllCSRBisaTrimClk, ///< Bit field DllCSRBisaTrimClk + BFDllCSRBisaTrimCsOdt, ///< Bit field DllCSRBisaTrimCsOdt + BFDllCSRBisaTrimAByte2, ///< Bit field DllCSRBisaTrimAByte2 + BFReduceLoop, ///< Bit field ReduceLoop + BFEffArbDis, ///< Bit field EffArbDis + BFDramCommand0, ///< Bit field for DramCommand0 register + BFDramCommand2, ///< Bit field for DramCommand2 register + BFDramLoopbackAndTrainingControl, ///< Bit field for DramLoopbackAndTrainingControl register + BFCurMemPstate, ///< Bit field CurMemPstate + + BFMxMr0, ///< Bit field for MxMr0 + BFMxMr1, ///< Bit field for MxMr1 + BFMxMr2, ///< Bit field for MxMr2 + BFMxMrsEn, ///< Bit field for MxMrsEn + + BFUrgentTknDis, ///< Bit field for "UrgentTknDis" + BFUrGmcMinTokens, ///< Bit field for "UrGmcMinTokens" + BFUrGmcTokenLimit, ///< Bit field for "UrGmcTokenLimit" + BFUrMctTokenLimit, ///< Bit field for "UrMctTokenLimit" + BFUrMctMinTokens, ///< Bit field for "UrMctMinTokens" + + BFChAM1FenceSave, ///< Bit field for "ChAM1FenceSave" + BFChBM1FenceSave, ///< Bit field for "ChBM1FenceSave" + + BFMctEccDisLatOptEn, ///< Bit field for "MctEccDisLatOptEn" + BFCpuElevPrioDis, ///< Bit field for "CpuElevPrioDis" + BFNbOffsetTrim, ///< Bit field for "NbOffsetTrim" + BFECCExclusionBaseLow, ///< Bit field for ECCExclusionBaseLow + BFECCExclusionBaseHigh, ///< Bit field for ECCExclusionBaseHigh + BFECCExclusionLimitLow, ///< Bit field for ECCExclusionLimitLow + BFECCExclusionLimitHigh, ///< Bit field for ECCExclusionLimitHigh + BFCpuElevPrioPeriod, ///< Bit field for CpuElevPrioPeriod + BFSbRdPtrInit, ///< Bit field for SbRdPtrInit + BFCmdRdPtrInit, ///< Bit field for CmdRdPtrInit + + BFChannelEn, ///< Bit field ChannelEn + BFDctEn, ///< Bit field DctEn + BFDramType, ///< Bit field DramType + BFPmuReset, ///< Bit field PmuReset + BFPmuStall, ///< Bit field PmuStall + BFMemResetL, ///< Bit field MemReset_L + BFAcsmCkeOride, ///< Bit field AcsmCkeOride + BFAcsmCkeEnb, ///< Bit field AcsmCkeEnb + BFDbiOnResetDrvEn, ///< Bit field DbiOnResetDrvEn + BFDbiOnResetVal, ///< Bit field DbiOnResetVal + + BFGnbVidReqDis, ///< Bit field GndVidReqDis + BFNbVidUseGnb, ///< Bit field NbVidUseGnb + BFVidChgBusy, ///< Bit field VidChgBusy + + BFTrrdlG5, ///< Bit field Trrdl for GDDR5 + BFTrrdsG5, ///< Bit field Trrds for GDDR5 + BFTrcG5, ///< Bit field Trc for GDDR5 + BFTrcdWrG5, ///< Bit field TrcdWr for GDDR5 + BFTrcdRdG5, ///< Bit field TrcdRd for GDDR5 + BFTrasG5, ///< Bit field Tras for GDDR5 + BFTrtplG5, ///< Bit field Trtpl for GDDR5 + BFTrtpsG5, ///< Bit field Trtps for GDDR5 + BFTwrG5, ///< Bit field Twr for GDDR5 + BFTrpG5, ///< Bit field Trp for GDDR5 + BFT32awG5, ///< Bit field T32aw for GDDR5 + BFTppdG5, ///< Bit field Tppd for GDDR5 + BFTfawG5, ///< Bit field Tfaw for GDDR5 + BFTrwtTOG5, ///< Bit field TrwtTO for GDDR5 + BFTccdlG5, ///< Bit field Tccdl for GDDR5 + BFTccdsG5, ///< Bit field Tccds for GDDR5 + BFTwtrlG5, ///< Bit field Twtrl for GDDR5 + BFTwtrsG5, ///< Bit field Twtrs for GDDR5 + BFTcrcwlG5, ///< Bit field Tcrcwl for GDDR5 + BFTwlG5, ///< Bit field Twl for GDDR5 + BFTcrcrlG5, ///< Bit field Tcrcrl for GDDR5 + BFTclG5, ///< Bit field Tcl for GDDR5 + BFTrfcG5, ///< Bit field Trfc for GDDR5 + BFTrefG5, ///< Bit field Tref for GDDR5 + BFMemClkFreqValG5, ///< Bit field MemClkFreqVal for GDDR5 + BFMemClkFreqG5, ///< Bit field MemClkFreq for GDDR5 + BFTmrdG5, ///< Bit field Tmrd for GDDR5 + BFTcksrxG5, ///< Bit field Tcksrx for GDDR5 + BFTcksreG5, ///< Bit field Tcksre for GDDR5 + BFTckeG5, ///< Bit field Tcke for GDDR5 + BFTpdG5, ///< Bit field Tpd for GDDR5 + BFAggrPDDelayG5, ///< Bit field AggrPDDelay for GDDR5 + BFPchgPDEnDelayG5, ///< Bit field PchgPDEnDelay for GDDR5 + BFTxpnG5, ///< Bit field Txpn + + BFBankGrpEn, ///< Bit field BankGrpEn for GDDR5 + BFPptInterval, ///< Bit field PptInterval for GDDR5 + BFPptEn, ///< Bit field PptEn for GDDR5 + BFStartWCK, ///< Bit field StartWCK for GDDR5 + BFWrCrcEn, ///< Bit field WrCrcEn + BFRdCrcEn, ///< Bit field RdCrcEn + BFWDBIDis, ///< Bit field WDBIDis for GDDR5 + BFRDBIDis, ///< Bit field RDBIDis for GDDR5 + BFABILowLimit, ///< Bit field ABILowLimit for GDDR5 + BFABIDis, ///< Bit field ABIDis for GDDR5 + BFDataScrambleEn, ///< Bit field DataScrambleEn for GDDR5 + BFRdEdcLatency, ///< Bit field RdEdcLatency for GDDR5 + BFWrEdcLatency, ///< Bit field WrEdcLatency for GDDR5 + + BFTclAdj, ///< Bit field TclAdj + BFPhyTclAdj, ///< Bit field PhyTclAdj + BFPhyDisable, ///< Bit field PhyDisable + BFG5Mode, ///< Bit field G5_Mode + BFG5ModeAbyte, ///< Bit field G5_Mode ABYTE + BFG5ModeDbyte, ///< Bit field G5_Mode DBYTE + BFG5ModeAbit, ///< Bit field G5_Mode ABIT + BFCalG5D3, ///< Bit field CalG5D3 + BFCalCmptrResTrim, ///< Bit field CalCmptrResTrim + BFDsRdy, ///< Bit field Rdy for downstream mailbox + BFDsMessage, ///< Bit field Message for downstream mailbox + BFUsRdy, ///< Bit field UsRdy for upstream mailbox + BFUsMessage, ///< Bit field Message for upstream mailbox + BFRdy, ///< Bit field Rdy for upstream mailbox + BFUs2Rdy, ///< Bit field UsRdy for upstream mailbox 2 + BFUs2Message, ///< Bit field Message for upstream mailbox 2 + BFRdy2, ///< Bit field Rdy for upstream mailbox 2 + BFPMUClkDiv, ///< Bit field PMUClkDiv + BFDisPredriverCal, ///< Bit field DisPredriverCal + BFPhyClkCtl, ///< Bit field PhyClkCtl + + // Reserved + BFReserved01, ///< Reserved 01 + BFReserved02, ///< Reserved 02 + BFReserved03, ///< Reserved 03 + BFReserved04, ///< Reserved 04 + BFReserved05, ///< Reserved 05 + BFReserved06, ///< Reserved 06 + BFReserved07, ///< Reserved 07 + BFReserved08, ///< Reserved 08 + BFReserved09, ///< Reserved 09 + BFReserved10, ///< Reserved 10 + + BFReserved11, ///< Reserved 11 + BFReserved12, ///< Reserved 12 + BFReserved13, ///< Reserved 13 + BFReserved14, ///< Reserved 14 + BFReserved15, ///< Reserved 15 + BFReserved16, ///< Reserved 16 + BFReserved17, ///< Reserved 17 + BFReserved18, ///< Reserved 18 + BFReserved19, ///< Reserved 19 + BFReserved20, ///< Reserved 20 + BFIdsCmnMemReg, ///< Reserved for ids only, the value may dynamic change + BFDctSelBaseAddrReg, ///< Bit field DctSelBaseAddrReg + BFDctSelBaseOffsetReg, ///< Bit field DctSelBaseOffsetReg + BFPDPhyPSDis, ///< Bit field PDPhyPSDis F2xA8[19] + + /* End of accessible list --- entries below this line are for private use ------------*/ + BFEndOfList, ///< End of bit field list + + // Only for Table Drive Support define. + BFRcvEnDly, ///< F2x[1,0]9C_x[2B:10] Dram DQS Receiver Enable Timing Control Registers + BFWrDatDly, ///< F2x[1, 0]9C_x[302:301, 202:201, 102:101, 02:01] DRAM Write Data Timing [High:Low] Registers + BFRdDqsDly, ///< F2x[1, 0]9C_x[306:305, 206:205, 106:105, 06:05] DRAM Read DQS Timing Control [High:Low] Registers + BFWrDqsDly, ///< F2x[1, 0]9C_x[4A:30] DRAM DQS Write Timing Control Registers + BFPhRecDly, ///< F2x[1, 0]9C_x[51:50] DRAM Phase Recovery Control Register [High:Low] Registers + BFRdDqs2dDly, ///< F2x[1, 0]9C_x0D0F_0[F,8:0]2[3:0] + /* Do not define any entries beyond this point */ + BFAbsLimit ///< Beyond this point is reserved for bit field manipulation + +} BIT_FIELD_NAME; + +/// Bit field aliases +#define BFMainPllOpFreqId BFNbFid +#define BFNbDid BFNbPs0NclkDiv +#define BFRdDramTrainMode BFPrefDramTrainMode +#define BFThrottleEn BFCmdThrottleMode +#define BFIntlvRegionEn BFIntLvRgnSwapEn +#define BFIntlvRegionBase BFIntLvRgnBaseAddr +#define BFIntlvRegionLimit BFIntLvRgnLmtAddr +#define BFRdOdtPatReg BFPhyRODTCSLow +#define BFWrOdtPatReg BFPhyWODTCSLow +#define BFLockDramCfg BFC6DramLock +#define BFRstRcvFifo BFTwr +#define BFDramCmd2Reg BFCmdBank +#define BFDramODTCtlReg BFRdOdtTrnOnDly +#define BFDctSelBankSwap BFBankSwapAddr8En + +/// Bit field names per DRAM CS base address register +typedef enum { + BFCSEnable = 0, ///< Chip select enable + BFSpare = 1, ///< Spare rank + BFTestFail = 2, ///< Memory test failed + BFOnDimmMirror = 3 ///< on-DIMM mirroring enable +} CS_BASE_BIT_FIELD; + +/// Flag for exclude dimm +typedef enum { + NORMAL, ///< Normal mode, exclude the dimm if there is new dimm failure + TRAINING, ///< Training mode, exclude dimms that fail during training after training is done + END_TRAINING ///< End training mode, exclude all dimms that failed during training +} DIMM_EXCLUDE_FLAG; + +#define BSP_DIE 0 +#define MAX_NODES_SUPPORTED 8 ///< Maximum number of nodes in the system. +#define MAX_CS_PER_CHANNEL 8 ///< Max CS per channel +#define MAX_BYTELANES 8 ///< 8 byte lanes +#define MAX_DELAYS 9 ///< 8 data bytes + 1 ECC byte +#define MAX_DIMMS 4 ///< 4 DIMMs per channel + +#define VDDIO_DETERMINED 0xFF ///< VDDIO has been determined yet. Further processing is not needed. + +/// Indicators for voltage stages +typedef enum { + VOLT_NORMAL_STAGE = 0, ///< Indicate normal voltage stage + VOLT_AMP_STAGE ///< Indicate AMP voltage stage +} VOLT_STAGE; + +/// +/// MEM_SHARED_DATA +/// This structure defines the shared data area that is used by the memory +/// code to share data between different northbridge objects. Each substructure +/// in the data area defines how this data area is used by a different purpose. +/// +/// There should only be one instance of this struct created for all of the memory +/// code to use. +/// +typedef struct _MEM_SHARED_DATA { + + // System memory map data + UINT32 CurrentNodeSysBase; ///< Base[47:16] (system address) DRAM base address for current node. + /// Memory map data for each node + BOOLEAN AllECC; ///< ECC support on the system + DIMM_EXCLUDE_FLAG DimmExcludeFlag; ///< Control the exclude dimm behavior + UINT8 VoltageMap; ///< The commonly supported voltage map in the system + + UINT8 TopNode; ///< Node that has its memory mapped to TOPMEM/TOPMEM2 + BOOLEAN C6Enabled; ///< TRUE if C6 is enabled + BOOLEAN AcpEngineEnabled; ///< TRUE if ACP Engine is enabled + + /// Data structure for NB register table + struct { + UINT64 FamilyId; ///< LogicalCpuid.Family + UINT32 *NBRegTable; ///< Pointer to allocated buffer for NBRegTable + } NBRegMap[MAX_NODES_SUPPORTED]; + + /// Data structure for node map + struct { + BOOLEAN IsValid; ///< TRUE if this node contains memory. + UINT32 SysBase; ///< Base[47:16] (system address) DRAM base address of this node. + UINT32 SysLimit; ///< Base[47:16] (system address) DRAM limit address of this node. + } NodeMap[MAX_NODES_SUPPORTED]; + BOOLEAN UndoHoistingAbove1TB; ///< Undo hoisting above 1TB + + /// Data structure for node interleave feature + struct { + BOOLEAN IsValid; ///< TRUE if the data in this structure is valid. + UINT8 NodeCnt; ///< Number of nodes in the system. + UINT32 NodeMemSize; ///< Total memory of this node. + UINT32 Dct0MemSize; ///< Total memory of this DCT 0. + UINT8 NodeIntlvSel; ///< Index to each node. + } NodeIntlv; + + /// Common Voltage Min/Max Values + UINT8 CommonSmallestMaxNegVref; ///< Common smallest negative Vref across platfrom + UINT8 CommonSmallestMaxPosVref; ///< Common smallest positive Vref across platform + +} MEM_SHARED_DATA; + +/// +/// MEM_MAIN_DATA_BLOCK +/// +typedef struct _MEM_MAIN_DATA_BLOCK { + struct _MEM_DATA_STRUCT *MemPtr; ///< Pointer to customer shared data + struct _MEM_NB_BLOCK *NBPtr; ///< Pointer to array of NB Blocks + struct _MEM_TECH_BLOCK *TechPtr; ///< Pointer to array of Tech Blocks + struct _MEM_SHARED_DATA *mmSharedPtr; ///< Pointer to shared data area. + UINT8 DieCount; ///< Total number of Dies installed +} MEM_MAIN_DATA_BLOCK; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + + +/* +node: Indicates the Node +- Value ranges from 0-7, 0xF: for all nodes +- Size - 4 Bits + +dct: Indicate the DRAM Controller +- Value is 0, 1 (0xF: apply setting to all DCTs) +- Size - 4 Bits + +dimm: This values specifies which DIMM register will be applied +- The value varies from 0 to 3, 0xF: all DIMMs +- Size - 4 Bits + +attr - Indicates if the value needs to be added, subtracted, overridden or Auto (not changed) +- 0: Do not change the current value in the register +- 1: Use the value provided in the table to override the current value in the register (the one that AGESA initially determined) +- 2: Add the value provided in the table as an offset to the current value in the register (the one that AGESA initially determined) +- 3: Subtract the value provided in the table as an offset to the current value in the register (the one that AGESA initially determined) +- Size - 2 Bits + +time - Indicate the timing for the register which is written. +- 0: Write register value before Dram init +- 1: Write register value before memory training +- 2: Write register value after memory training +- Size - 1 Bits + +bytelane: bytelane number +- This determines specifies which bytelane register will be applied +- Bit0 =1 - set value into Bytelane0 +- Bit1 =1 - set value into Bytelane1 +- Bit2 =1 - set value into Bytelane2 +... +... +- 0xFFFF: all bytelane +- Size - 16 Bits. + +bfIndex: Indicate the bitfield index +- Size - 16 Bits + +value - Value to be used +- This can be an offset (sub or Add) or an override value. +- Size - DWORD +*/ + +// Sample code +// NBACCESS (MTBeforeDInit, MTNodes, MTDct0, BFCSBaseAddr5Reg, MTOverride, 0x400001), +// NBACCESS (MTBeforeTrn, MTNodes, MTDct1, BFCSBaseAddr7Reg, MTOverride, 0xFFFFFFFF), +// DQSACCESS (MTAfterTrn, MTNodes, MTDcts, MTDIMM0, MTBL1+MTBL2, BFRcvEnDly, MTSubtract, 2), +// DQSACCESS (MTAfterTrn, MTNodes, MTDct1, MTDIMM1, MTBLNOECC, BFRcvEnDly, MTAdd, 1), + +#define ENDMEMTDS 0, 0, 0, 0, 0, 0, 0xFFFFFFFFul, 0 + +#define NBACCESS(time, node, dct, bitfield, attr, value) \ +{ (time), \ + ((node) & 0x0F) | ((dct) << 4), \ + (((attr) & 0x07) << 4) | (VT_MSK_VALUE << 7) , \ + (UINT8)((bitfield) & 0x000000FF), \ + (UINT8)(((bitfield) >> 8) & 0x000000FF), \ + (UINT8)(((bitfield) >> 16) & 0x000000FF), \ + (UINT8)(((bitfield) >> 24) & 0x000000FF), \ + 0, 0, \ + (UINT8)((value) & 0x000000FF), \ + (UINT8)(((value) >> 8) & 0x000000FF), \ + (UINT8)(((value) >> 16) & 0x000000FF), \ + (UINT8)(((value) >> 24) & 0x000000FF), \ + 0, 0, 0 \ +} + +#define DQSACCESS(time, node, dct, dimm, bitfield, attr, b0, b1, b2, b3, b4, b5, b6, b7, b8) \ +{ (time), \ + ((node) & 0x0F) | ((dct) << 4), \ + (((dimm) & 0x0F) | ((attr) & 0x07) << 4) | (VT_ARRAY << 7) , \ + (UINT8)((bitfield) & 0x000000FF), \ + (UINT8)(((bitfield) >> 8) & 0x000000FF), \ + (UINT8)(((bitfield) >> 16) & 0x000000FF), \ + (UINT8)(((bitfield) >> 24) & 0x000000FF), \ + (b0), (b1), (b2), (b3), (b4), (b5), (b6), (b7), (b8) \ +} + +#define DQS2DACCESS(time, node, dct, dimm, bitfield, attr, l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18) \ +{ (time), \ + ((node) & 0x0F) | ((dct) << 4), \ + (((dimm) & 0x0F) | ((attr) & 0x07) << 4) | (VT_ARRAY << 7) , \ + (UINT8)((bitfield) & 0x000000FF), \ + (UINT8)(((bitfield) >> 8) & 0x000000FF), \ + (UINT8)(((bitfield) >> 16) & 0x000000FF), \ + (UINT8)(((bitfield) >> 24) & 0x000000FF), \ + (l0, (l1), (l2), (l3), (l4), (l5), (l6), (l7), (l8), (l9), (l10), (l11), (l12), (l13), (l14), (l15), (l16), (l17), (l18) \ +} +/// Type of modification supported by table driven support. +typedef enum { + MTAuto, ///< Do not change the current value in the register + MTOverride, ///< Use the value provided in the table to override the current value in the register + MTSubtract, ///< Subtract the value provided in the table as an offset to the current value in the register + MTAdd, ///< Add the value provided in the table as an offset to the current value in the reg + MTAnd, ///< And the value provided in the table as an offset to the current value in the reg + MTOr ///< Or the value provided in the table as an offset to the current value in the reg +} MTAttr; + +/// Time for table driven support to make modification. +/// NOTE please keep the order of below MT points +typedef enum { + MTBeforeInitializeMCT = 0, ///< 00 Before InitializeMCT + MTAfterAutoCycTiming, ///< 01 After Auto Cycle Timing + MTAfterPlatformSpec, ///< 02 After Platform Specific Configuration + MTBeforeDInit, ///< 03 Before Dram init + MTBeforeTrn, ///< 04 Before memory training + MTAfterMemPstate1PartialTrn, ///< 05 After partial training at starting frequency + MTAfterTrn, ///< 06 After memory training + MTAfterSwWLTrn, ///< 07 After SW Based WL Training + MTAfterHwWLTrnP1, ///< 08 After HW Based WL Training Part 1 + MTAfterHwRxEnTrnP1, ///< 09 After HW Based Receiver Enable Training Part 1 + MTAfterFreqChg, ///< 10 After each frequency change + MTAfterHwWLTrnP2, ///< 11 After HW Based WL Training Part 2 + MTAfterHwRxEnTrnP2, ///< 12 After HW Based Receiver Enable Training Part 2 + MTAfterSwRxEnTrn, ///< 13 After SW Based Receiver Enable Training + MTAfterDqsRwPosTrn, ///< 14 After DQS Read/Write Position Training + MTAfterMaxRdLatTrn, ///< 15 After Max Read Latency Training + MTAfterNbPstateChange, ///< 16 After programming NB Pstate dependent registers + MTAfterInterleave, ///< 17 After Programming Interleave registers + MTAfterSettingMemoryPstate1, ///< 18 After programming registers for memory pstate 1 + MTAfterFinalizeMCT, ///< 19 After Finalize MCT Programming + + MTValidTimePointLimit, ///< Mark the upper bound of the supported time points + MTEnd = 0xFF ///< End of enum define. +} MTTime; + +/// Node on which modification should be made by table driven support. +typedef enum { + MTNode0, ///< Node 0. + MTNode1, ///< Node 1. + MTNode2, ///< Node 2. + MTNode3, ///< Node 3. + MTNode4, ///< Node 4. + MTNode5, ///< Node 5. + MTNode6, ///< Node 6. + MTNode7, ///< Node 7. + MTNodes = 0xF ///< all nodes +} MTNode; + +/// DCT on which modification should be made by table driven support. +typedef enum { + MTDct0, ///< DCT 0. + MTDct1, ///< DCT 1. + MTDcts = 0x7, ///< all dcts +} MTDct; + +/// Dimm on which modification should be made by table driven support. +typedef enum { + MTDIMM0, ///< Dimm 0. + MTDIMM1, ///< Dimm 1. + MTDIMM2, ///< Dimm 2. + MTDIMM3, ///< Dimm 3. + MTDIMMs = 0xF, ///< all Dimms +} MTDIMM; + +/// Bytelane on which modification should be made by table driven support. +typedef enum { + MTBL0 = 0x1, ///< set the value into Bytelane0 + MTBL1 = 0x2, ///< set the value into Bytelane1 + MTBL2 = 0x4, ///< set the value into Bytelane2 + MTBL3 = 0x8, ///< set the value into Bytelane3 + MTBL4 = 0x10, ///< set the value into Bytelane4 + MTBL5 = 0x20, ///< set the value into Bytelane5 + MTBL6 = 0x40, ///< set the value into Bytelane6 + MTBL7 = 0x80, ///< set the value into Bytelane7 + MTBL8 = 0x100, ///< set the value into ECC + MTBLNOECC = 0xFF, ///< all Bytelanes except ECC + MTBLs = 0xFFFF, ///< all Bytelanes +} MTBL; + +/// Values used to indicate which type of training is being done. +typedef enum { + TRN_RCVR_ENABLE, ///< Reciever Enable Training + TRN_DQS_POSITION, ///< Read/Write DQS Position training + TRN_MAX_READ_LATENCY ///< Max read Latency training +} TRAINING_TYPE; + +/// Memory Pstate +typedef enum { + MEMORY_PSTATE0, ///< Memory Pstate 0 + MEMORY_PSTATE1, ///< Memory Pstate 1 +} MEM_PSTATE; + +/// Memory Pstate Training Stage +typedef enum { + MEMORY_PSTATE_1ST_STAGE = 0xF1, ///< Memory Pstate processing stage 1, in which full training is done at DDR667 + MEMORY_PSTATE_2ND_STAGE, ///< Memory Pstate processing stage 2, in which partial trainig will be done at DDR800 - target speed + MEMORY_PSTATE_3RD_STAGE, ///< Memory Pstate processing stage 3, in which full training will be done at target frequency and MaxRdLatency training will start + MEMORY_PSTATE_S3_STAGE ///< Memory Pstate Processing in S3. +} MEM_PSTATE_STAGE; + +/// RdDqsDly Retrain status +typedef enum { + RDDQSDLY_RTN_NEEDED = 0xF1, ///< RdDqsDly retrain may be needed + RDDQSDLY_RTN_SUSPEND, ///< RdDqsDly retrain is suspected + RDDQSDLY_RTN_ONGOING ///< RdDqsDly retrain condition is just detected +} RDDQSDLY_RTN_STAT; +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +MemAmdFinalize ( + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +AGESA_STATUS +MemSocketScan ( + IN OUT MEM_MAIN_DATA_BLOCK *mmPtr + ); + +VOID +SetMemError ( + IN AGESA_STATUS Errorval, + IN OUT DIE_STRUCT *MCTPtr + ); + +VOID +AmdMemInitDataStructDefRecovery ( + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +VOID +SetMemRecError ( + IN AGESA_STATUS Errorval, + IN OUT DIE_STRUCT *MCTPtr + ); + +AGESA_STATUS +memDefRetSuccess ( VOID ); + +VOID +AmdMemFunctionListDef ( + IN OUT VOID *pMemData + ); + +VOID +MemMDisableScrubber ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); + +VOID +MemMRestoreScrubber ( + IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr + ); +#endif /* _MM_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mn.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mn.h new file mode 100644 index 0000000000..4783cd3e0d --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mn.h @@ -0,0 +1,1579 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mn.h + * + * Common Northbridge + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 87494 $ @e \$Date: 2013-02-04 12:06:47 -0600 (Mon, 04 Feb 2013) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MN_H_ +#define _MN_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#define _32MB_RJ16 0x0200 +#define _16MB_RJ16 0x0100 +#define _4GB_RJ16 (((UINT32) 4) << (30 - 16)) +#define _1TB_RJ16 (((UINT32) 1) << (40 - 16)) +#define HT_REGION_BASE_RJ16 ((UINT32)0x00FD0000ul) + +#define DCT_ACCESS_WRITE (UINT32) 0x40000000ul +#define MTRR_VALID 11 +#define THERMAL_OPT 31 + +#define NB_ACCESS 0 +#define DCT_PHY_ACCESS 1 +#define DCT_EXTRA 2 + +#define DCT_PHY_DIRECT 0xF1 + +#define VT_MSK_VALUE 0 +#define VT_ARRAY 1 +/*--------------------------------------------- + * TSEFO - Type Start End Function Offset + * + * 31:30 Type of access (2-bits) + * 29:29 Special (1-bit) + * 28:28 Phy Direct (1-bit) + * 27:27 Whole Register Access (1-bit) + * 26:26 Linked (1-bit) + * 25:21 Start bit (5-bits) + * 20:16 End bit (5-bits) + * 15:00 Function_Offset/Index (16-bits) + *--------------------------------------------- + */ +typedef UINT32 TSEFO; + +/** + MAKE_TSEFO(TableName, a, b, c, d, BitFieldIndex): + + @param[in] TableName + @param[in] BitFieldIndex + @param[in] a Type of access. + @param[in] b Index of register (can be in Function_Offset format). + @param[in] c Highest bit of the bit field. + @param[in] d Lowest bit of the bit field. + + @return TSEFO Access params encrypted in TSEFO format. +--*/ +#define MAKE_TSEFO(TableName, a, b, c, d, BitFieldIndex) \ +TableName[BitFieldIndex] = ( \ + (a == DCT_PHY_DIRECT) ? ( \ + (((UINT32) DCT_PHY_ACCESS) << 30) | (((UINT32) 1) << 28) | (((UINT32) b) & 0xFFFF) | (\ + ((c == 15) && (d == 0)) ? ( \ + (((UINT32) 1) << 27) | (((UINT32) b) & 0xF0000) \ + ) : ( \ + (c >= d) ? ( \ + (((UINT32) c) << 21) | (((UINT32) d) << 16) \ + ) : ( \ + (((UINT32) d) << 21) | (((UINT32) c) << 16) \ + ) \ + ) \ + ) \ + ) : ( \ + (((UINT32) a) << 30) | (((UINT32) b) & 0xFFFFFFF) | ( \ + (((UINT32) b) >> 16) ? ( \ + (((UINT32) 1) << 29) \ + ) : ( \ + (c >= d) ? ( \ + (((UINT32) c) << 21) | (((UINT32) d) << 16) \ + ) : ( \ + (((UINT32) d) << 21) | (((UINT32) c) << 16) \ + ) \ + ) \ + ) \ + ) \ +) + +/** + LINK_TSEFO(TableName, LowerBitFieldIndex, HigherBitFieldIndex): + This is one way link: any write to LowerBitFieldIndex would write to HigherBitFieldIndex, + but NOT the other way around. + Requirement: LowerBitFieldIndex must be declared *right* before HigherBitFieldIndex. + + @param[in] TableName + @param[in] LowerBitFieldIndex + @param[in] HigherBitFieldIndex + + @return TSEFO Access params encrypted in TSEFO format. +--*/ +#define LINK_TSEFO(TableName, LowerBitFieldIndex, HigherBitFieldIndex) { \ + ASSERT (LowerBitFieldIndex == (HigherBitFieldIndex - 1)) ; \ + TableName[LowerBitFieldIndex] = TableName[LowerBitFieldIndex] | (((UINT32) 1) << 26); \ +} + +// Indicate when a bitfield has multiple memory Pstate copy +#define MULTI_MPSTATE_COPY_TSEFO(TableName, BitFieldName) \ + TableName[BitFieldName] = TableName[BitFieldName] | (((UINT32) 1) << 29) + +#define TSEFO_TYPE(x) ((UINT8) (((UINT32) (x) >> 30) & 0x03)) +#define TSEFO_START(x) ((UINT8) (((UINT32) (x) >> 21) & 0x1F)) +#define TSEFO_END(x) ((UINT8) (((UINT32) (x) >> 16) & 0x1F)) +#define TSEFO_OFFSET(x) ((UINT32) (x) & 0xFFFF) +#define TSEFO_LINKED(x) ((UINT8) (((UINT32) (x) >> 26) & 0x01)) +#define TSEFO_DIRECT_EN(x) ((UINT8) (((UINT32) (x) >> 28) & 0x01)) +#define TSEFO_WHOLE_REG_ACCESS(x) ((UINT8) (((UINT32) (x) >> 27) & 0x01)) +#define _FN(x, y) (((UINT32) (x) << 12) + (UINT32) (y)) +#define TSEFO_MULTI_MPSTATE_COPY(x) ((UINT8) (((UINT32) (x) >> 29) & 1)) +#define _NOT_USED_ 0 + +/* */ +#define B0_DLY 0 +#define B1_DLY 1 +#define B2_DLY 2 +#define B3_DLY 3 +#define B4_DLY 4 +#define B5_DLY 5 +#define B6_DLY 6 +#define B7_DLY 7 +#define ECC_DLY 8 + +#define DDR2_TRAIN_FLOW 0 +#define DDR3_TRAIN_FLOW 1 + +// +// Minimum Data Eye width in consecutive 32nds of a UI of +// valid data +// +#define MIN_RD_DATAEYE_WIDTH_NB 4 +#define MIN_WR_DATAEYE_WIDTH_NB 4 + +// +// RELIABLE READ/WRITE MODE DEFINITIONS +// +#define PRECHARGE_ALL_BANKS 0xFF ///< Use to specify PrechargeAll Command to Precharge Cmd Function +#define CMD_TGT_A 0x00 ///< Issue Commands to Command Target A +#define CMD_TGT_AB 0x01 ///< Issue Commands to Command Targets A and B +#define CMD_TYPE_READ 0x00 ///< Read Command +#define CMD_TYPE_WRITE 0x01 ///< Write Command +#define CMD_TYPE_WR_RD 0x02 ///< Alternating Write and Read Commands +#define CPG_BANK_ADDRESS_A 0x0 ///< Dimm Bank address used in Reliable RD/RW mode training +#define CPG_BANK_ADDRESS_B 0x1 ///< Dimm Bank address used in Reliable RD/RW mode training +#define CPG_ROW_ADDRESS_A 0x0 ///< Dimm Row address used in Reliable RD/RW mode training +#define CPG_ROW_ADDRESS_B 0x0 ///< Dimm Row address used in Reliable RD/RW mode training +#define CPG_COL_ADDRESS_A 0x0 ///< Dimm Column address used in Reliable RD/RW mode training +#define CPG_COL_ADDRESS_B 0x0 ///< Dimm Column address used in Reliable RD/RW mode training +#define CPG_COMPARE_MASK_LOW 0x00000000ul ///< Dram DQMask[31:0] used to mask comparison on reads. 1=ignore +#define CPG_COMPARE_MASK_HI 0x00000000ul ///< Dram DQMask[63:32] used to mask comparison on reads. 1=ignore +#define CPG_COMPARE_MASK_ECC 0x00 ///< Dram EccMask used to mask comparison on reads. 1=ignore +#define PRBS_SEED_32 0x062221ul ///< Data PRBS Seed +#define PRBS_SEED_64 0x066665ul ///< Data PRBS Seed +#define PRBS_SEED_128 0x026666ul ///< Data PRBS Seed +#define PRBS_SEED_256 0x044443ul ///< Data PRBS Seed + + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/// Structure for Reliable Read/Write Mode Data +/// These are values that may need to be referenced by the low level functions +/// during training and are initialized at the beginning of a particular type of training. +typedef struct _RRW_SETTINGS { + UINT8 CmdTgt; ///< Value to program into CmdTgt + UINT8 TgtBankAddressA; ///< Target A Bank address + UINT32 TgtRowAddressA; ///< Target A Row address + UINT32 TgtColAddressA; ///< Target A Column address + UINT8 TgtBankAddressB; ///< Target B Bank address + UINT32 TgtRowAddressB; ///< Target B Row address + UINT32 TgtColAddressB; ///< Target B Column address + UINT32 CompareMaskLow; ///< Compare Mask Bits 31:0 + UINT32 CompareMaskHigh; ///< Compare Mask Bits 63:32 + UINT8 CompareMaskEcc; ///< Compare Mask Ecc + UINT32 DataPrbsSeed; ///< PRBS Seed value +} RRW_SETTINGS; + +/// DQS training related delays +typedef enum { + AccessRcvEnDly, ///< Receiver enable delay + AccessWrDatDly, ///< Write data delay + AccessRdDqsDly, ///< Read DQS delay + AccessWrDqsDly, ///< Write DQS delay + AccessPhRecDly, ///< Phase recovery delay + AccessRdDqs2dDly ///< Read DQS 2D delay +} TRN_DLY_TYPE; + +/// Training patterns for position training +typedef enum { + POS_PATTERN_72B, ///< 72 bit pattern + POS_PATTERN_256B, ///< 256 bit pattern +} POS_TRN_PATTERN_TYPE; + +/// ODT mode +typedef enum { + MISSION_MODE, ///< ODT during mission mode + WRITE_LEVELING_MODE ///< ODT during write leveling +} ODT_MODE; + +/* + * DRBN - Dimm-Rank-Byte-Nibble + * 31:12 Reserved + * 11:09 Dimm (3-bits) + * 08 Rank (1-bit) + * 07:05 Reserved + * 04:01 Byte (4-bits) + * 00 Nibble (1-bit) + */ +typedef UINT32 DRBN; +#define MAKE_DRBN(dimm, rank, byte, nibble) ((((UINT32) (dimm)) << 9) | (((UINT32) (rank)) << 8) | \ +(((UINT32) (byte)) << 1) | ((UINT32) (nibble)) ) +#define DIMM_BYTE_ACCESS(dimm, byte) ((((UINT32) (dimm)) << 9) | (((UINT32) (byte)) << 1)) +#define CS_NBBL_ACCESS(cs, nibble) ((((UINT32) (cs)) << 8) | ((UINT32) (nibble))) +#define DIMM_NBBL_ACCESS(dimm, nibble) ((((UINT32) (dimm)) << 9) | ((UINT32) (nibble))) +#define DRBN_DIMM(x) ((UINT8) (((UINT32) (x) >> 9) & 0x07)) +#define DRBN_RANK(x) ((UINT8) (((UINT32) (x) >> 8) & 0x01)) +#define DRBN_BYTE(x) ((UINT8) (((UINT32) (x) >> 1) & 0x0F)) +#define DRBN_NBBL(x) ((UINT8) (((UINT32) (x)) & 0x01)) +#define DRBN_DIMM_NBBL(x) ((UINT8) (((UINT32) (x)) & 0x1F)) + +/* Dimm Type mask */ +#define DT_X4 0x01 +#define DT_X8 0x02 +#define DT_X16 0x04 +#define DT_SR 0x10 +#define DT_DR 0x20 +#define DT_QR 0x40 + +#define DT_ANY_X4 0x71 +#define DT_ANY_X8 0x72 +#define DT_ANY_X16 0x74 +#define DT_ANY_SR 0x17 +#define DT_ANY_DR 0x27 +#define DT_ANY_QR 0x47 +#define DT_ANY_SR_DR (DT_ANY_SR | DT_ANY_DR) +#define DT_ANY (DT_ANY_SR | DT_ANY_DR | DT_ANY_QR) + +/// Delay Scaling Info Struct - Describes number of delay increments per UI of a delay type +/// +typedef struct _TRN_DLY_PARMS { + UINT8 Min; ///< Minimum Value + UINT8 Max; ///< Maximum Value + UINT8 Mask; ///< Mask to be applied (i.e. 0xFF if adjustable by one, 0xFE if adjustable by 2, etc.) +} TRN_DLY_PARMS; + +/// Structure for certain data saving needed for DCT. +typedef struct { + UINT8 RcvEnDlyCounts[8]; ///< DQS Receiver Enable Delay counts + UINT32 PhRecReg[3]; ///< 3 Phase recovery control registers + BOOLEAN Is2Dx4; ///< Check if 2D training is enabled and x4 DIMMs are installed +} MEM_DCT_CACHE; + +/// Structure for table driven support. +typedef struct _MEM_TBL_ALIAS { + UINT8 time; ///< Modification time. + UINT8 node:4; ///< Node on which to make modification. + UINT8 dct:4; ///< DCT on which to make modification. + UINT8 dimm:4; ///< Dimm on which to make modification. + UINT8 attr:3; ///< Attribute of modification. + UINT8 vtype:1; ///< Flag indicating value type. + UINT32 bfindex; ///< Bit field index that need to be modified. + union { ///< Union is defined to easy select between single and multiple bytelane cases. + struct { ///< Sub-struct used for one bytelane value. + UINT16 bytelane:16; ///< Bytelane on which to make modification. + UINT32 value; ///< Modified value. + UINT8 reserved[3]; ///< Reserved for this purpose + } s; ///< single value to one or multiple bytelanes + UINT8 bytelanevalue[9]; ///< Array to specify individual bytelane values + } data; +} MEM_TABLE_ALIAS; + +/// Structure for Platform Specific Block. +typedef struct _MEM_PS_BLOCK { + UINT8 DramTerm; ///< Dram Term + UINT8 QR_DramTerm; ///< Dram Term for QR + UINT8 DynamicDramTerm; ///< Dynamic Dram Term + UINT8 NumOfReg[MAX_DIMMS_PER_CHANNEL]; ///< Number of registers on each RDIMM (From SPD) + UINT8 MR0WR; ///< MR0WR + UINT8 MR0CL31; ///< MR0[CL][3:1] + UINT8 MR0CL0; ///< MR0CL[0] + UINT8 RttNom[8]; ///< RttNom value for maximum 8 chipsels per channel + UINT8 RttWr[8]; ///< RttWr value for maximum 8 chipsels per channel + UINT8 F0RC8; ///< F0RC8 + UINT8 F1RC0; ///< F1RC0 + UINT8 F1RC1; ///< F1RC1 + UINT8 F1RC2; ///< F1RC2 + UINT8 RC10OpSpd; ///< RC10[OperatingSpeed] + UINT8 LrdimmRowAddrBits[MAX_DIMMS_PER_CHANNEL]; ///< Effective Row address bits used by LRDIMMS + UINT16 SpeedLimit[VOLT1_25_ENCODED_VAL + 1]; ///< SpeedLimit of individual VDDIO + UINT8 WLSeedVal; ///< Seed value of WL training extracted from PSC table + UINT16 HWRxENSeedVal; ///< Seed value of HW RxEn training extracted from PSC table + BOOLEAN ProcessorOnDieTerminationOff; ///< processor ODT off + ///< FALSE = Phy enables receiver pad termination + ///< TRUE = Phy disables receiver pad termination + UINT8 CkeStrength; ///< CKE drive strength + UINT8 CsOdtStrength; ///< CS ODT drive strength + UINT8 AddrCmdStrength; ///< Addr Cmd drive strength + UINT8 ClkStrength; ///< CLK drive strength + UINT8 DqStrength; ///< Data drive strength + UINT8 DqsStrength; ///< DQS drive strength + UINT8 OdtStrength; ///< ODT drive strength + + /* PUBLIC functions */ + BOOLEAN (*MemPDoPs) (struct _MEM_NB_BLOCK *NBPtr); ///< Function that gets Form factor info. + VOID (*MemPGetPORFreqLimit) (struct _MEM_NB_BLOCK *NBPtr); ///< Function that gets the speed limit of a dimm population. + BOOLEAN (*MemPGetPass1Seeds) (struct _MEM_NB_BLOCK *NBPtr); ///< Function that gets pass1 seeds of WL and RxEn training. + + /* Bitmaps used in looking up PS tables */ + UINT8 NumOfDimmSlots; ///< See enum type NOD_SUPPORTED + UINT8 DimmType; ///< See enum type DIMM_TYPE + UINT16 RankType; ///< Rank type of all populated DIMMs. See MemPGetPsRankType. +} MEM_PS_BLOCK; + +/// Structure parameters needed in frequency change of client NB. +typedef struct _MEM_FREQ_CHANGE_PARAM { + UINT16 PllLockTimeDefault; ///< Default PllLockTime + UINT8 RdPtrInit667orHigher; ///< RdPtrInit for frequency 667MHz and higher + UINT8 RdPtrInitLower667; ///< RdPtrInit for frequency lower than 667MHz + UINT8 NclkPeriodMul2x; ///< Multiplier for NclkPeriod in parial sum calculation x 2 + UINT8 MemClkPeriodMul2x; ///< Multiplier for MemClkPeriod in parial sum calculation x 2 + UINT8 SyncTimeMul4x; ///< Multiplier for SyncTime + UINT16 TDataProp800orHigher; ///< TDataProp for frequency 800MHz or higher + UINT16 TDataPropLower800; ///< TDataProp for frequency lower than 800MHz +} MEM_FREQ_CHANGE_PARAM; + +/// List for NB items that are supported +typedef enum { + SetSpareEn, ///< Sets spare enable + CheckSpareEn, ///< Spare enabled + SetDllShutDown, ///< Sets DllShutDown + CheckEccDLLPwrDnConfig, ///< Checks to determine if EccDLLPwrDnConf needs to be adjusted + DimmBasedOnSpeed, ///< Checks to determine if Dimm number needs to be adjusted based on speed + CheckMaxDramRate, ///< Checks to determine the maximum rate + Check1GAlign, ///< Checks to determine if 1 GB alignment is supported + DramModeBeforeDimmPres, ///< Check to determine if DRAM mode needs to be set before dimm presence + DramModeAfterDimmPres, ///< Check to determine if DRAM mode needs to be set after dimm presence + CheckClearOnDimmMirror, ///< Check to determine if we need to clear on DIMM mirror + CheckDisDllShutdownSR, ///< Check to determine if DisDllShutdown needs to be set + CheckMemClkCSPresent, ///< Check to determine if chipselect needs to be set based on disabled memclocks + CheckChangeAvgValue, ///< Check to determine if we need to change average value + CheckMaxRdDqsDlyPtr, ///< Check to determine change Max Rd Dqs Delay + CheckPhyFenceTraining, ///< Check to determine if we need to Phy Fence training + CheckGetMCTSysAddr, ///< Check to determine if we need to GetMCTSysAddr + CheckSendAllMRCmds, ///< Check to determine if we need to SendAllMRCmds + CheckFindPSOverideWithSocket, ///< Check to determine if we need to Find PSOveride With Socket + CheckFindPSDct, ///< Check to determine if we need to Find PSOveride With DCT + CheckODTControls, ///< Check to determine if we need to set ODT controls + CheckDummyCLRead, ///< Check to determine if an extra dummy read is required + CheckDllStdBy, ///< Check to determine if setting DLL stand by is required + CheckSlewWithMarginImprv, ///< Check to determine if setting of Slew With MarginImprv is required + CheckSlewWithoutMarginImprv, ///< Check to determine if setting of Slew Without MarginImprv is required + CheckDllSpeedUp, ///< Check to determine if setting of Dll SpeedUp is required + CheckDllRegDis, ///< Check to determine if setting of DLL Regulator Disable is required + FenceTrnBeforeDramInit, ///< Check to determine if fence training has been done before Dram init + WLSeedAdjust, ///< Check to determine if WL seed needs to be adjusted + UnifiedNbFence, ///< Check to determine if Phy fence is of Unified NB + AdjustTwr, ///< Check to determine if Twr needs to be adjusted + ChannelPDMode, ///< Check to determine if channel power down mode is the only that is supported + ForceEnMemHoleRemapping, ///< Check to determine if we need to force enabling memory hole remapping + AdjustTrdrdSD, ///< Check to determine if we need to adjust TrdrdSD + ReverseMaxRdLatTrain, ///< Check to determine if reverse (pass to fail) algorithm is supported for MaxRdLat training + SkipErrTrain, ///< Check to determine if skip error training is supported + DramSrHys, ///< Check to determine if DRAM SR hysteresis is supported + PchgPDMode, ///< Check to determine if Precharge powerdown mode is supported + EccByteTraining, ///< Check to determine if DRAM ECC Byte training + CheckDrvImpCtrl, ///< Check to determine if we need to set DrvImpCtrl + CheckDramTerm, ///< Check to determine if we need to set DramTerm + CheckDramTermDyn, ///< Check to determine if we need to set DramTermDyn + CheckQoff, ///< Check to determine if we need to set Qoff + CheckSetSameDctODTsEn, ///< Check to defermine if we need to set "ODTsEn" the same on each DCT + WLNegativeDelay, ///< Check to determine if the NB can tolerate a negtive WL delay value + SchedDlySlot1Extra, ///< Check to determine if DataTxSchedDly Slot1 equation in slowMode to subtract an extra MEMCLK + TwoStageDramInit, ///< Check to determine if we need to seperate Draminit into 2 stages. The first one processes info on all nodes. The second one does Dram Init. + ExtraPclkInMaxRdLat, ///< Check to determine if an extra PCLK is needed for MaxRdLat + CsrPhyPllPdEn, ///< Check to determine if CSR Phy PLL Powerdown is enabled or not + AdjustTrc, ///< Check to determine if we need to adjust Trc + ProgramCsrComparator, ///< Check to determine if we need to program CsrComparator with the same value as D18F2x09C_x0D0F_0[7:0]1F[RxVioLvl] + EnProcOdtAdvForUDIMM, ///< Check to determine if we need to always enable ProcOdtAdv for UDIMM + SetTDqsForx8DimmOnly, ///< Only set MR1[TDQS] for x8 DIMMs when x4 and x8 DIMMs are both present on a channel + WlRttNomFor1of3Cfg, ///< Set Rtt_Nom = Rtt_Wr in one of three DIMMs per channel configurations + PerformanceOnly, ///< Only support performance policy, does not support battery life policy + AdjustTrp, ///< Check to determin if Trp needs to be adjusted + DllStaggerEn, ///< Check to determin if Dll Stagger should be turned on + RxChnMntClksEn, ///< Check to determin if Receive Channel Maintenance Clock Enable should be turned on + ForcePhyToM0, ///< Force Phy to M0 + G5DimmInD3Socket, ///< Check to determine if DDR3 DIMM socket will be used for GDDR5 DIMMs as well + MasterDct1Relocate, ///< Check to determine if Master DCT for channel is DCT 3 instead of DCT 1 + PerDimmAggressors2D, ///< Use only the even Chipselect of each installed DIMM as an Aggressor + OptimizedPatternWrite2D, ///< Optimize 2D training to Write Pattern Once, read many times. + AMPIsEnabled, ///< Check to detemine if AMP is exactly enabled. + ScrubberEn, ///< Check to determine if DRAM scrubber is already enabled + SwitchRdDqsDlyForMaxRdLatency, ///< Use the different RdDqsDly value for MaxRdLatency calculation before/after DQS training + + EnumSize ///< Size of list +} NB_SUPPORTED; + +/// List for family specific functions that are supported +typedef enum { + BeforePhyFenceTraining, ///< Family specific tasks before Phy Fence Training + BeforeMemClkFreqVal, ///< hook before setting MemClkFreqVal bit + AfterMemClkFreqVal, ///< Override PllMult and PllDiv + OverridePllMult, ///< Override PllMult + OverridePllDiv, ///< Override PllDiv + BeforeMemClr, ///< Before MemClr + SendMrsCmdsPerCs, ///< Send MRS commands per CS + SetupHwTrainingEngine, ///< Setup Hardware training engine for specific training type + OverrideRcvEnSeed, ///< Override seed for hardware based RcvEn training + AddlMaxRdLatTrain, ///< Perform additional MaxRdLat training if needed + ForceAutoComp, ///< Force Auto Comp + DetectMemPllError, ///< Detect MemPll Divide by 3 bug + ReEnablePhyComp, ///< Re-Enable Phy Compensation after RcvEn Training + ExtractWLODT, ///< Extract WL ODT value thr given ODT pattern + DCTSelectSwitch, ///< Select DCT when we switch DCT + ScrubberErratum, ///< Erratum for setting scrubber rate + MR0_PPD, ///< Override MR0[PPD] + GetDdrMaxRate, ///< Interpret DdrMaxRate with Familiy-specific encoding + ExitPhyAssistedTraining, ///< Perform family specific tasks when exiting phy assisted training + AfterSaveRestore, ///< Action after save/restore execution + OverrideDataTxFifoWrDly, ///< Override DataTxFifoWrDly based on training result of WrDatDly + OverrideRcvEnSeedPassN, ///< Override seed for hardware based RcvEn training where N greater than 0 + AfterMemClkFreqChg, ///< Reprogram DIMMs' buffers after MEMCLK frequency change + AdjustTxpdll, ///< Adjust Txpdll value to encoded register value + CalcWrDqDqsEarly, ///< Calculate WrDqDqsEarly + TrainWlPerNibble, ///< Train Write Leveling per nibble + TrainWlPerNibbleAdjustWLDly, ///< Train WL per nibble and adjust the WL delay + TrainWlPerNibbleSeed, ///< Save the seed for WL nibble based training + TrainRxEnPerNibble, ///< Train Rx Enable Training per nibble + TrainRxEnAdjustDlyPerNibble, ///< Train Rx Enable Training nibble and adjust the RxEn delay + TrainRxEnGetAvgDlyPerNibble, ///< Display Rx Enable Training average nibble value for each BL + InitPerNibbleTrn, ///< Initiates Per Nibble Training. + BeforeSetCsTri, ///< Modify CS tri-state bit map. + ForceRdDqsPhaseB, ///< Force RdDqsDly to phase B + ProgramPOdtOff, ///< Disable/enable receiver pad termination + SetDqsODT, ///< Set DQS ODT + DisLowPwrDrvStr, ///< Hook to skip setting LowPowerDriveStrengthEn + AdjustRdDqsDlyOffset, ///< Adjust the bit offset of the RdDqsDly Bit Bitfield before writing and after reading + ResetRxFifoPtr, ///< Reset RxFifo pointer during Read DQS training + EnableParityAfterMemRst, ///< Enable DRAM Address Parity after memory reset. + FinalizeVDDIO, ///< Finalize VDDIO + TrainingNibbleZero, ///< Check for see Nibble zero is being trained (individually or with x8 training) + ProgOdtControl, ///< Calculate RdOdtTrnOnDly and RdOdtOnDuration + SetSkewMemClk, ///< Set SkewMemClk + OverrideWLSeed, ///< Override WL seed + AdjustCSIntLvLowAddr, ///< Adjust CS interleaving low address + Adjust2DVrefStepSize, ///< Adjusts the step size for Vref during 2D RdDqs training + Adjust2DDelayStepSize, ///< Adjusts the step size for RdDqs during 2D RdDqs training + ReleaseNbPstate, ///< Release NB P-state + InitializeRxEnSeedlessTraining, ///< Initializes RxEn Seedless Training + TrackRxEnSeedlessRdWrNoWindBLError, ///< Track Bytelane Errors resulting from No window for RxEn Seedless Training + TrackRxEnSeedlessRdWrSmallWindBLError, ///< Track Bytelane Errors resulting from Small window for RxEn Seedless Training + InitialzeRxEnSeedlessByteLaneError, ///< Initializes ByteLaneError to False for RxEn Seedless Training + InitExtMMIOAddr, ///< Initializes extended MMIO address space + MemPstateStageChange, ///< handle training when multiple memory pstate is supported + ProgramFence2RxDll, ///< program RxDll in a different register + RdDqsDlyRestartChk, ///< Check to see if we need to restart RdDqsDly + BeforeWrDatTrn, ///< Check to see if special handling is needed before WrDatDly Training + ForceLvDimmVoltage, ///< Force LVDIMM voltage to 1.5V + BfAfExcludeDimm, ///< Workaround before and after excluding dimms + AdjustWrDqsBeforeSeedScaling, ///< For some family, negative WL is compensated and WrDqs needs to be adjusted before seed scaling + OverridePrevPassRcvEnDly, ///< Check to determine if we need override PrevPassRcvEnDly + AdjustRdPtrInit, ///< Adjust RdPtrInit value according to certain conditions + Adjust2DPhaseMaskBasedOnEcc, ///< Adjusts the Phase Mask Based on ECC + FixupSysAddr, ///< Adjust physical address before identifying DIMM. + RegAccessFence, ///< Make sure previous phy registers writes are done + WLMR1, ///< Check to see if we need to do special things when sending MR1 during WL + FixupUmaInfo, ///< Fix up UMA info for a specific family + RelocatePscTblEntryByMotherBoardLayer, ///< Relocate the PSC table entry pointer by mother board layer design + AmpVoltageDisp, ///< To display AMP voltage values + AdjustHwRcvEnSeedGross, ///< Adjust the SeedGross value for hardware receiver enable training under certaion conditions + ForceEccSymbolSize, ///< Force the ECC Symbol Size to x4 or x8 + AdjustRdDqsDlyForMaxRdLat, ///< Adjust RdDqsDly used for MaxRdLatency calculation + SetMaxRdLatBasedOnSeededRxEnDly, ///< Prior to DQS Receiver Enable Training, Set MaxRdLatency value based on seeded value of RxEnDly + /// 2D Read/Write Training Feature Functions + RdWr2DTraining, ///< Main Common 2D Rd/Wr Training Fucntion + CheckRdWr2DTrainingPerConfig, ///< Determine if 2D Training should be run on the current config + RdWr2DSelectIntExtVref, ///< 2D Training function to select internal or external Vref + RdWr2DProgramVref, ///< 2D Training function to Program Vref + RdWr2DScaleVref, ///< 2D Training function to scale Vref to the memory controller register + RdWr2DProgramDelays, ///< 2D Training function program delay values + RdWr2DProgramMaxVref, ///< 2D Training function to set final vref + RdWr2DDataCollection, ///< 2D Training Data Collection + RdWr2DInitVictim, ///< 2D Training Victim Initialization + RdWr2DInitVictimChipSel, ///< 2D Training Initialize Victim CS to be trained + RdWr2DStartVictim, ///< 2D Training Start Victim Data pattern + RdWr2DFinalizeVictim, ///< 2D Training Finalize Victim Traffic + RdWr2DCompareInPhase, ///< 2D Training In-Phase comparison + RdWr2DCompare180Phase, ///< 2D Training 180 Degree ou-of-phase comparison + RdWr2DProgramDataPattern, ///< 2D Training Program Data Pattern + /// End 2D Read/Write Training Functions + TurnOnAggressorChannels, ///< Enable the Aggressor channels. + StartAggressor, ///< Start Aggressor pattern generation. + StopAggressor, ///< Stop Aggressor pattern generation. + DisableMemHoleMapping, ///< Disable Memory Hole Settings + RestoreMemHoleMapping, ///< Enable Memory Hole Settings + PhyInitVref, ///< Program VrefSel during phy init + NumberOfHooks ///< Size of list +} FAMILY_SPECIFIC_FUNC_INDEX; + +///< Entry for SPD Timing +typedef struct { + BIT_FIELD_NAME BitField; ///< Bit field name of the timing + UINT8 Min; ///< Minimum value for timing + UINT8 Max; ///< Maximum value for timing + UINT8 Bias; ///< Bias from actual value + UINT8 Ratio_x2; ///< Actual value will be multiplied by (Ratio_x2/2) +} CTENTRY; + +/// Structure for northbridge block. +typedef struct _MEM_NB_BLOCK { + MEM_DATA_STRUCT *MemPtr; ///< Point to MEM_DATA_STRUCT. + MEM_PARAMETER_STRUCT *RefPtr; ///< Point to MEM_PARAMETER_STRUCT. + DIE_STRUCT *MCTPtr; ///< point to current Node's MCT struct + DCT_STRUCT *DCTPtr; ///< point to current Node's DCT struct + DCT_STRUCT *AllDCTPtr; ///< point to all Node's DCT structs + CH_DEF_STRUCT *ChannelPtr; ///< point to current channel data + SPD_DEF_STRUCT *SPDPtr; ///< Point to SPD data for current DCT. + struct _MEM_TECH_BLOCK *TechPtr; ///< point to technology block. + struct _MEM_FEAT_BLOCK_NB *FeatPtr; ///< point to NB Specific feature block. + struct _MEM_SHARED_DATA *SharedPtr; ///< Pointer to Memory scratchpad area + struct _MEM_NB_BLOCK *AdjacentDieNBPtr; ///< Pointer to Adjacent Die In same socket + BOOLEAN DieEnabled[MAX_NODES_SUPPORTED];///< Indicates the Dies that are enabled + SPD_DEF_STRUCT *AllNodeSPDPtr; ///< Point to SPD data for the system. + DIE_STRUCT *AllNodeMCTPtr; ///< point to all Node's MCT structs + UINT8 DimmToBeUsed; ///< Dimm to be used in recovery mode. + MEM_PS_BLOCK *PsPtr; ///< point to platform specific block + MEM_PS_BLOCK *PSBlock; ///< point to the first platform specific block on this node. + MEM_FREQ_CHANGE_PARAM *FreqChangeParam; ///< pointer to parameter of frequency change. + + PCI_ADDR PciAddr; ///< PCI address for this node + TSEFO *NBRegTable; ///< contains all bit field definitions + + UINT8 Node; ///< current node. + UINT8 Dct; ///< current DCT. + UINT8 Channel; ///< current channel. + UINT8 DctCount; ///< number of DCTs on the current NB. + UINT8 ChannelCount; ///< number of channels per DCT of the current NB. + UINT8 NodeCount; ///< number of Nodes supported + UINT8 CsPerDelay; ///< number of CS controlled per set of delay registers. + UINT8 CsPerChannel; ///< number of CS per channel. + BOOLEAN Ganged; ///< mode for current MCT controller. + POS_TRN_PATTERN_TYPE PosTrnPattern; ///< specifies the pattern that should be used for position training. + BOOLEAN MemCleared; ///< memory clear flag. + UINT32 CPGInit; ///< continuous pattern generation flag. + UINT16 StartupSpeed; ///< startup speed for DDR3. + UINT16 RcvrEnDlyLimit; ///< maximum value that RcvrEnDly field can take. + UINT32 McaNbCtlReg; ///< reserve MCA reports. + UINT32 VarMtrrHiMsk; ///< variable MTRR mask for upper 32 bits. + UINT32 CsRegMsk; ///< mask for CS base register + UINT32 NBClkFreq; ///< Current NB Clock frequency + UINT8 DefDctSelIntLvAddr; ///< Default DctSelIntLvAddr + UINT8 TrainingSequenceIndex; ///< Index into the Training Sequence + UINT8 RdDqsDlyForMaxRdLat; ///Maximum value of Read DQS Delay used in MaxRdLatency calculation + RRW_SETTINGS RrwSettings; /// Lo) ? (\ + (((UINT32) Hi << 6) | (UINT32) Lo) \ + ) : ( \ + (((UINT32) Lo << 6) | (UINT32) Hi) \ + ) \ + ) \ + ) + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ +VOID +MemNPmuResetNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNLoadPmuFirmwareNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN PMU_FIRMWARE_SET *FirmwareSet, + IN UINT16 NumberOfEntries + ); + +VOID +MemNStartPmuNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemNPendOnPmuCompletionNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +UINT32 +MemNCalcMR0 ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +UINT32 +MemNCalcMR1 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ChipSel + ); + +UINT32 +MemNCalcMR2 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ChipSel + ); + +#endif /* _MNPMU_H_ */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mnreg.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mnreg.h new file mode 100644 index 0000000000..6b8cf8d41e --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mnreg.h @@ -0,0 +1,533 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnreg.h + * + * Definitions for whole register tokens + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MNREG_H_ +#define _MNREG_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/// Registers used in memory initialization +typedef enum { + // NB_REG identifiers + NbRegRangeStart = BFEndOfList, ///< -------------------------- Start of NB_REG range + RegDramBase0, ///< Register DramBase0 + RegDramLimit0, ///< Register DramLimit0 + RegDramBaseHi0, ///< Register DramBaseHi0 + RegDramLimitHi0, ///< Register DramLimitHi0 + RegDramBase1, ///< Register DramBase1 + RegDramLimit1, ///< Register DramLimit1 + RegDramBaseHi1, ///< Register DramBaseHi1 + RegDramLimitHi1, ///< Register DramLimitHi1 + RegDramBase2, ///< Register DramBase2 + RegDramLimit2, ///< Register DramLimit2 + RegDramBaseHi2, ///< Register DramBaseHi2 + RegDramLimitHi2, ///< Register DramLimitHi2 + RegDramBase3, ///< Register DramBase3 + RegDramLimit3, ///< Register DramLimit3 + RegDramBaseHi3, ///< Register DramBaseHi3 + RegDramLimitHi3, ///< Register DramLimitHi3 + RegDramBase4, ///< Register DramBase4 + RegDramLimit4, ///< Register DramLimit4 + RegDramBaseHi4, ///< Register DramBaseHi4 + RegDramLimitHi4, ///< Register DramLimitHi4 + RegDramBase5, ///< Register DramBase5 + RegDramLimit5, ///< Register DramLimit5 + RegDramBaseHi5, ///< Register DramBaseHi5 + RegDramLimitHi5, ///< Register DramLimitHi5 + RegDramBase6, ///< Register DramBase6 + RegDramLimit6, ///< Register DramLimit6 + RegDramBaseHi6, ///< Register DramBaseHi6 + RegDramLimitHi6, ///< Register DramLimitHi6 + RegDramBase7, ///< Register DramBase7 + RegDramLimit7, ///< Register DramLimit7 + RegDramBaseHi7, ///< Register DramBaseHi7 + RegDramLimitHi7, ///< Register DramLimitHi7 + + RegDramHoleAddr, ///< Register DramHoleAddr + RegDctCfgSel, ///< Register DctCfgSel + RegDramBaseSysAddr, ///< Register DramBaseSysAddr + RegDramLimitSysAddr, ///< Register DramLimitSysAddr + + RegDramCtlrBase0, ///< Register DramCtlrBase0 + RegDramCtlrBase1, ///< Register DramCtlrBase1 + RegDramCtlrBase2, ///< Register DramCtlrBase2 + RegDramCtlrBase3, ///< Register DramCtlrBase3 + + RegDramCtlrLimit0, ///< Register DramCtlrLimit0 + RegDramCtlrLimit1, ///< Register DramCtlrLimit1 + RegDramCtlrLimit2, ///< Register DramCtlrLimit2 + RegDramCtlrLimit3, ///< Register DramCtlrLimit3 + + RegDctHiAddrOffset0, ///< Register DctHiAddrOffset0 + RegDctHiAddrOffset1, ///< Register DctHiAddrOffset1 + RegDctHiAddrOffset2, ///< Register DctHiAddrOffset2 + RegDctHiAddrOffset3, ///< Register DctHiAddrOffset3 + + RegDramCtl, ///< Register DramCtl + RegDramInit, ///< Register DramInit + RegDramBankAddr, ///< Register DramBankAddr + RegDramMRS, ///< Register DramMRS + RegDramTmgLo, ///< Register DramTmgLo + RegDramTmgHi, ///< Register DramTmgHi + RegDramConfigLo, ///< Register DramConfigLo + RegDramConfigHi, ///< Register DramConfigHi + + RegDctAddlOffset, ///< Register DctAddlOffset + RegDctAddlData, ///< Register DctAddlData + RegDctAddlOffsetBrdcst, ///< Register DctAddlOffset for broadcast + RegDctAddlDataBrdcst, ///< Register DctAddlData for broadcast + + RegDctTempThrottle, ///< Register DctTempThrottle + RegDramCtlrMisc2, ///< Register DramCtlrMisc2 + RegDramCtlrMisc3, ///< Register DramCtlrMisc3 + RegTraceBufferCtlr, ///< Register TraceBufferCtlr + RegSwapIntLvRgn, ///< Register SwapIntLvRgn + RegMctCfgLo, ///< Register MctCfgLo + RegMctCfgHi, ///< Register MctCfgHi + RegExtMctCfgLo, ///< Register ExtMctCfgLo + RegExtMctCfgHi, ///< Register ExtMctCfgHi + RegDramNbPstate, ///< Register DramNbPstate + + RegGmcToDctCtl0, ///< Register GmcToDctCtl0 + RegGmcToDctCtl1, ///< Register GmcToDctCtl1 + RegGmcToDctCtl2, ///< Register GmcToDctCtl2 + RegGmcToDctFifoCfg1, ///< Register GMC to DCT FIFO Config 1 + + RegCSBaseAddr0, ///< Register CSBaseAddr0 + RegCSBaseAddr1, ///< Register CSBaseAddr1 + RegCSBaseAddr2, ///< Register CSBaseAddr2 + RegCSBaseAddr3, ///< Register CSBaseAddr3 + RegCSMask0, ///< Register CSMask0 + RegCSMask1, ///< Register CSMask1 + RegDramCtlrSelLo, ///< Register DramCtlrSelLo + RegDramCtlrSelHi, ///< Register DramCtlrSelHi + + RegDdr3DramTmg0, ///< Register Ddr3DramTmg0 + RegDdr3DramTmg1, ///< Register Ddr3DramTmg1 + RegDdr3DramTmg2, ///< Register Ddr3DramTmg2 + RegDdr3DramTmg3, ///< Register Ddr3DramTmg3 + RegDdr3DramTmg4, ///< Register Ddr3DramTmg4 + RegDdr3DramTmg5, ///< Register Ddr3DramTmg5 + RegDdr3DramTmg6, ///< Register Ddr3DramTmg6 + RegDdr3DramTmg7, ///< Register Ddr3DramTmg7 + RegDdr3DramTmg8, ///< Register Ddr3DramTmg8 + RegDdr3DramTmg9, ///< Register Ddr3DramTmg9 + RegDdr3DramTmg10, ///< Register Ddr3DramTmg10 + RegPhyRODTCSLow , ///< Register RegPhyRODTCSLow + RegPhyRODTCSHigh, ///< Register RegPhyRODTCSHigh + RegPhyWODTCSLow , ///< Register RegPhyWODTCSLow + RegPhyWODTCSHigh, ///< Register RegPhyWODTCSHigh + RegDdr3DramPwrMng0, ///< Register Ddr3DramPwrMng0 + RegDdr3DramPwrMng1, ///< Register Ddr3DramPwrMng1 + RegDdr3DramOdtCtl, ///< Register Ddr3DramOdtClt + RegMemPsCtlSts, ///< Register MemPsCtlSts + RegMrsBuf0, ///< Register MRS Buffer 0 + RegMrsBuf1, ///< Register MRS Buffer 1 + + RegDramLpbkTrnCtl, ///< Register DramLpbkTrnCtl + RegTargetABase, ///< Register TargetABase + RegDramCmd0, ///< Register DramCmd0 + RegDramCmd1, ///< Register DramCmd1 + RegDramCmd2, ///< Register DramCmd2 + RegDramPRBS, ///< Register DramPRBS + RegDramStatus1, ///< Register DramStatus1 + RegDramDqMaskLo, ///< Register DramDqMaskLo + RegDramDqMaskHi, ///< Register DramDqMaskHi + RegDramEccMask, ///< Register DramEccMask + RegDQErrLo, ///< Register DQErrLo + RegDQErrHi, ///< Register DQErrHi + + RegGddr5DramTmg0, ///< Register Gddr5DramTmg0 + RegGddr5DramTmg1, ///< Register Gddr5DramTmg1 + RegGddr5DramTmg2, ///< Register Gddr5DramTmg2 + RegGddr5DramTmg3, ///< Register Gddr5DramTmg3 + RegGddr5DramTmg4, ///< Register Gddr5DramTmg4 + RegGddr5DramTmg5, ///< Register Gddr5DramTmg5 + RegGddr5DramTmg6, ///< Register Gddr5DramTmg6 + RegGddr5DramTmg7, ///< Register Gddr5DramTmg7 + RegGddr5DramTmg8, ///< Register Gddr5DramTmg8 + RegGddr5DramPowerMng0, ///< Register Gddr5DramPowerMng0 + RegGddr5DramPowerMng1, ///< Register Gddr5DramPowerMng1 + RegGddr5DramCtrl0, ///< Register Gddr5DramCtrl0 + RegGddr5DramNbPstate, ///< Register Gddr5DramNbPstate + + RegNbCap2, ///< Register NbCap2 + RegNbPstateCtl, ///< Register NbPstateCtl + RegNbPstateStatus, ///< Register NbPstateStatus + RegNbPstate0, ///< Register NB Pstate 0 + RegNbPstate1, ///< Register NB Pstate 1 + RegNbPstate2, ///< Register NB Pstate 2 + RegNbPstate3, ///< Register NB Pstate 3 + RegNbFusionCfg, ///< Register NB Fusion Configuration + RegCUPwrStsLo, ///< Register Compute Unit Power Status Low + RegCUPwrStsHi, ///< Register Compute Unit Power Status High + + RegCkeToCsMap, ///< Register Dram CKE to CS Map + + RegMcaNbCtl, ///< Register MCA NB Control + RegMcaNbCfg, ///< Register MCA NB Configuration + RegScrubRateCtl, ///< Register Scrub Rate Control + RegDramScrubAddrLo, ///< Register DRAM Scrub Address Low + RegDramScrubAddrHi, ///< Register DRAM Scrub Address High + RegNbCfg1Lo, ///< Register NB Configuration 1 Low + RegCpuid, ///< Register CPUID Family/Model/Stepping + RegExtMcaNbCfg, ///< Register Extended NB MCA Configuration + + RegReserved01, ///< Reserved + RegReserved02, ///< Reserved + RegReserved03, ///< Reserved + RegReserved04, ///< Reserved + RegReserved05, ///< Reserved + + NbRegRangeEnd, ///< -------------------------- End of NB_REG range + + // DCT_PHY_REG identifiers + DctPhyRegRangeStart, ///< -------------------------- Start of DCT_PHY_REG range + RegRxCtl1, ///< Register RxCtl1 + RegRdPtrInitVal, ///< Register RdPtrInitVal + RegDataRdPtrInitVal, ///< Register DataRdPtrInitVal + RegEdcRdPtrInitVal, ///< Register EdcRdPtrInitVal + RegDataRdPtrOffset, ///< Register DataRdPtrOffset + + RegPmuRst, ///< Register PmuRst + RegPwrStateCmd, ///< Register Power State Command + RegDsMbMsg, ///< Register DS Mailbox Message + RegDsMbProtocol, ///< Register DS Mailbox Protocol + RegMbProtocolShadow, ///< Register Mailbox Protocol Shadow + RegUsMbMsg, ///< Register US Mailbox Message + RegUsMbProtocol, ///< Register US Mailbox Protocol + RegUsMb2Msg, ///< Register US Mailbox 2 Message + RegUsMb2Protocol, ///< Register US Mailbox 2 Protocol + RegSramMsgBlk, ///< Register SRAM Message Block + RegGlobalCtl, ///< Register Global Control + RegGlobalCtlSlaveAbyte, ///< Register Global Control Slave ABYTE + RegGlobalCtlSlaveDbyte, ///< Register Global Control Slave DBYTE + RegGlobalCtlSlaveAbit, ///< Register Global Control Slave ABIT + RegCalMisc2, ///< Register Cal Misc 2 + RegPllMemPs0, ///< Register PLL Mem Pstate 0 + RegPllMemPs1, ///< Register PLL Mem Pstate 1 + RegPmuClkDiv, ///< Register PMU Clock divider + RegPllRegWaitTime, ///< Register PllRegWaitTime + RegPllLockTime, ///< Register PllRegLockTime + RegPhyCADCtl, ///< Register Phy CAD control + RegMemResetCtl, ///< Register Mem reset control + RegDisCal, ///< Register Disable calibration + + RegCadTxSlewRate, ///< Register CAD Tx Slew Rate + RegDataTxSlewRate, ///< Register DATA Tx Slew Rate + + RegAcsmCtrl13, ///< Register AcsmCtrl13 + RegX8DevIDCtl, ///< Register X8 DeviceID Control + + RegTxImpedance, ///< Register for all TX impedance + RegCadTxImpedance, ///< Register CAD Tx Impedance + RegDataTxImpedance, ///< Register Data Tx Impedance + RegDataRxImpedance, ///< Register Data Rx Impedance + + RegAcsmOdtCtrl0, ///< Register ACSM ODT Ctrl + RegAcsmOdtCtrl1, ///< Register ACSM ODT Ctrl + RegAcsmOdtCtrl2, ///< Register ACSM ODT Ctrl + RegAcsmOdtCtrl3, ///< Register ACSM ODT Ctrl + RegAcsmOdtCtrl4, ///< Register ACSM ODT Ctrl + RegAcsmOdtCtrl5, ///< Register ACSM ODT Ctrl + RegAcsmOdtCtrl6, ///< Register ACSM ODT Ctrl + RegAcsmOdtCtrl7, ///< Register ACSM ODT Ctrl + + RegVrefByteAbyte, ///< Register Vref Byte + RegVrefByteDbyte, ///< Register Vref Byte + RegVrefByteMaster, ///< Register Vref Byte + + RegProcOdtTmg, ///< Register Proc ODT Timing + RegPhyClkCtl, ///< Register Phy clock control + + RegTxDly, ///< Register TX delay + RegDataRxDly, ///< Register Data Rx Delay + RegDataTxDly, ///< Register Data Tx Delay + RegDataTxEqHiImp, ///< Register Data Tx EQ Hi Impedence + RegDataTxEqLoImp, ///< Register Data Tx EQ Lo Impedence + RegDataTxEqBoostImp, ///< Register Data Tx EQ Boost Impedence + + DctPhyRegRangeEnd, ///< -------------------------- End of DCT_PHY_REG range + + RegIdLimit ///< Total number of register identifiers + +} REG_BF_NAME; + +/// Bit field location +typedef struct { + UINT32 LoBit: 6; ///< Low bit of the bit field + UINT32 HiBit: 6; ///< High bit of the bit field + UINT32 RegIndex: 12; ///< Register that the bit field is on + UINT32 Reserved: 7; ///< Reserved + UINT32 Linked: 1; ///< 1: The bit field has high bits defined in the very next Bf identifier + ///< 0: The bit field has no further extension +} BF_LOCATION; + +/** + REG_DEF(TableName, RegIndex, Addr) + + @param[in] TableName + @param[in] RegIndex + @param[in] Addr + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define REG_DEF(TableName, RegIndex, Addr) \ + TableName[RegIndex] = Addr + +/** + _BF_DEF(TableName, RegIndex, BfIndex, Hi, Lo) + + @param[in] TableName + @param[in] RegIndex + @param[in] BfIndex + @param[in] Hi + @param[in] Lo + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define _BF_DEF(TableName, RegIndex, BfIndex, Hi, Lo) \ + TableName[BfIndex] = ( \ + ((UINT32) RegIndex << 12) | ( \ + (Hi > Lo) ? (\ + (((UINT32) Hi << 6) | (UINT32) Lo) \ + ) : ( \ + (((UINT32) Lo << 6) | (UINT32) Hi) \ + ) \ + ) \ + ) + +/** + LINK_BF(TableName, LowerBfIndex, HigherBfIndex): + This is one way link: any write to LowerBfIndex would write to HigherBfIndex, + but NOT the other way around. + Requirement: LowerBfIndex must be declared *right* before HigherBfIndex. + + @param[in] TableName + @param[in] LowerBfIndex + @param[in] HigherBfIndex + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define LINK_BF(TableName, LowerBfIndex, HigherBfIndex) { \ + ASSERT ((LowerBfIndex < BFEndOfList) || (LowerBfIndex > RegIdLimit)); \ + ASSERT ((HigherBfIndex < BFEndOfList) || (HigherBfIndex > RegIdLimit)); \ + ASSERT (LowerBfIndex == (HigherBfIndex - 1)) ; \ + TableName[LowerBfIndex] |= ((UINT32) 1) << 31; \ +} + +/*---------------------------------------------------------------------------- + * CHIP TO PAD TRANSLATION + * + *---------------------------------------------------------------------------- + */ + +/// Pad group names +typedef enum { + PAD_ALL = 0, ///< broadcast to all pads + PAD_CKE, ///< pad CKE + PAD_ADDR_CMD, ///< pad ADDR_CMD + PAD_CLK, ///< pad CLK + PAD_CS, ///< pad CS + PAD_ODT, ///< pad ODT + PAD_DQ_L, ///< pad DQ_L + PAD_DQ_H, ///< pad DQ_H + PAD_DQS_DM, ///< pad DQS_DM + PAD_DQS_H, ///< pad DQS_H + PAD_PROC_ODT, ///< pad PROC_ODT + PAD_DQ, ///< pad DQ + PAD_DQS, ///< pad DQS +} PAD_NAME; + +#define MEMCKE0 PAD_CKE +#define MEMADD0 PAD_ADDR_CMD +#define MEMBANK0 PAD_ADDR_CMD +#define MEMPAR0 PAD_ADDR_CMD +#define MEMCLK0_L PAD_CLK +#define MEMCLK0_H PAD_CLK +#define MEMCS0_L PAD_CS +#define MEMCAS0_L PAD_ADDR_CMD +#define MEMWE0_L PAD_ADDR_CMD +#define MEMRAS0_L PAD_ADDR_CMD +#define MEMODT0 PAD_ODT +#define MEMDQ_L PAD_DQ_L +#define MEMDQ_H PAD_DQ_H +#define MEMDQSDM PAD_DQS_DM +#define MEMDQS_H PAD_DQS_H +#define MEMDQ PAD_DQ +#define MEMDQS PAD_DQS + +/// DDR Chip to pad entry +typedef struct { + UINT16 PadName: 4; ///< Pad name + UINT16 Instance: 4; ///< Pad instance + UINT16 Chiplet: 4; ///< Chiplet number + UINT8 Group: 4; ///< Group number + UINT8 PadNum: 4; ///< Pad number +} DDR_CHIP_TO_PAD_ENTRY; + +/*---------------------------------------------------------------------------- + * BIT FIELD TOKEN ENCODING + * + *---------------------------------------------------------------------------- + */ + +/// Sub-structure used to parse a BF token +typedef struct { + UINT32 Index: 12; ///< Index into NBRegTable table + UINT32 Reserved: 4; ///< Reserved + UINT32 PadName: 5; ///< ie CKE, ODT, ADDR,... + UINT32 PadIdxPlus1: 5; ///< Pad instance of a certain type + UINT32 DLNPlus1: 4; ///< DIMM/DLL/NBPs number + UINT32 MemPsPlus1: 2; ///< MemPs number +} BF_TOKEN_PARSE; + +/// Bit field name encoding +typedef union { + BIT_FIELD_NAME FieldName; ///< BF token + BF_TOKEN_PARSE Parse; ///< BF token parse +} BF_NAME_ENC; + + +/** + SW_BC_DIS(BfIndex) + Specifies that set function to not attempt SW broadcast + + @param[in] BfIndex + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define SW_BC_DIS(BfIndex) ((BfIndex) | (0xFFFF0000ul)) + +/** + PER_MEM_PS(p, BfIndex) + Specifies that set function to only broadcast to Mem Pstate p of bit field BfIndex + + @param[in] p + @param[in] BfIndex + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define PER_MEM_PS(p, BfIndex) ((BfIndex) | ((UINT32) (((p) + 1) & 0x3) << 30)) +#define ALL_MEM_PS 2 + +/** + PER_NB_PS(p, BfIndex) + Specifies that set function to only broadcast to NB Pstate p of bit field BfIndex + + @param[in] p + @param[in] BfIndex + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define PER_NB_PS(p, BfIndex) ((BfIndex) | ((UINT32) (((p) + 1) & 0xF) << 26)) +#define NB_PS_PMU 8 +#define ALL_NB_PS 0xFF + +/** + PER_DIMM(p, BfIndex) + Specifies that set function to only broadcast to NB Pstate p of bit field BfIndex + + @param[in] d + @param[in] BfIndex + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define PER_DIMM(d, BfIndex) ((BfIndex) | ((UINT32) (((d) + 1) & 0xF) << 26)) +#ifndef ALL_DIMMS + #define ALL_DIMMS 0xFF +#endif + + +/** + PER_CAD_PAD(t, i, BfIndex) + Specifies that set function to only broadcast a certain pad (ie MEMCKE[3]) + + @param[in] t - pad type (ie MEMCKE) + @param[in] i - pad index (ie 3) + @param[in] BfIndex + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define PER_CAD_PAD(t, i, BfIndex) ((BfIndex) | ((UINT32) (t) << 16) | ((UINT32) (((i) + 1) & 0x1F) << 21)) +#define ALL_PADS 0xFF + +/** + PER_DATA_BYTE(t, b, BfIndex) + Specifies that set function to only broadcast a certain data pad (ie DQ byte 3) + + @param[in] t - data pin type (ie DQ) + @param[in] b - data byte (ie byte 3) + @param[in] BfIndex + + @return REG_BF_ENC Access params encrypted in REG_BF_ENC format. +--*/ +#define PER_DATA_BYTE(t, b, BfIndex) ((BfIndex) | ((UINT32) (t) << 16) | ((UINT32) (((b) + 1) & 0x1F) << 21)) +#define ECC_BYTE 8 +#define ALL_BYTES 0xFF + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +#endif /* _MNREG_H_ */ + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mp.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mp.h new file mode 100644 index 0000000000..c29548894f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mp.h @@ -0,0 +1,523 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mp.h + * + * Platform Specific common header file + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** +* + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* *************************************************************************** +* +*/ + +#ifndef _MP_H_ +#define _MP_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ +/// Type of an entry for Dram Term table +typedef struct { + UINT32 Speed; ///< BitMap for the supported speed + UINT8 Dimms; ///< BitMap for supported number of dimm + UINT8 QR_Dimms; ///< BitMap for supported number of QR dimm + UINT8 DramTerm; ///< DramTerm value + UINT8 QR_DramTerm; ///< DramTerm value for QR + UINT8 DynamicDramTerm; ///< Dynamic DramTerm +} DRAM_TERM_ENTRY; + +/// Type of an entry for POR speed limit table +typedef struct { + UINT16 DIMMRankType; ///< Bitmap of Ranks + UINT8 Dimms; ///< Number of dimm + UINT16 SpeedLimit_1_5V; ///< POR speed limit for 1.5V + UINT16 SpeedLimit_1_35V; ///< POR speed limit for 1.35V + UINT16 SpeedLimit_1_25V; ///< POR speed limit for 1.25V +} POR_SPEED_LIMIT; + +/// UDIMM&RDIMM Max. Frequency +typedef union { + struct { ///< PSCFG_MAXFREQ_ENTRY + UINT8 DimmPerCh; ///< Dimm slot per chanel + UINT16 Dimms:4; ///< Number of Dimms on a channel + UINT16 SR:4; ///< Number of single-rank Dimm + UINT16 DR:4; ///< Number of dual-rank Dimm + UINT16 QR:4; ///< Number of quad-rank Dimm + UINT16 Speed1_5V; ///< Speed limit with voltage 1.5V + UINT16 Speed1_35V; ///< Speed limit with voltage 1.35V + UINT16 Speed1_25V; ///< Speed limit with voltage 1.25V + } _MAXFREQ_ENTRY; + struct { + UINT8 DimmSlotPerCh; + UINT16 CDN; ///< Condition + UINT16 Speed[3]; ///< Speed limit + } MAXFREQ_ENTRY; +} PSCFG_MAXFREQ_ENTRY; + +/// LRDIMM Max. Frequency +typedef union { + struct { ///< PSCFG_LR_MAXFREQ_ENTRY + UINT8 DimmPerCh; ///< Dimm slot per chanel + UINT16 Dimms:4; ///< Number of Dimms on a channel + UINT16 LR:12; ///< Number of LR-DIMM + UINT16 Speed1_5V; ///< Speed limit with voltage 1.5V + UINT16 Speed1_35V; ///< Speed limit with voltage 1.35V + UINT16 Speed1_25V; ///< Speed limit with voltage 1.25V + } _LR_MAXFREQ_ENTRY; + struct { + UINT8 DimmSlotPerCh; + UINT16 CDN; + UINT16 Speed[3]; + } LR_MAXFREQ_ENTRY; +} PSCFG_LR_MAXFREQ_ENTRY; + +/// UDIMM&RDIMM RttNom and RttWr +typedef struct { + UINT64 DimmPerCh:8; ///< Dimm slot per chanel + UINT64 DDRrate:32; ///< Bitmap of DDR rate + UINT64 VDDIO:4; ///< Bitmap of VDDIO + UINT64 Dimm0:4; ///< Bitmap of rank type of Dimm0 + UINT64 Dimm1:4; ///< Bitmap of rank type of Dimm1 + UINT64 Dimm2:4; ///< Bitmap of rank type of Dimm2 + UINT64 Dimm:4; ///< Bitmap of rank type of Dimm + UINT64 Rank:4; ///< Bitmap of rank + UINT8 RttNom:3; ///< Dram term + UINT8 RttWr:5; ///< Dynamic dram term +} PSCFG_RTT_ENTRY; + +/// LRDIMM RttNom and RttWr +typedef struct { + UINT64 DimmPerCh:8; ///< Dimm slot per chanel + UINT64 DDRrate:32; ///< Bitmap of DDR rate + UINT64 VDDIO:4; ///< Bitmap of VDDIO + UINT64 Dimm0:4; ///< Dimm0 population + UINT64 Dimm1:4; ///< Dimm1 population + UINT64 Dimm2:12; ///< Dimm2 population + UINT8 RttNom:3; ///< Dram term + UINT8 RttWr:5; ///< Dynamic dram term +} PSCFG_LR_RTT_ENTRY; + +/// UDIMM&RDIMM&LRDIMM ODT pattern OF 1 DPC +typedef struct { + UINT16 Dimm0; ///< Bitmap of dimm0 rank type or dimm0 population of LRDIMM + UINT32 RdODTCSHigh; ///< RdODTCSHigh + UINT32 RdODTCSLow; ///< RdODTCSLow + UINT32 WrODTCSHigh; ///< WrODTCSHigh + UINT32 WrODTCSLow; ///< WrODTCSLow +} PSCFG_1D_ODTPAT_ENTRY; + +/// UDIMM&RDIMM&LRDIMM ODT pattern OF 2 DPC +typedef struct { + UINT16 Dimm0:4; ///< Bitmap of dimm0 rank type or dimm0 population of LRDIMM + UINT16 Dimm1:12; ///< Bitmap of dimm1 rank type or dimm1 population of LRDIMM + UINT32 RdODTCSHigh; ///< RdODTCSHigh + UINT32 RdODTCSLow; ///< RdODTCSLow + UINT32 WrODTCSHigh; ///< WrODTCSHigh + UINT32 WrODTCSLow; ///< WrODTCSLow +} PSCFG_2D_ODTPAT_ENTRY; + +/// UDIMM&RDIMM&LRDIMM ODT pattern OF 3 DPC +typedef struct { + UINT16 Dimm0:4; ///< Bitmap of dimm0 rank type or dimm0 population of LRDIMM + UINT16 Dimm1:4; ///< Bitmap of dimm1 rank type or dimm1 population of LRDIMM + UINT16 Dimm2:8; ///< Bitmap of dimm2 rank type or dimm2 population of LRDIMM + UINT32 RdODTCSHigh; ///< RdODTCSHigh + UINT32 RdODTCSLow; ///< RdODTCSLow + UINT32 WrODTCSHigh; ///< WrODTCSHigh + UINT32 WrODTCSLow; ///< WrODTCSLow +} PSCFG_3D_ODTPAT_ENTRY; + +/// UDIMM&RDIMM&LRDIMM SlowMode, AddrTmgCtl and ODC +typedef struct { + UINT64 DimmPerCh:8; ///< Dimm slot per channel + UINT64 DDRrate:32; ///< Bitmap of DDR rate + UINT64 VDDIO:4; ///< Bitmap of VDDIO + UINT64 Dimm0:4; ///< Bitmap of dimm0 rank type or dimm0 population of LRDIMM + UINT64 Dimm1:4; ///< Bitmap of dimm1 rank type or dimm1 population of LRDIMM + UINT64 Dimm2:11; ///< Bitmap of dimm2 rank type or dimm2 population of LRDIMM + UINT64 SlowMode:1; ///< SlowMode + UINT32 AddTmgCtl; ///< AddTmgCtl + UINT32 ODC; ///< ODC + UINT8 POdtOff; ///< POdtOff +} PSCFG_SAO_ENTRY; + +/// UDIMM&RDIMM&LRDIMM 2D training config entry +typedef struct { + UINT64 DimmPerCh:8; ///< Dimm per channel + UINT64 DDRrate:32; ///< Bitmap of DDR rate + UINT64 VDDIO:4; ///< Bitmap of VDDIO + UINT64 Dimm0:4; ///< Bitmap of dimm0 rank type or dimm0 population of LRDIMM + UINT64 Dimm1:4; ///< Bitmap of dimm1 rank type or dimm1 population of LRDIMM + UINT64 Dimm2:11; ///< Bitmap of dimm2 rank type or dimm2 population of LRDIMM + UINT64 Enable2D:1; ///< SlowMode +} PSCFG_S2D_ENTRY; + +/// UDIMM&RDIMM MR0[WR] +typedef struct { + UINT8 Timing; ///< Fn2_22C_dct[1:0][Twr] + UINT8 Value; ///< MR0[WR] : bit0 - bit2 available +} PSCFG_MR0WR_ENTRY; + +/// UDIMM&RDIMM MR0[CL] +typedef struct { + UINT8 Timing; ///< Fn2_200_dct[1:0][Tcl] + UINT8 Value:3; ///< MR0[CL] : bit0 - bit2 CL[3:1] + UINT8 Value1:5; ///< MR0[CL] : bit3 CL[0] +} PSCFG_MR0CL_ENTRY; + +/// UDIMM&RDIMM MR2[IBT] +typedef struct { + UINT64 DimmPerCh:4; ///< Dimm per channel + UINT64 DDRrate:32; ///< Bitmap of DDR rate + UINT64 VDDIO:4; ///< Bitmap of VDDIO + UINT64 Dimm0:4; ///< Bitmap of dimm0 rank type + UINT64 Dimm1:4; ///< Bitmap of dimm1 rank type + UINT64 Dimm2:4; ///< Bitmap of dimm2 rank type + UINT64 Dimm:4; ///< Bitmap of rank type of Dimm + UINT64 NumOfReg:4; ///< Number of registers + UINT64 IBT:4; ///< MR2[IBT] value +} PSCFG_MR2IBT_ENTRY; + +/// UDIMM&RDIMM&LRDIMM Operating Speed +typedef struct { + UINT32 DDRrate; ///< Bitmap of DDR rate + UINT8 OPSPD; ///< RC10[OperatingSpeed] +} PSCFG_OPSPD_ENTRY; + +/// LRDIMM IBT +typedef struct { + UINT64 DimmPerCh:4; ///< Dimm per channel + UINT64 DDRrate:32; ///< Bitmap of DDR rate + UINT64 VDDIO:4; ///< Bitmap of VDDIO + UINT64 Dimm0:4; ///< Dimm0 population + UINT64 Dimm1:4; ///< Dimm1 population + UINT64 Dimm2:4; ///< Dimm2 population + UINT64 F0RC8:3; ///< F0RC8 + UINT64 F1RC0:3; ///< F1RC0 + UINT64 F1RC1:3; ///< F1RC1 + UINT64 F1RC2:3; ///< F1RC2 +} PSCFG_L_IBT_ENTRY; + +/// LRDIMM F0RC13[NumPhysicalRanks] +typedef struct { + UINT8 NumRanks:3; ///< NumRanks + UINT8 NumPhyRanks:5; ///< NumPhyRanks +} PSCFG_L_NPR_ENTRY; + +/// LRDIMM F0RC13[NumLogicalRanks] +typedef struct { + UINT16 NumPhyRanks:3; ///< NumPhyRanks + UINT16 DramCap:4; ///< DramCap + UINT16 NumDimmSlot:9; ///< NumDimmSlot + UINT8 NumLogRanks; ///< NumLogRanks +} PSCFG_L_NLR_ENTRY; + +/// UDIMM&RDIMM&LRDIMM pass1 seed entry +typedef struct { + UINT8 DimmPerCh; ///< Dimm per channel + UINT8 Channel; ///< Channel# + UINT16 SeedVal; ///< Seed value +} PSCFG_SEED_ENTRY; + +/// Platform specific configuration types +typedef enum { + PSCFG_MAXFREQ, ///< PSCFG_MAXFREQ + PSCFG_LR_MAXFREQ, ///< PSCFG_LR_MAXFREQ + PSCFG_RTT, ///< PSCFG_RTT + PSCFG_LR_RTT, ///< PSCFG_LR_RTT + PSCFG_ODT_PAT_1D, ///< PSCFG_ODT_PAT_1D + PSCFG_ODT_PAT_2D, ///< PSCFG_ODT_PAT_2D + PSCFG_ODT_PAT_3D, ///< PSCFG_ODT_PAT_3D + PSCFG_LR_ODT_PAT_1D, ///< PSCFG_LR_ODT_PAT_1D + PSCFG_LR_ODT_PAT_2D, ///< PSCFG_LR_ODT_PAT_2D + PSCFG_LR_ODT_PAT_3D, ///< PSCFG_LR_ODT_PAT_3D + PSCFG_SAO, ///< PSCFG_SAO + PSCFG_LR_SAO, ///< PSCFG_LR_SAO + PSCFG_MR0WR, ///< PSCFG_MR0WR + PSCFG_MR0CL, ///< PSCFG_MR0CL + PSCFG_RC2IBT, ///< PSCFG_RC2IBT + PSCFG_RC10OPSPD, ///< PSCFG_RC10OPSPD + PSCFG_LR_IBT, ///< PSCFG_LR_IBT + PSCFG_LR_NPR, ///< PSCFG_LR_NPR + PSCFG_LR_NLR, ///< PSCFG_LR_NLR + PSCFG_S2D, ///< PSCFG_S2D + PSCFG_WL_PASS1_SEED, ///< PSCFG_WL_PASS1_SEED + PSCFG_HWRXEN_PASS1_SEED, ///< PSCFG_HWRXEN_SEED + PSCFG_CADBUS, ///< PSCFG_CADBUS + PSCFG_DATABUS, ///< PSCFG_DATABUS + + // The type of general table entries could be added between + // PSCFG_GEN_START and PSCFG_GEN_END so that the PSCGen routine + // is able to look for the entries per the PSCType. + PSCFG_GEN_START, ///< PSCFG_GEN_START + PSCFG_CLKDIS, ///< PSCFG_CLKDIS + PSCFG_CKETRI, ///< PSCFG_CKETRI + PSCFG_ODTTRI, ///< PSCFG_ODTTRI + PSCFG_CSTRI, ///< PSCFG_CSTRI + PSCFG_GEN_END ///< PSCFG_GEN_END +} PSCFG_TYPE; + +/// Dimm types +typedef enum { + UDIMM_TYPE = 0x01, ///< UDIMM_TYPE + RDIMM_TYPE = 0x02, ///< RDIMM_TYPE + SODIMM_TYPE = 0x04, ///< SODIMM_TYPE + LRDIMM_TYPE = 0x08, ///< LRDIMM_TYPE + SODWN_SODIMM_TYPE = 0x10, ///< SODWN_SODIMM_TYPE + DT_DONT_CARE = 0xFF ///< DT_DONT_CARE +} DIMM_TYPE; + +/// Number of DRAM devices or DIMM slots +typedef enum { + _1DIMM = 0x01, ///< _1DIMM + _2DIMM = 0x02, ///< _2DIMM + _3DIMM = 0x04, ///< _3DIMM + _4DIMM = 0x08, ///< _4DIMM + _DIMM_NONE = 0xF0, ///< _DIMM_NONE (no DIMM slot) + NOD_DONT_CARE = 0xFF ///< NOD_DONT_CARE +} NOD_SUPPORTED; + +/// Table header related definitions +typedef struct { + PSCFG_TYPE PSCType; ///< PSC Type + DIMM_TYPE DimmType; ///< Dimm Type + NOD_SUPPORTED NumOfDimm; ///< Numbef of dimm + CPU_LOGICAL_ID LogicalCpuid; ///< Logical Cpuid + UINT8 PackageType; ///< Package Type + TECHNOLOGY_TYPE TechType; ///< Technology type +} PSC_TBL_HEADER; + +/// Table entry +typedef struct { + PSC_TBL_HEADER Header; ///< PSC_TBL_HEADER + UINT8 TableSize; ///< Table size + VOID *TBLPtr; ///< Pointer of the table +} PSC_TBL_ENTRY; + +#define PT_DONT_CARE 0xFF +#define NP 1 +#define V1_5 1 +#define V1_35 2 +#define V1_25 4 +#define VOLT_ALL (V1_5 | V1_35 | V1_25) +#define DIMM_SR 2 +#define DIMM_DR 4 +#define DIMM_QR 8 +#define DIMM_LR 2 +#define R0 1 +#define R1 2 +#define R2 4 +#define R3 8 +#define CH_A 0x01 +#define CH_B 0x02 +#define CH_C 0x04 +#define CH_D 0x08 +#define CH_ALL 0x0F + +/// CAD Bus configuration +typedef struct { + UINT32 DimmPerCh:2; ///< Bitmap of Dimm slot per chanel + UINT32 DDRrate:18; ///< Bitmap of DDR rate + UINT32 VDDIO:4; ///< Bitmap of VDDIO + UINT32 Dimm0:4; ///< Bitmap of rank type of Dimm0 + UINT32 Dimm1:4; ///< Bitmap of rank type of Dimm1 + + UINT32 SlowMode:8; ///< SlowMode + UINT32 AddrCmdCtl:24; ///< AddrCmdCtl + + UINT8 CkeStrength; ///< CKE drive strength + UINT8 CsOdtStrength; ///< CS ODT drive strength + UINT8 AddrCmdStrength; ///< Addr Cmd drive strength + UINT8 ClkStrength; ///< CLK drive strength +} PSCFG_CADBUS_ENTRY; + +/// On die termination encoding +typedef enum { + ODT_OFF = 0, ///< 0 On die termination disabled + ODT_60 = 1, ///< 1 60 ohms + ODT_120 = 2, ///< 2 120 ohms + ODT_40 = 3, ///< 3 40 ohms + ODT_20 = 4, ///< 4 20 ohms + ODT_30 = 5, ///< 5 30 ohms +} ODT_ENC; + +/// Data Bus configuration +typedef struct { + UINT32 DimmPerCh:2; ///< Bitmap of Dimm slot per chanel + UINT32 DDRrate:18; ///< Bitmap of DDR rate + UINT32 VDDIO:4; ///< Bitmap of VDDIO + UINT32 Dimm0:4; ///< Bitmap of rank type of Dimm0 + UINT32 Dimm1:4; ///< Bitmap of rank type of Dimm1 + + UINT32 RttNom:4; ///< Rtt_Nom + UINT32 RttWr:4; ///< Rtt_Wr + UINT32 DqStrength:8; ///< Data drive strength + UINT32 DqsStrength:8; ///< DQS drive strength + UINT32 OdtStrength:8; ///< ODT drive strength +} PSCFG_DATABUS_ENTRY; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +AGESA_STATUS +MemPConstructPsUDef ( + IN OUT MEM_DATA_STRUCT *MemPtr, + IN OUT CH_DEF_STRUCT *ChannelPtr, + IN OUT MEM_PS_BLOCK *PsPtr + ); + +BOOLEAN +MemPGetDramTerm ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ArraySize, + IN CONST DRAM_TERM_ENTRY *DramTermPtr + ); + +UINT16 +MemPGetPorFreqLimit ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 FreqLimitSize, + IN CONST POR_SPEED_LIMIT *FreqLimitPtr + ); + +VOID +MemPGetPORFreqLimitDef ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +BOOLEAN +MemPPSCFlow ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemPConstructRankTypeMap ( + IN UINT16 Dimm0, + IN UINT16 Dimm1, + IN UINT16 Dimm2, + IN OUT UINT16 *RankTypeInTable + ); + +BOOLEAN +MemPIsIdSupported ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID LogicalId, + IN UINT8 PackageType + ); + +UINT16 +MemPGetPsRankType ( + IN CH_DEF_STRUCT *CurrentChannel + ); + +BOOLEAN +MemPRecPSCFlow ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemPRecConstructRankTypeMap ( + IN UINT16 Dimm0, + IN UINT16 Dimm1, + IN UINT16 Dimm2, + IN OUT UINT16 *RankTypeInTable + ); + +BOOLEAN +MemPRecIsIdSupported ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID LogicalId, + IN UINT8 PackageType + ); + +UINT16 +MemPRecGetPsRankType ( + IN CH_DEF_STRUCT *CurrentChannel + ); + +UINT16 +MemPProceedTblDrvOverride ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 ProceededPSOType + ); + +BOOLEAN +MemPGetPSCPass1Seed ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemPPreparePsTabLookupConditions ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +PSC_TBL_ENTRY * +MemPGetTableEntry ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN PSC_TBL_ENTRY *ListOfTables[], + OUT UINT8 *TableSize + ); + +BOOLEAN +MemPLookupCadBusCfgTabs ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN PSC_TBL_ENTRY *ListOfTables[] + ); + +BOOLEAN +MemPLookupDataBusCfgTabs ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN PSC_TBL_ENTRY *ListOfTables[] + ); + +#endif /* _MP_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mport.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mport.h new file mode 100644 index 0000000000..3e7e23b7ce --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mport.h @@ -0,0 +1,70 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mport.h + * + * API's to support different OS + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ + /***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + *=========================================================================== + * AMD Revision History + * Initial Version + * + */ +#ifndef _MPORT_H_ +#define _MPORT_H_ + +///< 64 bit data structure +///< lo - Lower 32 bits +///< hi - Upper 32 bits +typedef struct { + UINT32 lo; ///< Lower 32 bits + UINT32 hi; ///< Upper 32 bits +} S_UINT64; +/* + * SBDFO - Segment Bus Device Function Offset + * 31:28 Segment (4-bits) + * 27:20 Bus (8-bits) + * 19:15 Device (5-bits) + * 14:12 Function(3-bits) + * 11:00 Offset (12-bits) + */ +typedef UINT32 SBDFO; + +#define GET_SIZE_OF(x) (sizeof (x) / sizeof (x[0])) + +#endif /* _MPORT_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mt.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mt.h new file mode 100644 index 0000000000..90250a2ef0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mt.h @@ -0,0 +1,634 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mt.h + * + * Common Technology + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MT_H_ +#define _MT_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +#define FIRST_PASS 1 +#define SECOND_PASS 2 +#define BIGPAGE_X8_RJ16 0x80 +#define BIGPAGE_X8 0x800000ul +#define DQS_FAIL 1 +#define DQS_PASS 0 +#define DQS_WRITE_DIR 1 +#define WRITE_DAT_DIR 1 +#define DQS_READ_DIR 0 +#define MIN_DQS_WNDW 3 +#define ST_UNSTEADY 0 +#define ST_STEADY 1 +#define ST_GROSS_SWEEP 2 +#define ST_FINE_SWEEP 3 +#define ST_FINISH 4 +#define NIBBLE_0 0 +#define NIBBLE_1 1 + +#define MAX_BYTELANES_PER_CHANNEL (8 + 1) ///< Max Bytelanes per channel + +#define MAX_FILTER_DLY_DDR2 0x20 +#define MAX_FILTER_DLY_DDR3 0x28 + +#define NEW_RECEIVER_START_VALUE 0x4 +#define NEW_RECEIVER_STEP_1 4 +#define NEW_RECEIVER_STEP_2 7 + +#define NEW_RECEIVER_FINAL_OFFSETVALUE 5 + +#define MAX_POS_RX_EN_SEED_GROSS_RANGE 0x20 ///< Max Range RxEn Seed Gross +#define MAX_POS_RX_EN_SEED_GROSS_DIR 0x2 ///< Max RxEn Seed Gross Direction + +#define DBG_PRINT_STAGE 18 // "Stage" +#define DBG_PRINT_0_TO_64 23 // "0...64" +#define DBG_SPACES_4 21 // 4 spaces +#define DBG_POS_NEW_LINE 11 // New Line for POS training +#define DBG_WR_DLY 24 // "Write Delay: " +#define DBG_B_L_R_W_M 22 // " Bytelane Left Right Width Middle" +#define DBG_RX_EN_NEW_LINE 25 // New Line for Rx En +#define DBG_RX_EN_STAGE1 6 // "Receiver Enable Training Stage 1:" +#define DBG_RX_EN_STAGE2 7 // "Receiver Enable Training Stage 2:" +#define DBG_RX_EN_STAGE3 8 // "Receiver Enable Training Stage 3:" +#define DBG_DLY_PER_BL 9 // "Dly per BL -" +#define DBG_A_B_DLY 10 // "ALL BLs have Dly:" +#define DBG_RCVR_PRT_VALUE 0x0010Ful // PORT for RX EN training to print a value +#define DBG_RX_POS_PRT_VALUE 0x0011Ful // PORT for POS training to print a value + +#define DONE_FILTER 0 ///< optimized receiver enable training glitch search complete +#define START_FILTER 1 ///< optimized receiver enable training start glitch filter search +#define FILTER_FIRST_STAGE_COUNT 4 ///< optimized receiver enable training glitch filter first stage count +#define FILTER_SECOND_STAGE_COUNT 7 ///< optimized receiver enable training glitch second stage count +#define FILTER_OFFSET_VALUE 0x1C ///< optimized receiver enable training glitch filter offset value int preamble +#define FILTER_WINDOW_SIZE 0x28 ///< optimized receiver enable training glitch filter search window size +#define FILTER_MAX_REC_EN_DLY_VALUE 0x1FF ///< optimized receiver enable glitch filter max receiver value +#define FILTER_NEW_RECEIVER_START_VALUE 0x0 ///< optimized receiver enable glitch filter Start value +#define MAX_NUMBER_NIBBLES 18 ///< Maximum number of nibbles +#define MAX_NUMBER_LANES 18 ///< Maximum number of lanes (nibbles or bytes) +#define MAX_2D_VREF_ENTRIES 0x20 ///< Maximum number of vref entries +#define MAX_RD_DQS_ENTRIES 0x40 ///< Maximum number of RDDQS Entries +#define VREF_ADDITIONAL_STEP_SIZE 0x0 ///< Vref Additional Step size +#define RDDQS_ADDITIONAL_STEP_SIZE 0x0 ///< RdDqs Additional Step size +#define MAX_2D_DQS_SEED_COUNT 4 ///< Max Seed count +#define MAX_2D_RDDQS_CS_PER_CHANNEL 8 ///< Max CS per RdDQS delay group + +#define EYERIM_PARALLEL_SAMPLING TRUE +#define EYERIM_BROADCAST_DELAYS TRUE +#define SAMPLE_INDEX(l, y, x) (((l) * MAX_2D_VREF_ENTRIES * MAX_RD_DQS_ENTRIES) + ((y) * MAX_RD_DQS_ENTRIES) + (x)) + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ +/// List for Technology specific functions that are supported +typedef enum { + WlTrainingPrepareLrdimm, ///< Technology specific tasks to prepare LRDIMMs for Training + LrdimmControlRegInit, ///< Technology specific tasks to send control words to initialize an LRDIMM + LrdimmFreqChgCtrlWrd, ///< Technology specific tasks to send control words to reprogram LRDIMM's register + LrdimmSendAllMRCmds, ///< Technology specific tasks to send all MR commands + LrdimmRankMultiplication, ///< Determine Rank Multiplication to be used + LrdimmBuf2DramTrain, ///< Perform buffer to DRAM training for LRDIMMs + LrdimmSyncTrainedDlys, ///< Copy trained delay of the first rank of a QR LRDIMM to the third rank + LrdimmPresence, ///< Perform LRDIMM specific tasks at the time of Dimm Presence Detection + DataEyeSaveCompositeEyes, ///< Perform saving the composite data eyes to buffer + DataEyeCompressEyes, ///< Perform compress the composite data eyes. + NumberOfTechHooks ///< Size of list +} TECHNOLOGY_SPECIFIC_FUNC_INDEX; + +/// Structure for RD DQS 2D training RDDQS delays. +typedef struct { + UINT32 PosRdDqsDly; ///< Positive RdDQS Delay + UINT32 NegRdDqsDly; ///< Negative RdDQS Delay +} RD_DQS_2D; +/// Structure for RD DQS 2D training Vref delays +typedef struct { + RD_DQS_2D *Vref;///< pointer to Vref Entries + UINT16 Convolution[MAX_RD_DQS_ENTRIES]; ///< Total number of passes in each mask + UINT8 PosHeight[MAX_RD_DQS_ENTRIES / 2]; ///< Positive Vref height Height per Delay + UINT8 NegHeight[MAX_RD_DQS_ENTRIES / 2]; ///< Negative Vref height Height per Delay + UINT8 HalfDiamondHeight; ///< Half of the Height per BL (height of pos/neg vref) + UINT8 MaxRdDqs; ///< Max RdDqs from convolution function +} VREF_2D; +/// Structure for RD DQS 2D training Nibbles +typedef struct { + VREF_2D Lane[MAX_NUMBER_LANES]; ///< Bytelane or Nibble + UINT8 Vnom; // Nominal Vref value + UINT8 MaxRdDqsSweep; // Maximum RdDqs Sweep size + UINT8 SmallestPosMaxVrefperCS[MAX_2D_RDDQS_CS_PER_CHANNEL]; // Smallest Positive Max Vref per CS + UINT8 SmallestNegMaxVrefperCS[MAX_2D_RDDQS_CS_PER_CHANNEL]; // Smallest Negative Max Vref per CS + UINT8 DiamondLeft[MAX_2D_VREF_ENTRIES]; // Left edge of Diamond for shape display + UINT8 DiamondRight[MAX_2D_VREF_ENTRIES]; // Left edge of Diamond for shape display +} MEM_2D_ENTRY; + +/// Structure for RD DQS 2D training Nibbles +typedef struct { + VREF_2D LaneSaved[MAX_NUMBER_LANES]; ///< Bytelane or Nibble that was saved + INT8 xMin; //Minimum value for RdDqs delays + INT8 xMax; //Maximum value for RdDqs delays + INT8 yMin; //Minimum value for vref delays + INT8 yMax; //Maximum value for vref delays + BOOLEAN ParallelSampling; ///< Flag to indicate parallel sampling feature + BOOLEAN BroadcastDelays; ///< Flag to indicate if delays will be broadcast + UINT32 SampleCount; ///< Count of samples taken + UINT32 VrefUpdates; ///< Count of updates to Vref + UINT32 RdDqsDlyUpdates; ///< Count of updates to RdDqsDly + INT8 Dirs[2]; ///< List of directions to search for each axis +} MEM_2D_RIM_ENTRY; + +/// Structure for Technology block. +typedef struct _MEM_TECH_BLOCK { + MEM_NB_BLOCK *NBPtr; ///< point to northbridge block. + MEM_PARAMETER_STRUCT *RefPtr; ///< point to parameter list. + + /* Temporary storage */ + UINT32 HwcrLo; ///< value of HWCR. + UINT32 CR4reg; ///< CR4 register value. + UINT8 DramEcc; ///< value of Dram ECC bit. + UINT8 *TestBufPtr; ///< point to buffer to store read-back data. + UINT8 *PatternBufPtr; ///< point to pattern buffer. + UINT16 PatternLength; ///< the length of pattern buffer in cache lines. + UINT8 Direction; ///< direction during training. + UINT8 ChipSel; ///< chip select number. + INT8 RestartChipSel; ///< is used to save the chipsel at which first RdDqsDly retrain is issued + UINT16 MaxDlyForMaxRdLat; ///< Largest possible value for Receiver enable delay. + UINT16 PrevSpeed; ///< Previous MemClk frequency + TRAINING_TYPE TrainingType; ///< Type of training currently being done + UINT8 TargetDIMM; ///< Target DIMM to being trained + INT16 WLCriticalDelay; ///< Minimum WL Dly of all byte lanes and all DIMMs + UINT8 Bytelane; ///< Bytelane being trained + UINT8 TrnNibble; ///< Nibble being trained + + + UINT8 Pass; ///< current pass of training. + UINT16 DqsRdWrPosSaved; ///< for position training byte lane saved flag + UINT16 DqsRcvEnSaved; ///< for TrainRcvrEn UINT8 lane saved flag + UINT16 DqsRcvEnSavedS1; ///< for TrainRcvrEn UINT8 lane saved flag + UINT16 DqsRcvEnFirstPassVal; ///< for TrainRcvrEn UINT8 lane saved flag + BOOLEAN GetFirstPassVal; ///< If the first passing value has been found. + BOOLEAN RevertPassVal; ///< Flag to restart training during training process when glitch is found. + UINT8 MaxFilterDly; ///< Maximum filter delay value for RcvrTraining. + UINT16 RcvrEnDlyOpt[MAX_BYTELANES_PER_CHANNEL]; ///< Receiver Enable delay for optimized filter + UINT16 MaxRcvrEnDlyBlOpt[MAX_BYTELANES_PER_CHANNEL]; ///< Max Receiver Enable delay for optimized filter + UINT16 RcvrEnDlyLimitOpt[MAX_BYTELANES_PER_CHANNEL]; ///< Receiver Enable delay Limit for optimized filter + UINT16 FilterStatusOpt[MAX_BYTELANES_PER_CHANNEL]; ///< Filter status to indicate if a ByteLane is "DONE", "SKIP" or "CONTINUE" + UINT16 FilterCountOpt; ///< Filter count to indicate the total number of ByteLanes completed + BOOLEAN DqsRcvEnSavedOpt[MAX_BYTELANES_PER_CHANNEL]; ///< for optimized TrainRcvrEn lane saved flag + UINT16 DqsRcvEnFirstPassValOpt[MAX_BYTELANES_PER_CHANNEL]; ///< for TrainRcvrEn UINT8 lane saved flag for optimized + BOOLEAN GetFirstPassValOpt[MAX_BYTELANES_PER_CHANNEL]; ///< If the first passing value has been found for optimized. + BOOLEAN RevertPassValOpt[MAX_BYTELANES_PER_CHANNEL]; ///< Flag to restart training during training process when glitch is found for optimized. + UINT8 MaxFilterDlyBlOpt[MAX_BYTELANES_PER_CHANNEL]; ///< Maximum filter delay value for RcvrTraining for optimized. + BOOLEAN IncBy1ForNextCountOpt[MAX_BYTELANES_PER_CHANNEL]; ///< Used to determine when to increment by 1 in second stage of opt. rec. en. training + UINT8 FilterSidePassCountOpt[MAX_BYTELANES_PER_CHANNEL]; ///< Indicates that previous side passed + UINT16 DiffSeedGrossSeedPreGross[MAX_BYTELANES_PER_CHANNEL]; ///< Gross difference between GrossSeed and SeedPreGross for HwRxEn Training. + UINT16 PrevPassRcvEnDly[MAX_BYTELANES_PER_CHANNEL]; ///< Receiver Enable Delay value from the previous pass + BOOLEAN SmallDqsPosWindow; ///< Status flag to record small DQS position window event + UINT8 WlNibbleDly[MAX_BYTELANES_PER_CHANNEL]; ///< Nibble based trainig results for Nibble 0 of Write Levelization + UINT16 WlNibble0Seed[MAX_BYTELANES_PER_CHANNEL]; ///< Nibble based trainig seed value for Nibble 0 Write Levelization + UINT16 RxEnNibbleDly[MAX_BYTELANES_PER_CHANNEL]; ///< Nibble based trainig results for Nibble 0 of Rx En training + BOOLEAN ByteLaneError[MAX_BYTELANES_PER_CHANNEL]; ///< Indicates that an error has occured on a bytelane + UINT16 RxOrig[MAX_BYTELANES_PER_CHANNEL]; ///< Original RxEn Delays for seedless training + MEM_2D_ENTRY *Local2DData; ///< Pointer to local data structure + MEM_2D_RIM_ENTRY *SavedData; ///< Eye rim search save data + VOID *RdWr2DData; ///< 2D Read/Write Training Feature Data Struct Pointer + + /* PUBLIC functions */ + VOID (*SendAllMRCmds) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 ChipSel); ///< Send MRS command. + VOID (*FreqChgCtrlWrd) (struct _MEM_TECH_BLOCK *TechPtr); ///< Frequency change control word. + BOOLEAN (*SetDramMode) (struct _MEM_TECH_BLOCK *TechPtr); ///< Set dram mode (DDR2 or DDR3). + BOOLEAN (*DimmPresence) (struct _MEM_TECH_BLOCK *TechPtr); ///< determines if DIMMs present. + BOOLEAN (*SpdCalcWidth) (struct _MEM_TECH_BLOCK *TechPtr); ///< check the symmetry of DIMM pairs. + BOOLEAN (*SpdGetTargetSpeed) (struct _MEM_TECH_BLOCK *TechPtr); ///< get supported frequency. + BOOLEAN (*AutoCycTiming) (struct _MEM_TECH_BLOCK *TechPtr); ///< configure timing based on spd data. + BOOLEAN (*SpdSetBanks) (struct _MEM_TECH_BLOCK *TechPtr); ///< set bank address. + BOOLEAN (*SetDqsEccTmgs) (struct _MEM_TECH_BLOCK *TechPtr); ///< DQS training. + VOID (*GetCSIntLvAddr) (UINT8 BankEnc, UINT8 *LowBit, UINT8 *HiBit); ///< Get Chip select interleave address. + VOID (*AdjustTwrwr) (struct _MEM_TECH_BLOCK *TechPtr); ///< Adjust Twrwr for certain dimm technology. + VOID (*AdjustTwrrd) (struct _MEM_TECH_BLOCK *TechPtr); ///< Adjust Twrrd for certain dimm technology. + INT8 (*GetLD) (struct _MEM_TECH_BLOCK *TechPtr); ///< Get LD value for certain dimm technology. + VOID (*DramInit) (struct _MEM_TECH_BLOCK *TechPtr); ///< dram initialization. + + /* PRIVATE functions */ + VOID (*InitDQSPos4RcvrEn) (struct _MEM_TECH_BLOCK *TechPtr); ///< Initialize training register before training. + VOID (*SetRcvrEnDly) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver, UINT16 RcvEnDly); ///< Set receiver enable delay register value. + VOID (*LoadRcvrEnDly) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver); ///< Load receiver enable delay register value. + BOOLEAN (*SaveRcvrEnDly) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver, UINT16 RcvEnDly, UINT16 cmpResultRank0, UINT16 cmpResultRank1); ///< Save receiver enable delay register value. + BOOLEAN (*SaveRcvrEnDlyFilter) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver, UINT16 RcvEnDly, UINT16 cmpResultRank0, UINT16 cmpResultRank1); ///< saves passing DqsRcvEnDly values to the stack. + VOID (*ResetDCTWrPtr) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver); ///< resets the DCT input buffer write pointer. + UINT16 (*Compare1ClPattern) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Buffer[], UINT8 Pattern[]); ///< Compare training pattern of 1 cache line. + VOID (*SkipChipSelPass1) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 *ChipSel); ///< skips odd chip select if training at 800MT or above. + VOID (*SkipChipSelPass2) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 *ChipSel); ///< skips odd chip select if training at 800MT or above. + UINT16 (*CompareTestPatternFilter) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Buffer[], UINT8 Pattern[], UINT16 ByteCount); ///< compare training pattern with filter. + UINT8 (*MaxByteLanes) ( VOID ); ///< return maximum number of bytelanes. + VOID (*SetDQSDelayCSR) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 ByteLane, UINT8 Dly); ///< Set CSR. + VOID (*DQSWindowSave) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 ByteLane, UINT8 DlyMin, UINT8 DlyMax); ///< programs the trained DQS delay for the specified byte lane and stores its DQS window for reference. + BOOLEAN (*FindMaxDlyForMaxRdLat) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 *ChipSel); ///< Find maximum receiver enable delay value. + UINT8 (*DlyTableWidth) ( VOID ); ///< return the width of the delay tables (eg. RcvEnDlys, WrDqsDlys,...) in number of bytes. + UINT16 (*Compare1ClPatternOpt) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Buffer[], UINT8 Pattern[], UINT8 Side, UINT8 Receiver, BOOLEAN Side1En); ///< Compare training pattern of 1 cache line. + VOID (*LoadRcvrEnDlyOpt) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver); ///< Load receiver enable delay register value. + VOID (*SetRcvrEnDlyOpt) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver, UINT16 RcvEnDly); ///< Set receiver enable delay register value. + BOOLEAN (*CheckRcvrEnDlyLimitOpt) (struct _MEM_TECH_BLOCK *TechPtr); ///< Find limit for all bytelanes + UINT16 (*GetMaxValueOpt) (struct _MEM_TECH_BLOCK *TechPtr); ///< Returns the max value of all bytelanes + VOID (*InitializeVariablesOpt) (struct _MEM_TECH_BLOCK *TechPtr); ///< Initialized variables for optimized training + BOOLEAN (*SetSweepErrorOpt)(struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver, UINT8 DCT, BOOLEAN ErrorCheck); ///< records any errors generated from optimized sweep + VOID (*LoadInitialRcvrEnDlyOpt) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 Receiver); ///< Load the starting value for receiver DQS training. + BOOLEAN (*GetDimmSpdBuffer) (struct _MEM_TECH_BLOCK *TechPtr, UINT8 **SpdBuffer, UINT8 Dimm); ///< Gets pointer to spd buffer for a dimm on the current channel, if present + UINT8 (*GetMinMaxGrossDly) (struct _MEM_TECH_BLOCK *TechPtr, TRN_DLY_TYPE TrnDlyType, BOOLEAN IfMax); ///< Gets the minimum or maximum gross dly value + + /* Technology Specific Hooks */ + BOOLEAN (*(TechnologySpecificHook[NumberOfTechHooks])) (struct _MEM_TECH_BLOCK *TechPtr, VOID *OptParam); ///< Technology specific functions +} MEM_TECH_BLOCK; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +VOID +MemTDimmByteTrainInit ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTTrainMaxLatency ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTSetDQSEccTmgs ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTSetDQSEccTmgsRDdr3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTTrainRcvrEnSwPass1 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTTrainDQSEdgeDetectSw ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTTrainDQSEdgeDetect ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTDramInitSw3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); +VOID +MemTDramInitHw ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); +BOOLEAN +MemTFeatDef ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); +BOOLEAN +MemTSaveRcvrEnDlyByteFilter ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly, + IN UINT16 CmpResultRank0, + IN UINT16 CmpResultRank1 + ); + +BOOLEAN +MemTSaveRcvrEnDlyByteFilterOpt ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT16 RcvEnDly, + IN UINT16 CmpResultRank0, + IN UINT16 CmpResultRank1 + ); + +BOOLEAN +MemTNewRevTrainingSupport ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTTrainOptRcvrEnSwPass1 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTWriteLevelizationHw3Pass1 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTWriteLevelizationHw3Pass2 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTPreparePhyAssistedTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTExitPhyAssistedTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTDqsTrainRcvrEnHwPass1 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTDqsTrainRcvrEnHwPass2 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemRecTSetWrDatRdDqs ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 WrDatDly + ); + +VOID +MemRecTTrainDQSPosSw ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemRecTTrainRcvrEnSw ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemRecTTrainRcvrEnHw ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemRecTTrainRcvrEnHwSeedless ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemRecTBeginTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemRecTEndTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTSetSweepErrorOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Receiver, + IN UINT8 Dct, + IN BOOLEAN ErrorCheck + ); + +VOID +MemTInitializeVariablesOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +UINT16 +MemTGetMaxValueOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTCheckRcvrEnDlyLimitOptByte ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemTMarkTrainFail ( + IN OUT MEM_TECH_BLOCK *TechPtr +); + +VOID +MemTBeginTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemTEndTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemTSetDQSDelayAllCSR ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Dly + ); + +BOOLEAN +MemTExitPhyAssistedTrainingClient3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTFindMaxRcvrEnDlyRdDqsDlyByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + OUT UINT8 *ChipSel + ); + +BOOLEAN +MemTFindMaxRcvrEnDlyRdDqsDlyByteUnb ( + IN OUT MEM_TECH_BLOCK *TechPtr, + OUT UINT8 *ChipSel + ); + +VOID +MemTSendCtlWord3 ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 CmdNum, + IN UINT8 Value + ); + +VOID +MemTCommonTechInit ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTLrdimmConstructor3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTRdPosWithRxEnDlySeeds3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemTTrackRxEnSeedlessRdWrNoWindBLError ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemTTrackRxEnSeedlessRdWrSmallWindBLError ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN OUT VOID *OptParam + ); + +BOOLEAN +MemTAmdRdDqs2DTraining ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemT2DProgramVref ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 Vref + ); + +VOID +MemT2DPrograRdDQSDly ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN UINT8 RdDQSDly + ); + +BOOLEAN +MemT2DRdDQSHeight ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ); + +BOOLEAN +MemT2DRdDQSApplyMask ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ); + +UINT8 +MemGet2dRdDQSWidth ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ); + +BOOLEAN +MemT2DRdDQSPrograMaxRdDQSDly ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ); + +UINT8 +MemT2DGetMaxLanes ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +StoreResult ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data, + IN UINT32 InPhaseResult[], + IN UINT32 PhaseResult180[] + ); + +VOID +MemT2DProgramIntExtVrefSelect ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemCheck2dRdDQSDiamondMaskStep ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data, + IN UINT8 Vref, + IN UINT8 Lane + ); + +BOOLEAN +MemT2DRdDQSFinalVrefMargin ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ); + +BOOLEAN +MemT2DRdDQSFindCsVrefMargin ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ); + +BOOLEAN +MemTCheck2DTrainingPerConfig ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +BOOLEAN +MemT2DRdDQSEyeRimSearch ( + IN OUT MEM_TECH_BLOCK *TechPtr + ); + +VOID +MemT2DRdDqsDisplaySearch ( + IN OUT MEM_TECH_BLOCK *TechPtr, + IN MEM_2D_ENTRY *Data + ); + +BOOLEAN +MemTFindMaxRcvrEnDlyTrainedByPmuByte ( + IN OUT MEM_TECH_BLOCK *TechPtr, + OUT UINT8 *ChipSel + ); + +#endif /* _MT_H_ */ diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mu.h b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mu.h new file mode 100644 index 0000000000..1489fe8b5a --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/mu.h @@ -0,0 +1,272 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mu.h + * + * Utility support + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem) + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + **/ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *************************************************************************** + * + */ + +#ifndef _MU_H_ +#define _MU_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#ifndef PSO_ENTRY + #define PSO_ENTRY UINT8 +#endif + +// +// Maximum value macro +// +#ifndef MAX + #define MAX(X, Y) (((X) < (Y)) ? (Y) : (X)) +#endif +// +// Minimum Value macro +// +#ifndef MIN + #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#endif +// +// Absolute Value Macro +// +#ifndef ABS + #define ABS(X) (((X) < 0) ? (-(X)) : (X)) +#endif +// +// Taking ceiling of (a / b) +// +#ifndef CEIL_DIV + #define CEIL_DIV(a, b) (((a) + (b) - 1) / (b)) +#endif +// +// Check if value x is a power of 2 or not +// +#ifndef IS_POWER_OF_2 + #define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0) +#endif +// +// Find offset of a member variable in a struct +// +#ifndef OFFSET_OF + #define OFFSET_OF(s, m) ((UINTN) ( (UINT8 *)&((s *)0)->m - (UINT8 *)0 )) +#endif + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/// Test patterns for DQS training +typedef enum { + TestPattern0, ///< Test pattern used in first pass of receiver enable training + TestPattern1, ///< Test pattern used in first pass of receiver enable training + TestPattern2, ///< Test pattern used in second pass of receiver enable training + TestPatternJD1B, ///< 72-bit test pattern used in position training (ganged mode) + TestPatternJD1A, ///< 72-bit test pattern used in position training + TestPatternJD256B, ///< 256-bit test pattern used in position training (ganged mode) + TestPatternJD256A, ///< 256-bit test pattern used in position training + TestPatternML, ///< Test pattern used in first pass of max latency training + TestPattern3, ///< Test pattern used in first pass of receiver enable training + TestPattern4 ///< Test pattern used in first pass of receiver enable training +} TRAIN_PATTERN; + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +VOID +MemUWriteCachelines ( + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ); + +VOID +MemUReadCachelines ( + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ); + +VOID +MemUDummyCLRead ( + IN UINT32 Address + ); + +VOID +MemUFlushPattern ( + IN UINT32 Address, + IN UINT16 ClCount + ); + + +VOID +MemUFillTrainPattern ( + IN TRAIN_PATTERN Pattern, + IN UINT8 Buffer[], + IN UINT16 Size + ); + +UINT32 +MemUSetUpperFSbase ( + IN UINT32 Address, + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +VOID +MemUSetTargetWTIO ( + IN UINT32 Address, + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +VOID +MemUResetTargetWTIO ( + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +VOID +MemUProcIOClFlush ( + IN UINT32 Address, + IN UINT16 ClCount, + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +VOID +MemUWait10ns ( + IN UINT32 Count, + IN OUT MEM_DATA_STRUCT *MemPtr + ); + +VOID +MemUGetWrLvNblErr ( + IN OUT UINT16 *ErrBitmap, + IN UINT32 TestAddr, + IN UINT16 ClCount + ); + +VOID +AlignPointerTo16Byte ( + IN OUT UINT8 **BufferPtrPtr + ); + +VOID * +FindPSOverrideEntry ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN PSO_ENTRY EntryType, + IN UINT8 SocketID, + IN UINT8 ChannelID, + IN UINT8 DimmID, + IN CPU_LOGICAL_ID *LogicalIdPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GetMaxDimmsPerChannel ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN UINT8 ChannelID + ); + +UINT8 +GetMaxSolderedDownDimmsPerChannel ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN UINT8 ChannelID + ); + +UINT8 +GetMaxChannelsPerSocket ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GetMaxCSPerChannel ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN UINT8 ChannelID + ); + +UINT8 +GetSpdSocketIndex ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GetSpdChannelIndex ( + IN PSO_TABLE *PlatformMemoryConfiguration, + IN UINT8 SocketID, + IN UINT8 ChannelID, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GetVarMtrrHiMsk ( + IN CPU_LOGICAL_ID *LogicalIdPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +MemUMFenceInstr ( + VOID); + +UINT32 +MemUnsToMemClk ( + IN UINT32 Speed, + IN UINT32 NumberOfns + ); +#endif /* _MU_H_ */ + + -- cgit v1.2.3