diff options
author | efdesign98 <efdesign98@gmail.com> | 2011-07-13 16:43:39 -0700 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2011-07-15 14:17:00 +0200 |
commit | 229f7cb6d660ad4063c9f65e3fabfff80583f281 (patch) | |
tree | eaa627ceb717250c38f1bc6ca79868b331d12e23 /src/vendorcode/amd/agesa/f10/Proc/CPU | |
parent | 25f23f17bcb2bac9fb5af0f5d6d1d8c1c9ea16ff (diff) | |
download | coreboot-229f7cb6d660ad4063c9f65e3fabfff80583f281.tar.xz |
Add the AMD Family10 Agesa code
This change officially adds the Agesa code for the AMD Family 10
cpus. This code supports the G34 and C32 sockets.
Change-Id: Idae50417e530ad40a29fb6fff5b427f6b138126c
Signed-off-by: Frank Vibrans <frank.vibrans@amd.com>
Signed-off-by: efdesign98 <efdesign98@gmail.com>
Reviewed-on: http://review.coreboot.org/95
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/vendorcode/amd/agesa/f10/Proc/CPU')
143 files changed, 50879 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10MultiLinkPciTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10MultiLinkPciTables.c new file mode 100755 index 0000000000..4313e08695 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10MultiLinkPciTables.c @@ -0,0 +1,1442 @@ +/** + * @file + * + * AMD Family_10 PCI tables from Multi-Link BKDG paragraph recommended settings. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_F10MULTILINKPCITABLES_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 F10MultiLinkPciRegisters[] = +{ + // Function 0 + +// F0x68 - Link Transaction Control +// bit[14:13], BufPriRel = 02h + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + (AMD_F10_ALL & ~AMD_F10_Dx), // CpuRevision rev C or less. + }, + {AMD_PF_MULTI_LINK}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x68), // Address + 0x00004000, // regData + 0x00006000, // regMask + }} + }, + // F0x[F0,D0,B0,90] Link Base Buffer Count Register + // 27:25 FreeData: 2 + // 24:20 FreeCmd: 8 + // 19:18 RspData: 2 + // 17:16 NpReqData: 2 + // 15:12 ProbeCmd: 9 + // 11:8 RspCmd: 9 + // 7:5 PReq: 2 + // 4:0 NpReqCmd: 4 +{ + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + HT_HOST_FEAT_COHERENT, // link features + 0x10, // address + 0x048A9944, // data + 0x0FFFFFFF // mask + }} + }, + // F0x[F0,D0,B0,90] Link Base Buffer Count Register + // 27:25 FreeData: 2 + // 24:20 FreeCmd: 8 + // 19:18 RspData: 1 + // 17:16 NpReqData: 1 + // 15:12 ProbeCmd: 0 + // 11:8 RspCmd: 2 + // 7:5 PReq: 4 + // 4:0 NpReqCmd: 18 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + HT_HOST_FEAT_NONCOHERENT, // link features + 0x10, // address + 0x04850292, // data + 0x0FFFFFFF // mask + }} + }, + // F0x[F0,D0,B0,90] Link Base Buffer Count Register + // 27:25 FreeData: 0 + // 24:20 FreeCmd: 8 + // 19:18 RspData: 1 + // 17:16 NpReqData: 1 + // 15:12 ProbeCmd: 0 + // 11:8 RspCmd: 2 + // 7:5 PReq: 6 + // 4:0 NpReqCmd: 16 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + HT_HOST_FEAT_NONCOHERENT, // link features + 0x10, // address + 0x008502D0, // data + 0x0FFFFFFF // mask + }} + }, + // F0x[F0,D0,B0,90] Link Base Buffer Count Register + // 27:25 FreeData: 0 + // 24:20 FreeCmd: 8 + // 19:18 RspData: 3 + // 17:16 NpReqData: 2 + // 15:12 ProbeCmd: 8 + // 11:8 RspCmd: 9 + // 7:5 PReq: 2 + // 4:0 NpReqCmd: 4 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + HT_HOST_FEAT_COHERENT, // link features + 0x10, // address + 0x008E8944, // data + 0x0FFFFFFF // mask + }} + }, + // F0x[F0,D0,B0,90] Link Base Buffer Count Register + // 27:25 FreeData: 0 + // 24:20 FreeCmd: 8 + // 19:18 RspData: 1 + // 17:16 NpReqData: 1 + // 15:12 ProbeCmd: 0 + // 11:8 RspCmd: 2 + // 7:5 PReq: 6 + // 4:0 NpReqCmd: 15 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + HT_HOST_FEAT_NONCOHERENT, // link features + 0x10, // address + 0x008502CF, // data + 0x0FFFFFFF // mask + }} + }, + // F0x[F4,D4,B4,94] Link Base Buffer Count Register + // 28:27 IsocRspData: 0 + // 26:25 IsocNpReqData: 0 + // 24:22 IsocRspCmd: 0 + // 21:19 IsocPReq: 0 + // 18:16 IsocNpReqCmd: 0 +{ + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + HT_HOST_FEAT_COHERENT, // link features + 0x14, // address + 0x00000000, // data + 0x1FFF0000 // mask + }} + }, + // F0x[F4,D4,B4,94] Link Base Buffer Count Register + // 28:27 IsocRspData: 0 + // 26:25 IsocNpReqData: 0 + // 24:22 IsocRspCmd: 0 + // 21:19 IsocPReq: 0 + // 18:16 IsocNpReqCmd: 0 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + HT_HOST_FEAT_NONCOHERENT, // link features + 0x14, // address + 0x00000000, // data + 0x1FFF0000 // mask + }} + }, + // F0x[F4,D4,B4,94] Link Base Buffer Count Register + // 28:27 IsocRspData: 0 + // 26:25 IsocNpReqData: 1 + // 24:22 IsocRspCmd: 0 + // 21:19 IsocPReq: 0 + // 18:16 IsocNpReqCmd: 1 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + HT_HOST_FEAT_COHERENT, // link features + 0x14, // address + 0x02010000, // data + 0x1FFF0000 // mask + }} + }, + // F0x[F4,D4,B4,94] Link Base Buffer Count Register + // 28:27 IsocRspData: 0 + // 26:25 IsocNpReqData: 0 + // 24:22 IsocRspCmd: 0 + // 21:19 IsocPReq: 0 + // 18:16 IsocNpReqCmd: 1 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + HT_HOST_FEAT_NONCOHERENT, // link features + 0x14, // address + 0x00010000, // data + 0x1FFF0000 // mask + }} + }, + +// Function 3 - Misc. Control + +// F3x6C - Data Buffer Control +// XBAR buffer settings +// bits[2:0] UpReqDBC = 2 +// bits[5:4] DnReqDBC = 1 +// bits[7:6] DnRspDBC = 1 +// bit[15] DatBuf24 = 1 +// bits[18:16] UpRspDBC = 1 +// bits[30:28] IsocRspDBC = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + MAKE_SBDFO(0, 0, 24, FUNC_3, 0x6C), // Address + 0x00018052, // regData + 0x700780F7, // regMask + }} + }, +// F3x6C - Data Buffer Control +// XBAR buffer settings +// bits[2:0] UpReqDBC = 2 +// bits[5:4] DnReqDBC = 1 +// bits[7:6] DnRspDBC = 1 +// bit[15] DatBuf24 = 1 +// bits[18:16] UpRspDBC = 2 +// bits[30:28] IsocRspDBC = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + MAKE_SBDFO(0, 0, 24, FUNC_3, 0x6C), // Address + 0x00028052, // regData + 0x700780F7, // regMask + }} + }, +// F3x6C - Data Buffer Control +// bits[2:0] UpReqDBC = 2 +// bits[5:4] DnReqDBC = 1 +// bits[7:6] DnRspDBC = 1 +// bit[15] DatBuf24 = 1 +// bits[18:16] UpRspDBC = 1 +// bits[30:28] IsocRspDBC = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x6C), // Address + 0x10018052, // regData + 0x700780F7, // regMask + }} + }, +// F3x70 - SRI_to_XBAR Command Buffer Count +// bits[2:0] UpReqCBC = 3 +// bits[5:4] DnReqCBC = 1 +// bits[7:6] DnRspCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[18:16] UpRspCBC = 4 +// bits[22:20] IsocReqCBC = 0 +// bits[26:24] IsocPreqCBC = 0 +// bits[30:28] IsocRspCBC = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x70), // Address + 0x00041153, // regData + 0x777777F7, // regMask + }} + }, +// F3x70 - SRI_to_XBAR Command Buffer Count +// bits[2:0] UpReqCBC = 3 +// bits[5:4] DnReqCBC = 1 +// bits[7:6] DnRspCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[18:16] UpRspCBC = 5 +// bits[22:20] IsocReqCBC = 0 +// bits[26:24] IsocPreqCBC = 0 +// bits[30:28] IsocRspCBC = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x70), // Address + 0x00051153, // regData + 0x777777F7, // regMask + }} + }, +// F3x70 - SRI_to_XBAR Command Buffer Count +// bits[2:0] UpReqCBC = 3 +// bits[5:4] DnReqCBC = 1 +// bits[7:6] DnRspCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[18:16] UpRspCBC = 5 +// bits[22:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 0 +// bits[30:28] IsocRspCBC = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x70), // Address + 0x10151153, // regData + 0x777777F7, // regMask + }} + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 0 +// bits[26:24] IsocPreqCBC = 0 +// bits[30:28] DRReqCBC = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0x00081111, // regData + 0x00FF7777, // regMask + }} + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 0 +// bits[30:28] DRReqCBC = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0x00181111, // regData + 0x00FF7777, // regMask + }} + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 20 +// bits[11:8] Sri2XbarFreeXreqCBC = 9 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 9 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00090914, // regData + 0x707FFF1F, // regMask + }} + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 24 +// bits[11:8] Sri2XbarFreeXreqCBC = 9 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 9 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (CORE_RANGE_0 (COUNT_RANGE_LOW, 4) | COUNT_RANGE_NONE), // 4 or fewer cores. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00090A18, // regData + 0x007FFF1F, // regMask + }} + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 22 +// bits[11:8] Sri2XbarFreeXreqCBC = 9 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 9 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (CORE_RANGE_0 (5, COUNT_RANGE_HIGH) | COUNT_RANGE_NONE), // greater than 4, ex. 6. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00090A16, // regData + 0x707FFF1F, // regMask + }} + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 23 +// bits[11:8] Sri2XbarFreeXreqCBC = 9 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 9 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00090917, // regData + 0x707FFF1F, // regMask + }} + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 23 +// bits[11:8] Sri2XbarFreeXreqCBC = 9 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 9 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (CORE_RANGE_0 (COUNT_RANGE_LOW, 4) | COUNT_RANGE_NONE), // 4 or fewer cores. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00090917, // regData + 0x007FFF1F, // regMask + }} + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 21 +// bits[11:8] Sri2XbarFreeXreqCBC = 9 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 9 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (CORE_RANGE_0 (5, COUNT_RANGE_HIGH) | COUNT_RANGE_NONE), // greater than 4, ex. 6. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00090915, // regData + 0x707FFF1F, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 0 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 0 +// bits[23:20] FreeTok = A + { + ProcCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (PROCESSOR_RANGE_0 (COUNT_RANGE_LOW, 1) | PROCESSOR_RANGE_1 (3, COUNT_RANGE_HIGH)), // anything but two. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00A00755, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 0 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 0 +// bits[23:20] FreeTok = 8 + { + ProcCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (PROCESSOR_RANGE_0 (2, 2) | COUNT_RANGE_NONE), // exactly two. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00800755, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 1 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 1 +// bits[23:20] FreeTok = 10 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (DEGREE_RANGE_0 (COUNT_RANGE_LOW, 1) | COUNT_RANGE_NONE), // 2 Socket, half populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00A11755, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 1 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 1 +// bits[23:20] FreeTok = 9 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROBEFILTER, + (DEGREE_RANGE_0 (COUNT_RANGE_LOW, 1) | COUNT_RANGE_NONE), // 2 Socket, half populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00911755, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 1 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 1 +// bits[23:20] FreeTok = 5 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (DEGREE_RANGE_0 (3, 3) | COUNT_RANGE_NONE), // 2 Socket, fully populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00511755, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 1 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 1 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 1 +// bits[23:20] FreeTok = 7 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROBEFILTER, + (DEGREE_RANGE_0 (3, 3) | COUNT_RANGE_NONE), // 2 Socket, fully populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00711555, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 1 +// bits[15:14] IsocPreqTok = ] +// bits[17:16] IsocRspTok = 1 +// bits[23:20] FreeTok = 8 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (DEGREE_RANGE_0 (2, 2) | COUNT_RANGE_NONE), // 4 Socket, half populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00811755, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 1 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 2 +// bits[23:20] FreeTok = 2 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (DEGREE_RANGE_0 (4, COUNT_RANGE_HIGH) | COUNT_RANGE_NONE), // 4 Socket, fully populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00211755, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 1 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 1 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 1 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 1 +// bits[23:20] FreeTok = 6 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROBEFILTER, + (DEGREE_RANGE_0 (4, COUNT_RANGE_HIGH) | COUNT_RANGE_NONE), // 4 Socket, fully populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00611555, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 2 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 0 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 0 +// bits[23:20] FreeTok = 8 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C32_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (COUNT_RANGE_ALL | COUNT_RANGE_NONE), + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00800756, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 2 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 1 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 1 +// bits[23:20] FreeTok = 8 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C32_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + (COUNT_RANGE_ALL | COUNT_RANGE_NONE), + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00811756, // regData + 0x00F3FFFF, // regMask + }} + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 3 +// bits[7:4] ProbeTok = 3 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000033, // regData + 0x000000FF, // regMask + }} + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 5 +// bits[7:4] ProbeTok = 1 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + PERFORMANCE_PROBEFILTER, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000015, // regData + 0x000000FF, // regMask + }} + }, +// F3x144 - MCT to XCS Token Count +// All non probe filter configs +// bits[3:0] RspTok = 3 +// bits[7:4] ProbeTok = 3 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROFILE_ALL, + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000033, // regData + 0x000000FF, // regMask + }} + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 4 +// bits[7:4] ProbeTok = 1 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROBEFILTER, // Features + (DEGREE_RANGE_0 (COUNT_RANGE_LOW, 1) | DEGREE_RANGE_1 (4, COUNT_RANGE_HIGH)), // 2 Socket, half populated, or 4 Socket, fully populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000014, // regData + 0x000000FF, // regMask + }} + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 5 +// bits[7:4] ProbeTok = 1 + { + TokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROBEFILTER, // Features + (DEGREE_RANGE_0 (2, 2) | DEGREE_RANGE_1 (3, 3)), // 2 Socket, fully populated, or 4 Socket, half populated. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000015, // regData + 0x000000FF, // regMask + }} + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 5 +// bits[7:4] ProbeTok = 1 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C32_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + PERFORMANCE_PROBEFILTER, + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000015, // regData + 0x000000FF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 2 +// bits[9:8] IsocReqTok0 = 0 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + (COUNT_RANGE_ALL | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + HT_HOST_FEAT_GANGED, + 0x000000AA, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 1 +// bits[3:2] PReqTok0 = 1 +// bits[5:4] RspTok0 = 1 +// bits[7:6] ProbeTok0 = 1 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 1 +// bits[19:18] PReqTok1 = 1 +// bits[21:20] RspTok1 = 1 +// bits[23:22] ProbeTok1= 1 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (COUNT_RANGE_LOW, 1) | PROCESSOR_RANGE_1 (3, COUNT_RANGE_HIGH)), + PERFORMANCE_PROFILE_ALL, + HT_HOST_FEAT_UNGANGED, + 0x00550055, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 1 +// bits[3:2] PReqTok0 = 1 +// bits[5:4] RspTok0 = 1 +// bits[7:6] ProbeTok0 = 1 +// bits[9:8] IsocReqTok0 = 0 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 1 +// bits[17:16] ReqTok1 = 1 +// bits[19:18] PReqTok1 = 1 +// bits[21:20] RspTok1 = 1 +// bits[23:22] ProbeTok1= 1 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (2, 2) | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + HT_HOST_FEAT_UNGANGED, + 0x00554055, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 0 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (COUNT_RANGE_LOW, 2) | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + HT_HOST_FEAT_NONCOHERENT, + 0x0000012A, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 1 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 2 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (COUNT_RANGE_LOW, 2) | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + (HT_HOST_AND | HT_HOST_FEAT_COHERENT | HT_HOST_FEAT_GANGED), + 0x000001A6, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 1 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (COUNT_RANGE_LOW, 2) | COUNT_RANGE_NONE), + PERFORMANCE_PROBEFILTER, + (HT_HOST_AND | HT_HOST_FEAT_COHERENT | HT_HOST_FEAT_GANGED), + 0x0000016A, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 1 +// bits[3:2] PReqTok0 = 1 +// bits[5:4] RspTok0 = 1 +// bits[7:6] ProbeTok0 = 1 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 1 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 1 +// bits[19:18] PReqTok1 = 1 +// bits[21:20] RspTok1 = 1 +// bits[23:22] ProbeTok1= 1 +// bits[24] IsocReqTok1 = 1 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (COUNT_RANGE_LOW, 1) | PROCESSOR_RANGE_1 (3, COUNT_RANGE_HIGH)), + PERFORMANCE_PROFILE_ALL, + (HT_HOST_AND | HT_HOST_FEAT_COHERENT | HT_HOST_FEAT_UNGANGED), + 0x01550155, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 0 +// bits[9:8] IsocReqTok0 = 2 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (3, COUNT_RANGE_HIGH) | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + HT_HOST_FEAT_NONCOHERENT, + 0x0000022A, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 1 +// bits[3:2] PReqTok0 = 1 +// bits[5:4] RspTok0 = 1 +// bits[7:6] ProbeTok0 = 1 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 1 +// bits[17:16] ReqTok1 = 1 +// bits[19:18] PReqTok1 = 1 +// bits[21:20] RspTok1 = 1 +// bits[23:22] ProbeTok1= 1 +// bits[24] IsocReqTok1 = 1 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (2, 2) | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + (HT_HOST_AND | HT_HOST_FEAT_COHERENT | HT_HOST_FEAT_UNGANGED), + 0x01554155, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 1 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 2 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (3, COUNT_RANGE_HIGH) | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + (HT_HOST_AND | HT_HOST_FEAT_COHERENT | HT_HOST_FEAT_GANGED), + 0x000001A6, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 1 +// bits[5:4] RspTok0 =1 +// bits[7:6] ProbeTok0 = 2 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (PROCESSOR_RANGE_0 (3, COUNT_RANGE_HIGH) | COUNT_RANGE_NONE), + PERFORMANCE_PROBEFILTER, + (HT_HOST_AND | HT_HOST_FEAT_COHERENT | HT_HOST_FEAT_GANGED), + 0x00000196, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 2 +// bits[9:8] IsocReqTok0 = 0 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 3 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C32_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_NFCM)}, // platformFeatures + {{ + (COUNT_RANGE_ALL | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + HT_HOST_FEATURES_ALL, + 0x0000C0AA, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 0 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 2 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C32_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (COUNT_RANGE_ALL | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + HT_HOST_FEAT_NONCOHERENT, + 0x0000812A, // regData + 0xD5FFFFFF, // regMask + }} + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 2 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 2 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + HtTokenPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C32_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_MULTI_LINK | AMD_PF_IOMMU)}, // platformFeatures + {{ + (COUNT_RANGE_ALL | COUNT_RANGE_NONE), + PERFORMANCE_PROFILE_ALL, + HT_HOST_FEAT_COHERENT, + 0x000081AA, // regData + 0xD5FFFFFF, // regMask + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F10MultiLinkPciRegisterTable = { + PrimaryCores, + (sizeof (F10MultiLinkPciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10MultiLinkPciRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PackageType.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PackageType.h new file mode 100755 index 0000000000..7573da9c8f --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PackageType.h @@ -0,0 +1,83 @@ +/** + * @file + * + * AMD Family_10 Package Type Definitions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 6524 $ @e \$Date: 2008-06-24 17:00:51 -0500 (Tue, 24 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#ifndef _F10_PACKAGE_TYPE_H_ +#define _F10_PACKAGE_TYPE_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 + *--------------------------------------------------------------------------------------- + */ + +// Below equates are defined to cooperate with LibAmdGetPackageType. +#define PACKAGE_TYPE_FR2_FR5_FR6 (1 << 0) +#define PACKAGE_TYPE_AM2R2_AM3 (1 << 1) +#define PACKAGE_TYPE_S1G3_S1G4 (1 << 2) +#define PACKAGE_TYPE_G34 (1 << 3) +#define PACKAGE_TYPE_ASB2 (1 << 4) +#define PACKAGE_TYPE_C32 (1 << 5) + +#define PACKAGE_TYPE_FR2 PACKAGE_TYPE_FR2_FR5_FR6 +#define PACKAGE_TYPE_FR5 PACKAGE_TYPE_FR2_FR5_FR6 +#define PACKAGE_TYPE_FR6 PACKAGE_TYPE_FR2_FR5_FR6 +#define PACKAGE_TYPE_S1G3 PACKAGE_TYPE_S1G3_S1G4 +#define PACKAGE_TYPE_S1G4 PACKAGE_TYPE_S1G3_S1G4 + +/*--------------------------------------------------------------------------------------- + * 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 + *--------------------------------------------------------------------------------------- + */ + +#endif // _F10_PACKAGE_TYPE_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbCofVidInit.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbCofVidInit.c new file mode 100755 index 0000000000..1e87ce596b --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbCofVidInit.c @@ -0,0 +1,287 @@ +/** + * @file + * + * AMD Family_10 NB COF VID Initialization + * + * Performs the "BIOS Northbridge COF and VID Configuration" as + * described in the BKDG. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 6524 $ @e \$Date: 2008-06-24 17:00:51 -0500 (Tue, 24 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuF10PowerMgmt.h" +#include "cpuApicUtilities.h" +#include "OptionMultiSocket.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuF10Utilities.h" +#include "cpuCommonF10Utilities.h" +#include "F10PmNbCofVidInit.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_F10PMNBCOFVIDINIT_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 + *---------------------------------------------------------------------------------------- + */ +/// Structure used for performing the steps outlined in +/// the NB COFVID configuration sequence +typedef struct { + UINT8 NewNbVid; ///< Destination NB VID code + BOOLEAN NbVidUpdateAll; ///< Status of NbVidUpdateAll +} NB_COF_VID_INIT_WARM; + +/*---------------------------------------------------------------------------------------- + * 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 +PmNbCofVidInitP0P1Core ( + IN VOID *NewNbVid, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +PmNbCofVidInitWarmCore ( + IN VOID *FunctionData, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family 10h core 0 entry point for performing the "Northbridge COF and + * VID Configuration" algorithm. + * + * The steps are as follows: + * 1. Determine if the algorithm is necessary by checking if all NB FIDs + * match in the coherent fabric. If so, check to see if NbCofVidUpdate + * is zero for all CPUs. If that is also true, no further steps are + * necessary. If not + cold reset, proceed to step 2. If not + warm + * reset, proceed to step 8. + * 2. Determine NewNbVid & NewNbFid. + * 3. Copy Startup Pstate settings to P0/P1 MSRs on all local cores. + * 4. Copy NewNbVid to P0 NbVid on all local cores. + * 5. Transition to P1 on all local cores. + * 6. Transition to P0 on local core 0 only. + * 7. Copy NewNbFid to F3xD4[NbFid], set NbFidEn, and issue a warm reset. + * 8. Update all enabled Pstate MSRs' NbVids according to NbVidUpdateAll + * on all local cores. + * 9. Transition to Startup Pstate on all local cores. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParamsPtr Service related parameters (unused). + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F10PmNbCofVidInit ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN PerformNbCofVidCfg; + BOOLEAN SystemNbCofsMatch; + UINT8 NewNbFid; + UINT8 NewNbVid; + UINT32 Socket; + UINT32 Module; + UINT32 Core; + UINT32 SystemNbCof; + UINT32 AndMask; + UINT32 OrMask; + UINT32 Ignored; + UINT32 NewNbVoltage; + WARM_RESET_REQUEST Request; + AP_TASK TaskPtr; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + NB_COF_VID_INIT_WARM FunctionData; + + PerformNbCofVidCfg = TRUE; + OptionMultiSocketConfiguration.GetSystemNbCof (&SystemNbCof, &SystemNbCofsMatch, StdHeader); + if (SystemNbCofsMatch) { + if (!OptionMultiSocketConfiguration.GetSystemNbCofVidUpdate (StdHeader)) { + PerformNbCofVidCfg = FALSE; + } + } + if (PerformNbCofVidCfg) { + // get the local node ID + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + ASSERT (Core == 0); + + // get NewNbVid + FamilySpecificServices->GetNbFrequency (FamilySpecificServices, &PciAddress, &Ignored, &NewNbVoltage, StdHeader); + ASSERT (((1550000 - NewNbVoltage) % 12500) == 0); + NewNbVid = (UINT8) ((1550000 - NewNbVoltage) / 12500); + ASSERT (NewNbVid < 0x80); + + if (!(IsWarmReset (StdHeader))) { + + // determine NewNbFid + NewNbFid = (UINT8) ((SystemNbCof / 200) - 4); + + TaskPtr.FuncAddress.PfApTaskI = PmNbCofVidInitP0P1Core; + TaskPtr.DataTransfer.DataSizeInDwords = 1; + TaskPtr.DataTransfer.DataPtr = &NewNbVid; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = 0; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); + + // Transition core 0 to P0 and wait for change to complete + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) TRUE, StdHeader); + + PciAddress.Address.Register = CPTC0_REG; + AndMask = 0xFFFFFFFF; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->NbFid = 0; + OrMask = 0x00000000; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->NbFid = NewNbFid; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->NbFidEn = 1; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); + + // warm reset request + FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, &Request); + Request.RequestBit = TRUE; + FamilySpecificServices->SetWarmResetFlag (FamilySpecificServices, StdHeader, &Request); + } else { + // warm reset path + + FunctionData.NewNbVid = NewNbVid; + FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &FunctionData.NbVidUpdateAll, StdHeader); + + TaskPtr.FuncAddress.PfApTaskI = PmNbCofVidInitWarmCore; + TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (NB_COF_VID_INIT_WARM); + TaskPtr.DataTransfer.DataPtr = &FunctionData; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); + } + } // skip whole algorithm +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Cold reset support routine for F10PmNbCofVidInit. + * + * This function implements steps 3, 4, & 5 on each core. + * + * @param[in] NewNbVid NewNbVid determined by core 0 in step 2. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +PmNbCofVidInitP0P1Core ( + IN VOID *NewNbVid, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MsrAddress; + UINT64 MsrRegister; + CPU_SPECIFIC_SERVICES *FamilySpecificServices = NULL; + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + MsrAddress = (UINT32) ((((COFVID_STS_MSR *) &MsrRegister)->StartupPstate) + PS_REG_BASE); + LibAmdMsrRead (MsrAddress, &MsrRegister, StdHeader); + LibAmdMsrWrite ((UINT32) (PS_REG_BASE + 1), &MsrRegister, StdHeader); + ((PSTATE_MSR *) &MsrRegister)->NbVid = *(UINT8 *) NewNbVid; + LibAmdMsrWrite (PS_REG_BASE, &MsrRegister, StdHeader); + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 1, (BOOLEAN) FALSE, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Warm reset support routine for F10PmNbCofVidInit. + * + * This function implements steps 8 & 9 on each core. + * + * @param[in] FunctionData Contains NewNbVid determined by core 0 in step + * 2, and NbVidUpdateAll. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +PmNbCofVidInitWarmCore ( + IN VOID *FunctionData, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MsrAddress; + UINT64 MsrRegister; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + for (MsrAddress = PS_REG_BASE; MsrAddress <= PS_MAX_REG; MsrAddress++) { + LibAmdMsrRead (MsrAddress, &MsrRegister, StdHeader); + if (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1) { + if ((((PSTATE_MSR *) &MsrRegister)->NbDid == 0) || ((NB_COF_VID_INIT_WARM *) FunctionData)->NbVidUpdateAll) { + ((PSTATE_MSR *) &MsrRegister)->NbVid = ((NB_COF_VID_INIT_WARM *) FunctionData)->NewNbVid; + LibAmdMsrWrite (MsrAddress, &MsrRegister, StdHeader); + } + } + } + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) (((COFVID_STS_MSR *) &MsrRegister)->StartupPstate), (BOOLEAN) FALSE, StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbCofVidInit.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbCofVidInit.h new file mode 100755 index 0000000000..4e6f3e4e10 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbCofVidInit.h @@ -0,0 +1,76 @@ +/** + * @file + * + * AMD Family_10 NB COF VID Initialization + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 6524 $ @e \$Date: 2008-06-24 17:00:51 -0500 (Tue, 24 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_F10_PM_NB_COF_VID_INIT_H_ +#define _CPU_F10_PM_NB_COF_VID_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 + *--------------------------------------------------------------------------------------- + */ +VOID +F10PmNbCofVidInit ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F10_PM_NB_COF_VID_INIT_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbPstateInit.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbPstateInit.c new file mode 100755 index 0000000000..455f312090 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbPstateInit.c @@ -0,0 +1,186 @@ +/** + * @file + * + * AMD Family_10 NB Pstate Initialization + * + * Performs the action described in F3x1F0[NbPstate] as + * described in the BKDG. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 6524 $ @e \$Date: 2008-06-24 17:00:51 -0500 (Tue, 24 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuF10PowerMgmt.h" +#include "cpuApicUtilities.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "F10PmNbPstateInit.h" +#include "F10PackageType.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_F10PMNBPSTATEINIT_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 + *---------------------------------------------------------------------------------------- + */ +/// Structure used for modifying the P-state +/// MSRs on fuse enable CPUs. +typedef struct { + UINT8 NbVid1; ///< Destination NB VID code + UINT8 NbPstate; ///< Status of NbVidUpdateAll +} NB_PSTATE_INIT; + +/*---------------------------------------------------------------------------------------- + * 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 +PmNbPstateInitCore ( + IN VOID *NbPstateParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family 10h core 0 entry point for performing the actions described in the + * description of F3x1F0[NbPstate]. + * + * If F3x1F0[NbPstate] is non zero, it specifies the highest performance + * P-state in which to enable NbDid. Each core must loop through their + * P-state MSRs, enabling NbDid and changing NbVid to a lower voltage. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParamsPtr Service related parameters (unused). + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F10PmNbPstateInit ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Core; + UINT32 Module; + UINT32 PciRegister; + UINT32 ProcessorPackageType; + UINT32 Socket; + AP_TASK TaskPtr; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + NB_PSTATE_INIT ApParams; + + if (FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, StdHeader)) { + ProcessorPackageType = LibAmdGetPackageType (StdHeader); + if ((CpuEarlyParamsPtr->PlatformConfig.PlatformProfile.PlatformPowerPolicy == BatteryLife) || + (ProcessorPackageType != PACKAGE_TYPE_S1G3_S1G4)) { + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + ASSERT (Core == 0); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = 0x1F0; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if ((PciRegister & 0x00070000) != 0) { + ApParams.NbPstate = (UINT8) ((PciRegister & 0x00070000) >> 16); + ASSERT (ApParams.NbPstate < NM_PS_REG); + + PciAddress.Address.Function = FUNC_4; + PciAddress.Address.Register = 0x1F4; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ApParams.NbVid1 = (UINT8) ((PciRegister & 0x00003F80) >> 7); + + TaskPtr.FuncAddress.PfApTaskI = PmNbPstateInitCore; + TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (NB_PSTATE_INIT); + TaskPtr.DataTransfer.DataPtr = &ApParams; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); + + } + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F10PmNbPstateInit. + * + * This function modifies NbVid and NbDid on each core. + * + * @param[in] NbPstateParams Appropriate NbVid1 and NbPstate as determined by core 0. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +PmNbPstateInitCore ( + IN VOID *NbPstateParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MsrAddress; + UINT64 MsrRegister; + + for (MsrAddress = (PS_REG_BASE + ((NB_PSTATE_INIT *) NbPstateParams)->NbPstate); MsrAddress <= PS_MAX_REG; MsrAddress++) { + LibAmdMsrRead (MsrAddress, &MsrRegister, StdHeader); + if (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1) { + ((PSTATE_MSR *) &MsrRegister)->NbDid = 1; + ((PSTATE_MSR *) &MsrRegister)->NbVid = ((NB_PSTATE_INIT *) NbPstateParams)->NbVid1; + LibAmdMsrWrite (MsrAddress, &MsrRegister, StdHeader); + } + } +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbPstateInit.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbPstateInit.h new file mode 100755 index 0000000000..d4c868cd02 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10PmNbPstateInit.h @@ -0,0 +1,76 @@ +/** + * @file + * + * AMD Family_10 NB P-State Initialization + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 6524 $ @e \$Date: 2008-06-24 17:00:51 -0500 (Tue, 24 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_F10_PM_NB_PSTATE_INIT_H_ +#define _CPU_F10_PM_NB_PSTATE_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 + *--------------------------------------------------------------------------------------- + */ +VOID +F10PmNbPstateInit ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F10_PM_NB_PSTATE_INIT_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10SingleLinkPciTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10SingleLinkPciTables.c new file mode 100755 index 0000000000..a97214ad1a --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/F10SingleLinkPciTables.c @@ -0,0 +1,1267 @@ +/** + * @file + * + * AMD Family_10 PCI tables in Recommended Settings for Single Link Processors. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_F10SINGLELINKPCITABLES_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 F10SingleLinkPciRegisters[] = +{ +// F0x68 - Link Transaction Control +// bit[14:13], BufPriRel = 01b + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x68), // Address + 0x00002000, // regData + 0x00006000, // regMask + } + }, +// F0x68 - Link Transaction Control +// bit[24], DispRefModeEn = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_ALL, // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x68), // Address + 0x00000000, // regData + 0x01000000, // regMask + } + }, +// F0x68 - Link Transaction Control +// bit[24], DispRefModeEn = 1 for UMA, but can only set it on the warm reset. + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_UMA, // platform Features + { + PERFORMANCE_IS_WARM_RESET, + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x68), // Address + 0x01000000, // regData + 0x01000000, // regMask + } + }, + // F0x[F0,D0,B0,90] Link Base Buffer Count Register + // 27:25 FreeData: 2 + // 24:20 FreeCmd: 8 + // 19:18 RspData: 1 + // 17:16 NpReqData: 1 + // 15:12 ProbeCmd: 0 + // 11:8 RspCmd: 2 + // 7:5 PReq: 3 + // 4:0 NpReqCmd: 11 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), + { + HT_HOST_FEATURES_ALL, // Link Features + 0x10, // Address + 0x0885026B, // Data + 0x0FFFFFFF // Mask + }, + }, + // F0x[F0,D0,B0,90] Link Base Buffer Count Register + // 27:25 FreeData: 2 + // 24:20 FreeCmd: 8 + // 19:18 RspData: 1 + // 17:16 NpReqData: 1 + // 15:12 ProbeCmd: 0 + // 11:8 RspCmd: 2 + // 7:5 PReq: 6 + // 4:0 NpReqCmd: 15 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), + { + HT_HOST_FEATURES_ALL, // Link Features + 0x10, // Address + 0x008502CF, // Data + 0x0FFFFFFF // Mask + }, + }, + // F0x[F4,D4,B4,94] Link Base Buffer Count Register + // 28:27 IsocRspData: 0 + // 26:25 IsocNpReqData: 0 + // 24:22 IsocRspCmd: 0 + // 21:19 IsocPReq: 1 + // 18:16 IsocNpReqCmd: 7 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), + { + HT_HOST_FEATURES_ALL, // Link Features + 0x14, // Address + 0x000F0000, // Data + 0x1FFF0000 // Mask + }, + }, + // F0x[F4,D4,B4,94] Link Base Buffer Count Register + // 28:27 IsocRspData: 0 + // 26:25 IsocNpReqData: 0 + // 24:22 IsocRspCmd: 0 + // 21:19 IsocPReq: 0 + // 18:16 IsocNpReqCmd: 1 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), + { + HT_HOST_FEATURES_ALL, // Link Features + 0x14, // Address + 0x00010000, // Data + 0x1FFF0000 // Mask + }, + }, +// F0x170 - Link Extended Control Register - Link 0, sublink 0 +// bit[8] LS2En = 1 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x170), // Address + 0x00000100, // regData + 0x00000100, // regMask + } + }, +// F2x118 - Memory Controller Configuration Low Register +// bits[13:12] MctPriIsoc = 10b +// bits[31:28] MctVarPriCntLmt = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_UMA | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x118), // Address + 0x00002000, // regData + 0xF0003000, // regMask + } + }, +// F2x118 - Memory Controller Configuration Low Register +// bits[13:12] MctPriIsoc = 11b +// bits[31:28] MctVarPriCntLmt = 1 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_UMA | AMD_PF_UMA_IFCM), // platform Features + { + PERFORMANCE_MCT_ISOC_VARIABLE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x118), // Address + 0x10003000, // regData + 0xF0003000, // regMask + } + }, +// F2x[1,0]90 - DRAM Configuration Low Register +// bits [10] BurstLength32 0 +// It is okay to write both channels, if one is disabled, this bit has no effect on that channel. +// If the channels are ganged for 128 bit operation, the memory init code will resolve any conflict with this setting. + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_UMA | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x90), // Address + 0x00000000, // regData + 0x00000400, // regMask + } + }, +// F2x[1,0]90 - DRAM Configuration Low Register +// bits [10] BurstLength32 = 0 +// It is okay to write both channels, if one is disabled, this bit has no effect on that channel. +// If the channels are ganged for 128 bit operation, the memory init code will resolve any conflict with this setting. + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_UMA | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x190), // Address + 0x00000000, // regData + 0x00000400, // regMask + } + }, +// F2x[1,0]90 - DRAM Configuration Low Register +// bits [10] BurstLength32 = 1 +// It is okay to write both channels, if one is disabled, this bit has no effect on that channel. +// If the channels are ganged for 128 bit operation, the memory init code will resolve any conflict with this setting. + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_UMA | AMD_PF_UMA_IFCM), // platform Features + { + PERFORMANCE_REFRESH_REQUEST_32B, + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x90), // Address + 0x00000400, // regData + 0x00000400, // regMask + } + }, +// F2x[1,0]90 - DRAM Configuration Low Register +// bits [10] BurstLength32 = 1 +// It is okay to write both channels, if one is disabled, this bit has no effect on that channel. +// If the channels are ganged for 128 bit operation, the memory init code will resolve any conflict with this setting. + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_UMA | AMD_PF_UMA_IFCM), // platform Features + { + PERFORMANCE_REFRESH_REQUEST_32B, + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x190), // Address + 0x00000400, // regData + 0x00000400, // regMask + } + }, +// F3x6C - Data Buffer Control +// bits[2:0] UpReqDBC = 2 +// bits[5:4] DnReqDBC = 1 +// bits[7:6] DnRspDBC = 1 +// bit[15] DatBuf24 = 1 +// bits[18:16] UpRspDBC = 1 +// bits[30:28] IsocRspDBC = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_NFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x6C), // Address + 0x00018052, // regData + 0x700780F7, // regMask + } + }, +// F3x6C - Data Buffer Control +// bits[2:0] UpReqDBC = 1 +// bits[5:4] DnReqDBC = 1 +// bits[7:6] DnRspDBC = 1 +// bit[15] DatBuf24 = 1 +// bits[18:16] UpRspDBC = 1 +// bits[30:28] IsocRspDBC = 6 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x6C), // Address + 0x60018051, // regData + 0x700780F7, // regMask + } + }, +// F3x6C - Data Buffer Control +// bits[2:0] UpReqDBC = 2 +// bits[5:4] DnReqDBC = 1 +// bits[7:6] DnRspDBC = 1 +// bit[15] DatBuf24 = 1 +// bits[18:16] UpRspDBC = 1 +// bits[30:28] IsocRspDBC = 1 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x6C), // Address + 0x10018052, // regData + 0x700780F7, // regMask + } + }, +// F3x6C - Data Buffer Control +// bits[2:0] UpReqDBC = 1 +// bits[5:4] DnReqDBC = 1 +// bits[7:6] DnRspDBC = 1 +// bit[15] DatBuf24 = 1 +// bits[18:16] UpRspDBC = 1 +// bits[30:28] IsocRspDBC = 6 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x6C), // Address + 0x60018051, // regData + 0x700780F7, // regMask + } + }, +// F3x70 - SRI_to_XBAR Command Buffer Count +// bits[2:0] UpReqCBC = 3 +// bits[5:4] DnReqCBC = 1 +// bits[7:6] DnRspCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[18:16] UpRspCBC = 4 +// bits[22:20] IsocReqCBC = 0 +// bits[26:24] IsocPreqCBC = 0 +// bits[30:28] IsocRspCBC = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_NFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x70), // Address + 0x00041153, // regData + 0x777777F7, // regMask + } + }, +// F3x70 - SRI_to_XBAR Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[5:4] DnReqCBC = 1 +// bits[7:6] DnRspCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[18:16] UpRspCBC = 2 +// bits[22:20] IsocReqCBC = 2 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] IsocRspCBC = 6 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x70), // Address + 0x61221151, // regData + 0x777777F7, // regMask + } + }, +// F3x70 - SRI_to_XBAR Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[5:4] DnReqCBC = 1 +// bits[7:6] DnRspCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[18:16] UpRspCBC = 2 +// bits[22:20] IsocReqCBC = 2 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] IsocRspCBC = 6 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x70), // Address + 0x61221151, // regData + 0x777777F7, // regMask + } + }, +// F3x70 - SRI_to_XBAR Command Buffer Count +// bits[2:0] UpReqCBC = 3 +// bits[5:4] DnReqCBC = 1 +// bits[7:6] DnRspCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[18:16] UpRspCBC = 4 +// bits[22:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] IsocRspCBC = 1 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x70), // Address + 0x11141153, // regData + 0x777777F7, // regMask + } + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 1 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 1 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 0 +// bits[26:24] IsocPreqCBC = 0 +// bits[30:28] DRReqCBC = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_NFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0x00081111, // regData + 0xF7FF7777, // regMask + } + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// No Mct Variable Priority or 32 byte requests. +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 0 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 0 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] DRReqCBC = 9 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0x91180101, // regData + 0xF7FF7777, // regMask + } + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// No Mct Variable Priority or 32 byte requests. +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 0 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 0 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] DRReqCBC = 9 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0x91180101, // regData + 0xF7FF7777, // regMask + } + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 0 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 0 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] DRReqCBC = C + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + PERFORMANCE_MCT_ISOC_VARIABLE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0xC1180101, // regData + 0xF7FF7777, // regMask + } + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 0 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 0 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] DRReqCBC = C + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + PERFORMANCE_MCT_ISOC_VARIABLE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0xC1181111, // regData + 0xF7FF7777, // regMask + } + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 0 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 0 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] DRReqCBC = F + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + PERFORMANCE_REFRESH_REQUEST_32B, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0xF1180101, // regData + 0xF7FF7777, // regMask + } + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 0 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 0 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 1 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] DRReqCBC = F + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + PERFORMANCE_REFRESH_REQUEST_32B, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0xF1181111, // regData + 0xF7FF7777, // regMask + } + }, +// F3x74 - XBAR_to_SRI Command Buffer Count +// bits[2:0] UpReqCBC = 1 +// bits[6:4] DnReqCBC = 0 +// bits[10:8] UpPreqCBC = 1 +// bits[14:12] DnPreqCBC = 0 +// bits[19:16] ProbeCBC = 8 +// bits[23:20] IsocReqCBC = 8 +// bits[26:24] IsocPreqCBC = 1 +// bits[30:28] DRReqCBC = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x74), // Address + 0x01880101, // regData + 0xF7FF7777, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 20 +// bits[11:8] Sri2XbarFreeXreqCBC = 9 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 9 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_NFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00090914, // regData + 0x707FFF1F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// No Mct Variable Priority or 32 byte requests. +// bits[4:0] Xbar2SriFreeListCBC = 15 +// bits[11:8] Sri2XbarFreeXreqCBC = 8 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 7 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x0007080F, // regData + 0x007FFF1F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// No Mct Variable Priority or 32 byte requests. +// bits[4:0] Xbar2SriFreeListCBC = 15 +// bits[11:8] Sri2XbarFreeXreqCBC = 8 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 7 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x0007080F, // regData + 0x707FFF1F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 12 +// bits[11:8] Sri2XbarFreeXreqCBC = 8 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 7 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + PERFORMANCE_MCT_ISOC_VARIABLE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x0007080C, // regData + 0x007FFF1F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 12 +// bits[11:8] Sri2XbarFreeXreqCBC = 8 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 7 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + PERFORMANCE_MCT_ISOC_VARIABLE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x0007080C, // regData + 0x707FFF1F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 9 +// bits[11:8] Sri2XbarFreeXreqCBC = 8 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 7 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + PERFORMANCE_REFRESH_REQUEST_32B, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00070809, // regData + 0x007FFF1F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 9 +// bits[11:8] Sri2XbarFreeXreqCBC = 8 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 7 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + PERFORMANCE_REFRESH_REQUEST_32B , // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00070809, // regData + 0x707FFF1F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 17 +// bits[11:8] Sri2XbarFreeXreqCBC = 8 +// bits[15:12] Sri2XbarFreeRspCBC = 0 +// bits[19:16] Sri2XbarFreeXreqDBC = 7 +// bits[22:20] Sri2XbarFreeRspDBC = 0 +// bits[30:28] Xbar2SriFreeListCBInc = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00070811, // regData + 0x707FFF1F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 22, 1-core without L3 cache is 22 + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + PERFORMANCE_NO_L3_CACHE, + (CORE_RANGE_0 (1, 1) | COUNT_RANGE_NONE), // 1 core. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00000016, // regData + 0x0000001F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 20, 2-core is 20 + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + PERFORMANCE_NO_L3_CACHE, + (CORE_RANGE_0 (2, 2) | COUNT_RANGE_NONE), // 2 core. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00000014, // regData + 0x0000001F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 18, 3-core without L3 cache is 18. + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + PERFORMANCE_NO_L3_CACHE, + (CORE_RANGE_0 (3, 3) | COUNT_RANGE_NONE), // 3 core. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00000012, // regData + 0x0000001F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 14, 4-core without L3 cache is 16. + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + PERFORMANCE_NO_L3_CACHE, + (CORE_RANGE_0 (4, 4) | COUNT_RANGE_NONE), // 4 core. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x00000010, // regData + 0x0000001F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 14, 5-core without L3 cache is 14. + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + PERFORMANCE_NO_L3_CACHE, + (CORE_RANGE_0 (5, 5) | COUNT_RANGE_NONE), // 5 core. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x0000000E, // regData + 0x0000001F, // regMask + } + }, +// F3x7C - Free List Buffer Count +// bits[4:0] Xbar2SriFreeListCBC = 12, 6-core without L3 cache is 12. + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + PERFORMANCE_NO_L3_CACHE, + (CORE_RANGE_0 (6, 6) | COUNT_RANGE_NONE), // 6 core. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x7C), // Address + 0x0000000C, // regData + 0x0000001F, // regMask + } + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 2 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 0 +// bits[15:14] IsocPreqTok = 0 +// bits[17:16] IsocRspTok = 0 +// bits[23:20] FreeTok = 8 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_NFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00800756, // regData + 0x00F3FFFF, // regMask + } + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 2 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 3 +// bits[15:14] IsocPreqTok = 1 +// bits[17:16] IsocRspTok = 3 +// bits[23:20] FreeTok = 12 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00C37756, // regData + 0x00F3FFFF, // regMask + } + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 2 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 3 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 3 +// bits[15:14] IsocPreqTok = 1 +// bits[17:16] IsocRspTok = 3 +// bits[23:20] FreeTok = 12 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00C37756, // regData + 0x00F3FFFF, // regMask + } + }, +// F3x140 - SRI_to_XCS Token Count +// bits[1:0] UpReqTok = 2 +// bits[3:2] DnReqTok = 1 +// bits[5:4] UpPreqTokC = 1 +// bits[7:6] DnPreqTok = 1 +// bits[9:8] UpRspTok = 2 +// bits[11:10] DnRspTok = 1 +// bits[13:12] IsocReqTok = 3 +// bits[15:14] IsocPreqTok = 1 +// bits[17:16] IsocRspTok = 3 +// bits[23:20] FreeTok = 12 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x140), // Address + 0x00C37656, // regData + 0x00F3FFFF, // regMask + } + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 3 +// bits[7:4] ProbeTok = 3 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_NFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000033, // regData + 0x000000FF, // regMask + } + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 6 +// bits[7:4] ProbeTok = 3 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000036, // regData + 0x000000FF, // regMask + } + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 6 +// bits[7:4] ProbeTok = 3 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000036, // regData + 0x000000FF, // regMask + } + }, +// F3x144 - MCT to XCS Token Count +// bits[3:0] RspTok = 6 +// bits[7:4] ProbeTok = 3 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x144), // Address + 0x00000036, // regData + 0x000000FF, // regMask + } + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 2 +// bits[9:8] IsocReqTok0 = 0 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 3 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_NFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x148), // Address + 0x0000C0AA, // regData + 0xD5FFFFFF, // regMask + } + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 0 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 1 +// bits[13:12] IsocRspTok0 = 1 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 2 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x148), // Address + 0x8000152A, // regData + 0xD5FFFFFF, // regMask + } + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 0 +// bits[9:8] IsocReqTok0 = 1 +// bits[11:10] IsocPreqTok0 = 1 +// bits[13:12] IsocRspTok0 = 1 +// bits[15:14] FreeTok[1:0] = 0 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 2 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_UMA_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x148), // Address + 0x8000152A, // regData + 0xD5FFFFFF, // regMask + } + }, +// F3x148 - Link to XCS Token Count +// bits[1:0] ReqTok0 = 2 +// bits[3:2] PReqTok0 = 2 +// bits[5:4] RspTok0 = 2 +// bits[7:6] ProbeTok0 = 2 +// bits[9:8] IsocReqTok0 = 0 +// bits[11:10] IsocPreqTok0 = 0 +// bits[13:12] IsocRspTok0 = 0 +// bits[15:14] FreeTok[1:0] = 3 +// bits[17:16] ReqTok1 = 0 +// bits[19:18] PReqTok1 = 0 +// bits[21:20] RspTok1 = 0 +// bits[23:22] ProbeTok1= 0 +// bits[24] IsocReqTok1 = 0 +// bits[25] IsocPreqTok1 = 0 +// bits[28] IsocRspTok1 = 0 +// bits[31:30] FreeTok[3:2] = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_AND | AMD_PF_SINGLE_LINK | AMD_PF_IFCM), // platform Features + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x148), // Address + 0x0000C0AA, // regData + 0xD5FFFFFF, // regMask + } + }, + // F3x158 - Link to XCS Token Count Registers + // bits [3:0]LnkToXcsDRToken = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_NFCM | AMD_PF_IFCM | AMD_PF_IOMMU), + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x158), // Address + 0x00000000, + 0x0000000F + } + }, + // F3x158 - Link to XCS Token Count Registers + // bits [3:0]LnkToXcsDRToken = 3 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + (AMD_PF_UMA_IFCM | AMD_PF_UMA), + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x158), // Address + 0x00000003, + 0x0000000F + } + }, +}; + +CONST REGISTER_TABLE ROMDATA F10SingleLinkPciRegisterTable = { + PrimaryCores, + (sizeof (F10SingleLinkPciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10SingleLinkPciRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlCacheFlushOnHalt.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlCacheFlushOnHalt.c new file mode 100755 index 0000000000..c4f819a062 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlCacheFlushOnHalt.c @@ -0,0 +1,146 @@ +/** + * @file + * + * AMD CPU Cache Flush On Halt 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/Family/0x10/BL + * @e \$Revision: 10071 $ @e \$Date: 2008-12-17 08:03:04 +0800 (Wed, 17 Dec 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuPostInit.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_BL_F10BLCACHEFLUSHONHALT_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 + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P U B L I C F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * Enable BL-C Cpu Cache Flush On Halt Function + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in,out] PciAddress Pointer to Pci address struct. + * @param[in,out] AndMask Pointer to AND mask bits. + * @param[in,out] OrMask Pointer to Or mask bits. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + */ +VOID +GetF10BlCacheFlushOnHaltRegister ( + IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, + IN OUT PCI_ADDR *PciAddress, + IN OUT UINT32 *AndMask, + IN OUT UINT32 *OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CoreCount; + CPU_LOGICAL_ID CpuFamilyRevision; + + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + PciAddress->Address.Function = FUNC_3; + PciAddress->Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; + if (CpuFamilyRevision.Revision == AMD_F10_BL_C3) { + // + // F3xDC[25:19] = 04h + // F3xDC[18:16] = 111b + // + *AndMask = 0xFC00FFFF; + *OrMask = 0x00270000; + } else { + // + // F3xDC[25:19] = 28h + // F3xDC[18:16] = 111b + // + *AndMask = 0xFC00FFFF; + *OrMask = 0x01470000; + + // + //For BL_C2 single Core, F3xDC[18:16] = 0 + // + GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); + if (CoreCount == 1) { + if (CpuFamilyRevision.Revision == AMD_F10_BL_C2) { + *OrMask = 0x01400000; + } + } + } + +} + +CONST CPU_CFOH_FAMILY_SERVICES ROMDATA F10BlCacheFlushOnHalt = +{ + 0, + GetF10BlCacheFlushOnHaltRegister +};
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlEquivalenceTable.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlEquivalenceTable.c new file mode 100755 index 0000000000..b81e267c3a --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlEquivalenceTable.c @@ -0,0 +1,102 @@ +/** + * @file + * + * AMD Family_10 BL Equivalence Table related data + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6381 $ @e \$Date: 2008-06-15 17:26:25 -0500 (Sun, 15 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_BL_F10BLEQUIVALENCETABLE_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 UINT16 ROMDATA CpuF10BlMicrocodeEquivalenceTable[] = +{ + 0x1052, 0x1041, + 0x1053, 0x1043 +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] BlEquivalenceTablePtr 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 +GetF10BlMicrocodeEquivalenceTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **BlEquivalenceTablePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = ((sizeof (CpuF10BlMicrocodeEquivalenceTable) / sizeof (UINT16)) / 2); + *BlEquivalenceTablePtr = CpuF10BlMicrocodeEquivalenceTable; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlHtPhyTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlHtPhyTables.c new file mode 100755 index 0000000000..a3d744ccf9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlHtPhyTables.c @@ -0,0 +1,117 @@ +/** + * @file + * + * AMD Family_10 BL PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_BL_F10BLHTPHYTABLES_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 + *---------------------------------------------------------------------------------------- + */ + +// HT Phy T a b l e s +// ------------------------- +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F10BlHtPhyRegisters[] = +{ + +// +// NOTE: This entry is here for making this array not to be empty. +// This entry should be removed after adding another. +// +// +// Deemphasis Settings +// + +// For BL-C3, also set [7]TxLs23ClkGateEn. +//deemphasis level DL1[20:16], DL2[12:8], DP1[4:0] PostCur1En[31] PostCur2En[30] PreCur1En[29] MapPostCur2En[6] +// No deemphasis 00h 00h 00h 0 0 0 0 +// -3dB postcursor 12h 00h 00h 1 0 0 0 +// -6dB postcursor 1Fh 00h 00h 1 0 0 0 +// -8dB postcursor 1Fh 06h 00h 1 1 0 1 +// -11dB postcursor 1Fh 0Dh 00h 1 1 0 1 +// -11dB postcursor with +// -8dB precursor 1Fh 06h 07h 1 1 1 1 + + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_BL_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x00000080, // regData + 0xE01F1FDF, // regMask + } + }, +}; + +CONST REGISTER_TABLE ROMDATA F10BlHtPhyRegisterTable = { + PrimaryCores, + (sizeof (F10BlHtPhyRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10BlHtPhyRegisters +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlLogicalIdTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlLogicalIdTables.c new file mode 100755 index 0000000000..32a9fcb802 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlLogicalIdTables.c @@ -0,0 +1,102 @@ +/** + * @file + * + * AMD Family_10 BL Logical ID Table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 6261 $ @e \$Date: 2008-06-04 17:38:17 -0500 (Wed, 04 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_BL_F10BLLOGICALIDTABLES_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 CPU_LOGICAL_ID_XLAT ROMDATA CpuF10BlLogicalIdAndRevArray[] = +{ + { + 0x1052, + AMD_F10_BL_C2 + }, + { + 0x1053, + AMD_F10_BL_C3 + } +}; + +VOID +GetF10BlLogicalIdAndRev ( + OUT CONST CPU_LOGICAL_ID_XLAT **BlIdPtr, + OUT UINT8 *NumberOfElements, + OUT UINT64 *LogicalFamily, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = (sizeof (CpuF10BlLogicalIdAndRevArray) / sizeof (CPU_LOGICAL_ID_XLAT)); + *BlIdPtr = CpuF10BlLogicalIdAndRevArray; + *LogicalFamily = AMD_FAMILY_10_BL; +} + +//CONST LOGICAL_ID_TABLE ROMDATA CpuF10BlLogicalIdAndRev = +//{ +// (sizeof (CpuF10BlLogicalIdAndRevArray) / sizeof (CPU_LOGICAL_ID_XLAT)), +// (CPU_LOGICAL_ID_XLAT *) &CpuF10BlLogicalIdAndRevArray +//}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlMicrocodePatchTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlMicrocodePatchTables.c new file mode 100755 index 0000000000..2a1bfa9a56 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlMicrocodePatchTables.c @@ -0,0 +1,104 @@ +/** + * @file + * + * AMD Family_10 BL PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6049 $ @e \$Date: 2008-05-13 23:58:02 -0700 (Tue, 13 May 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_BL_F10BLMICROCODEPATCHTABLES_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 + *---------------------------------------------------------------------------------------- + */ +extern CONST MICROCODE_PATCHES ROMDATA *CpuF10BlMicroCodePatchArray[]; + + +/*---------------------------------------------------------------------------------------- + * 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] BlUcodePtr 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 +GetF10BlMicroCodePatchesStruct ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **BlUcodePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NumberOfUcode; + + for (NumberOfUcode = 0; CpuF10BlMicroCodePatchArray[NumberOfUcode] != 0; NumberOfUcode++) { + } + *NumberOfElements = NumberOfUcode; + *BlUcodePtr = &CpuF10BlMicroCodePatchArray[0]; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlMsrTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlMsrTables.c new file mode 100755 index 0000000000..fb7a30ddc3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlMsrTables.c @@ -0,0 +1,101 @@ +/** + * @file + * + * AMD Family_10 BL, MSR tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_BL_F10BLMSRTABLES_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 F10BlMsrRegisters[] = +{ +// M S R T a b l e s +// ---------------------- +// +// NOTE: This entry is here for making this array not to be empty. +// This entry should be removed after adding another. +// +// MSR_LS_CFG (0xC0011020) +// bit[1] = 0 + { + MsrRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_B0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MSR_LS_CFG, // MSR Address + 0x0000000000000000, // OR Mask + (1 << 1), // NAND Mask + } + } +}; + +CONST REGISTER_TABLE ROMDATA F10BlMsrRegisterTable = { + AllCores, + (sizeof (F10BlMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F10BlMsrRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlPciTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlPciTables.c new file mode 100755 index 0000000000..c3bbb55e23 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/BL/F10BlPciTables.c @@ -0,0 +1,174 @@ +/** + * @file + * + * AMD Family_10 BL PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "F10PackageType.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_BL_F10BLPCITABLES_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 F10BlPciRegisters[] = +{ + // Function 0 + +// F0x16C - Link Global Extended Control Register, Errata 351 +// bit[15:13] ForceFullT0 = 0 +// bit[5:0] T0Time = 0x14 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_BL_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00000014, // regData + 0x0000E03F, // regMask + } + }, +// F0x16C - Link Global Extended Control Register +// bit[7:6] InLnSt = 0x01 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_BL_C3 // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00000040, // regData + 0x000000C0, // regMask + } + }, +// F0x170 - Link Extended Control Register - Link 0, sublink 0 +// Errata 351 (only need to override single link case.) +// bit[8] LS2En = 0, + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_BL_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x170), // Address + 0x00000000, // regData + 0x00000100, // regMask + } + }, + + +// F3x80 - ACPI Power State Control +// ACPI FIDVID Change +// bits[0] CpuPrbEn = 1 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 0 +// bits[3] = 1 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 0 + { + HtFeatPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_BL_Cx // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + HT_HOST_FEATURES_ALL, // link feats + PACKAGE_TYPE_S1G3_S1G4, // package type + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x000B0000, // regData + 0x00FF0000, // regMask + } + }, +// F3xA0 - Power Control Miscellaneous +// bits[28] NbPstateForce = 1 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_BL_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x10000000, // regData + 0x10000000, // regMask + } + } +}; + +CONST REGISTER_TABLE ROMDATA F10BlPciRegisterTable = { + PrimaryCores, + (sizeof (F10BlPciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10BlPciRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaCacheFlushOnHalt.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaCacheFlushOnHalt.c new file mode 100755 index 0000000000..c1c9db0f33 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaCacheFlushOnHalt.c @@ -0,0 +1,136 @@ +/** + * @file + * + * AMD CPU Cache Flush On Halt 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/Family/0x10/DA + * @e \$Revision: 10071 $ @e \$Date: 2008-12-17 08:03:04 +0800 (Wed, 17 Dec 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuPostInit.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_DA_F10DACACHEFLUSHONHALT_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 + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P U B L I C F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * Enable DA-C Cpu Cache Flush On Halt Function + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in,out] PciAddress Pointer to Pci address struct. + * @param[in,out] AndMask Pointer to AND mask bits. + * @param[in,out] OrMask Pointer to Or mask bits. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + */ +VOID +GetF10DaCacheFlushOnHaltRegister ( + IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, + IN OUT PCI_ADDR *PciAddress, + IN OUT UINT32 *AndMask, + IN OUT UINT32 *OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CoreCount; + CPU_LOGICAL_ID LogicalId; + + // + // F3xDC[25:19] = 04h + // F3xDC[18:16] = 111b + // + PciAddress->Address.Function = FUNC_3; + PciAddress->Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; + *AndMask = 0xFC00FFFF; + *OrMask = 0x00270000; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + if (LogicalId.Revision == AMD_F10_DA_C2) { + // + //For DA_C2 single Core, F3xDC[18:16] = 0 + // + GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); + if (CoreCount == 1) { + *OrMask = 0x00200000; + } + } +} + +CONST CPU_CFOH_FAMILY_SERVICES ROMDATA F10DaCacheFlushOnHalt = +{ + 0, + GetF10DaCacheFlushOnHaltRegister +};
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaEquivalenceTable.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaEquivalenceTable.c new file mode 100755 index 0000000000..afedd8890d --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaEquivalenceTable.c @@ -0,0 +1,102 @@ +/** + * @file + * + * AMD Family_10 DA Equivalence Table related data + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6381 $ @e \$Date: 2008-06-15 17:26:25 -0500 (Sun, 15 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_DA_F10DAEQUIVALENCETABLE_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 UINT16 ROMDATA CpuF10DaMicrocodeEquivalenceTable[] = +{ + 0x1062, 0x1062, + 0x1063, 0x1043 +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] DaEquivalenceTablePtr 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 +GetF10DaMicrocodeEquivalenceTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **DaEquivalenceTablePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = ((sizeof (CpuF10DaMicrocodeEquivalenceTable) / sizeof (UINT16)) / 2); + *DaEquivalenceTablePtr = CpuF10DaMicrocodeEquivalenceTable; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaHtPhyTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaHtPhyTables.c new file mode 100755 index 0000000000..91ac42329e --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaHtPhyTables.c @@ -0,0 +1,278 @@ +/** + * @file + * + * AMD Family_10 DA PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_DA_F10DAHTPHYTABLES_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 + *---------------------------------------------------------------------------------------- + */ + +// HT Phy T a b l e s +// ------------------------- +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F10DaHtPhyRegisters[] = +{ + +// +// Deemphasis Settings +// + +// For DA, also set [7]TxLs23ClkGateEn. +//deemphasis level DL1[20:16], DL2[12:8], DP1[4:0] PostCur1En[31] PostCur2En[30] PreCur1En[29] MapPostCur2En[6] +// No deemphasis 00h 00h 00h 0 0 0 0 +// -3dB postcursor 12h 00h 00h 1 0 0 0 +// -6dB postcursor 1Fh 00h 00h 1 0 0 0 +// -8dB postcursor 1Fh 06h 00h 1 1 0 1 +// -11dB postcursor 1Fh 0Dh 00h 1 1 0 1 +// -11dB postcursor with +// -8dB precursor 1Fh 06h 07h 1 1 1 1 + + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x00000080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x00000080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__3, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x80120080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__3, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x80120080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__6, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x801F0080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__6, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x801F0080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xC01F06C0, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xC01F06C0, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__11, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xC01F0DC0, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__11, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xC01F0DC0, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__11_8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xE01F06C7, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__11_8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xE01F06C7, // regData + 0xE01F1FDF, // regMask + } + }, +}; + +CONST REGISTER_TABLE ROMDATA F10DaHtPhyRegisterTable = { + PrimaryCores, + (sizeof (F10DaHtPhyRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10DaHtPhyRegisters +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaLogicalIdTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaLogicalIdTables.c new file mode 100755 index 0000000000..0917fb3173 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaLogicalIdTables.c @@ -0,0 +1,102 @@ +/** + * @file + * + * AMD Family_10 DA Logical ID Table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 6261 $ @e \$Date: 2008-06-04 17:38:17 -0500 (Wed, 04 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_DA_F10DALOGICALIDTABLES_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 CPU_LOGICAL_ID_XLAT ROMDATA CpuF10DaLogicalIdAndRevArray[] = +{ + { + 0x1062, + AMD_F10_DA_C2 + }, + { + 0x1063, + AMD_F10_DA_C3 + } +}; + +VOID +GetF10DaLogicalIdAndRev ( + OUT CONST CPU_LOGICAL_ID_XLAT **DaIdPtr, + OUT UINT8 *NumberOfElements, + OUT UINT64 *LogicalFamily, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = (sizeof (CpuF10DaLogicalIdAndRevArray) / sizeof (CPU_LOGICAL_ID_XLAT)); + *DaIdPtr = CpuF10DaLogicalIdAndRevArray; + *LogicalFamily = AMD_FAMILY_10_DA; +} + +//CONST LOGICAL_ID_TABLE ROMDATA CpuF10DaLogicalIdAndRev = +//{ +// (sizeof (CpuF10DaLogicalIdAndRevArray) / sizeof (CPU_LOGICAL_ID_XLAT)), +// (CPU_LOGICAL_ID_XLAT *) &CpuF10DaLogicalIdAndRevArray +//}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaMicrocodePatchTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaMicrocodePatchTables.c new file mode 100755 index 0000000000..48a8cd0bb1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaMicrocodePatchTables.c @@ -0,0 +1,104 @@ +/** + * @file + * + * AMD Family_10 DA PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6049 $ @e \$Date: 2008-05-13 23:58:02 -0700 (Tue, 13 May 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_DA_F10DAMICROCODEPATCHTABLES_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 MICROCODE_PATCHES ROMDATA *CpuF10DaMicroCodePatchArray[]; + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] DaUcodePtr 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 +GetF10DaMicroCodePatchesStruct ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **DaUcodePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NumberOfUcode; + + for (NumberOfUcode = 0; CpuF10DaMicroCodePatchArray[NumberOfUcode] != 0; NumberOfUcode++) { + } + *NumberOfElements = NumberOfUcode; + *DaUcodePtr = &CpuF10DaMicroCodePatchArray[0]; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaMsrTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaMsrTables.c new file mode 100755 index 0000000000..836760aacc --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaMsrTables.c @@ -0,0 +1,101 @@ +/** + * @file + * + * AMD Family_10 DA, MSR tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_DA_F10DAMSRTABLES_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 F10DaMsrRegisters[] = +{ +// M S R T a b l e s +// ---------------------- +// +// NOTE: This entry is here for making this array not to be empty. +// This entry should be removed after adding another. +// +// MSR_LS_CFG (0xC0011020) +// bit[1] = 0 + { + MsrRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_B0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MSR_LS_CFG, // MSR Address + 0x0000000000000000, // OR Mask + (1 << 1), // NAND Mask + } + } +}; + +CONST REGISTER_TABLE ROMDATA F10DaMsrRegisterTable = { + AllCores, + (sizeof (F10DaMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F10DaMsrRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaPciTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaPciTables.c new file mode 100755 index 0000000000..77305cb549 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/DA/F10DaPciTables.c @@ -0,0 +1,172 @@ +/** + * @file + * + * AMD Family_10 DA PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "F10PackageType.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_DA_F10DAPCITABLES_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 F10DaPciRegisters[] = +{ +// F0x16C - Link Global Extended Control Register +// bit[7:6] InLnSt = 0x01 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_DA_ALL // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00000040, // regData + 0x000000C0, // regMask + } + }, + +// F3x80 - ACPI Power State Control +// ACPI FIDVID Change +// bits[0] CpuPrbEn = 1 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 0 +// bits[3] = 1 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 0 + { + HtFeatPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_DA_Cx // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + HT_HOST_FEATURES_ALL, // link feats + PACKAGE_TYPE_S1G3_S1G4, // package type + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x000B0000, // regData + 0x00FF0000, // regMask + } + }, +// F3xA0 - Power Control Miscellaneous +// bits[13:11] PllLockTime = 1 +// bits[28] NbPstateForce = 1 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_DA_ALL // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x10000800, // regData + 0x10003800, // regMask + } + }, +// F3xD4 - Clock Power/Timing Control 0 Register +// bits[30:28] NbClkDiv = 5 + { + HtFeatPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_DA_C2 // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + HT_HOST_FEAT_HT3, // link feats + PACKAGE_TYPE_S1G3_S1G4, // package type + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xD4), // Address + 0x50000000, // regData + 0x70000000, // regMask + } + }, +// F3x188 - NB Extended Configuration Low Register +// bits[4] EnStpGntOnFlushMaskWakeup = 1 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_DA_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x188), // Address + 0x00000010, // regData + 0x00000010, // regMask + } + } +}; + +CONST REGISTER_TABLE ROMDATA F10DaPciRegisterTable = { + PrimaryCores, + (sizeof (F10DaPciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10DaPciRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000085.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000085.c new file mode 100755 index 0000000000..949b846463 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000085.c @@ -0,0 +1,1035 @@ +/** + * @file + * + * AMD Family_10 Microcode patch. + * + * Fam10 Microcode Patch rev 01000085 for 1040 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10/REVC + * @e \$Revision: 5832 $ @e \$Date: 2008-04-15 16:30:24 -0700 (Tue, 15 Apr 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +// Patch code 01000085 for 1040 and equivalent +CONST MICROCODE_PATCHES ROMDATA CpuF10MicrocodePatch01000085 = +{ +0x08, +0x20, +0x01, +0x05, +0x85, +0x00, +0x00, +0x01, +0x00, +0x80, +0x20, +0x00, +0xc1, +0xb9, +0x5d, +0x3d, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x40, +0x10, +0x00, +0x00, +0x00, +0xaa, +0xaa, +0xaa, +0x2f, +0x02, +0x00, +0x00, +0xa0, +0x09, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xcf, +0xf8, +0xff, +0x2a, +0xc3, +0x3f, +0xd5, +0xfd, +0xbc, +0xff, +0xff, +0xb3, +0x0f, +0xff, +0x58, +0xd5, +0xf0, +0x35, +0x95, +0x03, +0x1d, +0xf8, +0x63, +0x7b, +0x40, +0x03, +0xd4, +0x00, +0x80, +0x77, +0xff, +0x7f, +0xfe, +0xe1, +0x98, +0x8a, +0x54, +0xfe, +0xaf, +0xff, +0xff, +0x87, +0x7f, +0xa9, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x00, +0xe0, +0xff, +0x7b, +0x1f, +0xc0, +0x65, +0xf4, +0x0d, +0xf0, +0xe0, +0x8f, +0xfe, +0x04, +0xde, +0x04, +0x03, +0xad, +0xc3, +0x2f, +0xfe, +0xa9, +0xfc, +0x07, +0x00, +0x3f, +0x0f, +0xff, +0x15, +0x00, +0xb0, +0x00, +0xf8, +0xaf, +0xe4, +0x3f, +0x07, +0xf8, +0x79, +0xf8, +0xfe, +0xff, +0x97, +0xa7, +0x1f, +0xe0, +0xe7, +0xe1, +0xbf, +0xf1, +0x00, +0xfe, +0x7f, +0x6f, +0x80, +0x03, +0x4a, +0x1a, +0x00, +0xc8, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0x81, +0x7f, +0x00, +0xc3, +0x3f, +0x80, +0x7f, +0xfc, +0x7f, +0x0f, +0x00, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0xbf, +0x07, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x03, +0x00, +0xff, +0xdf, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xef, +0x01, +0x80, +0xff, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0xff, +0xf7, +0x00, +0xc0, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0xff, +0x7b, +0x00, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x00, +0xf0, +0xff, +0x3d, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0x1e, +0x00, +0xf8, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x7f, +0x0f, +0x00, +0xfc, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0xbf, +0x07, +0x00, +0xfc, +0x07, +0xfe, +0x01, +0x0d, +0xff, +0x00, +0xfe, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x01, +0x80, +0xff, +0xef, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xd7, +0x00, +0x80, +0xfb, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0xfd, +0x6b, +0x00, +0xa0, +0xcf, +0x56, +0x0e, +0x80, +0xe0, +0x0f, +0xe8, +0x75, +0xf6, +0xff, +0xff, +0x00, +0xc3, +0xbb, +0x16, +0xf2, +0x04, +0x37, +0xf8, +0x13, +0x0e, +0x7f, +0x0c, +0xb8, +0xe0, +0xdc, +0x35, +0x00, +0x60, +0xff, +0xff, +0x1f, +0x7f, +0x78, +0xc7, +0xa2, +0x95, +0xff, +0xe9, +0x3f, +0xdf, +0xe0, +0xcf, +0x2a, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x00, +0xf8, +0xff, +0x1e, +0xff, +0xf2, +0xbf, +0xff, +0xfd, +0x1f, +0xfc, +0x7b, +0x0f, +0xc0, +0x23, +0xd0, +0xed, +0xf5, +0xe0, +0xef, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0x0f, +0x00, +0xfc, +0x7f, +0xfe, +0x03, +0xf9, +0x5f, +0x01, +0x7e, +0x1e, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0x4c, +0x06, +0x00, +0xbc, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xef, +0x01, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x00, +0xc0, +0xff, +0xf7, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0x7b, +0x00, +0xe0, +0xff, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0xff, +0x3d, +0x00, +0xf0, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0xff, +0x1e, +0x00, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x00, +0xfc, +0x7f, +0x0f, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0x07, +0x00, +0xfe, +0xbf, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0xdf, +0x03, +0x00, +0xff, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xef, +0x01, +0x80 +}; + +/*---------------------------------------------------------------------------------------- + * 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/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000086.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000086.c new file mode 100755 index 0000000000..e25ca890f1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000086.c @@ -0,0 +1,1035 @@ +/** + * @file + * + * AMD Family_10 Microcode patch. + * + * Fam10 Microcode Patch rev 01000086 for 1041 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10/REVC + * @e \$Revision: 5832 $ @e \$Date: 2008-04-15 16:30:24 -0700 (Tue, 15 Apr 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +// Patch code 01000086 for 1041 and equivalent +CONST MICROCODE_PATCHES ROMDATA CpuF10MicrocodePatch01000086 = +{ +0x08, +0x20, +0x01, +0x05, +0x86, +0x00, +0x00, +0x01, +0x00, +0x80, +0x20, +0x00, +0x04, +0xde, +0x30, +0x03, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x41, +0x10, +0x00, +0x00, +0x00, +0xaa, +0xaa, +0xaa, +0xa0, +0x09, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x97, +0xd1, +0x7f, +0x00, +0x83, +0x3f, +0x36, +0xc0, +0xa0, +0x1b, +0xf8, +0x13, +0x0e, +0xbf, +0x0c, +0xb4, +0xf2, +0x1f, +0xf8, +0xa7, +0x3c, +0xfc, +0x03, +0xfc, +0x40, +0x03, +0x54, +0x00, +0x92, +0xff, +0xe0, +0xbf, +0xe7, +0xe1, +0x1f, +0xe0, +0x5f, +0x9e, +0xfa, +0xff, +0x9f, +0x87, +0x7f, +0x80, +0x03, +0xf8, +0xff, +0xc6, +0x01, +0x0e, +0xfc, +0xbd, +0x00, +0xa0, +0x2a, +0x69, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0x3d, +0x00, +0xf0, +0xff, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0xff, +0x1e, +0x00, +0xf8, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0x81, +0x7f, +0x00, +0xc3, +0x3f, +0x80, +0x7f, +0xfc, +0x7f, +0x0f, +0x00, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0xbf, +0x07, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x03, +0x00, +0xff, +0xdf, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xef, +0x01, +0x80, +0xff, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0xff, +0xf7, +0x00, +0xc0, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0xff, +0x7b, +0x00, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x00, +0xf0, +0xff, +0x3d, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0x1e, +0x00, +0xf8, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x7f, +0x0f, +0x00, +0xfc, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0xbf, +0x07, +0x00, +0xfc, +0x07, +0xfe, +0x01, +0x0d, +0xff, +0x00, +0xfe, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x01, +0x80, +0xff, +0xef, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xd7, +0x00, +0x80, +0xfb, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0xfd, +0x6b, +0x00, +0xa0, +0xff, +0xfe, +0xff, +0xcb, +0xf0, +0xef, +0xf5, +0x7f, +0x8f, +0x40, +0x3f, +0x00, +0x83, +0xbf, +0xb7, +0xd7, +0xfc, +0x07, +0xfe, +0x01, +0x0d, +0xff, +0x00, +0xfe, +0xf0, +0xff, +0x3d, +0x00, +0xe4, +0x7f, +0xf9, +0x0f, +0x79, +0xf8, +0x07, +0xf8, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x00, +0xf0, +0x32, +0x19, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0x0f, +0x00, +0xfc, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0xbf, +0x07, +0x00, +0xfe, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xef, +0x01, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x00, +0xc0, +0xff, +0xf7, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0x7b, +0x00, +0xe0, +0xff, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0xff, +0x3d, +0x00, +0xf0, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0xff, +0x1e, +0x00, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x00, +0xfc, +0x7f, +0x0f, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0x07, +0x00, +0xfe, +0xbf, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0xdf, +0x03, +0x00, +0xff, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xef, +0x01, +0x80 +}; + +/*---------------------------------------------------------------------------------------- + * 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/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000098.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000098.c new file mode 100755 index 0000000000..090cd918da --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000098.c @@ -0,0 +1,1035 @@ +/** + * @file + * + * AMD Family_10 Microcode patch. + * + * Fam10 Microcode Patch rev 01000098 for 1062 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10/REVC + * @e \$Revision$ @e \$Date$ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +// Patch code 01000098 for 1062 and equivalent +CONST MICROCODE_PATCHES ROMDATA CpuF10MicrocodePatch01000098 = +{ +0x08, +0x20, +0x11, +0x11, +0x98, +0x00, +0x00, +0x01, +0x00, +0x80, +0x20, +0x00, +0xf8, +0x53, +0xca, +0x9a, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x62, +0x10, +0x00, +0x00, +0x00, +0xaa, +0xaa, +0xaa, +0x9a, +0x0b, +0x00, +0x00, +0x16, +0x0c, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x6f, +0x58, +0x39, +0x00, +0x81, +0x3f, +0xa0, +0xd7, +0x04, +0x00, +0xfc, +0xb7, +0x0f, +0xff, +0x58, +0xf7, +0x72, +0xc0, +0xff, +0x6f, +0x3c, +0xfc, +0x03, +0xfc, +0xc0, +0x18, +0xd5, +0x00, +0x80, +0xff, +0x66, +0x3c, +0xeb, +0xc0, +0x9f, +0xd9, +0x4d, +0xee, +0xf8, +0xff, +0xff, +0x83, +0x7f, +0xa6, +0x07, +0xe8, +0xff, +0xff, +0xe8, +0x1f, +0xbe, +0xb5, +0x00, +0x60, +0x2f, +0x6a, +0x0e, +0xc0, +0xd3, +0x37, +0x08, +0x70, +0xe0, +0x0f, +0xff, +0xaf, +0x13, +0xfc, +0xd7, +0xcf, +0xc3, +0xbf, +0xeb, +0x01, +0xfc, +0x67, +0xde, +0x00, +0x0f, +0xfe, +0x35, +0x00, +0xd0, +0x00, +0xff, +0x1f, +0x40, +0xfc, +0xc7, +0x42, +0x7e, +0x78, +0xef, +0xff, +0x16, +0xfe, +0x0f, +0x60, +0xcb, +0xe1, +0xb7, +0x72, +0x00, +0xee, +0x7e, +0x00, +0x9f, +0x83, +0x9f, +0x1a, +0x00, +0x58, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0x81, +0x7f, +0x00, +0xc3, +0x3f, +0x80, +0x7f, +0xfc, +0x7f, +0x0f, +0x00, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0xbf, +0x07, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x03, +0x00, +0xff, +0xdf, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xef, +0x01, +0x80, +0xff, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0xff, +0xf7, +0x00, +0xc0, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0xff, +0x7b, +0x00, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x00, +0xf0, +0xff, +0x3d, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0x1e, +0x00, +0xf8, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x7f, +0x0f, +0x00, +0xfc, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0xbf, +0x07, +0x00, +0xfc, +0x07, +0xfe, +0x01, +0x0d, +0xff, +0x00, +0xfe, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x01, +0x80, +0xff, +0xef, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xd7, +0x00, +0x00, +0xfa, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0xfc, +0x6b, +0x00, +0xe0, +0xf8, +0xff, +0x7f, +0x8b, +0xf0, +0x0f, +0x70, +0xd6, +0xff, +0xdb, +0x7f, +0x2c, +0xc3, +0x3f, +0xd6, +0xe2, +0xfc, +0x67, +0xeb, +0x01, +0x0f, +0xfd, +0x5e, +0x3e, +0xf0, +0xff, +0x3d, +0x00, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x00, +0xf8, +0xff, +0x1e, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0x0f, +0x00, +0xfc, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0xbf, +0x07, +0x00, +0xfe, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xef, +0x01, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x00, +0xc0, +0xff, +0xf7, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0x7b, +0x00, +0xe0, +0xff, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0xff, +0x3d, +0x00, +0xf0, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0xff, +0x1e, +0x00, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x00, +0xfc, +0x7f, +0x0f, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0x07, +0x00, +0xfe, +0xbf, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0xdf, +0x03, +0x00, +0xff, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xef, +0x01, +0x80 +}; + +/*---------------------------------------------------------------------------------------- + * 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/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000b6.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000b6.c new file mode 100755 index 0000000000..ae26d0f563 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000b6.c @@ -0,0 +1,1035 @@ +/** + * @file + * + * AMD Family_10 Microcode patch. + * + * Fam10 Microcode Patch rev 010000B6 for 1043 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10/REVC + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +// Patch code 010000b6 for 1043 and equivalent +CONST MICROCODE_PATCHES ROMDATA CpuF10MicrocodePatch010000b6 = +{ +0x09, +0x20, +0x31, +0x07, +0xb6, +0x00, +0x00, +0x01, +0x00, +0x80, +0x20, +0x00, +0xe9, +0x98, +0xda, +0x6b, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x43, +0x10, +0x00, +0x00, +0x00, +0xaa, +0xaa, +0xaa, +0x10, +0x0c, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x18, +0x80, +0x38, +0xc0, +0x83, +0x37, +0x80, +0xff, +0xb8, +0xff, +0xff, +0x13, +0x0e, +0xbf, +0x0c, +0xb6, +0x7a, +0xc4, +0xff, +0x2f, +0x3c, +0xfc, +0x6b, +0xfd, +0x40, +0x03, +0xd4, +0x00, +0x97, +0xff, +0xff, +0xff, +0xe7, +0xe1, +0x1f, +0xe0, +0x00, +0xfe, +0xbf, +0xf5, +0x9f, +0x87, +0x7e, +0x22, +0x01, +0xc6, +0x00, +0xc4, +0x7c, +0x1e, +0xfa, +0x01, +0x00, +0xe0, +0xff, +0x7b, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0x3d, +0x00, +0xf0, +0xff, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0xff, +0x1e, +0x00, +0xf8, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0x81, +0x7f, +0x00, +0xc3, +0x3f, +0x80, +0x7f, +0xfc, +0x7f, +0x0f, +0x00, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0xbf, +0x07, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x03, +0x00, +0xff, +0xdf, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xef, +0x01, +0x80, +0xff, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0xff, +0xf7, +0x00, +0xc0, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0xff, +0x7b, +0x00, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x00, +0xf0, +0xff, +0x3d, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0x1e, +0x00, +0xf8, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x7f, +0x0f, +0x00, +0xfc, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0xbf, +0x07, +0x00, +0xfc, +0x07, +0xfe, +0x01, +0x0d, +0xff, +0x00, +0xfe, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x01, +0x80, +0xff, +0xef, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xd7, +0x00, +0x80, +0xf8, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0xfc, +0x6b, +0x00, +0x20, +0x04, +0xff, +0xbf, +0xe8, +0xf0, +0xaf, +0xf5, +0xf3, +0xff, +0xd9, +0x7a, +0x00, +0x83, +0x3f, +0x31, +0xc0, +0x0c, +0x7d, +0xe3, +0x00, +0x0f, +0xfe, +0x80, +0x5e, +0xf0, +0xff, +0x3d, +0x00, +0x65, +0xfe, +0xff, +0x9f, +0x7f, +0xf8, +0xc7, +0xba, +0x96, +0xf2, +0xff, +0x7f, +0xfa, +0xe1, +0x1f, +0xeb, +0x45, +0x0e, +0xf8, +0xff, +0x9f, +0x87, +0x7f, +0x80, +0x00, +0xf8, +0xff, +0x1e, +0x07, +0xf0, +0x5f, +0x8c, +0x7b, +0x1d, +0xf8, +0x13, +0xbf, +0xe8, +0x1a, +0xff, +0xf4, +0xf3, +0xf0, +0x4f, +0xff, +0x2f, +0xe3, +0xff, +0xd7, +0xf5, +0xc3, +0xbf, +0x0f, +0x00, +0xfc, +0x7f, +0xd6, +0x03, +0xf8, +0xdf, +0x89, +0x01, +0x1e, +0xfc, +0xfb, +0x0f, +0xe0, +0x3f, +0xd6, +0xa2, +0x7f, +0xf8, +0xff, +0x7f, +0x82, +0xff, +0x97, +0xc1, +0xd6, +0xe1, +0x40, +0x02, +0x00, +0x14, +0x7f, +0xff, +0x01, +0xfc, +0xdf, +0x5a, +0xf4, +0x0f, +0xfe, +0xff, +0xef, +0x32, +0xfc, +0x03, +0x9c, +0x35, +0x7f, +0xf7, +0x5f, +0xcb, +0xf0, +0xaf, +0xf5, +0xff, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0x5a, +0x87, +0x5f, +0xad, +0x2b, +0xf8, +0xdf, +0xd6, +0x03, +0x1e, +0xfa, +0x89, +0x7c, +0x20, +0x7d, +0xc0, +0x9f, +0x75, +0xf8, +0x65, +0xb0, +0x80, +0xff, +0xef, +0x01, +0x00, +0xff, +0xdb, +0x7a, +0xc0, +0x83, +0x3f, +0x31, +0x01, +0xfc, +0x07, +0xfe, +0xf4, +0x0f, +0xdf, +0x5a, +0x4f, +0xa0, +0x3e, +0xe0, +0xd8, +0x3a, +0xfc, +0x32, +0x00, +0xc0, +0x01, +0x48, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0x7b, +0x00, +0xe0, +0xff, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0xff, +0x3d, +0x00, +0xf0, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0xff, +0x1e, +0x00, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x00, +0xfc, +0x7f, +0x0f, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0x07, +0x00, +0xfe, +0xbf, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0xdf, +0x03, +0x00, +0xff, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xef, +0x01, +0x80 +}; + +/*---------------------------------------------------------------------------------------- + * 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/f10/Proc/CPU/Family/0x10/RevC/F10RevCHtPhyTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCHtPhyTables.c new file mode 100755 index 0000000000..a15cad701f --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCHtPhyTables.c @@ -0,0 +1,436 @@ +/** + * @file + * + * AMD Family_10 Rev C HT PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_F10REVCHTPHYTABLES_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 + *---------------------------------------------------------------------------------------- + */ + +// HT Phy T a b l e s +// ------------------------- +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F10RevCHtPhyRegisters[] = +{ +// 0x60:0x68 + { + HtPhyRangeRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_C0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL0_ALL, // + 0x60, 0x68, // Address range + 0x00000040, // regData + 0x00000040, // regMask + } + }, +// 0x70:0x78 + { + HtPhyRangeRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_C0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL1_ALL, // + 0x70, 0x78, // Address range + 0x00000040, // regData + 0x00000040, // regMask + } + }, +// Erratum 354 +// 0x40:48 + { + HtPhyRangeRegister, + { + AMD_FAMILY_10, // CpuFamily + (AMD_F10_C2 | AMD_F10_C3) // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL0_HT3, // + 0x40, 0x48, // Address + 0x00000040, // regData + 0x00000040, // regMask + } + }, +// 0x50:0x58 + { + HtPhyRangeRegister, + { + AMD_FAMILY_10, // CpuFamily + (AMD_F10_C2 | AMD_F10_C3) // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL1_HT3, // + 0x50, 0x58, // Address + 0x00000040, // regData + 0x00000040, // regMask + } + }, +// 0xC0 + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL0_ALL, // + 0xC0, // Address + 0x40040000, // regData + 0xe01F0000, // regMask + } + }, +// 0xD0 + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL1_ALL, // + 0xD0, // Address + 0x40040000, // regData + 0xe01F0000, // regMask + } + }, +// 0xCF +// FIFO_PTR_OPT_VALUE + { + HtPhyProfileRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + PERFORMANCE_NB_PSTATES_ENABLE, + HTPHY_LINKTYPE_SL0_HT3, // + 0xCF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + } + }, +// 0xDF +// FIFO_PTR_OPT_VALUE + { + HtPhyProfileRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + PERFORMANCE_NB_PSTATES_ENABLE, + HTPHY_LINKTYPE_SL1_HT3, // + 0xDF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + } + }, +// 0x520A + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL0_ALL, // + 0x520A, // Address + 0x00004000, // regData + 0x00006000, // regMask + } + }, +// 0x530A + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL1_ALL, // + 0x530A, // Address + 0x00004000, // regData + 0x00006000, // regMask + } + }, + + + + +// +// Deemphasis Settings +// + +// For C3, also set [7]TxLs23ClkGateEn. +//deemphasis level DL1[20:16], DL2[12:8], DP1[4:0] PostCur1En[31] PostCur2En[30] PreCur1En[29] MapPostCur2En[6] +// No deemphasis 00h 00h 00h 0 0 0 0 +// -3dB postcursor 12h 00h 00h 1 0 0 0 +// -6dB postcursor 1Fh 00h 00h 1 0 0 0 +// -8dB postcursor 1Fh 06h 00h 1 1 0 1 +// -11dB postcursor 1Fh 0Dh 00h 1 1 0 1 +// -11dB postcursor with +// -8dB precursor 1Fh 06h 07h 1 1 1 1 + + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x00000080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x00000080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__3, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x80120080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__3, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x80120080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__6, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x801F0080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__6, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x801F0080, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xC01F06C0, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xC01F06C0, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__11, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xC01F0DC0, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__11, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xC01F0DC0, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__11_8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xE01F06C7, // regData + 0xE01F1FDF, // regMask + } + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + DEEMPHASIS_LEVEL__11_8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xE01F06C7, // regData + 0xE01F1FDF, // regMask + } + }, +}; + +CONST REGISTER_TABLE ROMDATA F10RevCHtPhyRegisterTable = { + PrimaryCores, + (sizeof (F10RevCHtPhyRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10RevCHtPhyRegisters +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCHwC1e.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCHwC1e.c new file mode 100755 index 0000000000..93b9216251 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCHwC1e.c @@ -0,0 +1,178 @@ +/** + * @file + * + * AMD Family_10 HW C1e feature support functions. + * + * Provides the functions necessary to initialize the hardware C1e feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "cpuHwC1e.h" +#include "cpuApicUtilities.h" +#include "cpuF10PowerMgmt.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_F10REVCHWC1E_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 +F10InitializeHwC1eOnCore ( + IN VOID *IntPendMsr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Should hardware C1e be enabled + * + * @param[in] HwC1eServices Pointer to this CPU's HW C1e family services. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HW C1e is supported. + * + */ +BOOLEAN +STATIC +F10IsHwC1eSupported ( + IN HW_C1E_FAMILY_SERVICES *HwC1eServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return TRUE; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable Hardware C1e on a family 10h CPU. + * + * @param[in] HwC1eServices Pointer to this CPU's HW C1e 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 +F10InitializeHwC1e ( + IN HW_C1E_FAMILY_SERVICES *HwC1eServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrRegister; + AP_TASK TaskPtr; + + MsrRegister = 0; + ((INTPEND_MSR *) &MsrRegister)->IoMsgAddr = PlatformConfig->C1ePlatformData; + ((INTPEND_MSR *) &MsrRegister)->IoMsgData = 0xC1; + ((INTPEND_MSR *) &MsrRegister)->IoRd = 1; + ((INTPEND_MSR *) &MsrRegister)->C1eOnCmpHalt = 1; + ((INTPEND_MSR *) &MsrRegister)->SmiOnCmpHalt = 0; + + TaskPtr.FuncAddress.PfApTaskI = F10InitializeHwC1eOnCore; + TaskPtr.DataTransfer.DataSizeInDwords = 2; + TaskPtr.DataTransfer.DataPtr = &MsrRegister; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable Hardware C1e on a family 10h core. + * + * @param[in] IntPendMsr MSR value to write to C001_0055 as determined by core 0. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +STATIC +F10InitializeHwC1eOnCore ( + IN VOID *IntPendMsr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrRegister; + + // Enable C1e + LibAmdMsrWrite (MSR_INTPEND, (UINT64 *) IntPendMsr, StdHeader); + + // Set OS Visible Workaround Status BIT1 to indicate that C1e + // is enabled. + LibAmdMsrRead (MSR_OSVW_Status, &MsrRegister, StdHeader); + MsrRegister |= BIT1; + LibAmdMsrWrite (MSR_OSVW_Status, &MsrRegister, StdHeader); +} + + +CONST HW_C1E_FAMILY_SERVICES ROMDATA F10HwC1e = +{ + 0, + F10IsHwC1eSupported, + F10InitializeHwC1e +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCMsrTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCMsrTables.c new file mode 100755 index 0000000000..bd1f788ca6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCMsrTables.c @@ -0,0 +1,130 @@ +/** + * @file + * + * AMD Family_10 Rev C, MSR tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_F10REVCMSRTABLES_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 F10RevCMsrRegisters[] = +{ +// M S R T a b l e s +// ---------------------- +// MSR_LS_CFG (0xC0011020) +// bit[1] = 0 + { + MsrRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_B0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MSR_LS_CFG, // MSR Address + 0x0000000000000000, // OR Mask + (1 << 1), // NAND Mask + } + }, + +// MSR_BU_CFG (0xC0011023) +// bit[21] = 1 + { + MsrRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_B0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MSR_BU_CFG, // MSR Address + (1 << 21), // OR Mask + (1 << 21), // NAND Mask + } + }, + +// MSR_BU_CFG2 (0xC001102A) +// bit[50] = 1 +// For GH rev C1 and later [RdMmExtCfgQwEn]=1 + { + MsrRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_C0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MSR_BU_CFG2, // MSR Address + 0x0004000000000000, // OR Mask + 0x0004000000000000, // NAND Mask + } + }, +}; + +CONST REGISTER_TABLE ROMDATA F10RevCMsrRegisterTable = { + AllCores, + (sizeof (F10RevCMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F10RevCMsrRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCPciTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCPciTables.c new file mode 100755 index 0000000000..6abe3895e6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCPciTables.c @@ -0,0 +1,261 @@ +/** + * @file + * + * AMD Family_10 Rev C PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10/RevC + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "F10PackageType.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_F10REVCPCITABLES_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 F10RevCPciRegisters[] = +{ +// Function 2 - DRAM Controller + +// F2x1B0 - Extended Memory Controller Configuration Low Register +// +// bit[5:4], AdapPrefNegativeStep = 0 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x1B0), // Address + 0x00000000, // regData + 0x00000030, // regMask + } + }, +// Function 3 - Misc. Control + +// F3x158 - Link to XCS Token Count +// bits[3:0] LnkToXcsDRToken = 3 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_A2 // CpuRevision + }, + AMD_PF_UMA, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x158), // Address + 0x00000003, // regData + 0x0000000F, // regMask + } + }, +// F3x80 - ACPI Power State Control +// ACPI State C2 +// bits[0] CpuPrbEn = 1 +// bits[1] NbLowPwrEn = 0 +// bits[2] NbGateEn = 0 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 1 +// ACPI State C3, C1E or Link init +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 7 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x0000E681, // regData + 0x0000FFFF, // regMask + } + }, +// F3x80 - ACPI Power State Control +// ACPI State C3, C1E or Link init +// bits[0] CpuPrbEn = 1 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 4 + { + HtFeatPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + HT_HOST_FEAT_HT1, // link feats + PACKAGE_TYPE_ASB2, // package type + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x00008700, // regData + 0x0000FF00, // regMask + } + }, +// F3x80 - ACPI Power State Control +// ACPI State C3, C1E or Link init +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 1 +// bits[7:5] ClkDivisor = 7 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + PERFORMANCE_VRM_HIGH_SPEED_ENABLE, // PerformanceFeatures + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x0000F600, // regData + 0x0000FF00, // regMask + } + }, +// F3x80 - ACPI Power State Control +// ACPI State C3, C1E or Link init +// bits[0] CpuPrbEn = 1 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 4 + { + HtFeatPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + HT_HOST_FEAT_HT1, // link feats + PACKAGE_TYPE_ALL & (~ PACKAGE_TYPE_ASB2), // package type + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x00008700, // regData + 0x0000FF00, // regMask + } + }, +// F3xDC - Clock Power Timing Control 2 +// bits[14:12] NbsynPtrAdj = 5 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xDC), // Address + 0x00005000, // regData + 0x00007000, // regMask + } + }, +// F3x180 - NB Extended Configuration +// bits[23] SyncFloodOnDramTempErr = 1 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x180), // Address + 0x00800000, // regData + 0x00800000, // regMask + } + }, +// F3x188 - NB Extended Configuration Low Register +// Must be set by BIOS + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Cx // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x188), // Address + 0x00400000, // regData + 0x00400000, // regMask + } + } +}; + +CONST REGISTER_TABLE ROMDATA F10RevCPciRegisterTable = { + PrimaryCores, + (sizeof (F10RevCPciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10RevCPciRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCUtilities.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCUtilities.c new file mode 100755 index 0000000000..06a4fa7632 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10RevCUtilities.c @@ -0,0 +1,401 @@ +/** + * @file + * + * AMD Family_10 revision Cx specific utility functions. + * + * Provides numerous utility functions specific to family 10h rev C. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuF10PowerMgmt.h" +#include "GeneralServices.h" +#include "cpuEarlyInit.h" +#include "cpuPostInit.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_F10REVCUTILITIES_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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Set down core register on a revision C processor. + * + * 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] StdHeader Header for library and services. + * + */ +VOID +F10CommonRevCSetDownCoreRegister ( + IN CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices, + IN UINT32 *Socket, + IN UINT32 *Module, + IN UINT32 *LeveledCores, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TempVar32_a; + UINT32 CoreDisableBits; + PCI_ADDR PciAddress; + AGESA_STATUS AgesaStatus; + + switch (*LeveledCores) { + case 1: + CoreDisableBits = DOWNCORE_MASK_SINGLE; + break; + case 2: + CoreDisableBits = DOWNCORE_MASK_DUAL; + break; + case 3: + CoreDisableBits = DOWNCORE_MASK_TRI; + break; + default: + CoreDisableBits = 0; + break; + } + + if (CoreDisableBits != 0) { + if (GetPciAddress (StdHeader, (UINT8) *Socket, (UINT8) *Module, &PciAddress, &AgesaStatus)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NORTH_BRIDGE_CAPABILITIES_REG; + + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar32_a, StdHeader); + TempVar32_a = (TempVar32_a >> 12) & 0x3; + if (TempVar32_a == 0) { + CoreDisableBits &= 0x1; + } else if (TempVar32_a == 1) { + CoreDisableBits &= 0x3; + } else if (TempVar32_a == 2) { + CoreDisableBits &= 0x7; + } else if (TempVar32_a == 3) { + CoreDisableBits &= 0x0F; + } + PciAddress.Address.Register = DOWNCORE_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar32_a, StdHeader); + TempVar32_a |= CoreDisableBits; + LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar32_a, StdHeader); + } + } + + return; +} + + +CONST CPU_CORE_LEVELING_FAMILY_SERVICES ROMDATA F10RevCCoreLeveling = +{ + 0, + F10CommonRevCSetDownCoreRegister +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Get CPU pstate current on a revision C processor. + * + * @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 +F10CommonRevCGetProcIddMax ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 Pstate, + OUT UINT32 *ProcIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 IddDiv; + UINT32 CmpCap; + UINT32 PciRegister; + UINT32 Socket; + UINT32 Module; + UINT32 Ignored; + UINT32 MsrAddress; + UINT32 SinglePlaneNbIdd; + UINT64 PstateMsr; + BOOLEAN IsPstateEnabled; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + IsPstateEnabled = FALSE; + + MsrAddress = (UINT32) (Pstate + PS_REG_BASE); + + ASSERT (MsrAddress <= PS_MAX_REG); + + LibAmdMsrRead (MsrAddress, &PstateMsr, StdHeader); + if (((PSTATE_MSR *) &PstateMsr)->PsEnable == 1) { + IdentifyCore (StdHeader, &Socket, &Module, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NB_CAPS_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); // F3xE8 + CmpCap = (UINT32) (((NB_CAPS_REGISTER *) &PciRegister)->CmpCapLo); + CmpCap++; + + switch (((PSTATE_MSR *) &PstateMsr)->IddDiv) { + case 0: + IddDiv = 1000; + break; + case 1: + IddDiv = 100; + break; + case 2: + IddDiv = 10; + break; + default: // IddDiv = 3 is reserved. Use 10 + ASSERT (FALSE); + IddDiv = 10; + break; + } + + PciAddress.Address.Register = PW_CTL_MISC_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); // F3xE8 + if (((POWER_CTRL_MISC_REGISTER *) &PciRegister)->PviMode == 1) { + *ProcIddMax = (UINT32) ((PSTATE_MSR *) &PstateMsr)->IddValue * IddDiv * CmpCap; + } else { + PciAddress.Address.Register = PRCT_INFO_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); // F3xE8 + SinglePlaneNbIdd = ((PRODUCT_INFO_REGISTER *) &PciRegister)->SinglePlaneNbIdd; + SinglePlaneNbIdd <<= 1; + *ProcIddMax = ((UINT32) ((PSTATE_MSR *) &PstateMsr)->IddValue * IddDiv * CmpCap) - SinglePlaneNbIdd; + } + IsPstateEnabled = TRUE; + } + return IsPstateEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10CommonRevCGetNbCofVidUpdate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT BOOLEAN *NbVidUpdateAll, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ProductInfoRegister; + + PciAddress->Address.Register = PRCT_INFO_REG; + PciAddress->Address.Function = FUNC_3; + LibAmdPciRead (AccessWidth32, *PciAddress, &ProductInfoRegister, StdHeader); + *NbVidUpdateAll = (BOOLEAN) (((PRODUCT_INFO_REGISTER *) &ProductInfoRegister)->NbVidUpdateAll == 1); + return (BOOLEAN) (((PRODUCT_INFO_REGISTER *) &ProductInfoRegister)->NbCofVidUpdate == 1); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the NB clock on the desired node. + * + * @CpuServiceMethod{::F_CPU_GET_NB_FREQ}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PciAddress The northbridge to query + * @param[out] FrequencyInMHz Northbridge clock frequency in MHz. + * @param[out] VoltageInuV Northbridge voltage in uV. + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F10CommonRevCGetNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT UINT32 *FrequencyInMHz, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ProductInfoRegister; + UINT32 PciRegister; + UINT32 NbFid; + UINT32 NbVid; + UINT64 MsrRegister; + + PciAddress->Address.Register = PRCT_INFO_REG; + PciAddress->Address.Function = FUNC_3; + LibAmdPciRead (AccessWidth32, *PciAddress, &ProductInfoRegister, StdHeader); + if ((((PRODUCT_INFO_REGISTER *) &ProductInfoRegister)->NbCofVidUpdate) == 0) { + PciAddress->Address.Register = CPTC0_REG; + LibAmdPciRead (AccessWidth32, *PciAddress, &PciRegister, StdHeader); + NbFid = ((CLK_PWR_TIMING_CTRL_REGISTER *) &PciRegister)->NbFid; + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + NbVid = (UINT32) ((COFVID_STS_MSR *) &MsrRegister)->CurNbVid; + } else { + NbFid = ((PRODUCT_INFO_REGISTER *) &ProductInfoRegister)->SinglePlaneNbFid; + NbVid = ((PRODUCT_INFO_REGISTER *) &ProductInfoRegister)->SinglePlaneNbVid; + PciAddress->Address.Register = PW_CTL_MISC_REG; + LibAmdPciRead (AccessWidth32, *PciAddress, &PciRegister, StdHeader); + if (((POWER_CTRL_MISC_REGISTER *) &PciRegister)->PviMode == 0) { + NbFid += ((PRODUCT_INFO_REGISTER *) &ProductInfoRegister)->DualPlaneNbFidOff; + NbVid -= ((PRODUCT_INFO_REGISTER *) &ProductInfoRegister)->DualPlaneNbVidOff; + } + } + *FrequencyInMHz = ((NbFid + 4) * 200); + *VoltageInuV = (1550000 - (12500 * NbVid)); + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Is the Northbridge PState feature enabled? + * + * @CpuServiceMethod{::F_IS_NB_PSTATE_ENABLED}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @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 +F10CommonRevCIsNbPstateEnabled ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Core; + UINT32 Module; + UINT32 NbPstate; + UINT32 Socket; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + CPU_LOGICAL_ID LogicalId; + BOOLEAN Result; + + Result = FALSE; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + if ((LogicalId.Revision & AMD_F10_C3) != 0) { + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = 0x1F0; + LibAmdPciReadBits (PciAddress, 18, 16, &NbPstate, StdHeader); + if (NbPstate != 0) { + Result = TRUE; + } + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get number of processor cores to be used in determining the brand string. + * + * @CpuServiceMethod{::F_CPU_NUMBER_OF_BRANDSTRING_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 cores to be used in brand string calculation. + */ +UINT8 +F10CommonRevCGetNumberOfCoresForBrandstring ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 Core; + UINT32 PciRegister; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NB_CAPS_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + return (UINT8) (((NB_CAPS_REGISTER *) &PciRegister)->CmpCapLo + 1); +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbEquivalenceTable.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbEquivalenceTable.c new file mode 100755 index 0000000000..79858d24a9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbEquivalenceTable.c @@ -0,0 +1,105 @@ +/** + * @file + * + * AMD Family_10 RB Equivalence Table related data + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6381 $ @e \$Date: 2008-06-15 17:26:25 -0500 (Sun, 15 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_RB_F10RBEQUIVALENCETABLE_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 UINT16 ROMDATA CpuF10RbMicrocodeEquivalenceTable[] = +{ + 0x1040, 0x1040, + 0x1041, 0x1041, + 0x1042, 0x1041, + 0x1043, 0x1043 +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] RbEquivalenceTablePtr 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 +GetF10RbMicrocodeEquivalenceTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **RbEquivalenceTablePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = ((sizeof (CpuF10RbMicrocodeEquivalenceTable) / sizeof (UINT16)) / 2); + *RbEquivalenceTablePtr = CpuF10RbMicrocodeEquivalenceTable; +} + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbHtPhyTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbHtPhyTables.c new file mode 100755 index 0000000000..424f5ca31a --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbHtPhyTables.c @@ -0,0 +1,115 @@ +/** + * @file + * + * AMD Family_10 RB PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_RB_F10RBHTPHYTABLES_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 + *---------------------------------------------------------------------------------------- + */ + +// HT Phy T a b l e s +// ------------------------- +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F10RbHtPhyRegisters[] = +{ +// Erratum 354 +// 0x40:0x48 + { + HtPhyRangeRegister, + { + AMD_FAMILY_10, // CpuFamily + (AMD_F10_RB_C1) // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL0_HT3, // + 0x40, 0x48, // Address + 0x00000040, // regData + 0x00000040, // regMask + } + }, +// 0x50:0x58 + { + HtPhyRangeRegister, + { + AMD_FAMILY_10, // CpuFamily + (AMD_F10_RB_C1) // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + HTPHY_LINKTYPE_SL1_HT3, // + 0x50, 0x58, // Address + 0x00000040, // regData + 0x00000040, // regMask + } + }, +}; + +CONST REGISTER_TABLE ROMDATA F10RbHtPhyRegisterTable = { + PrimaryCores, + (sizeof (F10RbHtPhyRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10RbHtPhyRegisters +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbLogicalIdTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbLogicalIdTables.c new file mode 100755 index 0000000000..c9d5aed20f --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbLogicalIdTables.c @@ -0,0 +1,109 @@ +/** + * @file + * + * AMD Family_10 RB Logical ID Table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 6261 $ @e \$Date: 2008-06-04 17:38:17 -0500 (Wed, 04 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_RB_F10RBLOGICALIDTABLES_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 CPU_LOGICAL_ID_XLAT ROMDATA CpuF10RbLogicalIdAndRevArray[] = +{ + { + 0x1040, + AMD_F10_RB_C0 + }, + { + 0x1041, + AMD_F10_RB_C1 + }, + { + 0x1042, + AMD_F10_RB_C2 + }, + { + 0x1043, + AMD_F10_RB_C3 + } +}; + +VOID +GetF10RbLogicalIdAndRev ( + OUT CONST CPU_LOGICAL_ID_XLAT **RbIdPtr, + OUT UINT8 *NumberOfElements, + OUT UINT64 *LogicalFamily, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = (sizeof (CpuF10RbLogicalIdAndRevArray) / sizeof (CPU_LOGICAL_ID_XLAT)); + *RbIdPtr = CpuF10RbLogicalIdAndRevArray; + *LogicalFamily = AMD_FAMILY_10_RB; +} + +//CONST LOGICAL_ID_TABLE ROMDATA CpuF10RbLogicalIdAndRev = +//{ +// (sizeof (CpuF10RbLogicalIdAndRevArray) / sizeof (CPU_LOGICAL_ID_XLAT)), +// (CPU_LOGICAL_ID_XLAT *) &CpuF10RbLogicalIdAndRevArray +//}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbMicrocodePatchTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbMicrocodePatchTables.c new file mode 100755 index 0000000000..7362ebdbd6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbMicrocodePatchTables.c @@ -0,0 +1,104 @@ +/** + * @file + * + * AMD Family_10 RB microcode patches + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6049 $ @e \$Date: 2008-05-13 23:58:02 -0700 (Tue, 13 May 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_RB_F10RBMICROCODEPATCHTABLES_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 + *---------------------------------------------------------------------------------------- + */ + +CONST MICROCODE_PATCHES ROMDATA *CpuF10RbMicroCodePatchArray[]; + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] RbUcodePtr 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 +GetF10RbMicroCodePatchesStruct ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **RbUcodePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NumberOfUcode; + + for (NumberOfUcode = 0; CpuF10RbMicroCodePatchArray[NumberOfUcode] != 0; NumberOfUcode++) { + } + *NumberOfElements = NumberOfUcode; + *RbUcodePtr = &CpuF10RbMicroCodePatchArray[0]; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbMsrTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbMsrTables.c new file mode 100755 index 0000000000..a4c0a91129 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbMsrTables.c @@ -0,0 +1,115 @@ +/** + * @file + * + * AMD Family_10 RB, MSR tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_RB_F10RBMSRTABLES_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 F10RbMsrRegisters[] = +{ +// M S R T a b l e s +// ---------------------- + +// MSR_DC_CFG (0xC0011022) +// bits[43:42] = 0 +// Errata #326 + { + MsrRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_RB_C0 // CpuRevision + }, + AMD_PF_MULTI_LINK, // platformFeatures + { + MSR_DC_CFG, // MSR Address + 0x0000000000000000, // OR Mask + 0x00000C0000000000, // NAND Mask + } + }, + +// MSR_BU_CFG (0xC0011023) +// Erratum #309 BU_CFG[23]=1 + { + MsrRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_RB_C0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MSR_BU_CFG, // MSR Address + (1 << 23), // OR Mask + (1 << 23), // NAND Mask + } + } +}; + +CONST REGISTER_TABLE ROMDATA F10RbMsrRegisterTable = { + AllCores, + (sizeof (F10RbMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F10RbMsrRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbPciTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbPciTables.c new file mode 100755 index 0000000000..6bfe0b6303 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/RB/F10RbPciTables.c @@ -0,0 +1,212 @@ +/** + * @file + * + * AMD Family_10 RB PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVC_RB_F10RBPCITABLES_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 F10RbPciRegisters[] = +{ + // Function 0 + +// F0x16C - Link Global Extended Control Register, Errata 351 +// bit[15:13] ForceFullT0 = 0 +// bit[5:0] T0Time = 0x14 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + (AMD_F10_RB_C0 | AMD_F10_RB_C1 | AMD_F10_RB_C2) // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00000014, // regData + 0x0000E03F, // regMask + } + }, +// F0x16C - Link Global Extended Control Register +// bit[7:6] InLnSt = 0x01 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_RB_C3 // CpuRevision + }, + AMD_PF_SINGLE_LINK, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00000040, // regData + 0x000000C0, // regMask + } + }, +// F0x170 - Link Extended Control Register - Link 0, sublink 0 +// Errata 351 (only need to override single link case.) +// bit[8] LS2En = 0, + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + (AMD_F10_RB_C0 | AMD_F10_RB_C1 | AMD_F10_RB_C2) // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x170), // Address + 0x00000000, // regData + 0x00000100, // regMask + } + }, + + +// F3xA0 - Power Control Miscellaneous +// bits[13:11] PllLockTime = 5 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_RB_C0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x00002800, // regData + 0x00003800, // regMask + } + }, +// F3xA0 - Power Control Miscellaneous +// bits[28] NbPstateForce = 1 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_RB_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x10000000, // regData + 0x10000000, // regMask + } + }, +// F3xDC - Clock Power Timing Control 2 +// bits[14:12] NbsynPtrAdj = 6 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_RB_ALL // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xDC), // Address + 0x00006000, // regData + 0x00007000, // regMask + } + }, +// F3xDC - Clock Power Timing Control 2 +// bits[14:12] NbsynPtrAdj = 5 + { + PciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C0 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xDC), // Address + 0x00005000, // regData + 0x00007000, // regMask + } + }, +// F3xDC - Clock Power Timing Control 2 +// bits[14:12] NbsynPtrAdj = 5 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + AMD_PF_ALL, // platformFeatures + { + PERFORMANCE_NB_PSTATES_ENABLE, // PerformanceFeatures + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xDC), // Address + 0x00005000, // regData + 0x00007000, // regMask + } + } +}; + +CONST REGISTER_TABLE ROMDATA F10RbPciRegisterTable = { + PrimaryCores, + (sizeof (F10RbPciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10RbPciRegisters, +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c4.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c4.c new file mode 100755 index 0000000000..a86f326b8d --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c4.c @@ -0,0 +1,1037 @@ +/** + * @file + * + * AMD Family_10 Microcode patch. + * + * Fam10 Microcode Patch rev 010000c4 for 1081 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10/REVD + * @e \$Revision$ @e \$Date$ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +// Patch code 010000c4 for 1081 and equivalent +CONST MICROCODE_PATCHES ROMDATA CpuF10MicrocodePatch010000c4 = +{ +{ +0x10, +0x20, +0x03, +0x03, +0xc4, +0x00, +0x00, +0x01, +0x00, +0x80, +0x20, +0x01, +0x4a, +0xe0, +0x9c, +0x93, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x81, +0x10, +0x00, +0x00, +0x00, +0xaa, +0xaa, +0xaa, +0xa7, +0x0b, +0x00, +0x00, +0x14, +0x0c, +0x00, +0x00, +0x55, +0x03, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0x51, +0x03, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x4f, +0xdf, +0x38, +0x00, +0x81, +0x3f, +0x20, +0xc0, +0x4e, +0xf0, +0xff, +0xbf, +0x0f, +0xff, +0x5e, +0x3f, +0xf0, +0xdf, +0xad, +0x07, +0x3d, +0xf8, +0x7b, +0x7b, +0xc0, +0x00, +0xd4, +0x00, +0x13, +0xf1, +0xff, +0xff, +0xac, +0xe1, +0x1f, +0xe0, +0x4e, +0xfe, +0xbb, +0xff, +0xfe, +0x87, +0x7f, +0xa7, +0x03, +0xf8, +0x7f, +0xd6, +0x7c, +0x1e, +0xfa, +0xbd, +0x00, +0xe0, +0xff, +0x7b, +0x0e, +0x00, +0x3d, +0x57, +0xe0, +0x73, +0xd0, +0x0f, +0xff, +0x2e, +0xfe, +0xff, +0xc0, +0xcf, +0xc3, +0x3f, +0xeb, +0x01, +0xfc, +0x77, +0x5a, +0x3e, +0x0f, +0xfd, +0x35, +0x00, +0x90, +0x3e, +0xff, +0x9f, +0xe0, +0xfd, +0x65, +0x60, +0x75, +0xf8, +0x9f, +0xff, +0x97, +0xff, +0x1f, +0xe0, +0xe7, +0xe1, +0x03, +0xf5, +0xde, +0xff, +0x7e, +0x2c, +0x9f, +0x87, +0xff, +0x1e, +0x00, +0xf8, +0x6f, +0x95, +0x03, +0x50, +0xf4, +0x03, +0xf8, +0x1c, +0xf8, +0xff, +0x3f, +0x00, +0xf0, +0xee, +0x84, +0xfc, +0xfe, +0xff, +0xff, +0x22, +0xc3, +0x1f, +0x51, +0x96, +0x38, +0x16, +0x0d, +0x00, +0xf8, +0xfe, +0xfe, +0x01, +0x0e, +0xfc, +0xb1, +0x01, +0xe5, +0xa6, +0xff, +0x1f, +0x79, +0xf8, +0x07, +0xf8, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfa, +0xbf, +0x07, +0x01, +0xfc, +0x3f, +0xe3, +0x3e, +0x0f, +0xfd, +0x50, +0x03, +0xb0, +0xdf, +0x8c, +0xf9, +0x3c, +0xf4, +0x43, +0x0e, +0xc0, +0xfd, +0x32, +0xe5, +0xf3, +0xd0, +0x0f, +0x03, +0x00, +0x03, +0x25, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xef, +0x01, +0x80, +0xff, +0xff, +0xff, +0x00, +0xfd, +0xbb, +0x14, +0xf2, +0xc3, +0x2f, +0xf8, +0x13, +0xcc, +0x7f, +0x0c, +0xb8, +0x0e, +0x74, +0xf5, +0x03, +0xf0, +0xf8, +0x33, +0x03, +0x1c, +0x2b, +0xd7, +0x00, +0x00, +0xeb, +0xe5, +0x1f, +0x80, +0xc0, +0x1f, +0x1b, +0xe0, +0x9e, +0x9b, +0x7f, +0x00, +0x03, +0x7f, +0x6c, +0x80, +0xf8, +0x7d, +0xfe, +0x01, +0x0e, +0xfc, +0xb1, +0x01, +0x80, +0xd7, +0x62, +0x00, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x00, +0xf0, +0xff, +0x3d, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0x1e, +0x00, +0xf8, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x7f, +0x0f, +0x00, +0xfc, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0xbf, +0x07, +0x00, +0xfc, +0x07, +0xfe, +0x01, +0x0d, +0xff, +0x00, +0xfe, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x01, +0x80, +0xff, +0xef, +0x38, +0x00, +0x43, +0xdf, +0xa0, +0xd7, +0x83, +0x3f, +0xe3, +0x00, +0x3c, +0x75, +0x80, +0x5e, +0x07, +0xfe, +0xff, +0xef, +0x7a, +0xc1, +0x73, +0xfd, +0x3c, +0xfc, +0xf7, +0x00, +0xc0, +0xff, +0xff, +0xff, +0x17, +0xff, +0xdf, +0xeb, +0xff, +0xe1, +0xb7, +0xf5, +0x00, +0xfe, +0x7f, +0x6e, +0x80, +0x07, +0xff, +0xff, +0x6f, +0x11, +0xfe, +0xb5, +0xaa, +0x1f, +0xff, +0x7b, +0x00, +0xe0, +0xff, +0xff, +0x7f, +0x8b, +0xf0, +0xaf, +0x75, +0xff, +0xff, +0xdb, +0x7f, +0x2f, +0xc3, +0xbf, +0x57, +0xf5, +0x0c, +0xf1, +0xff, +0xb7, +0x0f, +0xff, +0x00, +0x3f, +0x70, +0xa2, +0x35, +0x00, +0xe0, +0xff, +0x1b, +0x0f, +0x79, +0xe8, +0xd7, +0xf2, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x00, +0xf8, +0xff, +0x1e, +0x2f, +0x3a, +0xc1, +0xff, +0xfd, +0x3c, +0xfc, +0x6b, +0x1e, +0xc0, +0x7f, +0xb6, +0x0c, +0xf0, +0xe0, +0x4f, +0xff, +0x2f, +0x43, +0xfc, +0xc0, +0xcf, +0xc3, +0x3f, +0x0f, +0x00, +0xfc, +0x7f, +0xff, +0x67, +0x81, +0xff, +0xb1, +0xee, +0x1f, +0xfe, +0x1b, +0x0f, +0xe0, +0xff, +0xf7, +0xf6, +0x7a, +0xf0, +0xef, +0xbf, +0x96, +0xff, +0x1d, +0xab, +0xfe, +0xe1, +0xbf, +0x07, +0x00, +0xfe, +0x6f, +0xff, +0xb1, +0xfc, +0x7f, +0x58, +0x59, +0x0e, +0xc0, +0xff, +0x2f, +0x72, +0xfc, +0x03, +0xfc, +0x3c, +0x7f, +0x31, +0x1e, +0xc0, +0xe0, +0x4f, +0xec, +0x75, +0xff, +0xdf, +0x03, +0x00, +0xd7, +0xf8, +0xff, +0x45, +0x87, +0x7f, +0xa2, +0x9f, +0x19, +0xff, +0xff, +0x67, +0x1f, +0xfe, +0xb1, +0xae, +0x65, +0xfc, +0xff, +0xff, +0x7e, +0xf8, +0xf7, +0xba, +0x80, +0xff, +0xef, +0x01, +0x00, +0xff, +0xdb, +0x7a, +0xc0, +0x83, +0x3f, +0x31, +0x01, +0xfc, +0x67, +0xff, +0xf4, +0x0f, +0xdf, +0x5a, +0x4f, +0xf0, +0xff, +0xff, +0xd8, +0x3a, +0xfc, +0x32, +0x00, +0xc0, +0x01, +0x48, +0x7f, +0x97, +0xf1, +0xff, +0xe0, +0xac, +0xe1, +0x1f, +0xff, +0x5a, +0xfe, +0xbb, +0xad, +0xff, +0x87, +0x7f, +0xfe, +0x03, +0xf8, +0xff, +0xb5, +0xe8, +0x1f, +0xbe, +0x7b, +0x00, +0xe0, +0xff, +0xe0, +0x5f, +0xcb, +0x7f, +0xab, +0x75, +0xe5, +0xf0, +0xdb, +0x7a, +0x00, +0xff, +0x3f, +0x91, +0xcf, +0x43, +0x0f, +0xf8, +0x13, +0x90, +0xbf, +0x0c, +0xb6, +0x0e, +0xff, +0x3d, +0x00, +0xf0, +0x7f, +0x5b, +0x0f, +0xe0, +0xf0, +0x27, +0x06, +0x78, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x5b, +0x8b, +0xfe, +0xca, +0x07, +0xfc, +0x09, +0x87, +0x5f, +0x06, +0x5b, +0x20, +0x00, +0x09, +0x00, +0xb0, +0xc0, +0x8d, +0x03, +0x3c, +0xf8, +0x03, +0x02, +0x80, +0xf8, +0xff, +0x3f, +0xfc, +0xf0, +0xce, +0x85, +0x04, +0x3a, +0x0e, +0xfe, +0xae, +0xc3, +0x1f, +0x03, +0x00, +0xfc, +0x7f, +0x0f, +0x77, +0x01, +0x00, +0xf8, +0xee, +0x1f, +0xfe, +0xb9, +0x3f, +0x65, +0x40, +0xe0, +0xf8, +0x79, +0xf8, +0x07, +0xff, +0x94, +0xf3, +0xff, +0xea, +0xfa, +0xe0, +0x5f, +0x06, +0x00, +0x7a, +0xbc, +0xff, +0xa5, +0xfe, +0x77, +0x52, +0x3f, +0x0f, +0xff, +0xff, +0xef, +0xf2, +0xfe, +0x03, +0xfc, +0x3c, +0xfc, +0x77, +0x1f, +0xe0, +0x7f, +0x2f, +0xe5, +0xf3, +0xd0, +0xdf, +0x03, +0x00, +0xff, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xef, +0x01, +0x80 +} +}; + +/*---------------------------------------------------------------------------------------- + * 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/f10/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c5.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c5.c new file mode 100755 index 0000000000..ce01eabdc9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c5.c @@ -0,0 +1,1035 @@ +/** + * @file + * + * AMD Family_10 Microcode patch. + * + * Fam10 Microcode Patch rev 010000c5 for 1080 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10/REVD + * @e \$Revision$ @e \$Date$ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +// Patch code 010000c5 for 1080 and equivalent +CONST MICROCODE_PATCHES ROMDATA CpuF10MicrocodePatch010000c5 = +{{ +0x10, +0x20, +0x05, +0x03, +0xc5, +0x00, +0x00, +0x01, +0x00, +0x80, +0x20, +0x00, +0x83, +0xc5, +0x93, +0xcd, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x80, +0x10, +0x00, +0x00, +0x00, +0xaa, +0xaa, +0xaa, +0x89, +0x0b, +0x00, +0x00, +0x55, +0x03, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0x51, +0x03, +0x00, +0x00, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xf8, +0xff, +0x2e, +0xc3, +0x3f, +0xd7, +0xfd, +0xac, +0xff, +0xff, +0xbb, +0x0f, +0xff, +0x5c, +0xd7, +0xf3, +0xdf, +0xfd, +0xc7, +0x3f, +0xfc, +0xe3, +0xf5, +0x00, +0x1d, +0xd5, +0x00, +0x00, +0xfd, +0xff, +0x7f, +0xfa, +0xe1, +0xd9, +0xca, +0x00, +0x66, +0xfa, +0x71, +0x80, +0x07, +0x7f, +0x40, +0x67, +0xd9, +0xff, +0xff, +0xde, +0x1d, +0x7e, +0xb1, +0x00, +0xe0, +0xff, +0x7b, +0x0e, +0x40, +0xbd, +0x55, +0xe0, +0x73, +0xd0, +0x0f, +0xff, +0x00, +0xe0, +0xff, +0x13, +0xf2, +0xc3, +0xbb, +0xff, +0x8b, +0xf8, +0xff, +0x44, +0x59, +0x0e, +0x7f, +0x34, +0x00, +0x10, +0x59, +0xfb, +0x07, +0xe0, +0xfb, +0xc7, +0x06, +0x38, +0xf0, +0xfe, +0x7f, +0x94, +0x9b, +0x1f, +0xe0, +0xe7, +0xe1, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0xff, +0x1e, +0x00, +0xe8, +0xff, +0x8c, +0x07, +0xf0, +0xf4, +0x43, +0xf9, +0x3c, +0x7e, +0x33, +0x0e, +0xc0, +0xd0, +0x0f, +0xe5, +0xf3, +0xf7, +0xcb, +0x38, +0x00, +0x43, +0x3f, +0x94, +0xcf, +0x0c, +0x94, +0x0c, +0x00, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0xbf, +0x07, +0x03, +0xf4, +0xff, +0xff, +0xc8, +0x0f, +0xef, +0x52, +0x4f, +0x30, +0xbf, +0xe0, +0xe0, +0x3a, +0xfc, +0x31, +0x0f, +0xc0, +0xd3, +0xd5, +0x0c, +0x70, +0xe0, +0xcf, +0x03, +0x00, +0xac, +0x5c, +0x7f, +0x00, +0xae, +0x97, +0x6c, +0x80, +0x03, +0x7f, +0xfe, +0x01, +0x78, +0x6e, +0xb1, +0x01, +0x0e, +0xfc, +0xf9, +0x07, +0xe0, +0xf7, +0xc7, +0x06, +0x38, +0xf0, +0x8b, +0x01, +0x80, +0x5f, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0xff, +0xf7, +0x00, +0xc0, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0xff, +0x7b, +0x00, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x00, +0xf0, +0xff, +0x3d, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0x1e, +0x00, +0xf8, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x7f, +0x0f, +0x00, +0xfc, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0xbf, +0x07, +0x00, +0xfc, +0x07, +0xfe, +0x01, +0x0d, +0xff, +0x00, +0xfe, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x01, +0x80, +0xff, +0xef, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xd7, +0x00, +0x40, +0xf9, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0xfc, +0x6b, +0x00, +0x80, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0x81, +0x7f, +0x00, +0xc3, +0x3f, +0x80, +0x7f, +0xfc, +0x07, +0xfe, +0x01, +0x0d, +0xff, +0x00, +0xfe, +0xf0, +0xff, +0x3d, +0x00, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xc0, +0x3f, +0xbf, +0xe1, +0x1f, +0xc0, +0x00, +0xfe, +0x03, +0xff, +0xff, +0x86, +0x7f, +0x00, +0x00, +0xf8, +0xff, +0x1e, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x1f, +0xc0, +0x7f, +0xe0, +0xe0, +0xdf, +0xf0, +0x0f, +0x7f, +0x00, +0xff, +0x81, +0x80, +0x7f, +0xc3, +0x3f, +0x0f, +0x00, +0xfc, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0xf0, +0x0f, +0xe0, +0x3f, +0x07, +0xf0, +0x6f, +0xf8, +0xc0, +0x3f, +0x80, +0xff, +0x1f, +0xc0, +0xbf, +0xe1, +0xbf, +0x07, +0x00, +0xfe, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0x1f, +0xf8, +0x07, +0xf0, +0xfc, +0x03, +0xf8, +0x37, +0x7f, +0xe0, +0x1f, +0xc0, +0xf0, +0x0f, +0xe0, +0xdf, +0xff, +0xdf, +0x03, +0x00, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0x0f, +0xfc, +0x03, +0x1b, +0xfe, +0x01, +0xfc, +0xe0, +0x3f, +0xf0, +0x0f, +0x6f, +0xf8, +0x07, +0xf0, +0x80, +0xff, +0xef, +0x01, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x01, +0xfc, +0x07, +0xfe, +0xfe, +0x0d, +0xff, +0x00, +0x07, +0xf0, +0x1f, +0xf8, +0xf8, +0x37, +0xfc, +0x03, +0x00, +0xc0, +0xff, +0xf7, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0xff, +0x00, +0xfe, +0x03, +0x00, +0xff, +0x86, +0x7f, +0xfc, +0x03, +0xf8, +0x0f, +0x01, +0xfc, +0x1b, +0xfe, +0x7b, +0x00, +0xe0, +0xff, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0x81, +0x7f, +0x00, +0xff, +0x3f, +0x80, +0x7f, +0xc3, +0x07, +0xfe, +0x01, +0xfc, +0xff, +0x00, +0xfe, +0x0d, +0xff, +0x3d, +0x00, +0xf0, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xc0, +0x3f, +0x80, +0xe1, +0x1f, +0xc0, +0xbf, +0xfe, +0x03, +0xff, +0x00, +0x86, +0x7f, +0x00, +0xff, +0xf8, +0xff, +0x1e, +0x00, +0xf0, +0x1f, +0xf8, +0x07, +0x37, +0xfc, +0x03, +0xf8, +0xc0, +0x7f, +0xe0, +0x1f, +0xdf, +0xf0, +0x0f, +0xe0, +0x00, +0xff, +0x81, +0x7f, +0x7f, +0xc3, +0x3f, +0x80, +0x00, +0xfc, +0x7f, +0x0f, +0x03, +0xf8, +0x0f, +0xfc, +0xfc, +0x1b, +0xfe, +0x01, +0x0f, +0xe0, +0x3f, +0xf0, +0xf0, +0x6f, +0xf8, +0x07, +0x3f, +0x80, +0xff, +0xc0, +0xc0, +0xbf, +0xe1, +0x1f, +0x07, +0x00, +0xfe, +0xbf, +0xfe, +0x01, +0xfc, +0x07, +0x00, +0xfe, +0x0d, +0xff, +0xf8, +0x07, +0xf0, +0x1f, +0x03, +0xf8, +0x37, +0xfc, +0xe0, +0x1f, +0xc0, +0x7f, +0x0f, +0xe0, +0xdf, +0xf0, +0xdf, +0x03, +0x00, +0xff, +0x03, +0xff, +0x00, +0xfe, +0x7f, +0x00, +0xff, +0x86, +0x0f, +0xfc, +0x03, +0xf8, +0xfe, +0x01, +0xfc, +0x1b, +0x3f, +0xf0, +0x0f, +0xe0, +0xf8, +0x07, +0xf0, +0x6f, +0xff, +0xef, +0x01, +0x80 +}}; + +/*---------------------------------------------------------------------------------------- + * 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/f10/Proc/CPU/Family/0x10/RevD/F10RevD32.asm b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevD32.asm new file mode 100755 index 0000000000..ddd937ab66 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevD32.asm @@ -0,0 +1,113 @@ +;/** +; * @file +; * +; * AGESA Family 10h Revision D support routines. +; * +; * @xrefitem bom "File Content Label" "Release Content" +; * @e project: AGESA +; * @e sub-project: CPU/F10 +; * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. +; +;***************************************************************************** + + .XLIST + .LIST + + .586P + +;=============================================== +;=============================================== +;== +;== M E M O R Y P R E S E N T S E G M E N T +;== +;=============================================== +;=============================================== + .MODEL flat + .CODE + +;====================================================================== +; F10RevDProbeFilterCritical: Performs critical sequence for probe +; filter initialization. +; +; In: +; PciAddress Full PCI address of the node to init +; PciRegister Current value of F3x1D4 +; +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +F10RevDProbeFilterCritical PROC NEAR C PUBLIC USES EAX ECX EDX, PciAddress:DWORD, PciRegister:DWORD + + mov ecx, 0C001001Fh + rdmsr + push eax + push ecx + push edx + or dh, 40h + wrmsr + + mov eax, 810003D4h + + mov ecx, PciRegister + mov edx, PciAddress + shr edx, 4 + and dh, 0F8h + or ah, dh + + or cl, 2 + db 0Fh, 0AEh, 0F0h ; MFENCE + + mov dx, 0CF8h ; Set Reg Config Space + db 0Fh, 0AEh, 0F0h ; MFENCE + + out dx, eax + db 0Fh, 0AEh, 0F0h ; MFENCE + + mov dl, 0FCh ; Set DX to Pci Config Data + mov eax, ecx ;Set config Reg data + db 0Fh, 0AEh, 0F0h ; MFENCE + + out dx, eax ; move data to return position + db 0Fh, 0AEh, 0F0h ; MFENCE + + pop edx + pop ecx + pop eax + wrmsr + ret + +F10RevDProbeFilterCritical ENDP + +END diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevD64.asm b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevD64.asm new file mode 100755 index 0000000000..2804d29153 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevD64.asm @@ -0,0 +1,127 @@ +;/** +; * @file +; * +; * AGESA Family 10h Revision D support routines. +; * +; * @xrefitem bom "File Content Label" "Release Content" +; * @e project: AGESA +; * @e sub-project: CPU/F10 +; * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. +; +;***************************************************************************** + + .XLIST + .LIST + +;=============================================== +;=============================================== +;== +;== M E M O R Y P R E S E N T S E G M E N T +;== +;=============================================== +;=============================================== + .CODE + +;====================================================================== +; F10RevDProbeFilterCritical: Performs critical sequence for probe +; filter initialization. +; +; In: +; PciAddress Full PCI address of the node to init +; PciRegister Current value of F3x1D4 +; +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +PUBLIC F10RevDProbeFilterCritical +F10RevDProbeFilterCritical PROC + + push rax + push rcx + push rdx + push rsi + push rdi + + mov esi, ecx + mov edi, edx + + mov ecx, 0C001001Fh + rdmsr + push rax + push rcx + push rdx + or dh, 40h + wrmsr + + mov eax, 810003D4h + + mov ecx, edi + mov edx, esi + + shr edx, 4 + and dh, 0F8h + or ah, dh + + or cl, 2 + mfence + + mov dx, 0CF8h ; Set Reg Config Space + mfence + + out dx, eax + mfence + + mov dl, 0FCh ; Set DX to Pci Config Data + mov eax, ecx ;Set config Reg data + mfence + + out dx, eax ; move data to return position + mfence + + pop rdx + pop rcx + pop rax + wrmsr + + pop rdi + pop rsi + pop rdx + pop rcx + pop rax + ret + +F10RevDProbeFilterCritical ENDP + +END diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDHtAssist.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDHtAssist.c new file mode 100755 index 0000000000..538ebdaa29 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDHtAssist.c @@ -0,0 +1,454 @@ +/** + * @file + * + * AMD Family_10 RevD HT Assist feature support functions. + * + * Provides the functions necessary to initialize the HT Assist feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "CommonReturns.h" +#include "cpuRegisters.h" +#include "cpuF10PowerMgmt.h" +#include "cpuLateInit.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuHtAssist.h" +#include "F10PackageType.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_F10REVDHTASSIST_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/** + * The family 10h background scrubber context structure. + * + * These fields need to be saved, modified, then restored + * per die as part of HT Assist initialization. + */ +typedef struct { + UINT32 DramScrub:5; ///< DRAM scrub rate + UINT32 :3; ///< Reserved + UINT32 L3Scrub:5; ///< L3 scrub rate + UINT32 :3; ///< Reserved + UINT32 Redirect:1; ///< DRAM scrubber redirect enable + UINT32 :15; ///< Reserved +} F10_SCRUB_CONTEXT; + + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Check to see if the input CPU supports HT Assist. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HT Assist is supported. + * @retval FALSE HT Assist cannot be enabled. + * + */ +BOOLEAN +STATIC +F10IsHtAssistSupported ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Module; + UINT32 PciRegister; + BOOLEAN IsSupported; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredStatus; + + IsSupported = FALSE; + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NB_CAPS_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if (((NB_CAPS_REGISTER *) &PciRegister)->L3Capable == 1) { + IsSupported = TRUE; + } + break; + } + } + return IsSupported; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable the Probe filter feature. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +STATIC +F10HtAssistInit ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Module; + UINT32 PciRegister; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredStatus; + + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = L3_CACHE_PARAM_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((L3_CACHE_PARAM_REGISTER *) &PciRegister)->L3TagInit = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + do { + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + } while (((L3_CACHE_PARAM_REGISTER *) &PciRegister)->L3TagInit != 0); + + PciAddress.Address.Register = PROBE_FILTER_CTRL_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFMode = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + + F10RevDProbeFilterCritical (PciAddress, PciRegister); + + do { + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + } while (((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFInitDone != 1); + IDS_OPTION_HOOK (IDS_HT_ASSIST, &PciAddress, StdHeader); + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Save the current settings of the scrubbers, and disabled them. + * + * @param[in] HtAssistServices HT Assist 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. + * + */ +VOID +STATIC +F10GetL3ScrubCtrl ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE], + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Module; + UINT32 ScrubCtrl; + UINT32 ScrubAddr; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredStatus; + + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { + + ASSERT (Module < L3_SCRUBBER_CONTEXT_ARRAY_SIZE); + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = DRAM_SCRUB_ADDR_LOW_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &ScrubAddr, StdHeader); + + PciAddress.Address.Register = SCRUB_RATE_CTRL_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &ScrubCtrl, StdHeader); + + ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->DramScrub = + ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->DramScrub; + ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->L3Scrub = + ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->L3Scrub; + ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->Redirect = + ((DRAM_SCRUB_ADDR_LOW_REGISTER *) &ScrubAddr)->ScrubReDirEn; + + ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->DramScrub = 0; + ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->L3Scrub = 0; + ((DRAM_SCRUB_ADDR_LOW_REGISTER *) &ScrubAddr)->ScrubReDirEn = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &ScrubCtrl, StdHeader); + PciAddress.Address.Register = DRAM_SCRUB_ADDR_LOW_REG; + LibAmdPciWrite (AccessWidth32, PciAddress, &ScrubAddr, StdHeader); + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Restore the initial settings for the scrubbers. + * + * @param[in] HtAssistServices HT Assist 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. + * + */ +VOID +STATIC +F10SetL3ScrubCtrl ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE], + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Module; + UINT32 PciRegister; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredStatus; + + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { + + ASSERT (Module < L3_SCRUBBER_CONTEXT_ARRAY_SIZE); + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = SCRUB_RATE_CTRL_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((SCRUB_RATE_CTRL_REGISTER *) &PciRegister)->DramScrub = + ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->DramScrub; + ((SCRUB_RATE_CTRL_REGISTER *) &PciRegister)->L3Scrub = + ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->L3Scrub; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + + PciAddress.Address.Register = DRAM_SCRUB_ADDR_LOW_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((DRAM_SCRUB_ADDR_LOW_REGISTER *) &PciRegister)->ScrubReDirEn = + ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->Redirect; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Set MSR bits required for HT Assist on each core. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +STATIC +F10HookDisableCache ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrRegister; + + LibAmdMsrRead (MSR_BU_CFG2, &MsrRegister, StdHeader); + MsrRegister |= BIT42; + LibAmdMsrWrite (MSR_BU_CFG2, &MsrRegister, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Hook before the probe filter initialization sequence. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +STATIC +F10HookBeforeInit ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Module; + UINT32 PciRegister; + UINT32 PfCtrlRegister; + PCI_ADDR PciAddress; + CPU_LOGICAL_ID LogicalId; + AGESA_STATUS IgnoredStatus; + UINT32 PackageType; + + GetLogicalIdOfSocket (Socket, &LogicalId, StdHeader); + PackageType = LibAmdGetPackageType (StdHeader); + + PciRegister = 0; + ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFWayNum = 2; + ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFSubCacheEn = 15; + ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFLoIndexHashEn = 1; + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = PROBE_FILTER_CTRL_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PfCtrlRegister, StdHeader); + ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFPreferredSORepl = + ((PROBE_FILTER_CTRL_REGISTER *) &PfCtrlRegister)->PFPreferredSORepl; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + + // Assumption: all socket use the same CPU package. + if (((LogicalId.Revision & AMD_F10_D0) != 0) && (PackageType == PACKAGE_TYPE_C32)) { + // Apply erratum #384 + // Set F2x11C[13:12] = 11b + PciAddress.Address.Function = FUNC_2; + PciAddress.Address.Register = 0x11C; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + PciRegister |= 0x3000; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + } + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Check to see if the input CPU is running in the optimal configuration. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HT Assist is running sub-optimally. + * @retval FALSE HT Assist is running optimally. + * + */ +STATIC BOOLEAN +F10IsNonOptimalConfig ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN IsNonOptimal; + BOOLEAN IsMemoryPresent; + UINT32 Module; + UINT32 PciRegister; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredStatus; + + IsNonOptimal = FALSE; + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { + IsMemoryPresent = FALSE; + PciAddress.Address.Function = FUNC_2; + PciAddress.Address.Register = DRAM_CFG_HI_REG0; + + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreqVal == 1) { + IsMemoryPresent = TRUE; + if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreq < 4) { + IsNonOptimal = TRUE; + break; + } + } + + PciAddress.Address.Register = DRAM_CFG_HI_REG1; + + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreqVal == 1) { + IsMemoryPresent = TRUE; + if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreq < 4) { + IsNonOptimal = TRUE; + break; + } + } + if (!IsMemoryPresent) { + IsNonOptimal = TRUE; + break; + } + } + } + return IsNonOptimal; +} + + +CONST HT_ASSIST_FAMILY_SERVICES ROMDATA F10HtAssist = +{ + 0, + F10IsHtAssistSupported, + F10HtAssistInit, + F10GetL3ScrubCtrl, + F10SetL3ScrubCtrl, + F10HookBeforeInit, + (PF_HT_ASSIST_AFTER_INIT) CommonVoid, + F10HookDisableCache, + (PF_HT_ASSIST_ENABLE_CACHE) CommonVoid, + F10IsNonOptimalConfig +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDMsgBasedC1e.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDMsgBasedC1e.c new file mode 100755 index 0000000000..aa2c738ea1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDMsgBasedC1e.c @@ -0,0 +1,277 @@ +/** + * @file + * + * AMD Family_10 RevD Message-Based C1e feature support functions. + * + * Provides the functions necessary to initialize the message-based C1e feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 46667 $ @e \$Date: 2011-02-08 14:06:57 -0700 (Tue, 08 Feb 2011) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuMsgBasedC1e.h" +#include "cpuApicUtilities.h" +#include "cpuF10PowerMgmt.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_F10REVDMSGBASEDC1E_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 +F10InitializeMsgBasedC1eOnCore ( + IN VOID *BmStsAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +STATIC +IsDramScrubberEnabled ( + 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Should message-based C1e be enabled + * + * @param[in] MsgBasedC1eServices Pointer to this CPU's HW C1e family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HW C1e is supported. + * + */ +BOOLEAN +STATIC +F10IsMsgBasedC1eSupported ( + IN MSG_BASED_C1E_FAMILY_SERVICES *MsgBasedC1eServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_LOGICAL_ID LogicalId; + + GetLogicalIdOfSocket (Socket, &LogicalId, StdHeader); + return ((BOOLEAN) ((LogicalId.Revision & AMD_F10_GT_D0) != 0)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Core 0 task to enable message-based C1e on a family 10h CPU. + * + * @param[in] MsgBasedC1eServices Pointer to this CPU's HW C1e 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 +F10InitializeMsgBasedC1e ( + IN MSG_BASED_C1E_FAMILY_SERVICES *MsgBasedC1eServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 AndMask; + UINT32 Core; + UINT32 Module; + UINT32 OrMask; + UINT32 PciRegister; + UINT32 Socket; + AP_TASK TaskPtr; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { + // Note that this core 0 does NOT have the ability to launch + // any of its cores. Attempting to do so could lead to a system + // hang. + + // Set F3xA0[IdleExitEn] = 1 + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = PW_CTL_MISC_REG; + AndMask = 0xFFFFFFFF; + OrMask = 0; + ((POWER_CTRL_MISC_REGISTER *) &OrMask)->IdleExitEn = 1; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3xA0 + + // BIOS should set F3x1B8[5] + PciAddress.Address.Register = 0x1B8; + OrMask = 0x00000020; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3x1B8 + + // Set F3x188[EnStpGntOnFlushMaskWakeup] = 1 + PciAddress.Address.Register = NB_EXT_CFG_LO_REG; + OrMask = 0; + ((NB_EXT_CFG_LO_REGISTER *) &OrMask)->EnStpGntOnFlushMaskWakeup = 1; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3x188 + + // Set F3xD4[MTC1eEn] = 1, F3xD4[CacheFlushImmOnAllHalt] = 1 + // Set F3xD4[StutterScrubEn] = 1 if scrubbing is enabled + ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->StutterScrubEn = 0; + OrMask = 0; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->MTC1eEn = 1; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->CacheFlushImmOnAllHalt = 1; + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + + for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = CPTC0_REG; + if (IsDramScrubberEnabled (PciAddress, StdHeader)) { + ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->StutterScrubEn = 1; + } else { + ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->StutterScrubEn = 0; + } + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + PciRegister &= AndMask; + PciRegister |= OrMask; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + } + } + + } else if (EntryPoint == CPU_FEAT_AFTER_PM_INIT) { + // At early, this core 0 can launch its subordinate cores. + TaskPtr.FuncAddress.PfApTaskI = F10InitializeMsgBasedC1eOnCore; + TaskPtr.DataTransfer.DataSizeInDwords = 1; + TaskPtr.DataTransfer.DataPtr = &PlatformConfig->C1ePlatformData; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL); + } + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable message-based C1e on a family 10h core. + * + * @param[in] BmStsAddress System I/O address of the bus master status bit. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +STATIC +F10InitializeMsgBasedC1eOnCore ( + IN VOID *BmStsAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrRegister; + + // Set MSRC001_0055[SmiOnCmpHalt] = 0, MSRC001_0055[C1eOnCmpHalt] = 0 + LibAmdMsrRead (MSR_INTPEND, &MsrRegister, StdHeader); + ((INTPEND_MSR *) &MsrRegister)->SmiOnCmpHalt = 0; + ((INTPEND_MSR *) &MsrRegister)->C1eOnCmpHalt = 0; + ((INTPEND_MSR *) &MsrRegister)->BmStsClrOnHltEn = 1; + ((INTPEND_MSR *) &MsrRegister)->IntrPndMsgDis = 0; + ((INTPEND_MSR *) &MsrRegister)->IntrPndMsg = 0; + ((INTPEND_MSR *) &MsrRegister)->IoMsgAddr = (UINT64) *((UINT32 *) BmStsAddress); + LibAmdMsrWrite (MSR_INTPEND, &MsrRegister, StdHeader); + + // Set MSRC001_0015[HltXSpCycEn] = 1 + LibAmdMsrRead (MSR_HWCR, &MsrRegister, StdHeader); + MsrRegister |= BIT12; + LibAmdMsrWrite (MSR_HWCR, &MsrRegister, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Check to see if the DRAM background scrubbers are enabled or not. + * + * @param[in] PciAddress Address of F10 socket/module to check. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE Memory scrubbers are enabled on the current node. + * @retval FALSE Memory scrubbers are disabled on the current node. + */ +BOOLEAN +STATIC +IsDramScrubberEnabled ( + IN PCI_ADDR PciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PciRegister; + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = 0x58; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + return ((BOOLEAN) ((PciRegister & 0x1F) != 0)); +} + + +CONST MSG_BASED_C1E_FAMILY_SERVICES ROMDATA F10MsgBasedC1e = +{ + 0, + F10IsMsgBasedC1eSupported, + F10InitializeMsgBasedC1e +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDUtilities.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDUtilities.c new file mode 100755 index 0000000000..fe1b2d6ad5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10RevDUtilities.c @@ -0,0 +1,372 @@ +/** + * @file + * + * AMD Family_10 revision Dx specific utility functions. + * + * Provides numerous utility functions specific to family 10h rev D. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuF10PowerMgmt.h" +#include "GeneralServices.h" +#include "cpuEarlyInit.h" +#include "cpuRegisters.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_F10REVDUTILITIES_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 +F10CommonRevDGetNbCofVidUpdate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT BOOLEAN *NbVidUpdateAll, + IN AMD_CONFIG_PARAMS *StdHeader + ); +BOOLEAN +F10CommonRevDGetProcIddMax ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 Pstate, + OUT UINT32 *ProcIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ); +AGESA_STATUS +F10CommonRevDGetNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT UINT32 *FrequencyInMHz, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ); +UINT8 +F10CommonRevDGetNumberOfCoresForBrandstring ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Set down core register on a revision D processor. + * + * 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] StdHeader Header for library and services. + * + */ +STATIC VOID +F10CommonRevDSetDownCoreRegister ( + IN CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices, + IN UINT32 *Socket, + IN UINT32 *Module, + IN UINT32 *LeveledCores, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TempVar32_a; + UINT32 CoreDisableBits; + PCI_ADDR PciAddress; + AGESA_STATUS AgesaStatus; + + switch (*LeveledCores) { + case 1: + CoreDisableBits = DOWNCORE_MASK_SINGLE; + break; + case 2: + CoreDisableBits = DOWNCORE_MASK_DUAL; + break; + case 3: + CoreDisableBits = DOWNCORE_MASK_TRI; + break; + case 4: + CoreDisableBits = DOWNCORE_MASK_FOUR; + break; + case 5: + CoreDisableBits = DOWNCORE_MASK_FIVE; + break; + default: + CoreDisableBits = 0; + break; + } + + if (CoreDisableBits != 0) { + if (GetPciAddress (StdHeader, (UINT8) *Socket, (UINT8) *Module, &PciAddress, &AgesaStatus)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NORTH_BRIDGE_CAPABILITIES_REG; + + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar32_a, StdHeader); + TempVar32_a = ((TempVar32_a >> 12) & 0x3) | ((TempVar32_a >> 13) & 0x4); + if (TempVar32_a == 0) { + CoreDisableBits &= 0x1; + } else if (TempVar32_a == 1) { + CoreDisableBits &= 0x3; + } else if (TempVar32_a == 2) { + CoreDisableBits &= 0x7; + } else if (TempVar32_a == 3) { + CoreDisableBits &= 0x0F; + } else if (TempVar32_a == 4) { + CoreDisableBits &= 0x1F; + } else if (TempVar32_a == 5) { + CoreDisableBits &= 0x3F; + } + PciAddress.Address.Register = DOWNCORE_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar32_a, StdHeader); + TempVar32_a |= CoreDisableBits; + LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar32_a, StdHeader); + } + } + + return; +} + + +CONST CPU_CORE_LEVELING_FAMILY_SERVICES ROMDATA F10RevDCoreLeveling = +{ + 0, + F10CommonRevDSetDownCoreRegister +}; + +/*---------------------------------------------------------------------------------------*/ +/** + * Get CPU pstate current on a revision D processor. + * + * @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 +F10CommonRevDGetProcIddMax ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 Pstate, + OUT UINT32 *ProcIddMax, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 IddDiv; + UINT32 CmpCap; + UINT32 MultiNodeCpu; + UINT32 NbCaps; + UINT32 Socket; + UINT32 Module; + UINT32 Ignored; + UINT32 MsrAddress; + UINT64 PstateMsr; + BOOLEAN IsPstateEnabled; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + IsPstateEnabled = FALSE; + + MsrAddress = (UINT32) (Pstate + PS_REG_BASE); + ASSERT (MsrAddress <= PS_MAX_REG); + + LibAmdMsrRead (MsrAddress, &PstateMsr, StdHeader); + if (((PSTATE_MSR *) &PstateMsr)->PsEnable == 1) { + IdentifyCore (StdHeader, &Socket, &Module, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NB_CAPS_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &NbCaps, StdHeader); // F3xE8 + + switch (((PSTATE_MSR *) &PstateMsr)->IddDiv) { + case 0: + IddDiv = 1000; + break; + case 1: + IddDiv = 100; + break; + case 2: + IddDiv = 10; + break; + default: // IddDiv = 3 is reserved. Use 10 + IddDiv = 10; + break; + } + MultiNodeCpu = (UINT32) (((NB_CAPS_REGISTER *) &NbCaps)->MultiNodeCpu + 1); + CmpCap = (UINT32) (((NB_CAPS_REGISTER *) &NbCaps)->CmpCapHi << 2); + CmpCap |= (UINT32) (((NB_CAPS_REGISTER *) &NbCaps)->CmpCapLo); + CmpCap++; + *ProcIddMax = (UINT32) ((PSTATE_MSR *) &PstateMsr)->IddValue * IddDiv * CmpCap * MultiNodeCpu; + IsPstateEnabled = TRUE; + } + return IsPstateEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10CommonRevDGetNbCofVidUpdate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT BOOLEAN *NbVidUpdateAll, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NbVidUpdateAll = FALSE; + return FALSE; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the NB clock on the desired node. + * + * @CpuServiceMethod{::F_CPU_GET_NB_FREQ}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PciAddress The northbridge to query + * @param[out] FrequencyInMHz Northbridge clock frequency in MHz. + * @param[out] VoltageInuV Northbridge voltage in uV. + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F10CommonRevDGetNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT UINT32 *FrequencyInMHz, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PciRegister; + UINT32 NbFid; + UINT64 MsrRegister; + + PciAddress->Address.Function = FUNC_3; + PciAddress->Address.Register = CPTC0_REG; + LibAmdPciRead (AccessWidth32, *PciAddress, &PciRegister, StdHeader); + NbFid = ((CLK_PWR_TIMING_CTRL_REGISTER *) &PciRegister)->NbFid; + *FrequencyInMHz = ((NbFid + 4) * 200); + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + *VoltageInuV = (1550000 - (12500 * ((UINT32) ((COFVID_STS_MSR *) &MsrRegister)->CurNbVid))); + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get number of processor cores to be used in determining the brand string. + * + * @CpuServiceMethod{::F_CPU_NUMBER_OF_BRANDSTRING_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 cores to be used in brand string calculation. + */ +UINT8 +F10CommonRevDGetNumberOfCoresForBrandstring ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CmpCap; + UINT32 CmpCapOnNode; + UINT32 Socket; + UINT32 Module; + UINT32 Core; + UINT32 PciRegister; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + CmpCap = 0; + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NB_CAPS_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + CmpCapOnNode = (UINT8) (((NB_CAPS_REGISTER *) &PciRegister)->CmpCapHi << 2); + CmpCapOnNode |= (UINT8) (((NB_CAPS_REGISTER *) &PciRegister)->CmpCapLo); + CmpCapOnNode++; + CmpCap += CmpCapOnNode; + } + } + return ((UINT8) CmpCap); +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyEquivalenceTable.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyEquivalenceTable.c new file mode 100755 index 0000000000..6a2f04f5ff --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyEquivalenceTable.c @@ -0,0 +1,110 @@ +/** + * @file + * + * AMD Family_10 Hydra Equivalence Table related data + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6381 $ @e \$Date: 2008-06-15 17:26:25 -0500 (Sun, 15 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_HY_F10HYEQUIVALENCETABLE_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 + *---------------------------------------------------------------------------------------- + */ +VOID +GetF10HyMicrocodeEquivalenceTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **HyEquivalenceTablePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +STATIC CONST UINT16 ROMDATA CpuF10HyMicrocodeEquivalenceTable[] = +{ + 0x1080, 0x1080, + 0x1081, 0x1081, + 0x1091, 0x1081 +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] HyEquivalenceTablePtr 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 +GetF10HyMicrocodeEquivalenceTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **HyEquivalenceTablePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = ((sizeof (CpuF10HyMicrocodeEquivalenceTable) / sizeof (UINT16)) / 2); + *HyEquivalenceTablePtr = CpuF10HyMicrocodeEquivalenceTable; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyHtPhyTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyHtPhyTables.c new file mode 100755 index 0000000000..4b50153636 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyHtPhyTables.c @@ -0,0 +1,1290 @@ +/** + * @file + * + * AMD Family_10 Hydra Ht Phy tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_HY_F10HYHTPHYTABLES_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 + *---------------------------------------------------------------------------------------- + */ + +// HT Phy T a b l e s +// ------------------------- +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F10HyHtPhyRegisters[] = +{ +// 0x60:0x68 + { + HtPhyRangeRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_C0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + { + {HTPHY_LINKTYPE_SL0_ALL, // + 0x60, 0x68, // Address + 0x00000040, // regData + 0x00000040}, // regMask + } + }, +// 0x70:0x78 + { + HtPhyRangeRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_C0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + { + {HTPHY_LINKTYPE_SL1_ALL, // + 0x70, 0x78, // Address + 0x00000040, // regData + 0x00000040}, // regMask + } + }, +// 0xC0 + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + { + {HTPHY_LINKTYPE_SL0_ALL, // + 0xC0, // Address + 0x40040000, // regData + 0xe01F0000}, // regMask + } + }, +// 0xD0 + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + { + {HTPHY_LINKTYPE_SL1_ALL, // + 0xD0, // Address + 0x40040000, // regData + 0xe01F0000}, // regMask + } + }, +// 0xCF +// Default for HT3, unless overridden below. + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + { + {HTPHY_LINKTYPE_SL0_HT3, // + 0xCF, // Address + 0x0000002A, // regData + 0x000000FF}, // regMask + } + }, +// 0xDF +// Default for HT3, unless overridden below. + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + { + {HTPHY_LINKTYPE_SL1_HT3, // + 0xDF, // Address + 0x0000002A, // regData + 0x000000FF}, // regMask + } + }, + +// +// All the entries for XmtRdPtr 6 +// + +// 0xCF +// For HT frequencies 1200-1600 and NB Freq 1600, 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1200M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1200-1600 and NB Freq 1600, 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1200M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 1800 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1800 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 3200 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_3200M, HT_FREQUENCY_3200M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 3200 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_3200M, HT_FREQUENCY_3200M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 1200 and 1600 and NB Freq 1600 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1200M, HT_FREQUENCY_1200M) | FREQ_RANGE_1 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1200 and 1600 and NB Freq 1600 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1200M, HT_FREQUENCY_1200M) | FREQ_RANGE_1 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 1200 and 1800 and NB Freq 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1200M, HT_FREQUENCY_1200M) | FREQ_RANGE_1 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1200 and 1800 and NB Freq 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1200M, HT_FREQUENCY_1200M) | FREQ_RANGE_1 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000006A, // regData + 0x000000FF, // regMask + }} + }, + +// +// Entries for XmtRdPtr 5 +// + +// 0xCF +// For HT frequencies 1800-2600 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_2600M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1800-2600 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_2600M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2000 - 2800 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2000M, HT_FREQUENCY_2800M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2000 - 2800 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2000M, HT_FREQUENCY_2800M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 1400 and 1800 and NB Freq 1600 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1400M, HT_FREQUENCY_1400M) | FREQ_RANGE_1 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1400 and 1800 and NB Freq 1600 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1400M, HT_FREQUENCY_1400M) | FREQ_RANGE_1 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 1400 and 1600 and NB Freq 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1400M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1400 and 1600 and NB Freq 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1400M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, + +// +// Entries for XmtRdPtr 4 +// + +// 0xCF +// For HT frequencies 2800-3000 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2800M, HT_FREQUENCY_3000M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2800-3000 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2800M, HT_FREQUENCY_3000M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 3000 - 3200 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_3000M, HT_FREQUENCY_3200M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 3000 - 3200 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_3000M, HT_FREQUENCY_3200M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2000 - 2400 and 3200 and NB Freq 1600 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2000M, HT_FREQUENCY_2400M) | FREQ_RANGE_1 (HT_FREQUENCY_3200M, HT_FREQUENCY_3200M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2000 - 2400 and 3200 and NB Freq 1600 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2000M, HT_FREQUENCY_2400M) | FREQ_RANGE_1 (HT_FREQUENCY_3200M, HT_FREQUENCY_3200M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2000 - 2400 and NB Freq 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2000M, HT_FREQUENCY_2400M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2000 - 2400 and NB Freq 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2000M, HT_FREQUENCY_2400M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000004A, // regData + 0x000000FF, // regMask + }} + }, + +// +// Entries for XmtRdPtr 3 +// + +// 0xCF +// For HT frequencies 2600-3000 and NB Freq 1600 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2600M, HT_FREQUENCY_3000M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2600-3000 and NB Freq 1600 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2600M, HT_FREQUENCY_3000M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2600 - 3200 and NB Freq 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2600M, HT_FREQUENCY_3200M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2600 - 3200 and NB Freq 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2600M, HT_FREQUENCY_3200M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, + +// +// Rev D0 fixups for Erratum 398. +// + +// 0xCF +// For HT frequencies 1800, 2200 and NB Freq 1400 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | FREQ_RANGE_1 (HT_FREQUENCY_2200M, HT_FREQUENCY_2200M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1400M, HT_FREQUENCY_1400M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK1 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000000A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1800, 2200 and NB Freq 1400 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | FREQ_RANGE_1 (HT_FREQUENCY_2200M, HT_FREQUENCY_2200M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1400M, HT_FREQUENCY_1400M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK5 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000000A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2600, 3000 and NB Freq 1400 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2600M, HT_FREQUENCY_2600M) | FREQ_RANGE_1 (HT_FREQUENCY_3000M, HT_FREQUENCY_3000M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1400M, HT_FREQUENCY_1400M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK1 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000000A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2600, 3000 and NB Freq 1400 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2600M, HT_FREQUENCY_2600M) | FREQ_RANGE_1 (HT_FREQUENCY_3000M, HT_FREQUENCY_3000M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1400M, HT_FREQUENCY_1400M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK5 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000000A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2200, 2600 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2200M, HT_FREQUENCY_2200M) | FREQ_RANGE_1 (HT_FREQUENCY_2600M, HT_FREQUENCY_2600M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2200, 2600 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2200M, HT_FREQUENCY_2200M) | FREQ_RANGE_1 (HT_FREQUENCY_2600M, HT_FREQUENCY_2600M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 3000 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_3000M, HT_FREQUENCY_3000M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000002A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 3000 and NB Freq 1600 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_3000M, HT_FREQUENCY_3000M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000002A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2200, 2600 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2200M, HT_FREQUENCY_2200M) | FREQ_RANGE_1 (HT_FREQUENCY_2600M, HT_FREQUENCY_2600M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2200, 2600 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2200M, HT_FREQUENCY_2200M) | FREQ_RANGE_1 (HT_FREQUENCY_2600M, HT_FREQUENCY_2600M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 3000 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_3000M, HT_FREQUENCY_3000M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000002A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 3000 and NB Freq 1800 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_3000M, HT_FREQUENCY_3000M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000002A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 1800 and NB Freq 1600 for all links + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK0 | HTPHY_LINKTYPE_SL0_LINK1 | HTPHY_LINKTYPE_SL0_LINK2 | HTPHY_LINKTYPE_SL0_LINK3), + 0xCF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 1800 and NB Freq 1600 for all links + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_1800M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1600M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK4 | HTPHY_LINKTYPE_SL1_LINK5 | HTPHY_LINKTYPE_SL1_LINK6 | HTPHY_LINKTYPE_SL1_LINK7), + 0xDF, // Address + 0x0000003A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2200 and NB Freq 1600, 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2200M, HT_FREQUENCY_2200M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000002A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2200 and NB Freq 1600, 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2200M, HT_FREQUENCY_2200M) | COUNT_RANGE_NONE), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000002A, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// For HT frequencies 2600, 3000 and NB Freq 1600, 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2600M, HT_FREQUENCY_2600M) | FREQ_RANGE_1 (HT_FREQUENCY_3000M, HT_FREQUENCY_3000M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL0_LINK1), + 0xCF, // Address + 0x0000001A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// For HT frequencies 2600, 3000 and NB Freq 1600, 1800 only for link 1 + { + HtPhyFreqRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + (FREQ_RANGE_0 (HT_FREQUENCY_2600M, HT_FREQUENCY_2600M) | FREQ_RANGE_1 (HT_FREQUENCY_3000M, HT_FREQUENCY_3000M)), + (FREQ_RANGE_0 (HT_FREQUENCY_1600M, HT_FREQUENCY_1800M) | COUNT_RANGE_NONE), + (HTPHY_LINKTYPE_SL1_LINK5), + 0xDF, // Address + 0x0000001A, // regData + 0x000000FF, // regMask + }} + }, + +// +// Deemphasis Settings for D1 processors. +// + +// For D1, also set [7]TxLs23ClkGateEn. +//deemphasis level DL1[20:16], DL2[12:8], DP1[4:0] PostCur1En[31] PostCur2En[30] PreCur1En[29] MapPostCur2En[6] +// No deemphasis 00h 00h 00h 0 0 0 0 +// -3dB postcursor 12h 00h 00h 1 0 0 0 +// -6dB postcursor 1Fh 00h 00h 1 0 0 0 +// -8dB postcursor 1Fh 06h 00h 1 1 0 1 +// -11dB postcursor 1Fh 0Dh 00h 1 1 0 1 +// -11dB postcursor with +// -8dB precursor 1Fh 06h 07h 1 1 1 1 + + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x00000080, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x00000080, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__3, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x80120080, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__3, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x80120080, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__6, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x801F0080, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__6, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x801F0080, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xC01F06C0, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xC01F06C0, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__11, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xC01F0DC0, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__11, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xC01F0DC0, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__11_8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xE01F06C7, // regData + 0xE01F1FDF, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__11_8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xE01F06C7, // regData + 0xE01F1FDF, // regMask + }} + }, + +// 0x520A + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL0_ALL, // + 0x520A, // Address + 0x00004000, // regData + 0x00006000, // regMask + }} + }, +// 0x530A + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_HY_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL1_ALL, // + 0x530A, // Address + 0x00004000, // regData + 0x00006000, // regMask + }} + }, +}; + +CONST REGISTER_TABLE ROMDATA F10HyHtPhyRegisterTable = { + PrimaryCores, + (sizeof (F10HyHtPhyRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10HyHtPhyRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyInitEarlyTable.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyInitEarlyTable.c new file mode 100755 index 0000000000..ec31f2bf84 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyInitEarlyTable.c @@ -0,0 +1,138 @@ +/** + * @file + * + * Implements the workaround for erratum 419. + * + * 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/0x10/RevD/HY + * @e \$Revision$ @e \$Date$ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "F10PackageType.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_HY_F10HYINITEARLYTABLE_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 F_PERFORM_EARLY_INIT_ON_CORE McaInitializationAtEarly; +extern F_PERFORM_EARLY_INIT_ON_CORE SetRegistersFromTablesAtEarly; +extern F_PERFORM_EARLY_INIT_ON_CORE SetBrandIdRegistersAtEarly; +extern F_PERFORM_EARLY_INIT_ON_CORE LocalApicInitializationAtEarly; +extern F_PERFORM_EARLY_INIT_ON_CORE LoadMicrocodePatchAtEarly; +extern F_GET_EARLY_INIT_TABLE GetCommonEarlyInitOnCoreTable; + +CONST PF_PERFORM_EARLY_INIT_ON_CORE ROMDATA F10HyC32D0EarlyInitOnCoreTable[] = +{ + McaInitializationAtEarly, + SetRegistersFromTablesAtEarly, + LocalApicInitializationAtEarly, + LoadMicrocodePatchAtEarly, + SetBrandIdRegistersAtEarly, + NULL +}; + +/*------------------------------------------------------------------------------------*/ +/** + * Initializer routine that may be invoked at AmdCpuEarly to return the steps + * appropriate for the executing Rev D core. + * + * @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 +GetF10HyEarlyInitOnCoreTable ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST PF_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); +VOID +GetF10HyEarlyInitOnCoreTable ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST PF_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ProcessorPackageType; + CPU_LOGICAL_ID LogicalId; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + ProcessorPackageType = LibAmdGetPackageType (StdHeader); + + // Check if this CPU is affected by erratum 419. + if (((LogicalId.Revision & AMD_F10_HY_SCM_D0) != 0) && ((ProcessorPackageType & (PACKAGE_TYPE_G34 | PACKAGE_TYPE_FR2_FR5_FR6)) == 0)) { + // Return initialization steps such that the microcode patch is applied before + // brand string determination is performed. + *Table = F10HyC32D0EarlyInitOnCoreTable; + } else { + // No workaround is necessary. Return the standard table. + GetCommonEarlyInitOnCoreTable (FamilyServices, Table, EarlyParams, StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyLogicalIdTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyLogicalIdTables.c new file mode 100755 index 0000000000..4ff9ea5d0f --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyLogicalIdTables.c @@ -0,0 +1,112 @@ +/** + * @file + * + * AMD Family_10 Hydra Logical ID Table + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 6261 $ @e \$Date: 2008-06-04 17:38:17 -0500 (Wed, 04 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_HY_F10HYLOGICALIDTABLES_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 + *---------------------------------------------------------------------------------------- + */ +VOID +GetF10HyLogicalIdAndRev ( + OUT CONST CPU_LOGICAL_ID_XLAT **HyIdPtr, + OUT UINT8 *NumberOfElements, + OUT UINT64 *LogicalFamily, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + + +STATIC CONST CPU_LOGICAL_ID_XLAT ROMDATA CpuF10HyLogicalIdAndRevArray[] = +{ + { + 0x1080, + AMD_F10_HY_SCM_D0 + }, + { + 0x1090, + AMD_F10_HY_MCM_D0 + }, + { + 0x1081, + AMD_F10_HY_SCM_D1 + }, + { + 0x1091, + AMD_F10_HY_MCM_D1 + } +}; + +VOID +GetF10HyLogicalIdAndRev ( + OUT CONST CPU_LOGICAL_ID_XLAT **HyIdPtr, + OUT UINT8 *NumberOfElements, + OUT UINT64 *LogicalFamily, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = (sizeof (CpuF10HyLogicalIdAndRevArray) / sizeof (CPU_LOGICAL_ID_XLAT)); + *HyIdPtr = CpuF10HyLogicalIdAndRevArray; + *LogicalFamily = AMD_FAMILY_10_HY; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyMicrocodePatchTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyMicrocodePatchTables.c new file mode 100755 index 0000000000..9715ebc9e3 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyMicrocodePatchTables.c @@ -0,0 +1,112 @@ +/** + * @file + * + * AMD Family_10 Hydra PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6049 $ @e \$Date: 2008-05-13 23:58:02 -0700 (Tue, 13 May 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_HY_F10HYMICROCODEPATCHTABLES_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 ROMDATA *CpuF10HyMicroCodePatchArray[]; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +VOID +GetF10HyMicroCodePatchesStruct ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **HyUcodePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] HyUcodePtr 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 +GetF10HyMicroCodePatchesStruct ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **HyUcodePtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NumberOfUcode; + + for (NumberOfUcode = 0; CpuF10HyMicroCodePatchArray[NumberOfUcode] != 0; NumberOfUcode++) { + } + *NumberOfElements = NumberOfUcode; + *HyUcodePtr = &CpuF10HyMicroCodePatchArray[0]; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyMsrTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyMsrTables.c new file mode 100755 index 0000000000..2c441ca1f2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyMsrTables.c @@ -0,0 +1,139 @@ +/** + * @file + * + * AMD Family_10 HY MSR tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_HY_F10HYMSRTABLES_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 F10HyMsrRegisters[] = +{ +// M S R T a b l e s +// ---------------------- + +// MSR_LS_CFG (0xC0011020) +// bit[1] = 0 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_B0 // CpuRevision + }, + { AMD_PF_ALL }, // platformFeatures + { + { + MSR_LS_CFG, // MSR Address + 0x0000000000000000, // OR Mask + (1 << 1) // NAND Mask + } + } + }, + +// MSR_BU_CFG (0xC0011023) +// bit[21] = 1 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_B0 // CpuRevision + }, + { AMD_PF_ALL }, // platformFeatures + { + { + MSR_BU_CFG, // MSR Address + (1 << 21), // OR Mask + (1 << 21), // NAND Mask + } + } + }, + +// MSR_BU_CFG2 (0xC001102A) +// bit[50] = 1 +// For GH rev C1 and later [RdMmExtCfgQwEn]=1 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_C0 // CpuRevision + }, + { AMD_PF_ALL }, // platformFeatures + { + { + MSR_BU_CFG2, // MSR Address + 0x0004000000000000ull, // OR Mask + 0x0004000000000000ull, // NAND Mask + } + } + } +}; + +CONST REGISTER_TABLE ROMDATA F10HyMsrRegisterTable = { + AllCores, + (sizeof (F10HyMsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *) &F10HyMsrRegisters, +}; + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyPciTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyPciTables.c new file mode 100755 index 0000000000..c8fc912cdc --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/HY/F10HyPciTables.c @@ -0,0 +1,362 @@ +/** + * @file + * + * AMD Family_10 Hydra PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 46786 $ @e \$Date: 2011-02-09 18:32:59 -0700 (Wed, 09 Feb 2011) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_REVD_HY_F10HYPCITABLES_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 F10HyPciRegisters[] = +{ +// F0x68 - + // BufRelPri for rev D + // bits[14:13] BufRelPri = 1 + // bit [25] CHtExtAddrEn = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO(0, 0, 24, FUNC_0, 0x68), // Address + 0x02002000, // regData + 0x02006000, // regMask + }} + }, + // F0x[E4,A4,C4,84] Link Control Register + // bit [15] Addr64bitEn = 1 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {AMD_PF_ALL}, + {{ + HT_HOST_FEAT_NONCOHERENT, + 0x4, + 0x00008000, + 0x00008000, + }} + }, +// F0x150 - Link Global Retry Control Register +// bit[18:16] TotalRetryAttempts = 7 +// bit[13] HtRetryCrcDatInsDynEn = 1 +// bit[12]HtRetryCrcCmdPackDynEn = 1 +// bit[11:9] HtRetryCrcDatIns = 0 +// bit[8] HtRetryCrcCmdPack = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x150), // Address + 0x00073100, // regData + 0x00073F00, // regMask + }} + }, +// F0x16C - Link Global Extended Control Register +// bit[15:13] ForceFullT0 = 6 +// bit[5:0] T0Time = 0x26 + { + PCIREGISTER, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x0000C026, // regData + 0x0000E03F, // regMask + }} + }, +// F0x16C - Link Global Extended Control Register +// bit[9] RXCalEn = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00000200, // regData + 0x00000200, // regMask + }} + }, +// F0x16C - Link Global Extended Control Register +// bit[7:6] InLnSt = 01b (PHY_OFF) + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00000040, // regData + 0x000000C0, // regMask + }} + }, +// F0x[18C:170] - Link Extended Control Register - All connected links. +// bit[8] LS2En = 1 + { + HtLinkPciRegister, + { + AMD_FAMILY_10_HY, // CpuFamily + AMD_F10_D1 // CpuRevision + }, + {AMD_PF_ALL}, // platform Features + {{ + HT_HOST_FEATURES_ALL, + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x170), // Address + 0x00000100, // regData + 0x00000100, // regMask + }} + }, +// F2x1B0 - Extended Memory Controller Configuration Low +// bits[10:8], CohPrefPrbLmt = 0 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_PROBEFILTER, // Features + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x1B0), // Address + 0x00000000, // regData + 0x00000700, // regMask + }} + }, +// Function 3 - Misc. Control +// F3x158 - Link to XCS Token Count +// bits[3:0] LnkToXcsDRToken = 3 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_A2 // CpuRevision + }, + {AMD_PF_UMA}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x158), // Address + 0x00000003, // regData + 0x0000000F, // regMask + }} + }, + +// F3x80 - ACPI Power State Control +// ACPI State C2 +// bits[0] CpuPrbEn = 1 +// bits[1] NbLowPwrEn = 0 +// bits[2] NbGateEn = 0 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 1 +// ACPI State C3, C1E or Link init +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 5 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_Ax // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x0000A681, // regData + 0x0000FFFF, // regMask + }} + }, + +// F3x80 - ACPI Power State Control +// ACPI State C3, C1E or Link init +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 7 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x0000E600, // regData + 0x0000FF00, // regMask + }} + }, + +// F3xA0 - Power Control Miscellaneous +// bit[14] BpPinsTriEn = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x00004000, // regData + 0x00004000, // regMask + }} + }, + +// F3x188 - NB Extended Configuration Low Register +// Must be set by BIOS + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x188), // Address + 0x08000000, // regData + 0x08000000, // regMask + }} + }, + +// F3x1B8 - L3 Control +// Must be set by BIOS + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_D0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1B8), // Address + 0x00040000, // regData + 0x00040000, // regMask + }} + }, + +// F3x1B8 - L3 Control +// Must be set by BIOS + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1B8), // Address + 0x00800000, // regData + 0x00800000, // regMask + }} + }, + +// F3x1D4 - Probe Filter Control Register +// bits[21:20] PFPreferedSORepl = 2 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_Dx // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1D4), // Address + 0x00200000, // regData + 0x00300000, // regMask + }} + } +}; + +CONST REGISTER_TABLE ROMDATA F10HyPciRegisterTable = { + PrimaryCores, + (sizeof (F10HyPciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10HyPciRegisters, +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuCommonF10Utilities.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuCommonF10Utilities.c new file mode 100755 index 0000000000..0c21de5420 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuCommonF10Utilities.c @@ -0,0 +1,343 @@ +/** + * @file + * + * AMD Family_10 specific utility functions. + * + * Provides numerous utility functions specific to family 10h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 5893 $ @e \$Date: 2008-04-23 08:37:29 -0700 (Wed, 23 Apr 2008) $ + * + */ +/* + ***************************************************************************** + * + * 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuCommonF10Utilities.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUCOMMONF10UTILITIES_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 + *---------------------------------------------------------------------------------------- + */ +/** + * Node ID MSR register fields. + * Provide the layout of fields in the Node ID MSR. + */ +typedef struct { + UINT64 NodeId:3; ///< The core is on the node with this node id. + UINT64 NodesPerProcessor:3; ///< The number of Nodes in this processor. + UINT64 HeapIndex:6; ///< The AP core heap index. + UINT64 :(63 - 11); ///< Reserved. +} NODE_ID_MSR_FIELDS; + +/// Node ID MSR. +typedef union { + NODE_ID_MSR_FIELDS Fields; ///< Access the register as individual fields + UINT64 Value; ///< Access the register value. +} NODE_ID_MSR; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +VOID +F10SetApCoreNumber ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 Socket, + IN UINT32 Module, + IN UINT32 ApCoreNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); +UINT32 +F10GetApCoreNumber ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); +VOID +F10TransferApCoreNumber ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10SetAgesaWarmResetFlag ( + 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[in] Request Indicate warm reset status + * + */ +VOID +F10GetAgesaWarmResetFlag ( + 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 + 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); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10GetApMailboxFromHardware ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT AP_MAILBOXES *ApMailboxInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MailboxInfo; + + LibAmdMsrRead (MSR_MC_MISC_LINK_THRESHOLD, &MailboxInfo, StdHeader); + // Mailbox info is in bits 32 thru 43, 12 bits. + ApMailboxInfo->ApMailInfo.Info = (((UINT32) (MailboxInfo >> 32)) & (UINT32)0x00000FFF); + LibAmdMsrRead (MSR_MC_MISC_L3_THRESHOLD, &MailboxInfo, StdHeader); + // Mailbox info is in bits 32 thru 43, 12 bits. + ApMailboxInfo->ApMailExtInfo.Info = (((UINT32) (MailboxInfo >> 32)) & (UINT32)0x00000FFF); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Set the system AP core number in the AP's Mailbox. + * + * @CpuServiceMethod{::F_CPU_SET_AP_CORE_NUMBER}. + * + * Access the mailbox register used with this NB family. This is only intended to + * run on the BSC at the time of initial AP launch. + * + * @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. + * + */ +VOID +F10SetApCoreNumber ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 Socket, + IN UINT32 Module, + IN UINT32 ApCoreNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PciRegister; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredStatus; + + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus); + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = 0x170; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((AP_MAIL_EXT_INFO *) &PciRegister)->Fields.HeapIndex = ApCoreNumber; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10GetApCoreNumber ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + NODE_ID_MSR NodeIdMsr; + + LibAmdMsrRead (0xC001100C, &NodeIdMsr.Value, StdHeader); + return (UINT32) NodeIdMsr.Fields.HeapIndex; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Move the AP's core number from the mailbox to hardware. + * + * @CpuServiceMethod{::F_CPU_TRANSFER_AP_CORE_NUMBER}. + * + * Transfers this AP's system core number from the mailbox to + * the NodeId MSR and initializes the other NodeId fields. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +VOID +F10TransferApCoreNumber ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_MAILBOXES Mailboxes; + NODE_ID_MSR NodeIdMsr; + UINT64 ExtFeatures; + + NodeIdMsr.Value = 0; + FamilySpecificServices->GetApMailboxFromHardware (FamilySpecificServices, &Mailboxes, StdHeader); + NodeIdMsr.Fields.HeapIndex = Mailboxes.ApMailExtInfo.Fields.HeapIndex; + NodeIdMsr.Fields.NodeId = Mailboxes.ApMailInfo.Fields.Node; + NodeIdMsr.Fields.NodesPerProcessor = Mailboxes.ApMailInfo.Fields.ModuleType; + LibAmdMsrWrite (0xC001100C, &NodeIdMsr.Value, StdHeader); + + // Indicate that the NodeId MSR is supported. + LibAmdMsrRead (MSR_CPUID_EXT_FEATS, &ExtFeatures, StdHeader); + ExtFeatures = (ExtFeatures | BIT51); + LibAmdMsrWrite (MSR_CPUID_EXT_FEATS, &ExtFeatures, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10CpuAmdCoreIdPositionInInitialApicId ( + 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/f10/Proc/CPU/Family/0x10/cpuCommonF10Utilities.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuCommonF10Utilities.h new file mode 100755 index 0000000000..b135429ca9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuCommonF10Utilities.h @@ -0,0 +1,98 @@ +/** + * @file + * + * AMD Family_10 specific utility functions. + * + * Provides numerous utility functions specific to family 10h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: IDS + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_COMMON_F10_UTILITES_H_ +#define _CPU_COMMON_F10_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 + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +VOID +F10GetApMailboxFromHardware ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT AP_MAILBOXES *ApMailboxInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +CORE_ID_POSITION +F10CpuAmdCoreIdPositionInInitialApicId ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F10SetAgesaWarmResetFlag ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader, + IN WARM_RESET_REQUEST *Request + ); + +VOID +F10GetAgesaWarmResetFlag ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader, + IN WARM_RESET_REQUEST *Request + ); + +#endif // _CPU_COMMON_F10_UTILITES_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandId.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandId.c new file mode 100755 index 0000000000..7dbdf14c4b --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandId.c @@ -0,0 +1,155 @@ +/** + * @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 + * @e \$Revision: 6396 $ @e \$Date: 2008-06-16 05:52:20 -0700 (Mon, 16 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10BRANDID_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 + *---------------------------------------------------------------------------------------- + */ +VOID +GetF10BrandIdString1 ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **BrandString1Ptr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); +VOID +GetF10BrandIdString2 ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **BrandString2Ptr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +extern CPU_BRAND_TABLE *F10BrandIdString1Tables[]; +extern CPU_BRAND_TABLE *F10BrandIdString2Tables[]; +extern CONST UINT8 F10BrandIdString1TableCount; +extern CONST UINT8 F10BrandIdString2TableCount; + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns a table containing the appropriate beginnings of the CPU brandstring. + * + * @CpuServiceMethod{::F_CPU_GET_FAMILY_SPECIFIC_ARRAY}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] BrandString1Ptr 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 +GetF10BrandIdString1 ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **BrandString1Ptr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_BRAND_TABLE **TableEntryPtr; + + TableEntryPtr = &F10BrandIdString1Tables[0]; + *BrandString1Ptr = TableEntryPtr; + *NumberOfElements = F10BrandIdString1TableCount; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns a table containing the appropriate endings of the CPU brandstring. + * + * @CpuServiceMethod{::F_CPU_GET_FAMILY_SPECIFIC_ARRAY}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] BrandString2Ptr 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 +GetF10BrandIdString2 ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **BrandString2Ptr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_BRAND_TABLE **TableEntryPtr; + + TableEntryPtr = &F10BrandIdString2Tables[0]; + *BrandString2Ptr = TableEntryPtr; + *NumberOfElements = F10BrandIdString2TableCount; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdAm3.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdAm3.c new file mode 100755 index 0000000000..73e9bb3263 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdAm3.c @@ -0,0 +1,315 @@ +/** + * @file + * + * AMD CPU BrandId related functions and structures for socket Am3. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6396 $ @e \$Date: 2008-06-16 05:52:20 -0700 (Mon, 16 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +// PRIVATE FORMAT FOR BRAND TABLE ... FOR AMD USE ONLY + +// String1 +/*CHAR8 strEngSample[] = "AMD Engineering Sample"; +CHAR8 strTtkSample[] = "AMD Thermal Test Kit"; +CHAR8 strUnknown[] = "AMD Processor model unknown"; +*/ +//AM3 NC 0 +CONST CHAR8 ROMDATA str_SC_AthlonLE[] = "AMD Athlon(tm) Processor LE-"; +CONST CHAR8 ROMDATA str_SC_SempronLE[] = "AMD Sempron(tm) Processor LE-"; +CONST CHAR8 ROMDATA str_SC_Sempron_1[] = "AMD Sempron(tm) 1"; +CONST CHAR8 ROMDATA str_SC_Athlon_1[] = "AMD Athlon(tm) II 1"; + +//AM3 NC 1 +CONST CHAR8 ROMDATA str_Athlon[] = "AMD Athlon(tm) "; +CONST CHAR8 ROMDATA str_Athlon_II_XL_V[] = "AMD Athlon(tm) II XL V"; +CONST CHAR8 ROMDATA str_Athlon_II_XLT_V[] = "AMD Athlon(tm) II XLT V"; +CONST CHAR8 ROMDATA str_Athlon_II_X2_4[] = "AMD Athlon(tm) II X2 4"; +CONST CHAR8 ROMDATA str_Athlon_II_X2_2[] = "AMD Athlon(tm) II X2 2"; +CONST CHAR8 ROMDATA str_Athlon_II_X2_B[] = "AMD Athlon(tm) II X2 B"; +CONST CHAR8 ROMDATA str_Athlon_II_X2[] = "AMD Athlon(tm) II X2 "; +CONST CHAR8 ROMDATA str_Athlon_II_Neo_X2[] = "AMD Athlon(tm) II Neo X2 "; +CONST CHAR8 ROMDATA str_Phenom_II_X2_5[] = "AMD Phenom(tm) II X2 5"; +CONST CHAR8 ROMDATA str_Athlon_II_X2_5[] = "AMD Athlon(tm) II X2 5"; +CONST CHAR8 ROMDATA str_Athlon_II_X2_3[] = "AMD Athlon(tm) II X2 3"; +CONST CHAR8 ROMDATA str_Phenom_II_X2[] = "AMD Phenom(tm) II X2 "; +CONST CHAR8 ROMDATA str_Phenom_II_X2_B[] = "AMD Phenom(tm) II X2 B"; +CONST CHAR8 ROMDATA str_DC_Opteron13[] = "Dual-Core AMD Opteron(tm) Processor 13"; + +//AM3 NC2 +CONST CHAR8 ROMDATA str_Phenom[] = "AMD Phenom(tm) "; +CONST CHAR8 ROMDATA str_Phenom_II_X3_5[] = "AMD Phenom(tm) II X3 5"; +CONST CHAR8 ROMDATA str_Phenom_II_X3_4[] = "AMD Phenom(tm) II X3 4"; +CONST CHAR8 ROMDATA str_Phenom_II_X3_B[] = "AMD Phenom(tm) II X3 B"; +CONST CHAR8 ROMDATA str_Phenom_II_X3[] = "AMD Phenom(tm) II X3 "; +CONST CHAR8 ROMDATA str_Athlon_II_X3_3[] = "AMD Athlon(tm) II X3 3"; +CONST CHAR8 ROMDATA str_Athlon_II_Neo_X3[] = "AMD Athlon(tm) II Neo X3 "; +CONST CHAR8 ROMDATA str_Athlon_II_X3_4[] = "AMD Athlon(tm) II X3 4"; +CONST CHAR8 ROMDATA str_Phenom_II_X3_7[] = "AMD Phenom(tm) II X3 7"; +CONST CHAR8 ROMDATA str_Athlon_II_X3_B[] = "AMD Athlon(tm) II X3 B"; +CONST CHAR8 ROMDATA str_Athlon_II_X3[] = "AMD Athlon(tm) II X3 "; + +//AM3 NC 3 +CONST CHAR8 ROMDATA str_Phenom_FX[] = "AMD Phenom(tm) FX-"; +CONST CHAR8 ROMDATA str_Phenom_II_X4_9[] = "AMD Phenom(tm) II X4 9"; +CONST CHAR8 ROMDATA str_Phenom_II_X4_8[] = "AMD Phenom(tm) II X4 8"; +CONST CHAR8 ROMDATA str_Phenom_II_X4_7[] = "AMD Phenom(tm) II X4 7"; +CONST CHAR8 ROMDATA str_Phenom_II_X4_6[] = "AMD Phenom(tm) II X4 6"; +CONST CHAR8 ROMDATA str_Phenom_II_X4_B[] = "AMD Phenom(tm) II X4 B"; +CONST CHAR8 ROMDATA str_Phenom_II_X4[] = "AMD Phenom(tm) II X4 "; +CONST CHAR8 ROMDATA str_Phenom_II_Neo_X4[] = "AMD Phenom(tm) II Neo X4 "; +CONST CHAR8 ROMDATA str_Athlon_II_X4_6[] = "AMD Athlon(tm) II X4 6"; +CONST CHAR8 ROMDATA str_Athlon_II_X4_5[] = "AMD Athlon(tm) II X4 5"; +CONST CHAR8 ROMDATA str_Athlon_II_Neo_X4[] = "AMD Athlon(tm) II Neo X4 "; +CONST CHAR8 ROMDATA str_Athlon_II_X4_B[] = "AMD Athlon(tm) II X4 B"; +CONST CHAR8 ROMDATA str_Phenom_II__FX[] = "AMD Phenom(tm) II FX-"; +CONST CHAR8 ROMDATA str_Athlon_II_X4[] = "AMD Athlon(tm) II X4 "; +CONST CHAR8 ROMDATA str_Phenom_II[] = "AMD Phenom(tm) II "; +CONST CHAR8 ROMDATA str_Phenom_II_XLT_Q[] = "AMD Phenom(tm) II XLT Q"; +CONST CHAR8 ROMDATA str_QC_Opteron13[] = "Quad-Core AMD Opteron(tm) Processor 13"; + +// String2 +CONST CHAR8 ROMDATA str2_SE_AM3[] = " SE"; +CONST CHAR8 ROMDATA str2_HE_AM3[] = " HE"; +CONST CHAR8 ROMDATA str2_EE_AM3[] = " EE"; + +CONST CHAR8 ROMDATA str2_QCP_AM3[] = " Quad-Core Processor"; +CONST CHAR8 ROMDATA str2_00[] = "00"; +CONST CHAR8 ROMDATA str2_10[] = "10"; +CONST CHAR8 ROMDATA str2_20[] = "20"; +CONST CHAR8 ROMDATA str2_30[] = "30"; +CONST CHAR8 ROMDATA str2_40[] = "40"; +CONST CHAR8 ROMDATA str2_50[] = "50"; +CONST CHAR8 ROMDATA str2_60[] = "60"; +CONST CHAR8 ROMDATA str2_70[] = "70"; +CONST CHAR8 ROMDATA str2_80[] = "80"; +CONST CHAR8 ROMDATA str2_90[] = "90"; +CONST CHAR8 ROMDATA str2_DC_00[] = "00 Dual-Core Processor"; +CONST CHAR8 ROMDATA str2_DC_00e[] = "00e Dual-Core Processor"; +CONST CHAR8 ROMDATA str2_DC_00B[] = "00B Dual-Core Processor"; +CONST CHAR8 ROMDATA str2_DC_50[] = "50 Dual-Core Processor"; +CONST CHAR8 ROMDATA str2_DC_50e[] = "50e Dual-Core Processor"; +CONST CHAR8 ROMDATA str2_DC_50B[] = "50B Dual-Core Processor"; +CONST CHAR8 ROMDATA str2_Processor[] = " Processor"; +CONST CHAR8 ROMDATA str2_e_Processor[] = "e Processor"; +CONST CHAR8 ROMDATA str2_B_Processor[] = "B Processor"; +CONST CHAR8 ROMDATA str2_0e_Processor[] = "0e Processor"; +CONST CHAR8 ROMDATA str2_u_Processor[] = "u Processor"; +CONST CHAR8 ROMDATA str2_0_Processor[] = "0 Processor"; +CONST CHAR8 ROMDATA str2_L_Processor[] = "L Processor"; +CONST CHAR8 ROMDATA str2_C_Processor[] = "C Processor"; +CONST CHAR8 ROMDATA str2_TWKR_Black_Edition[] = " TWKR Black Edition"; + +CONST CHAR8 ROMDATA str2_TC_00[] = "00 Triple-Core Processor"; +CONST CHAR8 ROMDATA str2_TC_00e[] = "00e Triple-Core Processor"; +CONST CHAR8 ROMDATA str2_TC_00B[] = "00B Triple-Core Processor"; +CONST CHAR8 ROMDATA str2_TC_50[] = "50 Triple-Core Processor"; +CONST CHAR8 ROMDATA str2_TC_50e[] = "50e Triple-Core Processor"; +CONST CHAR8 ROMDATA str2_TC_50B[] = "50B Triple-Core Processor"; +CONST CHAR8 ROMDATA str2_QC_00[] = "00 Quad-Core Processor"; +CONST CHAR8 ROMDATA str2_QC_00e[] = "00e Quad-Core Processor"; +CONST CHAR8 ROMDATA str2_QC_00B[] = "00B Quad-Core Processor"; +CONST CHAR8 ROMDATA str2_QC_50[] = "50 Quad-Core Processor"; +CONST CHAR8 ROMDATA str2_QC_50e[] = "50e Quad-Core Processor"; +CONST CHAR8 ROMDATA str2_QC_50B[] = "50B Quad-Core Processor"; + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString1ArrayAm3[] = +{ + // AM3 + {1, 0, 0, DR_SOCKET_AM3, str_SC_AthlonLE, sizeof (str_SC_AthlonLE)}, + {1, 0, 1, DR_SOCKET_AM3, str_SC_SempronLE, sizeof (str_SC_SempronLE)}, + {1, 0, 2, DR_SOCKET_AM3, str_SC_Sempron_1, sizeof (str_SC_Sempron_1)}, + {1, 0, 3, DR_SOCKET_AM3, str_SC_Athlon_1, sizeof (str_SC_Athlon_1)}, + {2, 0, 0, DR_SOCKET_AM3, str_DC_Opteron13, sizeof (str_DC_Opteron13)}, + {2, 0, 1, DR_SOCKET_AM3, str_Athlon, sizeof (str_Athlon)}, + {2, 0, 2, DR_SOCKET_AM3, str_Athlon_II_X2_4, sizeof (str_Athlon_II_X2_4)}, + {2, 0, 3, DR_SOCKET_AM3, str_Athlon_II_X2_2, sizeof (str_Athlon_II_X2_2)}, + {2, 0, 4, DR_SOCKET_AM3, str_Athlon_II_X2_B, sizeof (str_Athlon_II_X2_B)}, + {2, 0, 5, DR_SOCKET_AM3, str_Athlon_II_X2, sizeof (str_Athlon_II_X2)}, + {2, 0, 6, DR_SOCKET_AM3, str_Athlon_II_Neo_X2, sizeof (str_Athlon_II_Neo_X2)}, + {2, 0, 7, DR_SOCKET_AM3, str_Phenom_II_X2_5, sizeof (str_Phenom_II_X2_5)}, + {2, 0, 8, DR_SOCKET_AM3, str_Athlon_II_X2_5, sizeof (str_Athlon_II_X2_5)}, + {2, 0, 9, DR_SOCKET_AM3, str_Athlon_II_X2_3, sizeof (str_Athlon_II_X2_3)}, + {2, 0, 10, DR_SOCKET_AM3, str_Phenom_II_X2, sizeof (str_Phenom_II_X2)}, + {2, 0, 11, DR_SOCKET_AM3, str_Phenom_II_X2_B, sizeof (str_Phenom_II_X2_B)}, + + {3, 0, 0, DR_SOCKET_AM3, str_Phenom, sizeof (str_Phenom)}, + {3, 0, 1, DR_SOCKET_AM3, str_Phenom_II_X3_5, sizeof (str_Phenom_II_X3_5)}, + {3, 0, 2, DR_SOCKET_AM3, str_Phenom_II_X3_4, sizeof (str_Phenom_II_X3_4)}, + {3, 0, 3, DR_SOCKET_AM3, str_Phenom_II_X3_B, sizeof (str_Phenom_II_X3_B)}, + {3, 0, 4, DR_SOCKET_AM3, str_Phenom_II_X3, sizeof (str_Phenom_II_X3)}, + {3, 0, 5, DR_SOCKET_AM3, str_Athlon_II_X3_3, sizeof (str_Athlon_II_X3_3)}, + {3, 0, 6, DR_SOCKET_AM3, str_Athlon_II_Neo_X3, sizeof (str_Athlon_II_Neo_X3)}, + {3, 0, 7, DR_SOCKET_AM3, str_Athlon_II_X3_4, sizeof (str_Athlon_II_X3_4)}, + {3, 0, 8, DR_SOCKET_AM3, str_Phenom_II_X3_7, sizeof (str_Phenom_II_X3_7)}, + {3, 0, 9, DR_SOCKET_AM3, str_Athlon_II_X3_B, sizeof (str_Athlon_II_X3_B)}, + {3, 0, 10, DR_SOCKET_AM3, str_Athlon_II_X3, sizeof (str_Athlon_II_X3)}, + + {4, 0, 0, DR_SOCKET_AM3, str_QC_Opteron13, sizeof (str_QC_Opteron13)}, + {4, 0, 1, DR_SOCKET_AM3, str_Phenom_FX, sizeof (str_Phenom_FX)}, + {4, 0, 2, DR_SOCKET_AM3, str_Phenom, sizeof (str_Phenom)}, + {4, 0, 3, DR_SOCKET_AM3, str_Phenom_II_X4_9, sizeof (str_Phenom_II_X4_9)}, + {4, 0, 4, DR_SOCKET_AM3, str_Phenom_II_X4_8, sizeof (str_Phenom_II_X4_8)}, + {4, 0, 5, DR_SOCKET_AM3, str_Phenom_II_X4_7, sizeof (str_Phenom_II_X4_7)}, + {4, 0, 6, DR_SOCKET_AM3, str_Phenom_II_X4_6, sizeof (str_Phenom_II_X4_6)}, + {4, 0, 7, DR_SOCKET_AM3, str_Phenom_II_X4_B, sizeof (str_Phenom_II_X4_B)}, + {4, 0, 8, DR_SOCKET_AM3, str_Phenom_II_X4, sizeof (str_Phenom_II_X4)}, + {4, 0, 9, DR_SOCKET_AM3, str_Phenom_II_Neo_X4, sizeof (str_Phenom_II_Neo_X4)}, + {4, 0, 10, DR_SOCKET_AM3, str_Athlon_II_X4_6, sizeof (str_Athlon_II_X4_6)}, + {4, 0, 11, DR_SOCKET_AM3, str_Athlon_II_X4_5, sizeof (str_Athlon_II_X4_5)}, + {4, 0, 12, DR_SOCKET_AM3, str_Athlon_II_Neo_X4, sizeof (str_Athlon_II_Neo_X4)}, + {4, 0, 13, DR_SOCKET_AM3, str_Athlon_II_X4_B, sizeof (str_Athlon_II_X4_B)}, + {4, 0, 14, DR_SOCKET_AM3, str_Phenom_II__FX, sizeof (str_Phenom_II__FX)}, + {4, 0, 15, DR_SOCKET_AM3, str_Athlon_II_X4, sizeof (str_Athlon_II_X4)}, + {2, 1, 1, DR_SOCKET_AM3, str_Athlon_II_XLT_V, sizeof (str_Athlon_II_XLT_V)}, + {2, 1, 2, DR_SOCKET_AM3, str_Athlon_II_XL_V, sizeof (str_Athlon_II_XL_V)}, + {4, 1, 0, DR_SOCKET_AM3, str_Phenom_II, sizeof (str_Phenom_II)}, + {4, 1, 1, DR_SOCKET_AM3, str_Phenom_II_XLT_Q, sizeof (str_Phenom_II_XLT_Q)} +}; //Cores, page, index, socket, stringstart, stringlength + + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString2ArrayAm3[] = +{ + // AM3 + {1, 0, 0x00, DR_SOCKET_AM3, str2_00, sizeof (str2_00)}, + {1, 0, 0x01, DR_SOCKET_AM3, str2_10, sizeof (str2_10)}, + {1, 0, 0x02, DR_SOCKET_AM3, str2_20, sizeof (str2_20)}, + {1, 0, 0x03, DR_SOCKET_AM3, str2_30, sizeof (str2_30)}, + {1, 0, 0x04, DR_SOCKET_AM3, str2_40, sizeof (str2_40)}, + {1, 0, 0x05, DR_SOCKET_AM3, str2_50, sizeof (str2_50)}, + {1, 0, 0x06, DR_SOCKET_AM3, str2_60, sizeof (str2_60)}, + {1, 0, 0x07, DR_SOCKET_AM3, str2_70, sizeof (str2_70)}, + {1, 0, 0x08, DR_SOCKET_AM3, str2_80, sizeof (str2_80)}, + {1, 0, 0x09, DR_SOCKET_AM3, str2_90, sizeof (str2_90)}, + {1, 0, 0x0A, DR_SOCKET_AM3, str2_Processor, sizeof (str2_Processor)}, + {1, 0, 0x0B, DR_SOCKET_AM3, str2_u_Processor, sizeof (str2_u_Processor)}, + {1, 0, 0x0F, DR_SOCKET_AM3, 0, 0}, //Size 0 for no suffix + {2, 0, 0x00, DR_SOCKET_AM3, str2_DC_00, sizeof (str2_DC_00)}, + {2, 0, 0x01, DR_SOCKET_AM3, str2_DC_00e,sizeof (str2_DC_00e)}, + {2, 0, 0x02, DR_SOCKET_AM3, str2_DC_00B,sizeof (str2_DC_00B)}, + {2, 0, 0x03, DR_SOCKET_AM3, str2_DC_50, sizeof (str2_DC_50)}, + {2, 0, 0x04, DR_SOCKET_AM3, str2_DC_50e,sizeof (str2_DC_50e)}, + {2, 0, 0x05, DR_SOCKET_AM3, str2_DC_50B,sizeof (str2_DC_50B)}, + {2, 0, 0x06, DR_SOCKET_AM3, str2_Processor,sizeof (str2_Processor)}, + {2, 0, 0x07, DR_SOCKET_AM3, str2_e_Processor,sizeof (str2_e_Processor)}, + {2, 0, 0x08, DR_SOCKET_AM3, str2_B_Processor,sizeof (str2_B_Processor)}, + {2, 0, 0x09, DR_SOCKET_AM3, str2_0_Processor,sizeof (str2_0_Processor)}, + {2, 0, 0x0A, DR_SOCKET_AM3, str2_0e_Processor,sizeof (str2_0e_Processor)}, + {2, 0, 0x0B, DR_SOCKET_AM3, str2_u_Processor,sizeof (str2_u_Processor)}, + {2, 0, 0x0F, DR_SOCKET_AM3, 0, 0}, // Size 0 for no suffix + {3, 0, 0x00, DR_SOCKET_AM3, str2_TC_00, sizeof (str2_TC_00)}, + {3, 0, 0x01, DR_SOCKET_AM3, str2_TC_00e,sizeof (str2_TC_00e)}, + {3, 0, 0x02, DR_SOCKET_AM3, str2_TC_00B,sizeof (str2_TC_00B)}, + {3, 0, 0x03, DR_SOCKET_AM3, str2_TC_50, sizeof (str2_TC_50)}, + {3, 0, 0x04, DR_SOCKET_AM3, str2_TC_50e,sizeof (str2_TC_50e)}, + {3, 0, 0x05, DR_SOCKET_AM3, str2_TC_50B,sizeof (str2_TC_50B)}, + {3, 0, 0x06, DR_SOCKET_AM3, str2_Processor,sizeof (str2_Processor)}, + {3, 0, 0x07, DR_SOCKET_AM3, str2_e_Processor,sizeof (str2_e_Processor)}, + {3, 0, 0x08, DR_SOCKET_AM3, str2_B_Processor,sizeof (str2_B_Processor)}, + {3, 0, 0x09, DR_SOCKET_AM3, str2_0e_Processor,sizeof (str2_0e_Processor)}, + {3, 0, 0x0A, DR_SOCKET_AM3, str2_0_Processor,sizeof (str2_0_Processor)}, + {3, 0, 0x0F, DR_SOCKET_AM3, 0, 0}, //Size 0 for no suffix + {4, 0, 0x00, DR_SOCKET_AM3, str2_QC_00, sizeof (str2_QC_00)}, + {4, 0, 0x01, DR_SOCKET_AM3, str2_QC_00e,sizeof (str2_QC_00e)}, + {4, 0, 0x02, DR_SOCKET_AM3, str2_QC_00B,sizeof (str2_QC_00B)}, + {4, 0, 0x03, DR_SOCKET_AM3, str2_QC_50, sizeof (str2_QC_50)}, + {4, 0, 0x04, DR_SOCKET_AM3, str2_QC_50e,sizeof (str2_QC_50e)}, + {4, 0, 0x05, DR_SOCKET_AM3, str2_QC_50B,sizeof (str2_QC_50B)}, + {4, 0, 0x06, DR_SOCKET_AM3, str2_Processor, sizeof (str2_Processor)}, + {4, 0, 0x07, DR_SOCKET_AM3, str2_e_Processor, sizeof (str2_e_Processor)}, + {4, 0, 0x08, DR_SOCKET_AM3, str2_B_Processor, sizeof (str2_B_Processor)}, + {4, 0, 0x09, DR_SOCKET_AM3, str2_0e_Processor, sizeof (str2_0e_Processor)}, + {4, 0, 0x0A, DR_SOCKET_AM3, str2_SE_AM3, sizeof (str2_SE_AM3)}, + {4, 0, 0x0B, DR_SOCKET_AM3, str2_HE_AM3, sizeof (str2_HE_AM3)}, + {4, 0, 0x0C, DR_SOCKET_AM3, str2_EE_AM3, sizeof (str2_EE_AM3)}, + {4, 0, 0x0D, DR_SOCKET_AM3, str2_QCP_AM3, sizeof (str2_QCP_AM3)}, + {4, 0, 0x0E, DR_SOCKET_AM3, str2_0_Processor, sizeof (str2_0_Processor)}, + {2, 1, 0x01, DR_SOCKET_AM3, str2_L_Processor, sizeof (str2_L_Processor)}, + {2, 1, 0x02, DR_SOCKET_AM3, str2_C_Processor, sizeof (str2_C_Processor)}, + {4, 1, 0x00, DR_SOCKET_AM3, str2_TWKR_Black_Edition, sizeof (str2_TWKR_Black_Edition)}, + {4, 1, 0x01, DR_SOCKET_AM3, str2_L_Processor, sizeof (str2_L_Processor)}, + {4, 0, 0x0F, DR_SOCKET_AM3, 0, 0} +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString1ArrayAm3 = { + (sizeof (CpuF10BrandIdString1ArrayAm3) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString1ArrayAm3 +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString2ArrayAm3 = { + (sizeof (CpuF10BrandIdString2ArrayAm3) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString2ArrayAm3 +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdAsb2.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdAsb2.c new file mode 100755 index 0000000000..1db5664235 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdAsb2.c @@ -0,0 +1,131 @@ +/** + * @file + * + * AMD CPU BrandId related functions and structures for package ASB2. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6396 $ @e \$Date: 2008-06-16 05:52:20 -0700 (Mon, 16 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "F10PackageType.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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +// String1 +CONST CHAR8 ROMDATA str_AMD_V[] = "AMD V"; +CONST CHAR8 ROMDATA str_Athlon_II_Neo_K[] = "AMD Athlon(tm) II Neo K"; +CONST CHAR8 ROMDATA str_Athlon_II_Neo_N[] = "AMD Athlon(tm) II Neo N"; +CONST CHAR8 ROMDATA str_Athlon_II_Neo_R[] = "AMD Athlon(tm) II Neo R"; +CONST CHAR8 ROMDATA str_Turion_II_Neo_K[] = "AMD Turion(tm) II Neo K"; +CONST CHAR8 ROMDATA str_Turion_II_Neo_N[] = "AMD Turion(tm) II Neo N"; + +// String2 +CONST CHAR8 ROMDATA str_Asb2_5_Processor[] = "5 Processor"; +CONST CHAR8 ROMDATA str_Asb2_5_Dual_Core_Processor[] = "5 Dual-Core Processor"; +CONST CHAR8 ROMDATA str_L_Processor[] = "L Processor"; +CONST CHAR8 ROMDATA str_L_Dual_Core_Processor[] = "L Dual-Core Processor"; + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString1ArrayAsb2[] = +{ + // ASB2 + {1, 0, 1, DR_SOCKET_ASB2, str_Athlon_II_Neo_K, sizeof (str_Athlon_II_Neo_K)}, + {1, 0, 2, DR_SOCKET_ASB2, str_AMD_V, sizeof (str_AMD_V)}, + {1, 0, 3, DR_SOCKET_ASB2, str_Athlon_II_Neo_R, sizeof (str_Athlon_II_Neo_R)}, + {2, 0, 1, DR_SOCKET_ASB2, str_Turion_II_Neo_K, sizeof (str_Turion_II_Neo_K)}, + {2, 0, 2, DR_SOCKET_ASB2, str_Athlon_II_Neo_K, sizeof (str_Athlon_II_Neo_K)}, + {2, 0, 3, DR_SOCKET_ASB2, str_AMD_V, sizeof (str_AMD_V)}, + {2, 0, 4, DR_SOCKET_ASB2, str_Turion_II_Neo_N, sizeof (str_Turion_II_Neo_N)}, + {2, 0, 5, DR_SOCKET_ASB2, str_Athlon_II_Neo_N, sizeof (str_Athlon_II_Neo_N)} +}; //Cores, page, index, socket, stringstart, stringlength + + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString2ArrayAsb2[] = +{ + // ASB2 + {1, 0, 0x01, DR_SOCKET_ASB2, str_Asb2_5_Processor, sizeof (str_Asb2_5_Processor)}, + {1, 0, 0x02, DR_SOCKET_ASB2, str_L_Processor, sizeof (str_L_Processor)}, + {2, 0, 0x01, DR_SOCKET_ASB2, str_Asb2_5_Dual_Core_Processor, sizeof (str_Asb2_5_Dual_Core_Processor)}, + {2, 0, 0x02, DR_SOCKET_ASB2, str_L_Dual_Core_Processor, sizeof (str_L_Dual_Core_Processor)}, + {1, 0, 0x0F, DR_SOCKET_ASB2, 0, 0}, //Size 0 for no suffix + {2, 0, 0x0F, DR_SOCKET_ASB2, 0, 0}, //Size 0 for no suffix +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString1ArrayAsb2 = { + (sizeof (CpuF10BrandIdString1ArrayAsb2) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString1ArrayAsb2 +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString2ArrayAsb2 = { + (sizeof (CpuF10BrandIdString2ArrayAsb2) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString2ArrayAsb2 +}; + + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdC32.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdC32.c new file mode 100755 index 0000000000..6cd250e6c2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdC32.c @@ -0,0 +1,131 @@ +/** + * @file + * + * AMD CPU BrandId related functions and structures for socket C32. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +// PRIVATE FORMAT FOR BRAND TABLE ... FOR AMD USE ONLY + +// String1 +CONST CHAR8 ROMDATA str_Opteron_41[] = "AMD Opteron(tm) Processor 41"; +CONST CHAR8 ROMDATA str_Embedded_Opteron_C32[] = "Embedded AMD Opteron(tm) Processor "; + +// String2 +CONST CHAR8 ROMDATA str2_HE_C32[] = " HE"; +CONST CHAR8 ROMDATA str2_EE_C32[] = " EE"; +CONST CHAR8 ROMDATA str2_QS_HE_C32[] = "QS HE"; +CONST CHAR8 ROMDATA str2_LE_HE_C32[] = "LE HE"; +CONST CHAR8 ROMDATA str2_KX_HE_C32[] = "KX HE"; +CONST CHAR8 ROMDATA str2_GL_EE_C32[] = "GL EE"; +CONST CHAR8 ROMDATA str2_CL_EE[] = "CL EE"; + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString1ArrayC32[] = +{ + // C32r1 string1: + {4, 0, 0x00, DR_SOCKET_C32, str_Opteron_41, sizeof (str_Opteron_41)}, + {4, 1, 0x01, DR_SOCKET_C32, str_Embedded_Opteron_C32, sizeof (str_Embedded_Opteron_C32)}, + {6, 0, 0x00, DR_SOCKET_C32, str_Opteron_41, sizeof (str_Opteron_41)}, + {6, 1, 0x01, DR_SOCKET_C32, str_Embedded_Opteron_C32, sizeof (str_Embedded_Opteron_C32)} +}; //Cores, page, index, socket, stringstart, stringlength + + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString2ArrayC32[] = +{ + // C32r1 string2: + {4, 0, 0x00, DR_SOCKET_C32, str2_HE_C32, sizeof (str2_HE_C32)}, + {4, 0, 0x01, DR_SOCKET_C32, str2_EE_C32, sizeof (str2_EE_C32)}, + {4, 0, 0x0F, DR_SOCKET_C32, 0, 0}, //Size 0 for no suffix + {4, 1, 0x01, DR_SOCKET_C32, str2_QS_HE_C32, sizeof (str2_QS_HE_C32)}, + {4, 1, 0x02, DR_SOCKET_C32, str2_LE_HE_C32, sizeof (str2_LE_HE_C32)}, + {4, 1, 0x03, DR_SOCKET_C32, str2_CL_EE, sizeof (str2_CL_EE)}, + {6, 0, 0x00, DR_SOCKET_C32, str2_HE_C32, sizeof (str2_HE_C32)}, + {6, 0, 0x01, DR_SOCKET_C32, str2_EE_C32, sizeof (str2_EE_C32)}, + {6, 0, 0x0F, DR_SOCKET_C32, 0, 0}, //Size 0 for no suffix + {6, 1, 0x01, DR_SOCKET_C32, str2_KX_HE_C32, sizeof (str2_KX_HE_C32)}, + {6, 1, 0x02, DR_SOCKET_C32, str2_GL_EE_C32, sizeof (str2_GL_EE_C32)} +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString1ArrayC32 = { + (sizeof (CpuF10BrandIdString1ArrayC32) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString1ArrayC32 +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString2ArrayC32 = { + (sizeof (CpuF10BrandIdString2ArrayC32) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString2ArrayC32 +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdFr1207.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdFr1207.c new file mode 100755 index 0000000000..a647bfd662 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdFr1207.c @@ -0,0 +1,176 @@ +/** + * @file + * + * AMD CPU BrandId related functions and structures for socket Fr1207. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6396 $ @e \$Date: 2008-06-16 05:52:20 -0700 (Mon, 16 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +// PRIVATE FORMAT FOR BRAND TABLE ... FOR AMD USE ONLY + +// String1 +/*CHAR8 strEngSample[] = "AMD Engineering Sample"; +CHAR8 strTtkSample[] = "AMD Thermal Test Kit"; +CHAR8 strUnknown[] = "AMD Processor model unknown"; +*/ +CONST CHAR8 ROMDATA str_DC_Opteron83[] = "Dual-Core AMD Opteron(tm) Processor 83"; +CONST CHAR8 ROMDATA str_DC_Opteron23[] = "Dual-Core AMD Opteron(tm) Processor 23"; +CONST CHAR8 ROMDATA str_QC_Opteron83[] = "Quad-Core AMD Opteron(tm) Processor 83"; +CONST CHAR8 ROMDATA str_QC_Opteron23[] = "Quad-Core AMD Opteron(tm) Processor 23"; +CONST CHAR8 ROMDATA str_eQC_Opteron83[] = "Embedded AMD Opteron(tm) Processor 83"; +CONST CHAR8 ROMDATA str_eQC_Opteron23[] = "Embedded AMD Opteron(tm) Processor 23"; +CONST CHAR8 ROMDATA str_eQC_Opteron13[] = "Embedded AMD Opteron(tm) Processor 13"; +CONST CHAR8 ROMDATA str_Embedded_Opteron[] = "Embedded AMD Opteron(tm) Processor "; +CONST CHAR8 ROMDATA str_SC_Opteron84[] = "Six-Core AMD Opteron(tm) Processor 84"; +CONST CHAR8 ROMDATA str_SC_Opteron24[] = "Six-Core AMD Opteron(tm) Processor 24"; + +CONST CHAR8 ROMDATA str_PhenomFX[] = "AMD Phenom(tm) FX-"; + + +// String2 +CONST CHAR8 ROMDATA str2_SE[] = " SE"; +CONST CHAR8 ROMDATA str2_HE[] = " HE"; +CONST CHAR8 ROMDATA str2_EE[] = " EE"; +CONST CHAR8 ROMDATA str2_VS[] = "VS"; +CONST CHAR8 ROMDATA str2_QS[] = "QS"; + +CONST CHAR8 ROMDATA str2_NP_HE[] = "NP HE"; +CONST CHAR8 ROMDATA str2_GF_HE[] = "GF HE"; +CONST CHAR8 ROMDATA str2_HF_HE[] = "HF HE"; +CONST CHAR8 ROMDATA str2_QS_HE[] = "QS HE"; +CONST CHAR8 ROMDATA str2_KH_HE[] = "KH HE"; +CONST CHAR8 ROMDATA str2_KS_EE[] = "KS EE"; +CONST CHAR8 ROMDATA str2_KS_HE[] = "KS HE"; + +CONST CHAR8 ROMDATA str2_QCP[] = " Quad-Core Processor"; + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString1ArrayFr1207[] = +{ + // FR2/FR4 1207 + {2, 0, 0, DR_SOCKET_1207, str_DC_Opteron83, sizeof (str_DC_Opteron83)}, + {2, 0, 1, DR_SOCKET_1207, str_DC_Opteron23, sizeof (str_DC_Opteron23)}, + {3, 0, 0, DR_SOCKET_1207, str_Embedded_Opteron, sizeof (str_Embedded_Opteron)}, + {4, 0, 0, DR_SOCKET_1207, str_QC_Opteron83, sizeof (str_QC_Opteron83)}, + {4, 0, 1, DR_SOCKET_1207, str_QC_Opteron23, sizeof (str_QC_Opteron23)}, + {4, 0, 2, DR_SOCKET_1207, str_eQC_Opteron83, sizeof (str_eQC_Opteron83)}, + {4, 0, 3, DR_SOCKET_1207, str_eQC_Opteron23, sizeof (str_eQC_Opteron23)}, + {4, 0, 4, DR_SOCKET_1207, str_eQC_Opteron13, sizeof (str_eQC_Opteron13)}, + {4, 0, 5, DR_SOCKET_1207, str_PhenomFX, sizeof (str_PhenomFX)}, + {4, 1, 1, DR_SOCKET_1207, str_Embedded_Opteron, sizeof (str_Embedded_Opteron)}, + {6, 0, 0, DR_SOCKET_1207, str_SC_Opteron84, sizeof (str_SC_Opteron84)}, + {6, 0, 1, DR_SOCKET_1207, str_SC_Opteron24, sizeof (str_SC_Opteron24)}, + {6, 1, 1, DR_SOCKET_1207, str_Embedded_Opteron, sizeof (str_Embedded_Opteron)}, +}; //Cores, page, index, socket, stringstart, stringlength + + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString2ArrayFr1207[] = +{ + // FR2/FR4 1207 + {2, 0, 0x0A, DR_SOCKET_1207, str2_SE, sizeof (str2_SE)}, + {2, 0, 0x0B, DR_SOCKET_1207, str2_HE, sizeof (str2_HE)}, + {2, 0, 0x0C, DR_SOCKET_1207, str2_EE, sizeof (str2_EE)}, + {2, 0, 0x0F, DR_SOCKET_1207, 0, 0}, //Size 0 for no suffix + {3, 0, 0x00, DR_SOCKET_1207, str2_NP_HE, sizeof (str2_NP_HE)}, + {3, 0, 0x0F, DR_SOCKET_1207, 0, 0}, //Size 0 for no suffix + {4, 0, 0x0A, DR_SOCKET_1207, str2_SE, sizeof (str2_SE)}, + {4, 0, 0x0B, DR_SOCKET_1207, str2_HE, sizeof (str2_HE)}, + {4, 0, 0x0C, DR_SOCKET_1207, str2_EE, sizeof (str2_EE)}, + {4, 0, 0x0D, DR_SOCKET_1207, str2_QCP, sizeof (str2_QCP)}, + {4, 0, 0x0F, DR_SOCKET_1207, 0, 0}, //Size 0 for no suffix + {4, 1, 0x01, DR_SOCKET_1207, str2_GF_HE, sizeof (str2_GF_HE)}, + {4, 1, 0x02, DR_SOCKET_1207, str2_HF_HE, sizeof (str2_HF_HE)}, + {4, 1, 0x03, DR_SOCKET_1207, str2_VS, sizeof (str2_VS)}, + {4, 1, 0x04, DR_SOCKET_1207, str2_QS_HE, sizeof (str2_QS_HE)}, + {4, 1, 0x05, DR_SOCKET_1207, str2_NP_HE, sizeof (str2_NP_HE)}, + {4, 1, 0x06, DR_SOCKET_1207, str2_KH_HE, sizeof (str2_KH_HE)}, + {4, 1, 0x07, DR_SOCKET_1207, str2_KS_EE, sizeof (str2_KS_EE)}, + {6, 0, 0x00, DR_SOCKET_1207, str2_SE, sizeof (str2_SE)}, + {6, 0, 0x01, DR_SOCKET_1207, str2_HE, sizeof (str2_HE)}, + {6, 0, 0x02, DR_SOCKET_1207, str2_EE, sizeof (str2_EE)}, + {6, 0, 0x0F, DR_SOCKET_1207, 0, 0}, //Size 0 for no suffix + {6, 1, 0x01, DR_SOCKET_1207, str2_QS, sizeof (str2_QS)}, + {6, 1, 0x02, DR_SOCKET_1207, str2_KS_HE, sizeof (str2_KS_HE)}, +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString1ArrayFr1207 = { + (sizeof (CpuF10BrandIdString1ArrayFr1207) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString1ArrayFr1207 +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString2ArrayFr1207 = { + (sizeof (CpuF10BrandIdString2ArrayFr1207) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString2ArrayFr1207 +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdG34.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdG34.c new file mode 100755 index 0000000000..ed312a7461 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdG34.c @@ -0,0 +1,124 @@ +/** + * @file + * + * AMD CPU BrandId related functions and structures for socket G34. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6396 $ @e \$Date: 2008-06-16 05:52:20 -0700 (Mon, 16 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +// PRIVATE FORMAT FOR BRAND TABLE ... FOR AMD USE ONLY + +// String1 +CONST CHAR8 ROMDATA str_Opteron_61[] = "AMD Opteron(tm) Processor 61"; +CONST CHAR8 ROMDATA str_Embedded_Opteron_G34[] = "Embedded AMD Opteron(tm) Processor "; + +// String2 +CONST CHAR8 ROMDATA str2_SE_G34[] = " SE"; +CONST CHAR8 ROMDATA str2_HE_G34[] = " HE"; +CONST CHAR8 ROMDATA str2_QS_G34[] = "QS"; +CONST CHAR8 ROMDATA str2_KS_G34[] = "KS"; + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString1ArrayG34[] = +{ + // G34r1 string1: + {8, 0, 0x00, DR_SOCKET_G34, str_Opteron_61, sizeof (str_Opteron_61)}, + {8, 1, 0x01, DR_SOCKET_G34, str_Embedded_Opteron_G34, sizeof (str_Embedded_Opteron_G34)}, + {12, 0, 0x00, DR_SOCKET_G34, str_Opteron_61, sizeof (str_Opteron_61)} +}; //Cores, page, index, socket, stringstart, stringlength + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString2ArrayG34[] = +{ + // G34r1 string2: + {8, 0, 0x00, DR_SOCKET_G34, str2_HE_G34, sizeof (str2_HE_G34)}, + {8, 0, 0x01, DR_SOCKET_G34, str2_SE_G34, sizeof (str2_SE_G34)}, + {8, 1, 0x01, DR_SOCKET_G34, str2_QS_G34, sizeof (str2_QS_G34)}, + {8, 1, 0x02, DR_SOCKET_G34, str2_KS_G34, sizeof (str2_KS_G34)}, + {8, 0, 0x0F, DR_SOCKET_G34, 0, 0}, //Size 0 for no suffix + {12, 0, 0x00, DR_SOCKET_G34, str2_HE_G34, sizeof (str2_HE_G34)}, + {12, 0, 0x01, DR_SOCKET_G34, str2_SE_G34, sizeof (str2_SE_G34)}, + {12, 0, 0x0F, DR_SOCKET_G34, 0, 0} //Size 0 for no suffix +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString1ArrayG34 = { + (sizeof (CpuF10BrandIdString1ArrayG34) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString1ArrayG34 +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString2ArrayG34 = { + (sizeof (CpuF10BrandIdString2ArrayG34) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString2ArrayG34 +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdS1g3.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdS1g3.c new file mode 100755 index 0000000000..c98d369f2d --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdS1g3.c @@ -0,0 +1,125 @@ +/** + * @file + * + * AMD CPU BrandId related functions and structures for socket S1g3. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6396 $ @e \$Date: 2008-06-16 05:52:20 -0700 (Mon, 16 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +// PRIVATE FORMAT FOR BRAND TABLE ... FOR AMD USE ONLY + +// String1 +/*CHAR8 strEngSample[] = "AMD Engineering Sample"; +CHAR8 strTtkSample[] = "AMD Thermal Test Kit"; +CHAR8 strUnknown[] = "AMD Processor model unknown"; +*/ +// S1g3 NC 0 +CONST CHAR8 ROMDATA str_Sempron_M1[] = "AMD Sempron(tm) M1"; + +// S1g3 NC 1 +CONST CHAR8 ROMDATA str_Turion_II_U_DC_M_M6[] = "AMD Turion(tm) II Ultra Dual-Core Mobile M6"; +CONST CHAR8 ROMDATA str_Turion_II_DC_M_M5[] = "AMD Turion(tm) II Dual-Core Mobile M5"; +CONST CHAR8 ROMDATA str_Athlon_II_DC_M3[] = "AMD Athlon(tm) II Dual-Core M3"; + +// String2 + + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString1ArrayS1g3[] = +{ + // S1g3 + {1, 0, 0, DR_SOCKET_S1G3, str_Sempron_M1, sizeof (str_Sempron_M1)}, + {2, 0, 0, DR_SOCKET_S1G3, str_Turion_II_U_DC_M_M6, sizeof (str_Turion_II_U_DC_M_M6)}, + {2, 0, 1, DR_SOCKET_S1G3, str_Turion_II_DC_M_M5, sizeof (str_Turion_II_DC_M_M5)}, + {2, 0, 2, DR_SOCKET_S1G3, str_Athlon_II_DC_M3, sizeof (str_Athlon_II_DC_M3)} +}; //Cores, page, index, socket, stringstart, stringlength + + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString2ArrayS1g3[] = +{ + // S1g3 + {1, 0, 0x0F, DR_SOCKET_S1G3, 0, 0}, //Size 0 for no suffix + {2, 0, 0x0F, DR_SOCKET_S1G3, 0, 0} //Size 0 for no suffix +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString1ArrayS1g3 = { + (sizeof (CpuF10BrandIdString1ArrayS1g3) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString1ArrayS1g3 +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString2ArrayS1g3 = { + (sizeof (CpuF10BrandIdString2ArrayS1g3) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString2ArrayS1g3 +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdS1g4.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdS1g4.c new file mode 100755 index 0000000000..343cda9a55 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10BrandIdS1g4.c @@ -0,0 +1,138 @@ +/** + * @file + * + * AMD CPU BrandId related functions and structures for package S1g4. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6396 $ @e \$Date: 2008-06-16 05:52:20 -0700 (Mon, 16 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuEarlyInit.h" +#include "F10PackageType.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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +// String1 +CONST CHAR8 ROMDATA str_AMD_V_S1g4[] = "AMD V"; +CONST CHAR8 ROMDATA str_Turion_II_P[] = "AMD Turion(tm) II P"; +CONST CHAR8 ROMDATA str_Athlon_II_P[] = "AMD Athlon(tm) II P"; +CONST CHAR8 ROMDATA str_Phenom_II_X[] = "AMD Phenom(tm) II X"; +CONST CHAR8 ROMDATA str_Turion_II_N[] = "AMD Turion(tm) II N"; +CONST CHAR8 ROMDATA str_Athlon_II_N[] = "AMD Athlon(tm) II N"; +CONST CHAR8 ROMDATA str_Phenom_II_P[] = "AMD Phenom(tm) II P"; +CONST CHAR8 ROMDATA str_Phenom_II_N[] = "AMD Phenom(tm) II N"; + +// String2 +CONST CHAR8 ROMDATA str_0_Processor[] = "0 Processor"; +CONST CHAR8 ROMDATA str_0_Dual_Core_Processor[] = "0 Dual-Core Processor"; +CONST CHAR8 ROMDATA str_0_Triple_Core_Processor[] = "0 Triple-Core Processor"; +CONST CHAR8 ROMDATA str_0_Quad_Core_Processor[] = "0 Quad-Core Processor"; + +/*--------------------------------------------------------------------------------------- + * T Y P E D E F S, S T R U C T U R E S, E N U M S + *--------------------------------------------------------------------------------------- + */ + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString1ArrayS1g4[] = +{ + // S1g4 + {1, 0, 1, DR_SOCKET_S1G4, str_AMD_V_S1g4, sizeof (str_AMD_V_S1g4)}, + {2, 0, 3, DR_SOCKET_S1G4, str_Turion_II_P, sizeof (str_Turion_II_P)}, + {2, 0, 4, DR_SOCKET_S1G4, str_Athlon_II_P, sizeof (str_Athlon_II_P)}, + {2, 0, 5, DR_SOCKET_S1G4, str_Phenom_II_X, sizeof (str_Phenom_II_X)}, + {2, 0, 6, DR_SOCKET_S1G4, str_Phenom_II_N, sizeof (str_Phenom_II_N)}, + {2, 0, 7, DR_SOCKET_S1G4, str_Turion_II_N, sizeof (str_Turion_II_N)}, + {2, 0, 8, DR_SOCKET_S1G4, str_Athlon_II_N, sizeof (str_Athlon_II_N)}, + {3, 0, 2, DR_SOCKET_S1G4, str_Phenom_II_P, sizeof (str_Phenom_II_P)}, + {3, 0, 3, DR_SOCKET_S1G4, str_Phenom_II_N, sizeof (str_Phenom_II_N)}, + {4, 0, 1, DR_SOCKET_S1G4, str_Phenom_II_P, sizeof (str_Phenom_II_P)}, + {4, 0, 2, DR_SOCKET_S1G4, str_Phenom_II_X, sizeof (str_Phenom_II_X)}, + {4, 0, 3, DR_SOCKET_S1G4, str_Phenom_II_N, sizeof (str_Phenom_II_N)} +}; //Cores, page, index, socket, stringstart, stringlength + + +CONST AMD_CPU_BRAND ROMDATA CpuF10BrandIdString2ArrayS1g4[] = +{ + // S1g4 + {1, 0, 0x01, DR_SOCKET_S1G4, str_0_Processor, sizeof (str_0_Processor)}, + {2, 0, 0x02, DR_SOCKET_S1G4, str_0_Dual_Core_Processor, sizeof (str_0_Dual_Core_Processor)}, + {3, 0, 0x02, DR_SOCKET_S1G4, str_0_Triple_Core_Processor, sizeof (str_0_Triple_Core_Processor)}, + {4, 0, 0x01, DR_SOCKET_S1G4, str_0_Quad_Core_Processor, sizeof (str_0_Quad_Core_Processor)}, + {1, 0, 0x0F, DR_SOCKET_S1G4, 0, 0}, //Size 0 for no suffix + {2, 0, 0x0F, DR_SOCKET_S1G4, 0, 0}, //Size 0 for no suffix + {3, 0, 0x0F, DR_SOCKET_S1G4, 0, 0}, //Size 0 for no suffix + {4, 0, 0x0F, DR_SOCKET_S1G4, 0, 0} //Size 0 for no suffix +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString1ArrayS1g4 = { + (sizeof (CpuF10BrandIdString1ArrayS1g4) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString1ArrayS1g4 +}; + + +CONST CPU_BRAND_TABLE ROMDATA F10BrandIdString2ArrayS1g4 = { + (sizeof (CpuF10BrandIdString2ArrayS1g4) / sizeof (AMD_CPU_BRAND)), + CpuF10BrandIdString2ArrayS1g4 +}; + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10CacheDefaults.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10CacheDefaults.c new file mode 100755 index 0000000000..4f2296ce8f --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10CacheDefaults.c @@ -0,0 +1,124 @@ +/** + * @file + * + * AMD Family_10 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/0x10 + * @e \$Revision: 6163 $ @e \$Date: 2008-05-28 15:41:06 -0500 (Wed, 28 May 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuCacheInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10CACHEDEFAULTS_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 + *---------------------------------------------------------------------------------------- + */ +VOID +GetF10CacheInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **CacheInfoPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#define BSP_STACK_SIZE 16384 +#define CORE0_STACK_SIZE 16384 +#define CORE1_STACK_SIZE 4096 +#define MEM_TRAINING_BUFFER_SIZE 16384 +#define VAR_MTRR_MASK 0x0000FFFFFFFFFFFFull + +#define SHARED_MEM_SIZE 0 + +CONST CACHE_INFO ROMDATA CpuF10CacheInfo = +{ + BSP_STACK_SIZE, + CORE0_STACK_SIZE, + CORE1_STACK_SIZE, + MEM_TRAINING_BUFFER_SIZE, + SHARED_MEM_SIZE, + VAR_MTRR_MASK +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +GetF10CacheInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **CacheInfoPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = 1; + *CacheInfoPtr = &CpuF10CacheInfo; +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10CacheFlushOnHalt.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10CacheFlushOnHalt.c new file mode 100755 index 0000000000..1c638c7a8a --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10CacheFlushOnHalt.c @@ -0,0 +1,136 @@ +/** + * @file + * + * AMD CPU Cache Flush On Halt 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/Family/0x10 + * @e \$Revision: 6626 $ @e \$Date: 2008-07-04 02:01:02 +0800 (Fri, 04 Jul 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuPostInit.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10CACHEFLUSHONHALT_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 + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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,out] PciAddress Pointer to Pci address struct. + * @param[in,out] AndMask Pointer to AND mask bits. + * @param[in,out] OrMask Pointer to Or mask bits. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + */ +STATIC VOID +GetF10CacheFlushOnHaltRegister ( + IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, + IN OUT PCI_ADDR *PciAddress, + IN OUT UINT32 *AndMask, + IN OUT UINT32 *OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CoreCount; + CPU_LOGICAL_ID LogicalId; + + // + // F3xDC[25:19] = 28h + // F3xDC[18:16] = 111b + // + PciAddress->Address.Function = FUNC_3; + PciAddress->Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; + *AndMask = 0xFC00FFFF; + *OrMask = 0x01470000; + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + if ((LogicalId.Revision & AMD_F10_C2) != 0) { + // + //For F10_C2 single Core, F3xDC[18:16] = 0 + // + GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); + if (CoreCount == 1) { + *OrMask = 0x01400000; + } + } +} + +CONST CPU_CFOH_FAMILY_SERVICES ROMDATA F10CacheFlushOnHalt = +{ + 0, + GetF10CacheFlushOnHaltRegister +};
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Dmi.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Dmi.c new file mode 100755 index 0000000000..f72cb0fd1b --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Dmi.c @@ -0,0 +1,411 @@ +/** + * @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: 6049 $ @e \$Date: 2008-05-13 23:58:02 -0700 (Tue, 13 May 2008) $ + * + */ +/***************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuLateInit.h" +#include "cpuF10PowerMgmt.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10DMI_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 +F10Translate7BitVidTo6Bit ( + IN OUT UINT8 * MaxVidPtr + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF10GetInfo + * + * Get CPU type information + * + * @param[in,out] CpuInfoPtr Pointer to CPU_TYPE_INFO struct. + * @param[in, out] StdHeader Standard Head Pointer + * + */ +STATIC VOID +DmiF10GetInfo ( + 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 + CpuInfoPtr->BrandId.Pg = (UINT8) (CpuId.EBX_Reg >> 15) & 0x1; // bit 15 + CpuInfoPtr->BrandId.String1 = (UINT8) (CpuId.EBX_Reg >> 11) & 0xF; // bit 14:11 + CpuInfoPtr->BrandId.Model = (UINT8) (CpuId.EBX_Reg >> 4) & 0x7F; // bit 10:4 + CpuInfoPtr->BrandId.String2 = (UINT8) (CpuId.EBX_Reg & 0xF); // bit 3:0 + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + CpuInfoPtr->TotalCoreNumber = FamilySpecificServices->GetNumberOfCoresForBrandstring (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 DR_SOCKET_1207: + CpuInfoPtr->ProcUpgrade = P_UPGRADE_F1207; + break; + case DR_SOCKET_AM3: + CpuInfoPtr->ProcUpgrade = P_UPGRADE_AM3; + break; + case DR_SOCKET_S1G3: + CpuInfoPtr->ProcUpgrade = P_UPGRADE_S1GX; + break; + case DR_SOCKET_G34: + CpuInfoPtr->ProcUpgrade = P_UPGRADE_G34; + break; + case DR_SOCKET_ASB2: + CpuInfoPtr->ProcUpgrade = P_UPGRADE_NONE; + break; + case DR_SOCKET_C32: + CpuInfoPtr->ProcUpgrade = P_UPGRADE_C32; + break; + default: + CpuInfoPtr->ProcUpgrade = P_UPGRADE_UNKNOWN; + break; + } + +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF10GetVoltage + * + * Get the voltage value according to SMBIOS SPEC's requirement. + * + * @param[in, out] StdHeader Standard Head Pointer + * + * @retval Voltage - CPU Voltage. + * + */ +STATIC UINT8 +DmiF10GetVoltage ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxVid; + UINT8 Voltage; + UINT32 Pvimode; + UINT32 CurrentNodeNum; + UINT64 MsrData; + PCI_ADDR TempAddr; + + // Voltage = 0x80 + (voltage at boot time * 10) + GetCurrentNodeNum (&CurrentNodeNum, StdHeader); + TempAddr.AddressValue = MAKE_SBDFO (0, 0, (24 + CurrentNodeNum), FUNC_3, PW_CTL_MISC_REG); + LibAmdPciReadBits (TempAddr, 8, 8, &Pvimode, (VOID *)StdHeader); + //Pvimode is a 1-bit register field: 1-PVI 0-SVI + + LibAmdMsrRead (MSR_COFVID_STS, &MsrData, StdHeader); + MaxVid = (UINT8) (((COFVID_STS_MSR *)&MsrData)->MaxVid); + if (MaxVid == 0) { + LibAmdMsrRead (MSR_PSTATE_0, &MsrData, StdHeader); + MaxVid = (UINT8) (((PSTATE_MSR *)&MsrData)->CpuVid); + } + + if (Pvimode) { + // PVI mode + F10Translate7BitVidTo6Bit (&MaxVid); + if (MaxVid >= 0x20) { + Voltage = (UINT8) ((7625 - (125 * (MaxVid - 0x20)) + 500) / 1000); + } else { + Voltage = (UINT8) ((1550 - (25 * MaxVid) + 50) / 100); + } + } else { + // is SVI mode + if ((MaxVid >= 0x7C) && (MaxVid <= 0x7F)) { + Voltage = 0; + } else { + Voltage = (UINT8) ((15500 - (125 * MaxVid) + 500) / 1000); + } + } + + Voltage += 0x80; + return (Voltage); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * DmiF10GetMaxSpeed + * + * Get the Max Speed + * + * @param[in, out] StdHeader Standard Head Pointer + * + * @retval MaxSpeed - CPU Max Speed. + * + */ +STATIC UINT16 +DmiF10GetMaxSpeed ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 TempVar8_a; + UINT64 MsrData; + UINT16 MaxSpeed; + + // CPU COF = 100MHz * (CpuFid + 0x10) / (2 ^ CpuDid) + LibAmdMsrRead (MSR_PSTATE_0, &MsrData, StdHeader); + TempVar8_a = (UINT8) ((PSTATE_MSR *) &MsrData)->CpuDid; + switch (TempVar8_a) { + case 0: + TempVar8_a = 1; + break; + case 1: + TempVar8_a = 2; + break; + case 2: + TempVar8_a = 4; + break; + case 3: + TempVar8_a = 8; + break; + case 4: + TempVar8_a = 16; + break; + default: + TempVar8_a = 1; + break; + } + + MaxSpeed = (UINT16) (MsrData & 0x3F); // get CpuFid + MaxSpeed = (100 * (MaxSpeed + 0x10)) / TempVar8_a; + return (MaxSpeed); +} + + +/*--------------------------------------------------------------------------------------- + * Processor Family Table + * + * Note: 'x' means we don't care this field + * 002h = "Unknown" + * 038h = "AMD Turion(TM) II Ultra Dual-Core Mobile M Processor Family" + * 039h = "AMD Turion(TM) II Dual-Core Mobile M Processor Family" + * 03Ah = "AMD Athlon(TM) II Dual-Core M Processor Family" + * 083h = "AMD Athlon(tm) 64 Processor Family" + * 084h = "AMD Opteron(TM) Processor Family" + * 085h = "AMD Sempron(tm) Processor Family" + * 087h = "Dual-Core AMD Opteron Processor Family" + * 08Ah = "Quad-Core AMD Opteron Processor Family" + * 08Ch = "AMD Phenom FX Quad-Core Processor Family" + * 08Dh = "AMD Phenom X4 Quad-Core Processor Family" + * 08Eh = "AMD Phenom X2 Dual-Core Processor Family" + * 08Fh = "AMD Athlon X2 Dual-Core Processor Family" + * 0E6h = "Embedded AMD Opteron Processor Family" + * 0E7h = "AMD Phenom Triple-Core Processor Family" + * 0ECh = "AMD Phenom(TM) II Processor Family" + * 0EDh = "AMD Athlon(TM) II Processor Family" + * 0EEh = "Six-Core AMD Opteron(TM) Processor Family" + * 0EFh = "AMD Sempron(TM) M Processor Family" + *-------------------------------------------------------------------------------------*/ +CONST DMI_BRAND_ENTRY ROMDATA Family10BrandList[] = +{ + // Brand --> DMI ID translation table + // PackageType, PgOfBrandId, NumberOfCores, String1ofBrandId, ValueSetToDmiTable + // {'x', 'x', 'x', 'x', 0x02} MUST be the last one. + {0, 0, 1, 0, 0x87}, + {0, 0, 1, 1, 0x87}, + {0, 0, 2, 0, 0xE6}, + {0, 0, 3, 0, 0x8A}, + {0, 0, 3, 1, 0x8A}, + {0, 0, 3, 2, 0xE6}, + {0, 0, 3, 3, 0xE6}, + {0, 0, 3, 4, 0xE6}, + {0, 0, 3, 5, 0x8C}, + {0, 0, 5, 0, 0xEE}, + {0, 0, 5, 1, 0xEE}, + {0, 1, 3, 1, 0xE6}, + {1, 0, 0, 0, 0x83}, + {1, 0, 0, 1, 0x85}, + {1, 0, 0, 2, 0x85}, + {1, 0, 0, 3, 0xED}, + {1, 0, 1, 0, 0x87}, + {1, 0, 1, 1, 0x8F}, + {1, 0, 1, 2, 0xED}, + {1, 0, 1, 3, 0xED}, + {1, 0, 1, 4, 0xED}, + {1, 0, 1, 5, 0xED}, + {1, 0, 1, 6, 0xED}, + {1, 0, 1, 7, 0xEC}, + {1, 0, 1, 8, 0xED}, + {1, 0, 1, 9, 0xED}, + {1, 0, 1, 0xA, 0xEC}, + {1, 0, 1, 0xB, 0xEC}, + {1, 0, 2, 0, 0xE7}, + {1, 0, 2, 1, 0xEC}, + {1, 0, 2, 2, 0xEC}, + {1, 0, 2, 3, 0xEC}, + {1, 0, 2, 4, 0xEC}, + {1, 0, 2, 5, 0xED}, + {1, 0, 2, 6, 0xED}, + {1, 0, 2, 7, 0xED}, + {1, 0, 2, 8, 0xEC}, + {1, 0, 2, 9, 0xED}, + {1, 0, 2, 0xA, 0xED}, + {1, 0, 3, 0, 0x8A}, + {1, 0, 3, 1, 0x8C}, + {1, 0, 3, 2, 0x8D}, + {1, 0, 3, 3, 0xEC}, + {1, 0, 3, 4, 0xEC}, + {1, 0, 3, 5, 0xEC}, + {1, 0, 3, 6, 0xEC}, + {1, 0, 3, 7, 0xEC}, + {1, 0, 3, 8, 0xEC}, + {1, 0, 3, 9, 0xEC}, + {1, 0, 3, 0xA, 0xED}, + {1, 0, 3, 0xB, 0xED}, + {1, 0, 3, 0xC, 0xED}, + {1, 0, 3, 0xD, 0xED}, + {1, 0, 3, 0xE, 0xEC}, + {1, 0, 3, 0xF, 0xED}, + {1, 1, 1, 1, 0xED}, + {1, 1, 1, 2, 0xED}, + {1, 1, 3, 0, 0xEC}, + {1, 1, 3, 1, 0xEC}, + {2, 0, 0, 0, 0xEF}, + {2, 0, 0, 1, 0xEF}, + {2, 0, 1, 0, 0x38}, + {2, 0, 1, 1, 0x39}, + {2, 0, 1, 2, 0x3A}, + {2, 0, 1, 3, 0x39}, + {2, 0, 1, 4, 0xED}, + {2, 0, 1, 5, 0xEC}, + {2, 0, 1, 6, 0xEC}, + {2, 0, 1, 7, 0x39}, + {2, 0, 1, 8, 0xED}, + {2, 0, 2, 2, 0xEC}, + {2, 0, 2, 3, 0xEC}, + {2, 0, 3, 1, 0xEC}, + {2, 0, 3, 2, 0xEC}, + {2, 0, 3, 3, 0xEC}, + {3, 0, 7, 0, 0x84}, + {3, 0, 0xB, 0, 0x84}, + {4, 0, 0, 1, 0xED}, + {4, 0, 1, 1, 0x39}, + {4, 0, 1, 2, 0xED}, + {5, 'x', 'x', 'x', 0x84}, + {'x', 'x', 'x', 'x', 0x02} + }; + +CONST PROC_FAMILY_TABLE ROMDATA ProcFamily10DmiTable = +{ +// This table is for Processor family 10h + AMD_FAMILY_10, // ID for Family 10h + DmiF10GetInfo, // Transfer vectors for family + DmiF10GetVoltage, // specific routines (above) + DmiF10GetMaxSpeed, + (sizeof (Family10BrandList) / sizeof (Family10BrandList[0])), // Number of entries in following table + &Family10BrandList[0] +}; + + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * F10Translate7BitVidTo6Bit + * + * translate 7 bit VID to 6 bit VID + * + * @param[in] MaxVidPtr - Pointer to MaxVid. + */ +VOID +STATIC +F10Translate7BitVidTo6Bit ( + IN OUT UINT8 * MaxVidPtr + ) +{ + if ((*MaxVidPtr >= 0x5E) && (*MaxVidPtr <= 0x7F)) { + *MaxVidPtr = 0x3F; + } else if ((*MaxVidPtr >= 0x3F) && (*MaxVidPtr <= 0x5D)) { + *MaxVidPtr = *MaxVidPtr - 0x1F; + } else if (*MaxVidPtr <= 0x3E) { + *MaxVidPtr = (*MaxVidPtr & 0x7E) >> 1; + } +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10EarlyInit.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10EarlyInit.c new file mode 100755 index 0000000000..d5c98aa59d --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10EarlyInit.c @@ -0,0 +1,403 @@ +/** + * @file + * + * AMD Family_10 after warm reset sequence + * + * Performs the "CPU 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/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuF10PowerMgmt.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "cpuF10Utilities.h" +#include "cpuF10EarlyInit.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10EARLYINIT_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 + *---------------------------------------------------------------------------------------- + */ +/// Enum for handling code branching while transitioning to the +/// minimum P-state after a warm reset +typedef enum { + EXIT_SEQUENCE, ///< Exit the sequence + STEP7, ///< Go to step 7 + STEP17, ///< Go to step 17 + STEP20 ///< Go to step 20 +} GO_TO_STEP; + +/*---------------------------------------------------------------------------------------- + * 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 +F10PmAfterResetCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +WaitForCpuFidAndDidToMatch ( + IN UINT32 PstateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family 10h core 0 entry point for performing the necessary steps after + * a warm reset has occurred. + * + * The steps are as follows: + * 1. Modify F3xDC[PstateMaxVal] to reflect the lowest performance P-state + * supported, as indicated in MSRC001_00[68:64][PstateEn] + * 2. If MSRC001_0071[CurNbDid] = 0, set MSRC001_001F[GfxNbPstateDis] + * 3. If MSRC001_0071[CurPstate] != F3xDC[PstateMaxVal], go to step 20 + * 4. If F3xDC[PstateMaxVal] = 0 or F3xDC[PstateMaxVal] != 4, go to step 7 + * 5. If MSRC001_0061[CurPstateLimit] <= F3xDC[PstateMaxVal]-1, go to step 17 + * 6. Exit the sequence + * 7. Copy the P-state register pointed to by F3xDC[PstateMaxVal] to the P-state + * register pointed to by F3xDC[PstateMaxVal]+1 + * 8. Write F3xDC[PstateMaxVal]+1 to F3xDC[PstateMaxVal] + * 9. Write (the new) F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] + * 10. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state + * register pointed to by (the new) F3xDC[PstateMaxVal] + * 11. Copy (the new) F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd] + * 12. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state + * register pointed to by (the new) F3xDC[PstateMaxVal]-1 + * 13. If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis] + * 14. If required, transition the NB COF and VID to the NbDid and NbVid from the + * P-state register pointed to by MSRC001_0061[CurPstateLimit] using the NB COF + * and VID transition sequence after a warm reset + * 15. Write MSRC001_00[68:64][PstateEn]=0 for the P-state pointed to by F3xDC[PstateMaxVal] + * 16. Write (the new) F3xDC[PstateMaxVal]-1 to F3xDC[PstateMaxVal] and exit the sequence + * 17. Copy F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd] + * 18. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state + * register pointed to by F3xDC[PstateMaxVal]-1 + * 19. If MSRC001_0071[CurNbDid] = 0, set MSRC001_001F[GfxNbPstateDis] + * 20. Copy F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] + * 21. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state + * register pointed to by F3xDC[PstateMaxVal] + * 22. If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis] + * 23. Issue an LDTSTOP assertion in the IO hub and exit sequence + * 24. If required, transition the NB COF and VID to the NbDid and NbVid from the + * P-state register pointed to by F3xDC[PstateMaxVal] using the NB COF and VID + * transition sequence after a warm reset + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParamsPtr Service parameters + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F10PmAfterReset ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 PsMaxVal; + UINT32 CoreNum; + UINT32 MsrAddr; + UINT32 Core; + UINT32 AndMask; + UINT32 OrMask; + UINT64 MsrRegister; + PCI_ADDR PciAddress; + AP_TASK TaskPtr; + AGESA_STATUS IgnoredSts; + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + GetActiveCoresInCurrentSocket (&CoreNum, StdHeader); + + ASSERT (Core == 0); + + // Step 1 Modify F3xDC[PstateMaxVal] to reflect the lowest performance + // P-state supported, as indicated in MSRC001_00[68:64][PstateEn] + for (MsrAddr = PS_MAX_REG; MsrAddr > PS_REG_BASE; --MsrAddr) { + LibAmdMsrRead (MsrAddr, &MsrRegister, StdHeader); + if (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1) { + break; + } + } + PsMaxVal = MsrAddr - PS_REG_BASE; + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = CPTC2_REG; + AndMask = 0xFFFFFFFF; + OrMask = 0x00000000; + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->PstateMaxVal = 0; + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->PstateMaxVal = PsMaxVal; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); + + // Launch each local core to perform the remaining steps. + TaskPtr.FuncAddress.PfApTask = F10PmAfterResetCore; + TaskPtr.DataTransfer.DataSizeInDwords = 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 F10PmAfterReset to perform MSR initialization on all + * cores of a family 10h socket. + * + * This function implements steps 2 - 24 on each core. + * + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F10PmAfterResetCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 Ignored; + UINT32 PsMaxVal; + UINT32 PciRegister; + UINT64 MsrRegister; + UINT64 CurrentLimitMsr; + PCI_ADDR PciAddress; + GO_TO_STEP GoToStep; + AGESA_STATUS IgnoredSts; + CPU_LOGICAL_ID LogicalId; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + // Step 2 If MSR C001_0071[CurNbDid] = 0, set MSR C001_001F[GfxNbPstateDis] + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + GetCpuServicesFromLogicalId (&LogicalId, &FamilySpecificServices, StdHeader); + if ((LogicalId.Revision & (AMD_F10_C3 | AMD_F10_DA_C2)) != 0) { + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + if (((COFVID_STS_MSR *) &MsrRegister)->CurNbDid == 0) { + LibAmdMsrRead (NB_CFG, &MsrRegister, StdHeader); + MsrRegister |= BIT62; + LibAmdMsrWrite (NB_CFG, &MsrRegister, StdHeader); + } + } + + GoToStep = EXIT_SEQUENCE; + + LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &CurrentLimitMsr, StdHeader); + PsMaxVal = (UINT32) (((PSTATE_CURLIM_MSR *) &CurrentLimitMsr)->PstateMaxVal); + + // Step 3 If MSRC001_0071[CurPstate] != F3xDC[PstateMaxVal], go to step 20 + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + if (((COFVID_STS_MSR *) &MsrRegister)->CurPstate != + ((PSTATE_CURLIM_MSR *) &CurrentLimitMsr)->PstateMaxVal) { + GoToStep = STEP20; + } else { + // Step 4 If F3xDC[PstateMaxVal] = 0 || F3xDC[PstateMaxVal] != 4, go to step 7 + if ((PsMaxVal == 0) || (PsMaxVal != 4)) { + GoToStep = STEP7; + } else { + // Step 5 If MSRC001_0061[CurPstateLimit] <= F3xDC[PstateMaxVal]-1, go to step 17 + if (((PSTATE_CURLIM_MSR *) &CurrentLimitMsr)->CurPstateLimit <= + (((PSTATE_CURLIM_MSR *) &CurrentLimitMsr)->PstateMaxVal - 1)) { + GoToStep = STEP17; + } + } + } + switch (GoToStep) { + default: + case EXIT_SEQUENCE: + // Step 6 Exit the sequence + break; + case STEP7: + // Step 7 Copy the P-state register pointed to by F3xDC[PstateMaxVal] to the P-state + // register pointed to by F3xDC[PstateMaxVal]+1 + LibAmdMsrRead ((MSR_PSTATE_0 + PsMaxVal), &MsrRegister, StdHeader); + LibAmdMsrWrite ((MSR_PSTATE_0 + (PsMaxVal + 1)), &MsrRegister, StdHeader); + + // Step 8 Write F3xDC[PstateMaxVal]+1 to F3xDC[PstateMaxVal] + IdentifyCore (StdHeader, &Socket, &Module, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = CPTC2_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal = PsMaxVal + 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + + // Step 9 Write (the new) F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) (PsMaxVal + 1), (BOOLEAN) FALSE, StdHeader); + + // Step 10 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state + // register pointed to by (the new) F3xDC[PstateMaxVal] + WaitForCpuFidAndDidToMatch ((UINT32) (PsMaxVal + 1), StdHeader); + + // Step 11 Copy (the new) F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd] + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) PsMaxVal, (BOOLEAN) FALSE, StdHeader); + + // Step 12 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state + // register pointed to by (the new) F3xDC[PstateMaxVal]-1 + WaitForCpuFidAndDidToMatch (PsMaxVal, StdHeader); + + // Step 13 If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis] + if ((LogicalId.Revision & (AMD_F10_C3 | AMD_F10_DA_C2)) != 0) { + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + if (((COFVID_STS_MSR *) &MsrRegister)->CurNbDid == 1) { + LibAmdMsrRead (NB_CFG, &MsrRegister, StdHeader); + MsrRegister |= BIT62; + LibAmdMsrWrite (NB_CFG, &MsrRegister, StdHeader); + } + } + + // Step 14 If required, transition the NB COF and VID to the NbDid and NbVid from the + // P-state register pointed to by MSRC001_0061[CurPstateLimit] using the NB COF + // and VID transition sequence after a warm reset + + // Step 15 Write 0 to PstateEn of the P-state register pointed to by (the new) F3xDC[PstateMaxVal] + LibAmdMsrRead ((MSR_PSTATE_0 + (PsMaxVal + 1)), &MsrRegister, StdHeader); + ((PSTATE_MSR *) &MsrRegister)->PsEnable = 0; + LibAmdMsrWrite ((MSR_PSTATE_0 + (PsMaxVal + 1)), &MsrRegister, StdHeader); + + // Step 16 Write (the new) F3xDC[PstateMaxVal]-1 to F3xDC[PstateMaxVal] + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal = PsMaxVal; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + break; + case STEP17: + // Step 17 Copy F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd] + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) (PsMaxVal - 1), (BOOLEAN) FALSE, StdHeader); + + // Step 18 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state + // register pointed to by F3xDC[PstateMaxVal]-1 + WaitForCpuFidAndDidToMatch ((UINT32) (PsMaxVal - 1), StdHeader); + + // Step 19 If MSR C001_0071[CurNbDid] = 0, set MSR C001_001F[GfxNbPstateDis] + if ((LogicalId.Revision & (AMD_F10_C3 | AMD_F10_DA_C2)) != 0) { + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + if (((COFVID_STS_MSR *) &MsrRegister)->CurNbDid == 0) { + LibAmdMsrRead (NB_CFG, &MsrRegister, StdHeader); + MsrRegister |= BIT62; + LibAmdMsrWrite (NB_CFG, &MsrRegister, StdHeader); + } + } + + // Fall through from step 19 to step 20 + case STEP20: + // Step 20 Copy F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) PsMaxVal, (BOOLEAN) FALSE, StdHeader); + + // Step 21 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state + // register pointed to by F3xDC[PstateMaxVal] + WaitForCpuFidAndDidToMatch (PsMaxVal, StdHeader); + + // Step 22 If MSR C001_0071[CurNbDid] = 1, set MSR C001_001F[GfxNbPstateDis] and exit + // the sequence + if ((LogicalId.Revision & (AMD_F10_C3 | AMD_F10_DA_C2)) != 0) { + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + if (((COFVID_STS_MSR *) &MsrRegister)->CurNbDid == 1) { + LibAmdMsrRead (NB_CFG, &MsrRegister, StdHeader); + MsrRegister |= BIT62; + LibAmdMsrWrite (NB_CFG, &MsrRegister, StdHeader); + break; + } + } + + // Step 23 Issue an LDTSTOP and exit the sequence + + // Step 24 If required, transition the NB COF and VID to the NbDid and NbVid from the + // P-state register pointed to by F3xDC[PstateMaxVal] using the NB COF and VID + // transition sequence after a warm reset + break; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F10PmAfterResetCore to wait for Cpu FID and DID to + * match a specific P-state. + * + * This function implements steps 11, 13, 18, and 20 on each core as needed. + * + * @param[in] PstateNumber P-state settings to match + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +WaitForCpuFidAndDidToMatch ( + IN UINT32 PstateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 TargetPsMsr; + UINT64 CurrentStatus; + + // Get target P-state settings + LibAmdMsrRead ((MSR_PSTATE_0 + PstateNumber), &TargetPsMsr, StdHeader); + + // Wait for current CPU FID/DID to match target FID/DID + do { + LibAmdMsrRead (MSR_COFVID_STS, &CurrentStatus, StdHeader); + } while ((((COFVID_STS_MSR *) &CurrentStatus)->CurCpuFid != ((PSTATE_MSR *) &TargetPsMsr)->CpuFid) || + (((COFVID_STS_MSR *) &CurrentStatus)->CurCpuDid != ((PSTATE_MSR *) &TargetPsMsr)->CpuDid)); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10EarlyInit.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10EarlyInit.h new file mode 100755 index 0000000000..a55a4832b7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10EarlyInit.h @@ -0,0 +1,78 @@ +/** + * @file + * + * AMD Family_10 Early Init related functions Prototypes. + * + * Contains code that provide power management functionality + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_F10_EARLY_INIT_H_ +#define _CPU_F10_EARLY_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 + *--------------------------------------------------------------------------------------- + */ +VOID +F10PmAfterReset ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F10_EARLY_INIT_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10FeatureLeveling.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10FeatureLeveling.c new file mode 100755 index 0000000000..12a2e88977 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10FeatureLeveling.c @@ -0,0 +1,389 @@ +/** + * @file + * + * AMD Family_10 specific feature leveling functions. + * + * Provides feature leveling functions specific to family 10h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6626 $ @e \$Date: 2008-07-04 02:01:02 +0800 (Fri, 04 Jul 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuRegisters.h" +#include "cpuPostInit.h" +#include "cpuF10FeatureLeveling.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10FEATURELEVELING_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 + *---------------------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +cpuFeatureListNeedUpdate ( + IN CPU_FEATURES_LIST *globalCpuFeatureList, + IN CPU_FEATURES_LIST *thisCoreCpuFeatureList + ); + +VOID +STATIC +updateCpuFeatureList ( + IN CPU_FEATURES_LIST *globalCpuFeatureList, + IN CPU_FEATURES_LIST *thisCoreCpuFeatureList + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function get features which CPU supports. + * + * @CpuServiceMethod{::F_CPU_SAVE_FEATURES}. + * + * Read features from MSR_C0011004 and MSR_C0011005. + * + * @param[in] FamilySpecificServices - Pointer to CPU_SPECIFIC_SERVICES struct. + * @param[in,out] cpuFeatureList - Pointer to CPU_FEATURES_LIST struct. + * @param[in] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + */ +VOID +F10SaveFeatures ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT CPU_FEATURES_LIST *cpuFeatureList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 CpuMsrData; + BOOLEAN *FirstTime; + BOOLEAN *NeedLeveling; + CPU_F10_FEATURES *CpuF10Features; + CPU_F10_EXT_FEATURES *CpuF10ExtFeatures; + CPU_FEATURES_LIST thisCoreCpuFeatureList; + + FirstTime = (BOOLEAN *) ((UINT8 *) cpuFeatureList + sizeof (CPU_FEATURES_LIST)); + NeedLeveling = (BOOLEAN *) ((UINT8 *) cpuFeatureList + sizeof (CPU_FEATURES_LIST) + sizeof (BOOLEAN)); + + LibAmdMemFill (&thisCoreCpuFeatureList, 0x0, sizeof (CPU_FEATURES_LIST), StdHeader); + LibAmdMsrRead (MSR_CPUID_FEATS, &CpuMsrData, StdHeader); + CpuF10Features = (CPU_F10_FEATURES *) &CpuMsrData; + + thisCoreCpuFeatureList.APIC = (UINT8) CpuF10Features->CpuF10FeaturesLo.APIC; + thisCoreCpuFeatureList.CLFSH = (UINT8) CpuF10Features->CpuF10FeaturesLo.CLFSH; + thisCoreCpuFeatureList.CMOV = (UINT8) CpuF10Features->CpuF10FeaturesLo.CMOV; + thisCoreCpuFeatureList.CMPXCHG8B = (UINT8) CpuF10Features->CpuF10FeaturesLo.CMPXCHG8B; + thisCoreCpuFeatureList.DE = (UINT8) CpuF10Features->CpuF10FeaturesLo.DE; + thisCoreCpuFeatureList.FPU = (UINT8) CpuF10Features->CpuF10FeaturesLo.FPU; + thisCoreCpuFeatureList.FXSR = (UINT8) CpuF10Features->CpuF10FeaturesLo.FXSR; + thisCoreCpuFeatureList.HTT = (UINT8) CpuF10Features->CpuF10FeaturesLo.HTT; + thisCoreCpuFeatureList.MCA = (UINT8) CpuF10Features->CpuF10FeaturesLo.MCA; + thisCoreCpuFeatureList.MCE = (UINT8) CpuF10Features->CpuF10FeaturesLo.MCE; + thisCoreCpuFeatureList.MMX = (UINT8) CpuF10Features->CpuF10FeaturesLo.MMX; + thisCoreCpuFeatureList.MSR = (UINT8) CpuF10Features->CpuF10FeaturesLo.MSR; + thisCoreCpuFeatureList.MTRR = (UINT8) CpuF10Features->CpuF10FeaturesLo.MTRR; + thisCoreCpuFeatureList.PAE = (UINT8) CpuF10Features->CpuF10FeaturesLo.PAE; + thisCoreCpuFeatureList.PAT = (UINT8) CpuF10Features->CpuF10FeaturesLo.PAT; + thisCoreCpuFeatureList.PGE = (UINT8) CpuF10Features->CpuF10FeaturesLo.PGE; + thisCoreCpuFeatureList.PSE = (UINT8) CpuF10Features->CpuF10FeaturesLo.PSE; + thisCoreCpuFeatureList.PSE36 = (UINT8) CpuF10Features->CpuF10FeaturesLo.PSE36; + thisCoreCpuFeatureList.SSE = (UINT8) CpuF10Features->CpuF10FeaturesLo.SSE; + thisCoreCpuFeatureList.SSE2 = (UINT8) CpuF10Features->CpuF10FeaturesLo.SSE2; + thisCoreCpuFeatureList.SysEnterSysExit = (UINT8) CpuF10Features->CpuF10FeaturesLo.SysEnterSysExit; + thisCoreCpuFeatureList.TimeStampCounter = (UINT8) CpuF10Features->CpuF10FeaturesLo.TimeStampCounter; + thisCoreCpuFeatureList.VME = (UINT8) CpuF10Features->CpuF10FeaturesLo.VME; + + thisCoreCpuFeatureList.CMPXCHG16B = (UINT8) CpuF10Features->CpuF10FeaturesHi.CMPXCHG16B; + thisCoreCpuFeatureList.Monitor = (UINT8) CpuF10Features->CpuF10FeaturesHi.Monitor; + thisCoreCpuFeatureList.POPCNT = (UINT8) CpuF10Features->CpuF10FeaturesHi.POPCNT; + thisCoreCpuFeatureList.SSE3 = (UINT8) CpuF10Features->CpuF10FeaturesHi.SSE3; + + LibAmdMsrRead (MSR_CPUID_EXT_FEATS, &CpuMsrData, StdHeader); + CpuF10ExtFeatures = (CPU_F10_EXT_FEATURES *) &CpuMsrData; + + thisCoreCpuFeatureList.ThreeDNow = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.ThreeDNow; + thisCoreCpuFeatureList.ThreeDNowExt = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.ThreeDNowExt; + thisCoreCpuFeatureList.APIC = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.APIC; + thisCoreCpuFeatureList.CMOV = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.CMOV; + thisCoreCpuFeatureList.CMPXCHG8B = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.CMPXCHG8B; + thisCoreCpuFeatureList.DE = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.DE; + thisCoreCpuFeatureList.FFXSR = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.FFXSR; + thisCoreCpuFeatureList.FPU = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.FPU; + thisCoreCpuFeatureList.FXSR = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.FXSR; + thisCoreCpuFeatureList.LM = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.LM; + thisCoreCpuFeatureList.MCA = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MCA; + thisCoreCpuFeatureList.MCE = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MCE; + thisCoreCpuFeatureList.MMX = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MMX; + thisCoreCpuFeatureList.MmxExt = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MmxExt; + thisCoreCpuFeatureList.MSR = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MSR; + thisCoreCpuFeatureList.MTRR = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MTRR; + thisCoreCpuFeatureList.NX = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.NX; + thisCoreCpuFeatureList.PAE = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PAE; + thisCoreCpuFeatureList.Page1GB = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.Page1GB; + thisCoreCpuFeatureList.PAT = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PAT; + thisCoreCpuFeatureList.PGE = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PGE; + thisCoreCpuFeatureList.PSE = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PSE; + thisCoreCpuFeatureList.PSE36 = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PSE36; + thisCoreCpuFeatureList.RDTSCP = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.RDTSCP; + thisCoreCpuFeatureList.SysCallSysRet = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.SysCallSysRet; + thisCoreCpuFeatureList.TimeStampCounter = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.TimeStampCounter; + thisCoreCpuFeatureList.VME = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesLo.VME; + + thisCoreCpuFeatureList.ThreeDNowPrefetch = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.ThreeDNowPrefetch; + thisCoreCpuFeatureList.ABM = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.ABM; + thisCoreCpuFeatureList.AltMovCr8 = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.AltMovCr8; + thisCoreCpuFeatureList.CmpLegacy = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.CmpLegacy; + thisCoreCpuFeatureList.ExtApicSpace = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.ExtApicSpace; + thisCoreCpuFeatureList.IBS = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.IBS; + thisCoreCpuFeatureList.LahfSahf = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.LahfSahf; + thisCoreCpuFeatureList.MisAlignSse = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.MisAlignSse; + thisCoreCpuFeatureList.OSVW = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.OSVM; + thisCoreCpuFeatureList.SKINIT = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.SKINIT; + thisCoreCpuFeatureList.SSE4A = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.SSE4A; + thisCoreCpuFeatureList.SVM = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.SVM; + thisCoreCpuFeatureList.WDT = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.WDT; + thisCoreCpuFeatureList.NodeId = (UINT8) CpuF10ExtFeatures->CpuF10ExtFeaturesHi.NodeId; + + if (*FirstTime) { + updateCpuFeatureList (cpuFeatureList, &thisCoreCpuFeatureList); + *FirstTime = FALSE; + } else if (cpuFeatureListNeedUpdate (cpuFeatureList, &thisCoreCpuFeatureList)) { + updateCpuFeatureList (cpuFeatureList, &thisCoreCpuFeatureList); + *NeedLeveling = TRUE; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function set features which All CPUs support. + * + * @CpuServiceMethod{::F_CPU_WRITE_FEATURES}. + * + * Write least common features to MSR_C0011004 and MSR_C0011005. + * + * @param[in] FamilySpecificServices - Pointer to CPU_SPECIFIC_SERVICES struct. + * @param[in,out] cpuFeatureList - Pointer to CPU_FEATURES_LIST struct. + * @param[in] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. + * + */ +VOID +F10WriteFeatures ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT CPU_FEATURES_LIST *cpuFeatureList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 CpuMsrData; + CPU_F10_FEATURES *CpuF10Features; + CPU_F10_EXT_FEATURES *CpuF10ExtFeatures; + + CpuMsrData = 0; + CpuF10Features = (CPU_F10_FEATURES *) &CpuMsrData; + + CpuF10Features->CpuF10FeaturesLo.APIC = cpuFeatureList->APIC; + CpuF10Features->CpuF10FeaturesLo.CLFSH = cpuFeatureList->CLFSH; + CpuF10Features->CpuF10FeaturesLo.CMOV = cpuFeatureList->CMOV; + CpuF10Features->CpuF10FeaturesLo.CMPXCHG8B = cpuFeatureList->CMPXCHG8B; + CpuF10Features->CpuF10FeaturesLo.DE = cpuFeatureList->DE; + CpuF10Features->CpuF10FeaturesLo.FPU = cpuFeatureList->FPU; + CpuF10Features->CpuF10FeaturesLo.FXSR = cpuFeatureList->FXSR; + CpuF10Features->CpuF10FeaturesLo.HTT = cpuFeatureList->HTT; + CpuF10Features->CpuF10FeaturesLo.MCA = cpuFeatureList->MCA; + CpuF10Features->CpuF10FeaturesLo.MCE = cpuFeatureList->MCE; + CpuF10Features->CpuF10FeaturesLo.MMX = cpuFeatureList->MMX; + CpuF10Features->CpuF10FeaturesLo.MSR = cpuFeatureList->MSR; + CpuF10Features->CpuF10FeaturesLo.MTRR = cpuFeatureList->MTRR; + CpuF10Features->CpuF10FeaturesLo.PAE = cpuFeatureList->PAE; + CpuF10Features->CpuF10FeaturesLo.PAT = cpuFeatureList->PAT; + CpuF10Features->CpuF10FeaturesLo.PGE = cpuFeatureList->PGE; + CpuF10Features->CpuF10FeaturesLo.PSE = cpuFeatureList->PSE; + CpuF10Features->CpuF10FeaturesLo.PSE36 = cpuFeatureList->PSE36; + CpuF10Features->CpuF10FeaturesLo.SSE = cpuFeatureList->SSE; + CpuF10Features->CpuF10FeaturesLo.SSE2 = cpuFeatureList->SSE2; + CpuF10Features->CpuF10FeaturesLo.SysEnterSysExit = cpuFeatureList->SysEnterSysExit; + CpuF10Features->CpuF10FeaturesLo.TimeStampCounter = cpuFeatureList->TimeStampCounter; + CpuF10Features->CpuF10FeaturesLo.VME = cpuFeatureList->VME; + + CpuF10Features->CpuF10FeaturesHi.CMPXCHG16B = cpuFeatureList->CMPXCHG16B; + CpuF10Features->CpuF10FeaturesHi.Monitor = cpuFeatureList->Monitor; + CpuF10Features->CpuF10FeaturesHi.POPCNT = cpuFeatureList->POPCNT; + CpuF10Features->CpuF10FeaturesHi.SSE3 = cpuFeatureList->SSE3; + + LibAmdMsrWrite (MSR_CPUID_FEATS, &CpuMsrData, StdHeader); + + CpuMsrData = 0; + CpuF10ExtFeatures = (CPU_F10_EXT_FEATURES *) &CpuMsrData; + + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.ThreeDNow = cpuFeatureList->ThreeDNow; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.ThreeDNowExt = cpuFeatureList->ThreeDNowExt; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.APIC = cpuFeatureList->APIC; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.CMOV = cpuFeatureList->CMOV; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.CMPXCHG8B = cpuFeatureList->CMPXCHG8B; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.DE = cpuFeatureList->DE; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.FFXSR = cpuFeatureList->FFXSR; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.FPU = cpuFeatureList->FPU; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.FXSR = cpuFeatureList->FXSR; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.LM = cpuFeatureList->LM; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MCA = cpuFeatureList->MCA; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MCE = cpuFeatureList->MCE; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MMX = cpuFeatureList->MMX; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MmxExt = cpuFeatureList->MmxExt; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MSR = cpuFeatureList->MSR; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.MTRR = cpuFeatureList->MTRR; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.NX = cpuFeatureList->NX; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PAE = cpuFeatureList->PAE; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.Page1GB = cpuFeatureList->Page1GB; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PAT = cpuFeatureList->PAT; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PGE = cpuFeatureList->PGE; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PSE = cpuFeatureList->PSE; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.PSE36 = cpuFeatureList->PSE36; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.RDTSCP = cpuFeatureList->RDTSCP; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.SysCallSysRet = cpuFeatureList->SysCallSysRet; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.TimeStampCounter = cpuFeatureList->TimeStampCounter; + CpuF10ExtFeatures->CpuF10ExtFeaturesLo.VME = cpuFeatureList->VME; + + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.ThreeDNowPrefetch = cpuFeatureList->ThreeDNowPrefetch; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.ABM = cpuFeatureList->ABM; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.AltMovCr8 = cpuFeatureList->AltMovCr8; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.CmpLegacy = cpuFeatureList->CmpLegacy; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.ExtApicSpace = cpuFeatureList->ExtApicSpace; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.IBS = cpuFeatureList->IBS; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.LahfSahf = cpuFeatureList->LahfSahf; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.MisAlignSse = cpuFeatureList->MisAlignSse; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.OSVM = cpuFeatureList->OSVW; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.SKINIT = cpuFeatureList->SKINIT; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.SSE4A = cpuFeatureList->SSE4A; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.SVM = cpuFeatureList->SVM; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.WDT = cpuFeatureList->WDT; + CpuF10ExtFeatures->CpuF10ExtFeaturesHi.NodeId = cpuFeatureList->NodeId; + LibAmdMsrWrite (MSR_CPUID_EXT_FEATS, &CpuMsrData, StdHeader); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * cpuFeatureListNeedUpdate + * + * Compare global CPU feature list with this core feature list to see if global CPU feature list + * needs updated. + * + * @param[in] globalCpuFeatureList - Pointer to global CPU Feature List. + * @param[in] thisCoreCpuFeatureList - Pointer to this core CPU Feature List. + * + * @retval FALSE globalCpuFeatureList is equal to thisCoreCpuFeatureList + * @retval True globalCpuFeatureList is NOT equal to thisCoreCpuFeatureList + */ +BOOLEAN +STATIC +cpuFeatureListNeedUpdate ( + IN CPU_FEATURES_LIST *globalCpuFeatureList, + IN CPU_FEATURES_LIST *thisCoreCpuFeatureList + ) +{ + BOOLEAN flag; + UINT8 *global; + UINT8 *thisCore; + UINT8 i; + + flag = FALSE; + global = (UINT8 *) globalCpuFeatureList; + thisCore = (UINT8 *) thisCoreCpuFeatureList; + + for (i = 0; i < sizeof (CPU_FEATURES_LIST); i++) { + if ((*global) != (*thisCore)) { + flag = TRUE; + break; + } + global++; + thisCore++; + } + return flag; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * updateCpuFeatureList + * + * Update global CPU feature list + * + * @param[in] globalCpuFeatureList - Pointer to global CPU Feature List. + * @param[in] thisCoreCpuFeatureList - Pointer to this core CPU Feature List. + * + */ +VOID +STATIC +updateCpuFeatureList ( + IN CPU_FEATURES_LIST *globalCpuFeatureList, + IN CPU_FEATURES_LIST *thisCoreCpuFeatureList + ) +{ + UINT8 *globalFeatureList; + UINT8 *thisCoreFeatureList; + UINT32 sizeInByte; + + globalFeatureList = (UINT8 *) globalCpuFeatureList; + thisCoreFeatureList = (UINT8 *) thisCoreCpuFeatureList; + + for (sizeInByte = 0; sizeInByte < sizeof (CPU_FEATURES_LIST); sizeInByte++) { + *globalFeatureList &= *thisCoreFeatureList; + globalFeatureList++; + thisCoreFeatureList++; + } +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10FeatureLeveling.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10FeatureLeveling.h new file mode 100755 index 0000000000..6d27821b8d --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10FeatureLeveling.h @@ -0,0 +1,194 @@ +/** + * @file + * + * AMD Family_10 specific feature leveling functions. + * + * Provides feature leveling functions specific to family 10h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x10 + * @e \$Revision: 6626 $ @e \$Date: 2008-07-04 02:01:02 +0800 (Fri, 04 Jul 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_F10_FEATURE_LEVELING_H_ +#define _CPU_F10_FEATURE_LEVELING_H_ + +#include "cpuFamilyTranslation.h" +#include "cpuPostInit.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 + *--------------------------------------------------------------------------------------- + */ +/// F10 CPU Feature Low +typedef struct { + UINT32 FPU:1; ///< Bit0 + UINT32 VME:1; ///< Bit1 + UINT32 DE:1; ///< Bit2 + UINT32 PSE:1; ///< Bit3 + UINT32 TimeStampCounter:1; ///< Bit4 + UINT32 MSR:1; ///< Bit5 + UINT32 PAE:1; ///< Bit6 + UINT32 MCE:1; ///< Bit7 + UINT32 CMPXCHG8B:1; ///< Bit8 + UINT32 APIC:1; ///< Bit9 + UINT32 Reserved1:1; ///< Bit10 + UINT32 SysEnterSysExit:1; ///< Bit11 + UINT32 MTRR:1; ///< Bit12 + UINT32 PGE:1; ///< Bit13 + UINT32 MCA:1; ///< Bit14 + UINT32 CMOV:1; ///< Bit15 + UINT32 PAT:1; ///< Bit16 + UINT32 PSE36:1; ///< Bit17 + UINT32 Reserved2:1; ///< Bit18 + UINT32 CLFSH:1; ///< Bit19 + UINT32 Reserved3:3; ///< Bit20~22 + UINT32 MMX:1; ///< Bit23 + UINT32 FXSR:1; ///< Bit24 + UINT32 SSE:1; ///< Bit25 + UINT32 SSE2:1; ///< Bit26 + UINT32 Reserved4:1; ///< Bit27 + UINT32 HTT:1; ///< Bit28 + UINT32 Reserved5:3; ///< Bit29~31 +} CPU_F10_FEATURES_LO; + +/// F10 CPU Feature High +typedef struct { + UINT32 SSE3:1; ///< Bit0 + UINT32 Reserved1:2; ///< Bit1~2 + UINT32 Monitor:1; ///< Bit3 + UINT32 Reserved2:9; ///< Bit4~12 + UINT32 CMPXCHG16B:1; ///< Bit13 + UINT32 Reserved3:9; ///< Bit14~22 + UINT32 POPCNT:1; ///< Bit23 + UINT32 Reserved4:8; ///< Bit24~31 +} CPU_F10_FEATURES_HI; + +/// F10 CPU Feature +typedef struct { + CPU_F10_FEATURES_LO CpuF10FeaturesLo; ///< Low + CPU_F10_FEATURES_HI CpuF10FeaturesHi; ///< High +} CPU_F10_FEATURES; + +/// F10 CPU Extended Feature Low +typedef struct { + UINT32 FPU:1; ///< Bit0 + UINT32 VME:1; ///< Bit1 + UINT32 DE:1; ///< Bit2 + UINT32 PSE:1; ///< Bit3 + UINT32 TimeStampCounter:1; ///< Bit4 + UINT32 MSR:1; ///< Bit5 + UINT32 PAE:1; ///< Bit6 + UINT32 MCE:1; ///< Bit7 + UINT32 CMPXCHG8B:1; ///< Bit8 + UINT32 APIC:1; ///< Bit9 + UINT32 Reserved1:1; ///< Bit10 + UINT32 SysCallSysRet:1; ///< Bit11 + UINT32 MTRR:1; ///< Bit12 + UINT32 PGE:1; ///< Bit13 + UINT32 MCA:1; ///< Bit14 + UINT32 CMOV:1; ///< Bit15 + UINT32 PAT:1; ///< Bit16 + UINT32 PSE36:1; ///< Bit17 + UINT32 Reserved2:2; ///< Bit18~19 + UINT32 NX:1; ///< Bit20 + UINT32 Reserved3:1; ///< Bit21 + UINT32 MmxExt:1; ///< Bit22 + UINT32 MMX:1; ///< Bit23 + UINT32 FXSR:1; ///< Bit24 + UINT32 FFXSR:1; ///< Bit25 + UINT32 Page1GB:1; ///< Bit26 + UINT32 RDTSCP:1; ///< Bit27 + UINT32 Reserved4:1; ///< Bit28 + UINT32 LM:1; ///< Bit29 + UINT32 ThreeDNowExt:1; ///< Bit30 + UINT32 ThreeDNow:1; ///< Bit31 +} CPU_F10_EXT_FEATURES_LO; + +/// F10 CPU Extended Feature High +typedef struct { + UINT32 LahfSahf:1; ///< Bit0 + UINT32 CmpLegacy:1; ///< Bit1 + UINT32 SVM:1; ///< Bit2 + UINT32 ExtApicSpace:1; ///< Bit3 + UINT32 AltMovCr8:1; ///< Bit4 + UINT32 ABM:1; ///< Bit5 + UINT32 SSE4A:1; ///< Bit6 + UINT32 MisAlignSse:1; ///< Bit7 + UINT32 ThreeDNowPrefetch:1; ///< Bit8 + UINT32 OSVM:1; ///< Bit9 + UINT32 IBS:1; ///< Bit10 + UINT32 Reserved1:1; ///< Bit11 + UINT32 SKINIT:1; ///< Bit12 + UINT32 WDT:1; ///< Bit13 + UINT32 Reserved2:5; ///< Bit14~18 + UINT32 NodeId:1; ///< Bit19 + UINT32 Reserved3:12; ///< Bit20~31 +} CPU_F10_EXT_FEATURES_HI; + +/// F10 CPU Extended Feature +typedef struct { + CPU_F10_EXT_FEATURES_LO CpuF10ExtFeaturesLo; ///< Low + CPU_F10_EXT_FEATURES_HI CpuF10ExtFeaturesHi; ///< High +} CPU_F10_EXT_FEATURES; +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +VOID +F10SaveFeatures ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT CPU_FEATURES_LIST *cpuFeatureList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F10WriteFeatures ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT CPU_FEATURES_LIST *cpuFeatureList, + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif // _CPU_F10_FEATURE_LEVELING_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10HtPhyTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10HtPhyTables.c new file mode 100755 index 0000000000..ecf85c12e2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10HtPhyTables.c @@ -0,0 +1,747 @@ +/** + * @file + * + * AMD Family_10 DR PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10HTPHYTABLES_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 + *---------------------------------------------------------------------------------------- + */ + +// HT P C I T a b l e s +// ------------------------- +STATIC CONST TABLE_ENTRY_FIELDS ROMDATA F10HtPhyRegisters[] = +{ +// 0xCF +// HT_PHY_HT1_FIFO_PTR_OPT_VALUE + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL0_HT1, // + 0xCF, // Address + 0x0000006D, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// HT_PHY_HT1_FIFO_PTR_OPT_VALUE + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL1_HT1, // + 0xDF, // Address + 0x0000006D, // regData + 0x000000FF, // regMask + }} + }, +// 0xCF +// Default for HT3, unless overridden below. + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL0_HT3, // + 0xCF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xDF +// Default for HT3, unless overridden below. + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL1_HT3, // + 0xDF, // Address + 0x0000005A, // regData + 0x000000FF, // regMask + }} + }, +// 0xD1 +// [29:22] LfcMax = 20h, [21:14] LfcMin = 10h + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL1_HT3, // + 0xD1, // Address + 0x08040000, // regData + 0x3FFFC000, // regMask + }} + }, +// 0xC1 +// [29:22] LfcMax = 20h, [21:14] LfcMin = 10h + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL0_HT3, // + 0xC1, // Address + 0x08040000, // regData + 0x3FFFC000, // regMask + }} + }, +// 0xD1 +// [29:22] LfcMax = 10h, [21:14] LfcMin = 08h + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL1_HT1, // + 0xD1, // Address + 0x04020000, // regData + 0x3FFFC000, // regMask + }} + }, +// 0xC1 +// [29:22] LfcMax = 10h, [21:14] LfcMin = 08h + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL0_HT1, // + 0xC1, // Address + 0x04020000, // regData + 0x3FFFC000, // regMask + }} + }, +// +// Deemphasis Settings +// + +// HT1: clear any warm reset deemphasis settings. + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL0_HT1, // + 0xC5, // Address + 0x00000000, // regData + 0xE01F1FDF, // regMask + }} + }, + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL1_HT1, // + 0xD5, // Address + 0x00000000, // regData + 0xE01F1FDF, // regMask + }} + }, + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL0_HT1, // + 0xC4, // Address + 0x00000000, // regData + 0x0000FC00, // regMask + }} + }, + { + HtPhyRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HTPHY_LINKTYPE_SL1_HT1, // + 0xD4, // Address + 0x00000000, // regData + 0x0000FC00, // regMask + }} + }, + +//deemphasis level DL1[20:16], DL2[12:8], DP1[4:0] PostCur1En[31] PostCur2En[30] PreCur1En[29] MapPostCur2En[6] +// No deemphasis 00h 00h 00h 0 0 0 0 +// -3dB postcursor 12h 00h 00h 1 0 0 0 +// -6dB postcursor 1Fh 00h 00h 1 0 0 0 +// -8dB postcursor 1Fh 06h 00h 1 1 0 1 +// -11dB postcursor 1Fh 0Dh 00h 1 1 0 1 +// -11dB postcursor with +// -8dB precursor 1Fh 06h 07h 1 1 1 1 + + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x00000000, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL_NONE, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x00000000, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__3, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x80120000, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__3, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x80120000, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__6, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0x801F0000, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__6, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0x801F0000, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xC01F0640, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xC01F0640, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__11, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xC01F0D40, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__11, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xC01F0D40, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__11_8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC5, // Address + 0xE01F0647, // regData + 0xE01F1F5F, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DEEMPHASIS_LEVEL__11_8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD5, // Address + 0xE01F0647, // regData + 0xE01F1F5F, // regMask + }} + }, + +// Far-device deemphasis setting DCV[15:10] +// No deemphasis 20h +// -2dB postcursor 19h +// -3dB postcursor 17h +// -5dB postcursor 11h +// -6dB postcursor 10h +// -7dB postcursor 0Eh +// -8dB postcursor 0Dh +// -9dB postcursor 0Bh +// -11dB postcursor 09h + + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL_NONE, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00008000, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL_NONE, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00008000, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__2, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00006400, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__2, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00006400, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__3, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00005C00, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__3, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00005C00, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__5, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00004400, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__5, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00004400, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__6, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00004000, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__6, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00004000, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__7, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00003800, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__7, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00003800, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__8, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00003400, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__8, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00003400, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__9, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00002C00, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__9, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00002C00, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__11, + HTPHY_LINKTYPE_SL0_HT3, // + 0xC4, // Address + 0x00002400, // regData + 0x0000FC00, // regMask + }} + }, + { + DeemphasisRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + DCV_LEVEL__11, + HTPHY_LINKTYPE_SL1_HT3, // + 0xD4, // Address + 0x00002400, // regData + 0x0000FC00, // regMask + }} + }, + +}; + +CONST REGISTER_TABLE ROMDATA F10HtPhyRegisterTable = { + PrimaryCores, + (sizeof (F10HtPhyRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10HtPhyRegisters, +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10MsrTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10MsrTables.c new file mode 100755 index 0000000000..29840c8185 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10MsrTables.c @@ -0,0 +1,270 @@ +/** + * @file + * + * AMD Family_10 DR, MSR tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10MSRTABLES_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 F10MsrRegisters[] = +{ +// M S R T a b l e s +// ---------------------- + +// MSR_TOM2 (0xC001001D) +// bits[63:0] - TOP_MEM2 = 0 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_TOM2, // MSR Address + 0x0000000000000000ull, // OR Mask + 0xFFFFFFFFFFFFFFFFull, // NAND Mask + }} + }, +// MSR_SYS_CFG (0xC0010010) +// bit[21] = 1 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_SYS_CFG, // MSR Address + (1 << 21), // OR Mask + (1 << 21), // NAND Mask + }} + }, +// MSR_HWCR (0xC0010015) +// Do not set bit[24] = 1, it will be set in AmdInitPost. +// bit[4] = 1 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_HWCR, // MSR Address + 0x0000000000000010ull, // OR Mask + 0x0000000000000010ull, // NAND Mask + }} + }, +// MSR_MC4_CTL_MASK (0xC0010048) +// bit[10] = 1 +// bits[22:19] = 1111b + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_MC4_CTL_MASK, // MSR Address + 0x0000000000780400ull, // OR Mask + 0x0000000000780400ull, // NAND Mask + }} + }, +// MSR_DC_CFG (0xC0011022) +// bits[35:34] = 01 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_MULTI_LINK}, // platformFeatures + {{ + MSR_DC_CFG, // MSR Address + 0x0000000400000000ull, // OR Mask + 0x0000000C00000000ull, // NAND Mask + }} + }, +// MSR_NB_CFG (0xC001001F) +// bit[54] = 1 +// bit[52:51] = 11b for Erratum #372 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_NB_CFG, // MSR Address + 0x0058000000000000ull, // OR Mask + 0x0058000000000000ull, // NAND Mask + }} + }, +// MSR_DC_CFG (0xC0011022) +// bit[24] = 1 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_DC_CFG, // MSR Address + (1 << 24), // OR Mask + (1 << 24), // NAND Mask + }} + }, +// MSR_CPUID_FEATS (0xC0011004) +// bit[28] = 1 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_MULTI_CORE | AMD_PF_DUAL_CORE)}, // platformFeatures + {{ + MSR_CPUID_FEATS, // MSR Address + (1 << 28), // OR Mask + (1 << 28), // NAND Mask + }} + }, +// MSR_CPUID_EXT_FEATS (0xC0011005) +// bit[33] = 1 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_DUAL_CORE}, // platformFeatures + {{ + MSR_CPUID_EXT_FEATS, // MSR Address + 0x0000000200000000ull, // OR Mask + 0x0000000200000000ull, // NAND Mask + }} + }, +// MSR_OSVW_ID_Length (0xC0010140) +// bit[15:0] = 4 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_OSVW_ID_Length, // MSR Address + 0x0000000000000004ull, // OR Mask + 0x000000000000FFFFull, // NAND Mask + }} + }, +// MSR_OSVW_Status (0xC0010141) +// bit[3] = 1 for Erratum #383 +// bit[2] = 1 for Erratum #415 + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_OSVW_Status, // MSR Address + 0x000000000000000Cull, // OR Mask + 0x000000000000000Cull, // NAND Mask + }} + }, +// This MSR should be set after the code that most errata would be applied in +// MSR_MC0_CTL (0x00000400) +// bits[63:0] = 0xFFFFFFFFFFFFFFFF + { + MSRREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MSR_MC0_CTL, // MSR Address + 0xFFFFFFFFFFFFFFFFull, // OR Mask + 0xFFFFFFFFFFFFFFFFull, // NAND Mask + }} + } +}; + +CONST REGISTER_TABLE ROMDATA F10MsrRegisterTable = { + AllCores, + (sizeof (F10MsrRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + (TABLE_ENTRY_FIELDS *)F10MsrRegisters, +}; + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PciTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PciTables.c new file mode 100755 index 0000000000..a977be06d2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PciTables.c @@ -0,0 +1,768 @@ +/** + * @file + * + * AMD Family_10 DR PCI tables with values as defined in BKDG + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/FAMILY/0x10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "Table.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10PCITABLES_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 F10PciRegisters[] = +{ +// Function 0 - HT Config + +// F0x68 - Link Transaction Control +// bit[11] , RespPassPW = 1 +// bit[19:17], for 8bit APIC config +// bit[22:21], DsNpReqLmt = 10h + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x68), // Address + 0x004E0800, // regData + 0x006E0800, // regMask + }} + }, +// F0x68 - Link Transaction Control +// For uni-processor systems (that is, single link package processors), single core, and no L3: +// [10, DisFillP] = 1b +// [3, DisWrDwP] = 1b +// [2, DisWrBP] = 1b +// [1, DisRdDwP] = 1b +// [0, DisRdBP] = 1b + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_AND | AMD_PF_SINGLE_CORE | AMD_PF_SINGLE_LINK)}, // platformFeatures + {{ + PERFORMANCE_NO_L3_CACHE, + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x68), // Address + 0x0000040F, // regData + 0x0000040F, // regMask + }} + }, +// F0x[E4,C4,A4,84] - Link 0 Control Register +// bit[13] LdtStopTriEn = 1 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HT_HOST_FEATURES_ALL, // link feats + 0x04, // Address + 0x00002000, // regData + 0x00002000, // regMask + }} + }, +// F0x[E4,C4,A4,84] - Link 0 Control Register +// bit [12] IsocEn = 0 default + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_NFCM | AMD_PF_UMA)}, // platformFeatures + {{ + HT_HOST_FEATURES_ALL, // link feats + 0x04, // Address + 0x00000000, // regData + 0x00001000, // regMask + }} + }, +// F0x[E4,C4,A4,84] - Link 0 Control Register +// bit [12] IsocEn = 1 for Isochronous control flow modes. + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {(AMD_PF_UMA_IFCM | AMD_PF_IFCM | AMD_PF_IOMMU)}, // platformFeatures + {{ + HT_HOST_FEATURES_ALL, // link feats + 0x04, // Address + 0x00001000, // regData + 0x00001000, // regMask + }} + }, +// F0x[F0,D0,B0,90] - Link Base Channel Buffer Count +// bit[31] LockBc = 1 + { + HtHostPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + HT_HOST_FEATURES_ALL, // link feats + 0x10, // Address + 0x80000000, // regData + 0x80000000, // regMask + }} + }, +// F0x150 - Link Global Retry Control Register +// bit[18:16] TotalRetryAttempts = 7 +// bit[13] HtRetryCrcDatInsDynEn = 1 +// bit[12]HtRetryCrcCmdPackDynEn = 1 +// bit[11:9] HtRetryCrcDatIns = 4 +// bit[8] HtRetryCrcCmdPack = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x150), // Address + 0x00073900, // regData + 0x00073F00, // regMask + }} + }, +// F0x16C - Link Global Extended Control Register +// bit[15:13] ForceFullT0 = 0 +// bit[5:0] T0Time = 0x14 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00000014, // regData + 0x0000E03F, // regMask + }} + }, +// F0x16C - Link Global Extended Control Register +// bit[15:13] ForceFullT0 = 6 +// bit[5:0] T0Time = 0x26 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_SINGLE_LINK}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x0000C026, // regData + 0x0000E03F, // regMask + }} + }, +// F0x16C - Link Global Extended Control Register +// bit[22:17] FullT0Time = 0x33 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_0, 0x16C), // Address + 0x00660000, // regData + 0x007E0000, // regMask + }} + }, + +// Function 1 - Map Init + +// Before reading F1x114_x2 or F1x114_x3 software must initialize +// the registers or NB Array MCA errors may occur. BIOS should +// initialize index 0h of F1x114_x2 and F1x114_x3 to prevent reads +// from F1x114 from generating NB Array MCA errors. +// BKDG Doc #3116 Rev 1.07 + +// F1x110 - Extended Address Map + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_1, 0x110), // Address + 0x20000000, // regData + 0xFFFFFFFF, // regMask + }} + }, +// F1x114 - Extended Address Map + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_1, 0x114), // Address + 0x00000000, // regData + 0xFFFFFFFF, // regMask + }} + }, +// F1x110 - Extended Address Map + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_1, 0x110), // Address + 0x30000000, // regData + 0xFFFFFFFF, // regMask + }} + }, +// F1x114 - Extended Address Map + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_1, 0x114), // Address + 0x00000000, // regData + 0xFFFFFFFF, // regMask + }} + }, + +// F2x1B0 - Extended Memory Controller Configuration Low +// bits[10:8], CohPrefPrbLmt = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_2, 0x1B0), // Address + 0x00000100, // regData + 0x00000700, // regMask + }} + }, + +// Function 3 - Misc. Control +// F3x40 - MCA NB Control +// +// bit[8], MstrAbrtEn = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x40), // Address + 0x00000100, // regData + 0x00000100, // regMask + }} + }, +// F3x44 - MCA NB Configuration +// bit[30] SyncOnDramAdrParErrEn = 1 +// bit[27] NB MCA to CPU0 Enable = 1 +// bit[25] DisPciCfgCpuErrRsp = 1 +// bit[21] SyncOnErr = 1 +// bit[20] SyncOnWDTEn = 1 +// bit[6] CpuErrDis = 1 +// bit[4] SyncPktPropDis = 1 +// bit[3] SyncPktGenDis = 1 +// bit[2] SyncOnUcEccEn = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x44), // Address + 0x4A30005C, // regData + 0x4A30005C, // regMask + }} + }, +// F3x80 - ACPI Power State Control +// ACPI FIDVID Change +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 0 +// bits[2] NbGateEn = 0 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 0 +// ACPI State S1 +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 7 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0xE6000000, // regData + 0xFFFF0000, // regMask + }} + }, +// F3x80 - ACPI Power State Control +// ACPI FIDVID Change +// bits[0] CpuPrbEn = 1 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 0 +// bits[3] = 1 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 0 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x80), // Address + 0x000B0000, // regData + 0x00FF0000, // regMask + }} + }, +// F3x84 - ACPI Power State Control +// ACPI State S3 +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 7 +// ACPI State Throttling +// bits[0] CpuPrbEn = 1 +// bits[1] NbLowPwrEn = 0 +// bits[2] NbGateEn = 0 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 2 +// ACPI State S4/S5 +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 1 +// bits[2] NbGateEn = 1 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 7 +// ACPI State C1 +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 0 +// bits[2] NbGateEn = 0 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 5 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x84), // Address + 0x01E641E6, // regData + 0xFFFFFFFF, // regMask + }} + }, +// F3x84 - ACPI Power State Control +// ACPI State C1 +// bits[0] CpuPrbEn = 0 +// bits[1] NbLowPwrEn = 0 +// bits[2] NbGateEn = 0 +// bits[3] = 0 +// bits[4] AltVidEn = 0 +// bits[7:5] ClkDivisor = 4 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C2 // CpuRevision + }, + {AMD_PF_SINGLE_CORE}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x84), // Address + 0x80000000, // regData + 0xFF000000, // regMask + }} + }, +// F3x8C - NB Configuration High +// Errata 373, bits[25] DisFastTprWr = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x8C), // Address + 0x02000000, // regData + 0x02000000, // regMask + }} + }, +// F3x8C - NB Configuration High +// Must be cleared by BIOS + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platform Features + {{ + PERFORMANCE_L3_CACHE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x8C), // Address + 0x00000000, // regData + 0x02000000, // regMask + }} + }, +// F3xA0 - Power Control Miscellaneous +// bits[13:11] PllLockTime = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_C0 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x00000800, // regData + 0x00003800, // regMask + }} + }, +// F3xA0 - Power Control Miscellaneous +// bits[9] SviHighFreqSel = 1, if PERFORMANCE_VRM_HIGH_SPEED_ENABLE == TRUE + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_VRM_HIGH_SPEED_ENABLE, // PerformanceFeatures + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA0), // Address + 0x00000200, // regData + 0x00000200, // regMask + }} + }, +// F3xA4 - Reported Temperature Control +// bits[12:8] PerStepTimeDn = 15 +// bits[7] TmpSlewDnEn = 1 +// bits[6:5] TmpMaxDiffUp = 3 +// bits[4:0] PerStepTimeUp = 15 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xA4), // Address + 0x00000FEF, // regData + 0x00001FFF, // regMask + }} + }, +// F3xD4 - Clock Power Timing Control 0 +// bits[11:8] ClkRampHystSel = 1 +// bits[30:28] NbClkDiv = 1 +// bits[31] NbClkDivApplyAll = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xD4), // Address + 0xC0010F00, // regData + 0xF0030F00, // regMask + }} + }, +// F3xD8 - Clock Power Timing Control 1 +// bits[2:0] VSSlamTime = 6 +// bits[6:4] VSRampTime = 1 +// bits[26:24] ReConDel = 3 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xD8), // Address + 0x03000016, // regData + 0x0F000077, // regMask + }} + }, +// F3xDC - Clock Power Timing Control 2 +// bits[14:12] NbsynPtrAdj = 6 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xDC), // Address + 0x00006000, // regData + 0x00007000, // regMask + }} + }, +// F3xDC - Clock Power Timing Control 2 +// bits[18:16] CacheFlushOnHaltCtl = 0 to ensure AP cache stability at Early + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_Bx // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0xDC), // Address + 0x00000000, // regData + 0x00070000, // regMask + }} + }, +// F3x180 - NB Extended Configuration +// bits[1] SyncFloodOnUsPwDataErr = 1 +// bits[5] DisPciCfgCpuMstAbtRsp = 1 +// bits[6] SyncFloodOnDatErr = 1 +// bits[7] SyncFloodOnTgtAbtErr = 1 +// bits[8] SyncOnProtEn = 1 +// bits[9] SyncOnUncNbAryEn = 1 +// bits[20] SyncFloodOnL3LeakErr = 1 +// bits[21] SyncFloodOnCpuLeakErr = 1 +// bits[22] SyncFloodOnTblWalkErr = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x180), // Address + 0x007003E2, // regData + 0x007003E2, // regMask + }} + }, +// F3x188 - NB Extended Configuration Low Register +// bits[4] EnStpGntOnFlushMaskWakeup = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_C3 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x188), // Address + 0x00000010, // regData + 0x00000010, // regMask + }} + }, +// F3x1A0 - L3 Buffer Count Register +// bits[14:12] L3ToSriReqCBC = 4, 4 or fewer cores with L3 cache is 4. + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_L3_CACHE, + (CORE_RANGE_0 (COUNT_RANGE_LOW, 4) | COUNT_RANGE_NONE), // 4 or fewer cores. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1A0), // Address + 0x00004000, // regData + 0x00007000, // regMask + }} + }, +// F3x1A0 - L3 Buffer Count Register +// bits[14:12] L3ToSriReqCBC = 5, 5-core with L3 cache is 5. + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_L3_CACHE, + (CORE_RANGE_0 (5, 5) | COUNT_RANGE_NONE), // 5 core. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1A0), // Address + 0x00005000, // regData + 0x00007000, // regMask + }} + }, +// F3x1A0 - L3 Buffer Count Register +// bits[14:12] L3ToSriReqCBC = 6, 6-core with L3 cache is 6. + { + CoreCountsPciRegister, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_L3_CACHE, + (CORE_RANGE_0 (6, 6) | COUNT_RANGE_NONE), // 6 core. + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1A0), // Address + 0x00006000, // regData + 0x00007000, // regMask + }} + }, +// F3x1B8 - L3 Control +// bits[12] Must be set by BIOS. + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1B8), // Address + 0x00001000, // regData + 0x00001000, // regMask + }} + }, + // F4x1C4 - L3 Power Control Register + // bits[8] L3PwrSavEn = 1 + { + ProfileFixup, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_ALL // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + PERFORMANCE_L3_CACHE, // Features + MAKE_SBDFO (0, 0, 24, FUNC_4, 0x1C4), // Address + 0x00000100, // regData + 0x00000100, // regMask + }} + }, +// F3x1CC - IBS Control +// bits[8] LvtOffsetVal = 1 + { + PCIREGISTER, + { + AMD_FAMILY_10, // CpuFamily + AMD_F10_GT_A2 // CpuRevision + }, + {AMD_PF_ALL}, // platformFeatures + {{ + MAKE_SBDFO (0, 0, 24, FUNC_3, 0x1CC), // Address + 0x00000100, // regData + 0x00000100, // regMask + }} + } +}; + +CONST REGISTER_TABLE ROMDATA F10PciRegisterTable = { + PrimaryCores, + (sizeof (F10PciRegisters) / sizeof (TABLE_ENTRY_FIELDS)), + F10PciRegisters, +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerCheck.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerCheck.c new file mode 100755 index 0000000000..67ef653d23 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerCheck.c @@ -0,0 +1,376 @@ +/** + * @file + * + * AMD Family_10 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/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuF10PowerMgmt.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "cpuF10PowerCheck.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuF10Utilities.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10POWERCHECK_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 +F10PmPwrCheckCore ( + IN VOID *ErrorData, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F10PmPwrChkCopyPstate ( + IN UINT8 Dest, + IN UINT8 Src, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family 10h core 0 entry point for performing the family 10h 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. 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[StcPstateLimit] + * 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 F3xDC[PstateMaxVal]!= 000b, copy the contents of the P-state + * MSR pointed to by F3xDC[PstateMaxVal] to MSRC001_0064 and set + * MSRC001_0064[PstateEn] + * c. Write 000b to MSRC001_0062[PstateCmd] and wait for MSRC001_0063 + * [CurPstate] to reflect the new value. + * d. Adjust the following P-state parameters to zero: + * 1. F3x64[HtcPstateLimit] + * 2. F3x68[StcPstateLimit] + * 3. F3xDC[PstateMaxVal] + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParams Service parameters + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F10PmPwrCheck ( + 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 PciRegister; + UINT32 Socket; + UINT32 Module; + UINT32 Core; + UINT32 AndMask; + UINT32 OrMask; + UINT32 PstateLimit; + PCI_ADDR PciAddress; + UINT64 MsrRegister; + AP_TASK TaskPtr; + AGESA_STATUS IgnoredSts; + PWRCHK_ERROR_DATA ErrorData; + + // get the socket number + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + ErrorData.SocketNumber = (UINT8)Socket; + + ASSERT (Core == 0); + + // get the Max P-state value + for (PsMaxVal = NM_PS_REG - 1; PsMaxVal != 0; --PsMaxVal) { + LibAmdMsrRead (PS_REG_BASE + PsMaxVal, &MsrRegister, StdHeader); + if (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1) { + break; + } + } + + ErrorData.HwPstateNumber = (UINT8) (PsMaxVal + 1); + + DisPsNum = 0; + for (Pstate = 0; Pstate < ErrorData.HwPstateNumber; Pstate++) { + if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, Pstate, &ProcIddMax, StdHeader)) { + if (ProcIddMax > CpuEarlyParams->PlatformConfig.VrmProperties.CurrentLimit) { + // Add to event log the Pstate that exceeded the current limit + PutEventLog (AGESA_WARNING, + CPU_EVENT_PM_PSTATE_OVERCURRENT, + Socket, Pstate, 0, 0, StdHeader); + DisPsNum++; + } else { + break; + } + } + } + + // If all P-state registers are disabled, move P[PsMaxVal] to P0 + // and transition to P0, then wait for CurPstate = 0 + + ErrorData.AllowablePstateNumber = ((PsMaxVal + 1) - DisPsNum); + + // We only need to log this event on the BSC + if (ErrorData.AllowablePstateNumber == 0) { + PutEventLog (AGESA_FATAL, + CPU_EVENT_PM_ALL_PSTATE_OVERCURRENT, + Socket, 0, 0, 0, StdHeader); + } + + if (DisPsNum != 0) { + TaskPtr.FuncAddress.PfApTaskI = F10PmPwrCheckCore; + TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (PWRCHK_ERROR_DATA); + TaskPtr.DataTransfer.DataPtr = &ErrorData; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParams); + + // Final Step + // F3x64[HtPstatelimit] -= disPsNum + // F3x68[StcPstateLimit]-= disPsNum + // F3xDC[PstateMaxVal]-= disPsNum + + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + PciAddress.Address.Function = FUNC_3; + + PciAddress.Address.Register = HTC_REG; + AndMask = 0xFFFFFFFF; + ((HTC_REGISTER *) &AndMask)->HtcPstateLimit = 0; + OrMask = 0x00000000; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); // F3x64 + PstateLimit = ((HTC_REGISTER *) &PciRegister)->HtcPstateLimit; + if (PstateLimit > DisPsNum) { + PstateLimit -= DisPsNum; + ((HTC_REGISTER *) &OrMask)->HtcPstateLimit = PstateLimit; + } + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3x64 + + PciAddress.Address.Register = STC_REG; + AndMask = 0xFFFFFFFF; + ((STC_REGISTER *) &AndMask)->StcPstateLimit = 0; + OrMask = 0x00000000; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); // F3x68 + PstateLimit = ((STC_REGISTER *) &PciRegister)->StcPstateLimit; + if (PstateLimit > DisPsNum) { + PstateLimit -= DisPsNum; + ((STC_REGISTER *) &OrMask)->StcPstateLimit = PstateLimit; + } + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3x68 + + PciAddress.Address.Register = CPTC2_REG; + AndMask = 0xFFFFFFFF; + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->PstateMaxVal = 0; + OrMask = 0x00000000; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); // F3xDC + PstateLimit = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal; + if (PstateLimit > DisPsNum) { + PstateLimit -= DisPsNum; + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->PstateMaxVal = PstateLimit; + } + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3xDC + + // Now that P0 has changed, recalculate VSSlamTime + F10ProgramVSSlamTimeOnSocket (&PciAddress, CpuEarlyParams, StdHeader); + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Core-level 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 +F10PmPwrCheckCore ( + IN VOID *ErrorData, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 i; + UINT8 PsMaxVal; + UINT8 DisPsNum; + UINT8 CurrentPs; + UINT64 MsrRegister; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + PsMaxVal = (((PWRCHK_ERROR_DATA *) ErrorData)->HwPstateNumber - 1); + DisPsNum = (((PWRCHK_ERROR_DATA *) ErrorData)->HwPstateNumber - + ((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber); + + LibAmdMsrRead (MSR_PSTATE_STS, &MsrRegister, StdHeader); + CurrentPs = (UINT8) (((PSTATE_STS_MSR *) &MsrRegister)->CurPstate); + + if (((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber == 0) { + + // Step 1 + // Transition to Pstate Max if not there already + + if (CurrentPs != PsMaxVal) { + FamilySpecificServices->TransitionPstate (FamilySpecificServices, PsMaxVal, (BOOLEAN) TRUE, StdHeader); + } + + + // Step 2 + // If Pstate Max is not P0, copy Pstate max contents to P0 and switch + // to P0. + + if (PsMaxVal != 0) { + F10PmPwrChkCopyPstate (0, PsMaxVal, StdHeader); + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) TRUE, StdHeader); + } + } else { + + // move remaining P-state register(s) up + // Step 1 + // Transition to a valid Pstate if current Pstate has been disabled + + if (CurrentPs < DisPsNum) { + FamilySpecificServices->TransitionPstate (FamilySpecificServices, DisPsNum, (BOOLEAN) TRUE, StdHeader); + CurrentPs = DisPsNum; + } + + // Step 2 + // Move enabled Pstates up and disable the remainder + + for (i = 0; (i + DisPsNum) <= PsMaxVal; ++i) { + F10PmPwrChkCopyPstate (i, (i + DisPsNum), StdHeader); + } + + // Step 3 + // Transition to current COF/VID at shifted location + + CurrentPs = (CurrentPs - DisPsNum); + FamilySpecificServices->TransitionPstate (FamilySpecificServices, CurrentPs, (BOOLEAN) TRUE, StdHeader); + } + i = ((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber; + if (i == 0) { + ++i; + } + while (i <= PsMaxVal) { + FamilySpecificServices->DisablePstate (FamilySpecificServices, i, StdHeader); + ++i; + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10PmPwrChkCopyPstate ( + IN UINT8 Dest, + IN UINT8 Src, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrRegister; + + LibAmdMsrRead ((UINT32) (PS_REG_BASE + Src), &MsrRegister, StdHeader); + LibAmdMsrWrite ((UINT32) (PS_REG_BASE + Dest), &MsrRegister, StdHeader); +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerCheck.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerCheck.h new file mode 100755 index 0000000000..a02e05a056 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerCheck.h @@ -0,0 +1,81 @@ +/** + * @file + * + * AMD Family_10 Power related functions and structures + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_F10_POWER_CHECK_H_ +#define _CPU_F10_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; ///< Hardware P-state Number + UINT8 AllowablePstateNumber; ///< Allowable P-state Number +} PWRCHK_ERROR_DATA; + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ +VOID +F10PmPwrCheck ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F10_POWER_CHECK_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerMgmt.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerMgmt.h new file mode 100755 index 0000000000..a3ce49a1cf --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerMgmt.h @@ -0,0 +1,516 @@ +/** + * @file + * + * AMD Family_10 Power Management related stuff + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPUF10POWERMGMT_H_ +#define _CPUF10POWERMGMT_H_ + +/* + * Family 10h CPU Power Management MSR definitions + * + */ + +/* Interrupt Pending and CMP-Halt MSR Register 0xC0010055 */ +#define MSR_INTPEND 0xC0010055 + +/// Interrupt Pending and CMP-Halt MSR Register +typedef struct { + UINT64 IoMsgAddr:16; ///< IO message address + UINT64 IoMsgData:8; ///< IO message data + UINT64 IntrPndMsgDis:1; ///< Interrupt pending message disable + UINT64 IntrPndMsg:1; ///< Interrupt pending message + UINT64 IoRd:1; ///< IO read + UINT64 SmiOnCmpHalt:1; ///< SMI on chip multi-processing halt + UINT64 C1eOnCmpHalt:1; ///< C1E on chip multi-processing halt + UINT64 BmStsClrOnHltEn:1; ///< Clear BM status bit on server C1e entry + UINT64 :34; ///< Reserved +} INTPEND_MSR; + + +/* P-state Current Limit Register 0xC0010061 */ +#define MSR_PSTATE_CURRENT_LIMIT 0xC0010061 + +/// 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 0xC0010062 + +/// 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 0xC0010063 + +/// Pstate Status MSR Register +typedef struct { + UINT64 CurPstate:3; ///< Current Pstate + UINT64 :61; ///< Reserved +} PSTATE_STS_MSR; + + +/* P-state Registers 0xC001006[8:4] */ +#define MSR_PSTATE_0 0xC0010064 +#define MSR_PSTATE_1 0xC0010065 +#define MSR_PSTATE_2 0xC0010066 +#define MSR_PSTATE_3 0xC0010067 +#define MSR_PSTATE_4 0xC0010068 + +#define PS_REG_BASE MSR_PSTATE_0 /* P-state Register base */ +#define PS_MAX_REG MSR_PSTATE_4 /* Maximum P-State Register */ +#define PS_MIN_REG MSR_PSTATE_0 /* Minimum P-State Register */ +#define NM_PS_REG 5 /* number of P-state MSR registers */ + +/// Pstate MSR +typedef struct { + UINT64 CpuFid:6; ///< CpuFid + UINT64 CpuDid:3; ///< CpuDid + UINT64 CpuVid:7; ///< CpuVid + UINT64 :6; ///< Reserved + UINT64 NbDid:1; ///< NbDid + UINT64 :2; ///< Reserved + UINT64 NbVid:7; ///< NbVid + UINT64 IddValue:8; ///< IddValue + UINT64 IddDiv:2; ///< IddDiv + UINT64 :21; ///< Reserved + UINT64 PsEnable:1; ///< Pstate Enable +} PSTATE_MSR; + + +/* COFVID Control Register 0xC0010070 */ +#define MSR_COFVID_CTL 0xC0010070 + +/// COFVID Control MSR Register +typedef struct { + UINT64 CpuFid:6; ///< CpuFid + UINT64 CpuDid:3; ///< CpuDid + UINT64 CpuVid:7; ///< CpuVid + UINT64 PstateId:3; ///< Pstate ID + UINT64 :3; ///< Reserved + UINT64 NbDid:1; ///< NbDid + UINT64 :2; ///< Reserved + UINT64 NbVid:7; ///< NbVid + UINT64 :32; ///< Reserved +} COFVID_CTRL_MSR; + + +/* COFVID Status Register 0xC0010071 */ +#define MSR_COFVID_STS 0xC0010071 + +/// COFVID Status MSR Register +typedef struct { + UINT64 CurCpuFid:6; ///< Current CpuFid + UINT64 CurCpuDid:3; ///< Current CpuDid + UINT64 CurCpuVid:7; ///< Current CpuVid + UINT64 CurPstate:3; ///< Current Pstate + UINT64 :3; ///< Reserved + UINT64 CurNbDid:1; ///< Current NbDid + UINT64 :2; ///< Reserved + UINT64 CurNbVid:7; ///< Current NbVid + UINT64 StartupPstate:3; ///< Startup Pstate + UINT64 MaxVid:7; ///< MaxVid + UINT64 MinVid:7; ///< MinVid + UINT64 MaxCpuCof:6; ///< MaxCpuCof + UINT64 :1; ///< Reserved + UINT64 CurPstateLimit:3; ///< Current Pstate Limit + UINT64 MaxNbFid:5; ///< MaxNbFid +} COFVID_STS_MSR; + + +/* + * Family 10h CPU Power Management PCI definitions + * + */ + +/* DRAM Configuration High Register F2x[1,0]94 */ +#define DRAM_CFG_HI_REG0 0x94 +#define DRAM_CFG_HI_REG1 0x194 + +/// DRAM Configuration High PCI Register +typedef struct { + UINT32 MemClkFreq:3; ///< Memory clock frequency + UINT32 MemClkFreqVal:1; ///< Memory clock frequency valid + UINT32 :4; ///< Reserved + UINT32 Ddr3Mode:1; ///< DDR3 mode + UINT32 LegacyBiosMode:1; ///< Legacy BIOS mode + UINT32 ZqcsInterval:2; ///< ZQ calibration short interval + UINT32 RDqsEn:1; ///< Read DQS enable + UINT32 DisSimulRdWr:1; ///< Disable simultaneous read and write + UINT32 DisDramInterface:1; ///< Disable the DRAM interface + UINT32 PowerDownEn:1; ///< Power down mode enable + UINT32 PowerDownMode:1; ///< Power down mode + UINT32 :1; ///< Reserved + UINT32 FourRankRDimm:1; ///< Four rank registered DIMM connected + UINT32 DcqArbBypassEn:1; ///< DRAM controller arbiter bypass enable + UINT32 SlowAccessMode:1; ///< Slow access mode + UINT32 FreqChgInProg:1; ///< Frequency change in progress + UINT32 BankSwizzleMode:1; ///< Bank swizzle mode + UINT32 ProcOdtDis:1; ///< Processor on-die termination disable + UINT32 DcqBypassMax:4; ///< DRAM controller queue bypass maximum + UINT32 FourActWindow:4; ///< Four bank activate window +} DRAM_CFG_HI_REGISTER; + + +/* 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 SpecPrefDis:1; ///< Speculative prefetch disable + UINT32 SpecPrefMis:1; ///< Speculative prefetch predict miss + UINT32 SpecPrefThreshold:3; ///< Speculative prefetch threshold + UINT32 :4; ///< 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; + + +/* Scrub Rate Control Register F3x58 */ +#define SCRUB_RATE_CTRL_REG 0x58 + +/// Scrub Rate Control PCI Register +typedef struct { + UINT32 DramScrub:5; ///< DRAM scrub rate + UINT32 :3; ///< Reserved + UINT32 L2Scrub:5; ///< L2 cache scrub rate + UINT32 :3; ///< Reserved + UINT32 DcacheScrub:5; ///< Data cache scrub rate + UINT32 :3; ///< Reserved + UINT32 L3Scrub:5; ///< L3 cache scrub rate + UINT32 :3; ///< Reserved +} SCRUB_RATE_CTRL_REGISTER; + +/* DRAM Scrub Address Low Register F3x5C */ +#define DRAM_SCRUB_ADDR_LOW_REG 0x5C + +/// DRAM Scrub Address Low PCI Register +typedef struct { + UINT32 ScrubReDirEn:1; ///< DRAM scrubber redirect enable + UINT32 :5; ///< Reserved + UINT32 ScrubAddrLo:26; ///< DRAM scrubber address bits[31:6] +} DRAM_SCRUB_ADDR_LOW_REGISTER; + + +/* Hardware thermal control register F3x64 */ +#define HTC_REG 0x64 + +/// 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 int enable + UINT32 PslApicLoEn:1; ///< P-state limit lower APIC int 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 thermal control register F3x68 */ +#define STC_REG 0x68 + +/// Software Thermal Control PCI Register +typedef struct { + UINT32 StcSbcTmpHiEn:1; ///< STC SBC temperature high enable + UINT32 StcSbcTmpLoEn:1; ///< STC SBC temperature low enable + UINT32 StcApcTmpHiEn:1; ///< STC APIC temperature high enable + UINT32 StcApcTmpLoEn:1; ///< STC APIC temperature low enable + UINT32 :1; ///< Reserved + UINT32 StcPstateEn:1; ///< STC P-state enable + UINT32 StcTmpHiSts:1; ///< STC temperature high status + UINT32 StcTmpLoSts:1; ///< STC temperature low status + UINT32 :8; ///< Reserved + UINT32 StcTmpLmt:7; ///< STC temperature limit + UINT32 StcSlewSel:1; ///< STC slew-controlled temp select + UINT32 StcHystLmt:4; ///< STC hysteresis + UINT32 StcPstateLimit:3; ///< STC P-state limit select + UINT32 :1; ///< Reserved +} STC_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 :1; ///< Reserved + UINT8 AltVidEn:1; ///< alternate VID enable + 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 C3C1eLinkInit; ///< [15:8] SMAF Code 001b - C3, C1e or Link init + ACPI_STATE_SMAF FidVidChg; ///< [23:16] SMAF Code 010b - FIDVID Change + 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; + + +/* Power Control Miscellaneous Register F3xA0 */ +#define PW_CTL_MISC_REG 0xA0 + +/// Power Control Miscellaneous PCI Register +typedef struct { + UINT32 PsiVid:7; ///< PSI_L VID threshold + UINT32 PsiVidEn:1; ///< PSI_L VID enable + UINT32 PviMode:1; ///< Parallel VID interface mode + UINT32 SviHighFreqSel:1; ///< SVI high frequency select + UINT32 IdleExitEn:1; ///< IDLEEXIT_L Enable + UINT32 PllLockTime:3; ///< PLL synchronization lock time + UINT32 BpPinsTriEn:1; ///< Breakpoint pins tristate enable + UINT32 :1; ///< Reserved + UINT32 PstateId:12; ///< Pstate ID + UINT32 :1; ///< Reserved + UINT32 SlamVidMode:1; ///< Slam voltage ID mode + UINT32 :1; ///< Reserved + UINT32 CofVidProg:1; ///< COF and VID of Pstate programmed +} POWER_CTRL_MISC_REGISTER; + +/* Popup P-state Register F3xA8 */ +#define POPUP_PSTATE_REG 0xA8 + +/// Popup P-state Register +typedef struct { + UINT32 PopupEn:1; ///< Popup enable + UINT32 :1; ///< Reserved + UINT32 PopupPstate:3; ///< Popup P-state + UINT32 PopupCpuVid:7; ///< Popup core VID + UINT32 PopupCpuFid:6; ///< Popup core FID + UINT32 PopupCpuDid:3; ///< Popup core DID + UINT32 :11; ///< Reserved +} POPUP_PSTATE_REGISTER; + +/* Clock Power/Timing Control 0 Register F3xD4 */ +#define CPTC0_REG 0xD4 + +/// Clock Power Timing Control PCI Register +typedef struct { + UINT32 NbFid:5; ///< NbFid + UINT32 NbFidEn:1; ///< NbFidEn + UINT32 :2; ///< Reserved + UINT32 ClkRampHystSel:4; ///< Clock Ramp Hysteresis Select + UINT32 ClkRampHystCtl:1; ///< Clock Ramp Hysteresis Control + UINT32 MTC1eEn:1; ///< Message Triggered C1e Enable + UINT32 CacheFlushImmOnAllHalt:1; ///< Cache Flush Immediate on All Halt + UINT32 StutterScrubEn:1; ///< Stutter Mode Scrub Enable + UINT32 LnkPllLock:2; ///< Link PLL Lock + UINT32 :2; ///< 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 + +/// Clock Power Timing Control 1 PCI Register +typedef struct { + UINT32 VSSlamTime:3; ///< Voltage stabilization slam time + UINT32 :1; ///< Reserved + UINT32 VSRampTime:3; ///< Voltage stabilization ramp time + UINT32 :1; ///< Reserved + UINT32 TdpVid:7; ///< Thermal design power VID + UINT32 :1; ///< Reserved + UINT32 AltVidStart:7; ///< Alternate VID start limit + UINT32 :1; ///< Reserved + UINT32 ReConDel:4; ///< Link reconnect delay + UINT32 PwrPlanes:1; ///< Power planes + UINT32 :3; ///< Reserved +} CLK_PWR_TIMING_CTRL1_REGISTER; + + +/* Clock Power/Timing Control 2 Register F3xDC */ +#define CPTC2_REG 0xDC + +/// Clock Power Timing Control 2 PCI Register +typedef struct { + UINT32 AltVid:7; ///< Alternate VID + UINT32 :1; ///< Reserved + UINT32 PstateMaxVal:3; ///< P-state maximum value + UINT32 :1; ///< Reserved + UINT32 NbsynPtrAdj:3; ///< NB/Core sync FIFO ptr adjust + UINT32 :1; ///< Reserved + UINT32 CacheFlushOnHaltCtl:3; ///< Cache flush on halt control + UINT32 CacheFlushOnHaltTmr:7; ///< Cache flush on halt timer + UINT32 :1; ///< Reserved + UINT32 SlamTimeMode:2; ///< Slam time mode + UINT32 AltvidVSSlamTime:3; ///< Altvid voltage stabilization slam time +} CLK_PWR_TIMING_CTRL2_REGISTER; + + +/* Northbridge Capabilities Register F3xE8 */ +#define NB_CAPS_REG 0xE8 + +/// Northbridge Capabilities PCI Register +typedef struct { + UINT32 DctDualCap:1; ///< Two-channel DRAM capable + UINT32 DualNodeCap:1; ///< Dual-node multi-processor capable + UINT32 EightNodeCap:1; ///< Eight-node multi-processor capable + UINT32 EccCapable:1; ///< ECC capable + UINT32 ChipkillCapable:1; ///< Chipkill ECC capable + UINT32 DdrMaxRate:3; ///< Maximum DRAM data rate + UINT32 MctCap:1; ///< Memory controller capable + UINT32 SvmCapable:1; ///< SVM capable + UINT32 HtcCapable:1; ///< HTC capable + UINT32 LnkRtryCap:1; ///< Link error-retry capable + UINT32 CmpCapLo:2; ///< CMP capable[1:0] + UINT32 MultiVidPlaneCap:1; ///< Multiple VID plane capable + UINT32 CmpCapHi:1; ///< CMP capable[2] + UINT32 MpCap:3; ///< MP capability + UINT32 :1; ///< Reserved + UINT32 UnGangEn:4; ///< Link unganging enabled + UINT32 :1; ///< Reserved + UINT32 L3Capable:1; ///< L3 capable + UINT32 HtAcCapable:1; ///< HT AC capable + UINT32 :2; ///< Reserved + UINT32 MultiNodeCpu:1; ///< Multinode processor + UINT32 IntNodeNum:2; ///< Internal node number +} NB_CAPS_REGISTER; + + +/* NB Extended Configuration Low Register F3x188 */ +#define NB_EXT_CFG_LO_REG 0x188 + +/// Northbridge Extended Configuration Low PCI Register +typedef struct { + UINT32 :4; ///< Reserved + UINT32 EnStpGntOnFlushMaskWakeup:1; ///< Enable stop grant on flush mask wakeup + UINT32 :27; ///< Reserved +} NB_EXT_CFG_LO_REGISTER; + + +/* L3 Cache Parameter Register F3x1C4 */ +#define L3_CACHE_PARAM_REG 0x1C4 + +/// L3 Cache Parameter PCI Register +typedef struct { + UINT32 L3SubcacheSize0:1; ///< L3 subcache size 0 + UINT32 :3; ///< Reserved + UINT32 L3SubcacheSize1:1; ///< L3 subcache size 1 + UINT32 :3; ///< Reserved + UINT32 L3SubcacheSize2:2; ///< L3 subcache size 2 + UINT32 :2; ///< Reserved + UINT32 L3SubcacheSize3:2; ///< L3 subcache size 3 + UINT32 :17; ///< Reserved + UINT32 L3TagInit:1; ///< L3 tag initialization +} L3_CACHE_PARAM_REGISTER; + + +/* Probe Filter Control Register F3x1D4 */ +#define PROBE_FILTER_CTRL_REG 0x1D4 + +/// Probe Filter Control PCI Register +typedef struct { + UINT32 PFMode:2; ///< Probe Filter Mode + UINT32 PFWayNum:2; ///< Probe Filter way number + UINT32 PFSubCacheSize0:2; ///< Probe filter subcache 0 size + UINT32 PFSubCacheSize1:2; ///< Probe filter subcache 1 size + UINT32 PFSubCacheSize2:2; ///< Probe filter subcache 2 size + UINT32 PFSubCacheSize3:2; ///< Probe filter subcache 3 size + UINT32 PFSubCacheEn:4; ///< Probe filter subcache enable + UINT32 :3; ///< Reserved + UINT32 PFInitDone:1; ///< Probe filter initialization done + UINT32 PFPreferredSORepl:2; ///< PF preferredSO replacement mode + UINT32 PFErrInt:2; ///< Probe filter error interrupt type + UINT32 PFErrIntLvtOff:4; ///< Probe filter error interrupt LVT offset + UINT32 PFEccError:1; ///< Probe filter ECC error + UINT32 PFLoIndexHashEn:1; ///< Probe filter low index hash enable + UINT32 :2; ///< Reserved +} PROBE_FILTER_CTRL_REGISTER; + + +/* Product Info Register F3x1FC */ +#define PRCT_INFO_REG 0x1FC + +/// Product Information PCI Register +typedef struct { + UINT32 NbCofVidUpdate:1; ///< NbCofVidUpdate + UINT32 NbVidUpdateAll:1; ///< NbVidUpdateAll + UINT32 SinglePlaneNbFid:5; ///< SinglePlaneNbFid + UINT32 SinglePlaneNbVid:7; ///< SinglePlaneNbVid + UINT32 DualPlaneNbFidOff:3; ///< DualPlaneNbFidOff + UINT32 DualPlaneNbVidOff:5; ///< DualPlaneNbVidOff + UINT32 SinglePlaneNbIdd:4; ///< SinglePlaneNbIdd +} PRODUCT_INFO_REGISTER; + + +#endif /* _CPUF10POWERMGMT_H */ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerMgmtSystemTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerMgmtSystemTables.c new file mode 100755 index 0000000000..b697720f4a --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerMgmtSystemTables.c @@ -0,0 +1,164 @@ +/** + * @file + * + * AMD Family_10 Power Management related stuff + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6410 $ @e \$Date: 2008-06-17 06:08:25 -0500 (Tue, 17 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "IdsF10AllService.h" +#include "cpuPowerMgmtSystemTables.h" +#include "cpuF10EarlyInit.h" +#include "cpuF10SoftwareThermal.h" +#include "cpuF10PowerPlane.h" +#include "cpuF10PowerCheck.h" +#include "F10PmNbCofVidInit.h" +#include "F10PmNbPstateInit.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10POWERMGMTSYSTEMTABLES_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 + *---------------------------------------------------------------------------------------- + */ +VOID +GetF10SysPmTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **SysPmTblPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/* Family 10h Only Table */ +/* ---------------------- */ +CONST SYS_PM_TBL_STEP ROMDATA CpuF10SysPmTableArray[] = +{ + IDS_INITIAL_F10_PM_STEP + + // Step 1 - Configure F3x[84:80]. Handled by PCI register table. + // Step 2 - Configure Northbridge COF and VID. + // Execute both cold & warm + { + 0, + F10PmNbCofVidInit + }, + + // Step 3 - Dual-plane Only Support. Not required by any Arch2008 supported CPU. + // Step 4 - Configure Nb-Pstates. + // Execute only after warm reset + { + PM_EXEFLAGS_WARM_ONLY, // ExeFlags + F10PmNbPstateInit + }, + // Step 5 - Power Plane Initialization + // Execute both cold & warm + { + 0, // ExeFlags + F10CpuAmdPmPwrPlaneInit // Function Pointer + }, + + // Step 6 - Pmin Transition After Reset + // Execute only after warm reset + { + PM_EXEFLAGS_WARM_ONLY, // ExeFlags + F10PmAfterReset // Function Pointer + }, + + // Step 7 - Current Delivery Check + // Execute only after warm reset + { + PM_EXEFLAGS_WARM_ONLY, // ExeFlags + F10PmPwrCheck // Function Pointer + }, + + // Step x - Software Thermal Control Init + // Execute only after warm reset + { + PM_EXEFLAGS_WARM_ONLY, // ExeFlags + F10PmThermalInit // Function Pointer + }, +}; + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +GetF10SysPmTable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **SysPmTblPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = (sizeof (CpuF10SysPmTableArray) / sizeof (SYS_PM_TBL_STEP)); + *SysPmTblPtr = CpuF10SysPmTableArray; +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerPlane.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerPlane.c new file mode 100755 index 0000000000..3ce6d5f4e1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerPlane.c @@ -0,0 +1,469 @@ +/** + * @file + * + * AMD Family_10 Power Plane Initialization + * + * Performs the "BIOS Requirements for Power Plane Initialization" as described + * in the BKDG. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuF10PowerMgmt.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuF10Utilities.h" +#include "Table.h" +#include "cpuF10PowerPlane.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10POWERPLANE_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +// Register encodings for F3xD4[PowerStepUp/PowerStepDown] +CONST UINT16 ROMDATA PowerStepEncodings[16] = +{ + 400, // 0000b: 400ns + 300, // 0001b: 300ns + 200, // 0010b: 200ns + 100, // 0011b: 100ns + 90, // 0100b: 90ns + 80, // 0101b: 80ns + 70, // 0110b: 70ns + 60, // 0111b: 60ns + 50, // 1000b: 50ns + 45, // 1001b: 45ns + 40, // 1010b: 40ns + 35, // 1011b: 35ns + 30, // 1100b: 30ns + 25, // 1101b: 25ns + 20, // 1110b: 20ns + 15 // 1111b: 15ns +}; + +// Register encodings for F3xDC[AltvidVSSlamTime] +CONST UINT32 ROMDATA AltvidSlamTime[8] = +{ + 0, // 000b: <1us + 10, // 001b: 10us + 20, // 010b: 20us + 40, // 011b: 40us + 50, // 100b: 50us + 70, // 101b: 70us + 80, // 110b: 80us + 90 // 111b: 90us +}; + +/*---------------------------------------------------------------------------------------- + * 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 +F10PmPwrPlaneInitPviCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +STATIC +F10CalculateAltvidVSSlamTimeOnCore ( + IN BOOLEAN PviModeFlag, + IN PCI_ADDR *PciAddress, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +F10PmVrmLowPowerModeEnable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Family 10h core 0 entry point for performing power plane initialization. + * + * The steps are as follows: + * 1. If single plane, program lower VID code of CpuVid & NbVid for all + * enabled P-States. + * 2. Configure F3xA0[SlamMode] & F3xD8[VsRampTime & VsSlamTime] based on + * platform requirements. + * 3. Configure F3xD4[PowerStepUp & PowerStepDown] + * 4. Optionally configure F3xA0[PsiVidEn & PsiVid] + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParams Service parameters + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F10CpuAmdPmPwrPlaneInit ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN PviModeFlag; + PCI_ADDR PciAddress; + UINT16 PowerStepTime; + UINT32 PowerStepEncoded; + UINT32 PciRegister; + UINT32 VsSlamTime; + UINT32 Socket; + UINT32 Module; + UINT32 Core; + UINT32 NumOfCores; + UINT32 LowCore; + UINT32 AndMask; + UINT32 OrMask; + UINT64 MsrRegister; + AP_TASK TaskPtr; + AGESA_STATUS IgnoredSts; + PLATFORM_FEATS Features; + CPU_LOGICAL_ID LogicalId; + + // Initialize the union + Features.PlatformValue = 0; + GetPlatformFeatures (&Features, &CpuEarlyParams->PlatformConfig, StdHeader); + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + ASSERT (Core == 0); + + GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); + + // Set SlamVidMode + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = PW_CTL_MISC_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + AndMask = 0xFFFFFFFF; + OrMask = 0x00000000; + if (((POWER_CTRL_MISC_REGISTER *) &PciRegister)->PviMode == 1) { + PviModeFlag = TRUE; + ((POWER_CTRL_MISC_REGISTER *) &AndMask)->SlamVidMode = 0; + + // Have all single plane cores adjust their NB and CPU VID fields + TaskPtr.FuncAddress.PfApTask = F10PmPwrPlaneInitPviCore; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParams); + + } else { + PviModeFlag = FALSE; + ((POWER_CTRL_MISC_REGISTER *) &OrMask)->SlamVidMode = 1; + } + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); + + F10ProgramVSSlamTimeOnSocket (&PciAddress, CpuEarlyParams, StdHeader); + + // Configure PowerStepUp/PowerStepDown + PciAddress.Address.Register = CPTC0_REG; + if ((Features.PlatformFeatures.PlatformSingleLink == 1) || + (Features.PlatformFeatures.PlatformUma == 1) || + (Features.PlatformFeatures.PlatformUmaIfcm == 1) || + (Features.PlatformFeatures.PlatformIfcm == 1) || + (Features.PlatformFeatures.PlatformIommu == 1)) { + PowerStepEncoded = 0x8; + } else { + GetGivenModuleCoreRange ((UINT32) Socket, + (UINT32) Module, + &LowCore, + &NumOfCores, + StdHeader); + NumOfCores = ((NumOfCores - LowCore) + 1); + PowerStepTime = (UINT16) (400 / NumOfCores); + for (PowerStepEncoded = 0xF; PowerStepEncoded > 0; PowerStepEncoded--) { + if (PowerStepTime <= PowerStepEncodings[PowerStepEncoded]) { + break; + } + } + } + AndMask = 0xFFFFFFFF; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->PowerStepUp = 0; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->PowerStepDown = 0; + OrMask = 0x00000000; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->PowerStepUp = PowerStepEncoded; + ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->PowerStepDown = PowerStepEncoded; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); + + if ((LogicalId.Revision & AMD_F10_C3) != 0) { + // Set up Pop up P-state register + PciAddress.Address.Register = CPTC2_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + AndMask = 0xFFFFFFFF; + ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupPstate = 0; + ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuVid = 0; + ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuFid = 0; + ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuDid = 0; + OrMask = 0x00000000; + ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupEn = 0; + ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupPstate = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal; + LibAmdMsrRead ((((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal + PS_REG_BASE), &MsrRegister, StdHeader); + ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuVid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuVid; + ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuFid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuFid; + ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuDid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuDid; + PciAddress.Address.Register = POPUP_PSTATE_REG; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); + + // Set AltVidStart + PciAddress.Address.Register = CPTC1_REG; + AndMask = 0xFFFFFFFF; + ((CLK_PWR_TIMING_CTRL1_REGISTER *) &AndMask)->AltVidStart = 0; + OrMask = 0x00000000; + ((CLK_PWR_TIMING_CTRL1_REGISTER *) &OrMask)->AltVidStart = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuVid; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); + + // Set up Altvid slam time + PciAddress.Address.Register = CPTC2_REG; + VsSlamTime = F10CalculateAltvidVSSlamTimeOnCore (PviModeFlag, &PciAddress, CpuEarlyParams, StdHeader); + AndMask = 0xFFFFFFFF; + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->AltvidVSSlamTime = 0; + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->SlamTimeMode = 0; + OrMask = 0x00000000; + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->AltvidVSSlamTime = VsSlamTime; + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->SlamTimeMode = 2; + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); + } + + if (IsWarmReset (StdHeader) && !PviModeFlag) { + // Configure PsiVid + F10PmVrmLowPowerModeEnable (FamilySpecificServices, CpuEarlyParams, StdHeader); + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Support routine for F10CpuAmdPmPwrPlaneInit. + * + * This function implements step 1 on each core. + * + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F10PmPwrPlaneInitPviCore ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 MsrAddr; + UINT32 NbVid; + UINT32 CpuVid; + UINT64 MsrRegister; + + for (MsrAddr = PS_REG_BASE; MsrAddr <= PS_MAX_REG; MsrAddr++) { + LibAmdMsrRead (MsrAddr, &MsrRegister, StdHeader); + if (((PSTATE_MSR *) &MsrRegister)->PsEnable == (UINT64) 1) { + NbVid = (UINT32) (((PSTATE_MSR *) &MsrRegister)->NbVid); + CpuVid = (UINT32) (((PSTATE_MSR *) &MsrRegister)->CpuVid); + if (NbVid != CpuVid) { + if (NbVid > CpuVid) { + NbVid = CpuVid; + } + ((PSTATE_MSR *) &MsrRegister)->NbVid = NbVid; + ((PSTATE_MSR *) &MsrRegister)->CpuVid = NbVid; + LibAmdMsrWrite (MsrAddr, &MsrRegister, StdHeader); + } + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the encoded altvid voltage stabilization slam time for the executing + * family 10h core. + * + * This function calculates how much time it will take for the voltage to + * stabilize when transitioning from altvid to Pmin, and returns the necessary + * encoded value for the amount of time discovered. + * + * @param[in] PviModeFlag Whether or not the platform uses VRMs that + * employ the parallel VID interface. + * @param[in] PciAddress Full PCI address of the executing core's config space. + * @param[in] CpuEarlyParams Service parameters + * @param[in] StdHeader Config handle for library and services. + * + * @retval Encoded register value. + * + */ +UINT32 +STATIC +F10CalculateAltvidVSSlamTimeOnCore ( + IN BOOLEAN PviModeFlag, + IN PCI_ADDR *PciAddress, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NbVid; + UINT8 AltVidCode; + UINT8 PminVidCode; + UINT32 MsrAddr; + UINT32 PciRegister; + UINT64 MsrRegister; + PCI_ADDR LocalPciAddress; + + // Calculate Slam Time + // VSSlamTime = 0.4us/mV (or 0.2us/mV) * Vpmin - Altvid + // In our case, we will scale the values by 100 to avoid + // decimals. + + // Get Pmin's index + LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &MsrRegister, StdHeader); + MsrAddr = (UINT32) ((((PSTATE_CURLIM_MSR *) &MsrRegister)->PstateMaxVal) + PS_REG_BASE); + + // Get Pmin's VID + LibAmdMsrRead (MsrAddr, &MsrRegister, StdHeader); + PminVidCode = (UINT8) (((PSTATE_MSR *) &MsrRegister)->CpuVid); + + // If SVI, we only care about CPU VID. + // If PVI, determine the higher voltage b/t NB and CPU + if (PviModeFlag) { + NbVid = (UINT8) (((PSTATE_MSR *) &MsrRegister)->NbVid); + if (PminVidCode > NbVid) { + PminVidCode = NbVid; + } + } + + // Get Alt VID + LocalPciAddress.AddressValue = PciAddress->AddressValue; + LocalPciAddress.Address.Function = FUNC_3; + LocalPciAddress.Address.Register = CPTC2_REG; + LibAmdPciRead (AccessWidth32, LocalPciAddress, &PciRegister, StdHeader); + AltVidCode = (UINT8) (((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->AltVid); + + return (F10GetSlamTimeEncoding (PminVidCode, AltVidCode, CpuEarlyParams, AltvidSlamTime, StdHeader)); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Sets up PSI_L operation. + * + * This function implements the LowPowerThreshold parameter. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParams Contains VrmLowPowerThreshold parameter. + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +STATIC +F10PmVrmLowPowerModeEnable ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Pstate; + UINT32 PstateCurrent; + UINT32 NextPstateCurrent; + UINT32 AndMask; + UINT32 OrMask; + UINT32 PreviousVID; + UINT32 PstateVID; + UINT64 PstateMsr; + UINT64 PstateLimitMsr; + BOOLEAN EnablePsi; + PCI_ADDR PciAddress; + + if (CpuEarlyParams->PlatformConfig.VrmProperties.LowPowerThreshold != 0) { + EnablePsi = FALSE; + PreviousVID = 0x7F; // Initialize to invalid zero volt VID code + PstateVID = 0x7F; + LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &PstateLimitMsr, StdHeader); + + for (Pstate = 0; Pstate <= (UINT32) ((PSTATE_CURLIM_MSR *) &PstateLimitMsr)->PstateMaxVal; Pstate++) { + if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) Pstate, &PstateCurrent, StdHeader)) { + LibAmdMsrRead ((UINT32) (Pstate + PS_REG_BASE), &PstateMsr, StdHeader); + PstateVID = (UINT32) (((PSTATE_MSR *) &PstateMsr)->CpuVid); + if ((Pstate + 1) > (UINT32) ((PSTATE_CURLIM_MSR *) &PstateLimitMsr)->PstateMaxVal) { + NextPstateCurrent = 0; + } else if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrent, StdHeader)) { + NextPstateCurrent = CpuEarlyParams->PlatformConfig.VrmProperties.InrushCurrentLimit + NextPstateCurrent; + } + if ((PstateCurrent <= CpuEarlyParams->PlatformConfig.VrmProperties.LowPowerThreshold) && (NextPstateCurrent <= CpuEarlyParams->PlatformConfig.VrmProperties.LowPowerThreshold) && (PstateVID != PreviousVID)) { + EnablePsi = TRUE; + break; + } + PreviousVID = PstateVID; + } + } + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = PW_CTL_MISC_REG; + AndMask = 0xFFFFFFFF; + OrMask = 0x00000000; + ((POWER_CTRL_MISC_REGISTER *) &AndMask)->PsiVid = 0; + if (EnablePsi) { + ((POWER_CTRL_MISC_REGISTER *) &OrMask)->PsiVid = PstateVID; + ((POWER_CTRL_MISC_REGISTER *) &OrMask)->PsiVidEn = 1; + } else { + ((POWER_CTRL_MISC_REGISTER *) &AndMask)->PsiVidEn = 0; + } + ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerPlane.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerPlane.h new file mode 100755 index 0000000000..17c9777742 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10PowerPlane.h @@ -0,0 +1,76 @@ +/** + * @file + * + * AMD Family_10 Power Plane related functions and structures + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_F10_POWER_PLANE_H_ +#define _CPU_F10_POWER_PLANE_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 +F10CpuAmdPmPwrPlaneInit ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F10_POWER_PLANE_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Pstate.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Pstate.c new file mode 100755 index 0000000000..ef52322d12 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Pstate.c @@ -0,0 +1,154 @@ +/** + * @file + * + * AMD Family_10 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/F10 + * @e \$Revision: 18309 $ @e \$Date: 2009-08-27 15:48:22 +0800 (Thu, 27 Aug 2009) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuPstateTables.h" +#include "Table.h" +#include "cpuFamilyTranslation.h" +#include "cpuFamRegisters.h" +#include "CommonReturns.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10PSTATE_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 BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10IsPstatePsdDependent ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN OUT PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + CPU_LOGICAL_ID CpuLogicalId; + PLATFORM_FEATS Features; + + // Initialize the union + Features.PlatformValue = 0; + GetLogicalIdOfCurrentCore (&CpuLogicalId, StdHeader); + GetPlatformFeatures (&Features, PlatformConfig, StdHeader); + + // + // RevC Single link has PSD option, default is dependent. + // If multi-link, always return independent. + // + if ((Features.PlatformFeatures.PlatformSingleLink) && ((CpuLogicalId.Revision & AMD_F10_Cx) != 0)) { + if (PlatformConfig->ForcePstateIndependent) { + return FALSE; + } + return TRUE; + } + return FALSE; +} + +/** + * Family specific call to set core TscFreqSel. + * + * @param[in] PstateCpuServices Pstate CPU services. + * @param[in] StdHeader Config Handle for library, services. + * + */ +VOID +STATIC +F10SetTscFreqSel ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrValue; + + LibAmdMsrRead (MSR_HWCR, &MsrValue, StdHeader); + if (UserOptions.OptionMultisocket) { + // + // If Agesa need to do p-state leveling on multi-socket, changing the P0 + // frequency after setting this bit has no effect on the TSC rate. + // + ASSERT ((MsrValue & BIT24) == 0); + } + MsrValue = MsrValue | BIT24; + LibAmdMsrWrite (MSR_HWCR, &MsrValue, StdHeader); +} + +CONST PSTATE_CPU_FAMILY_SERVICES ROMDATA F10PstateServices = +{ + 0, + F10IsPstatePsdDependent, + F10SetTscFreqSel +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10SoftwareThermal.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10SoftwareThermal.c new file mode 100755 index 0000000000..d7e03d4b79 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10SoftwareThermal.c @@ -0,0 +1,120 @@ +/** + * @file + * + * AMD Family_10 thermal initialization + * + * Performs processor thermal initialization. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuF10PowerMgmt.h" +#include "cpuF10SoftwareThermal.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10SOFTWARETHERMAL_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 initializing the Thermal Control + * safety net feature. + * + * This must be run by all Family 10h core 0s in the system. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuEarlyParamsPtr Service parameters. + * @param[in] StdHeader Config handle for library and services. + */ +VOID +F10PmThermalInit ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Core; + UINT32 Module; + UINT32 PciRegister; + UINT32 Socket; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); + ASSERT (Core == 0); + + if (GetPciAddress (StdHeader, Socket, 0, &PciAddress, &IgnoredSts)) { + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = NB_CAPS_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if (((NB_CAPS_REGISTER *) &PciRegister)->HtcCapable == 1) { + // Enable HTC + PciAddress.Address.Register = HTC_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((HTC_REGISTER *) &PciRegister)->HtcSlewSel = 0; + ((HTC_REGISTER *) &PciRegister)->HtcEn = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + } + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10SoftwareThermal.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10SoftwareThermal.h new file mode 100755 index 0000000000..4715f3b95d --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10SoftwareThermal.h @@ -0,0 +1,78 @@ +/** + * @file + * + * AMD Family_10 thermal initialization related functions and structures + * + * Performs processor thermal initialization. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_F10_SOFTWARE_THERMAL_H_ +#define _CPU_F10_SOFTWARE_THERMAL_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 +F10PmThermalInit ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F10_SOFTWARE_THERMAL_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Utilities.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Utilities.c new file mode 100755 index 0000000000..549c59e134 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Utilities.c @@ -0,0 +1,1768 @@ +/** + * @file + * + * AMD Family_10 specific utility functions. + * + * Provides numerous utility functions specific to family 10h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/F10 + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuF10PowerMgmt.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuF10Utilities.h" +#include "cpuPostInit.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10UTILITIES_FILECODE + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +// Register encodings for F3xD8[VSRampTime/VSSlamTime] +CONST UINT32 ROMDATA VSSlamTime[8] = +{ + 10, // 000b: 10us + 20, // 001b: 20us + 30, // 010b: 30us + 40, // 011b: 40us + 60, // 100b: 60us + 100, // 101b: 100us + 200, // 110b: 200us + 500 // 111b: 500us +}; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +F10GetNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT UINT32 *FrequencyInMHz, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ); +VOID +F10GetHtLinkFeatures ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINTN *Link, + IN PCI_ADDR *LinkBase, + OUT HT_HOST_FEATS *HtHostFeats, + IN AMD_CONFIG_PARAMS *StdHeader + ); +BOOLEAN +F10DoesLinkHaveHtPhyFeats ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR CapabilitySet, + IN UINT32 Link, + IN HT_PHY_LINK_FEATS *HtPhyLinkType, + OUT BOOLEAN *MatchedSublink1, + OUT HT_FREQUENCIES *Frequency0, + OUT HT_FREQUENCIES *Frequency1, + IN AMD_CONFIG_PARAMS *StdHeader + ); +VOID +F10SetHtPhyRegister ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN HT_PHY_TYPE_ENTRY_DATA *HtPhyEntry, + IN PCI_ADDR CapabilitySet, + IN UINT32 Link, + IN AMD_CONFIG_PARAMS *StdHeader + ); +VOID +F10SetRegisterForHtLinkTokenEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Performs the necessary steps for the 'Software Initiated CPU + * Voltage Transitions.' + * + * @param[in] VidCode VID code to transition to + * @param[in] StdHeader Header for library and services + * + */ +VOID +F10PmSwVoltageTransition ( + IN UINT32 VidCode, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PciRegister; + UINT32 Socket; + UINT32 Module; + UINT32 Ignored; + UINT64 MsrRegister; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + IdentifyCore (StdHeader, &Socket, &Module, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = PW_CTL_MISC_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if (((POWER_CTRL_MISC_REGISTER *) &PciRegister)->SlamVidMode == 1) { + LibAmdMsrRead (MSR_COFVID_CTL, &MsrRegister, StdHeader); + ((COFVID_CTRL_MSR *) &MsrRegister)->CpuVid = VidCode; + LibAmdMsrWrite (MSR_COFVID_CTL, &MsrRegister, StdHeader); + F10WaitOutVoltageTransition (TRUE, StdHeader); + } else + return; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Performs the necessary steps for the 'Software Initiated NB + * Voltage Transitions.' + * + * This can only be run by a local core 0. + * + * @param[in] VidCode VID code to transition to + * @param[in] SlamMode Whether voltage is to be slammed, or stepped + * @param[in] StdHeader Header for library and services + * + */ +VOID +F10PmSwVoltageTransitionServerNb ( + IN UINT32 VidCode, + IN BOOLEAN SlamMode, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Core; + UINT32 NbVidStatus; + UINT32 Socket; + UINT32 IgnoredModule; + UINT32 IgnoredCore; + UINT32 CoreNum; + AP_TASK TaskPtr; + AGESA_STATUS IgnoredSts; + SW_VOLT_TRANS_NB RemoteInput; + + RemoteInput.VidCode = VidCode; + RemoteInput.SlamMode = SlamMode; + TaskPtr.FuncAddress.PfApTaskIO = F10SwVoltageTransitionServerNbCore; + TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (SW_VOLT_TRANS_NB); + TaskPtr.DataTransfer.DataPtr = &RemoteInput; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + + IdentifyCore (StdHeader, &Socket, &IgnoredModule, &IgnoredCore, &IgnoredSts); + GetActiveCoresInCurrentSocket (&CoreNum, StdHeader); + + do { + NbVidStatus = TaskPtr.FuncAddress.PfApTaskIO (&RemoteInput, StdHeader); + for (Core = 1; Core < (UINT8) CoreNum; Core++) { + NbVidStatus |= ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8)Core, &TaskPtr, StdHeader); + } + F10WaitOutVoltageTransition (SlamMode, StdHeader); + } while (NbVidStatus != 0); + return; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns current VsSlamTime in microseconds. + * + * @param[out] VsTimeUsecs Provides the wait time needed for a Slam Voltage transition. + * @param[in] SlamMode Whether voltage is to be slammed, or stepped + * @param[in] StdHeader Header for library and services + * + */ +VOID +F10GetCurrentVsTimeInUsecs ( + OUT UINT32 *VsTimeUsecs, + IN BOOLEAN SlamMode, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 RegisterEncoding; + UINT32 PciRegister; + UINT32 Socket; + UINT32 Module; + UINT32 Ignored; + CONST UINT16 SlamTimes[8] = {10, 20, 30, 40, 60, 100, 200, 500}; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + IdentifyCore (StdHeader, &Socket, &Module, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = CPTC1_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + + if (SlamMode) { + RegisterEncoding = (UINT8) ((CLK_PWR_TIMING_CTRL1_REGISTER *) &PciRegister)->VSSlamTime; + } else { + RegisterEncoding = (UINT8) ((CLK_PWR_TIMING_CTRL1_REGISTER *) &PciRegister)->VSRampTime; + } + + *VsTimeUsecs = (UINT32) SlamTimes[RegisterEncoding]; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Spins until VsSlamTime microseconds have expired. + * + * @param[in] SlamMode Whether voltage is to be slammed, or stepped + * @param[in] StdHeader Header for library and services + * + */ +VOID +F10WaitOutVoltageTransition ( + IN BOOLEAN SlamMode, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 VsTimeUsecs; + + F10GetCurrentVsTimeInUsecs (&VsTimeUsecs, SlamMode, StdHeader); + WaitMicroseconds (VsTimeUsecs, StdHeader); + return; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Code required to be run on every local core in order to perform + * the steps necessary for 'Software Initiated NB Voltage + * Transitions.' + * + * @param[out] InputData Family specific data needed to perform a Voltage transition. + * @param[in] StdHeader Header for library and services. + * + * @retval zero All Voltage Transitions are completed. + * @retval one There are Voltage transitions remaining to reach target. + * + */ +UINT32 +F10SwVoltageTransitionServerNbCore ( + IN VOID *InputData, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 VidCode; + UINT64 MsrRegister; + + if (((SW_VOLT_TRANS_NB *) InputData)->SlamMode) { + VidCode = ((SW_VOLT_TRANS_NB *) InputData)->VidCode; + } else { + LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); + VidCode = (UINT32) (((COFVID_STS_MSR *) &MsrRegister)->CurNbVid); + if (VidCode > ((SW_VOLT_TRANS_NB *) InputData)->VidCode) { + --VidCode; + } else if (VidCode < ((SW_VOLT_TRANS_NB *) InputData)->VidCode) { + ++VidCode; + } + } + LibAmdMsrRead (MSR_COFVID_CTL, &MsrRegister, StdHeader); + ((COFVID_CTRL_MSR *) &MsrRegister)->NbVid = VidCode; + LibAmdMsrWrite (MSR_COFVID_CTL, &MsrRegister, StdHeader); + + if (VidCode == ((SW_VOLT_TRANS_NB *) InputData)->VidCode) { + return 0; + } else { + return 1; + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Calculate and reprogram F3xD8[VSSlamTime] based on the algorithm in the BKDG. + * + * This function determines the largest voltage step that the core will have + * to make, calculates how much time it will take for the voltage to stabilize, + * and programs the necessary encoded value for the amount of time discovered. + * + * @param[in] PciAddress Segment/bus/device of a module on the socket + * to program. + * @param[in] CpuEarlyParams Service parameters + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F10ProgramVSSlamTimeOnSocket ( + IN PCI_ADDR *PciAddress, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NbVid; + UINT8 P0VidCode; + UINT8 PminVidCode; + UINT32 AndMask; + UINT32 MsrAddr; + UINT32 OrMask; + UINT32 PciRegister; + UINT64 MsrRegister; + BOOLEAN IsPviMode; + PCI_ADDR LocalPciAddress; + + // Get F3xA0[PviMode] + LocalPciAddress.AddressValue = PciAddress->AddressValue; + LocalPciAddress.Address.Function = FUNC_3; + LocalPciAddress.Address.Register = PW_CTL_MISC_REG; + LibAmdPciRead (AccessWidth32, LocalPciAddress, &PciRegister, StdHeader); + if (((POWER_CTRL_MISC_REGISTER *) &PciRegister)->PviMode == 1) { + IsPviMode = TRUE; + } else { + IsPviMode = FALSE; + } + + // Get P0's voltage + LibAmdMsrRead (PS_REG_BASE, &MsrRegister, StdHeader); + P0VidCode = (UINT8) (((PSTATE_MSR *) &MsrRegister)->CpuVid); + + // If SVI, we only care about CPU VID. + // If PVI, determine the higher voltage between NB and CPU + if (IsPviMode) { + NbVid = (UINT8) (((PSTATE_MSR *) &MsrRegister)->NbVid); + if (P0VidCode > NbVid) { + P0VidCode = NbVid; + } + } + + // Get Pmin's index + LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &MsrRegister, StdHeader); + MsrAddr = (UINT32) ((((PSTATE_CURLIM_MSR *) &MsrRegister)->PstateMaxVal) + PS_REG_BASE); + + // Get Pmin's VID + LibAmdMsrRead (MsrAddr, &MsrRegister, StdHeader); + PminVidCode = (UINT8) (((PSTATE_MSR *) &MsrRegister)->CpuVid); + + // If SVI, we only care about CPU VID. + // If PVI, determine the higher voltage b/t NB and CPU + if (IsPviMode) { + NbVid = (UINT8) (((PSTATE_MSR *) &MsrRegister)->NbVid); + if (PminVidCode > NbVid) { + PminVidCode = NbVid; + } + } + + // Program F3xD8[VSSlamTime] + LocalPciAddress.Address.Register = CPTC1_REG; + AndMask = 0xFFFFFFFF; + ((CLK_PWR_TIMING_CTRL1_REGISTER *) &AndMask)->VSSlamTime = 0; + OrMask = 0x00000000; + ((CLK_PWR_TIMING_CTRL1_REGISTER *) &OrMask)->VSSlamTime = + F10GetSlamTimeEncoding (P0VidCode, PminVidCode, CpuEarlyParams, VSSlamTime, StdHeader); + ModifyCurrentSocketPci (&LocalPciAddress, AndMask, OrMask, StdHeader); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Returns the encoded voltage stabilization slam time for the executing + * family 10h core. + * + * This function looks up the appropriate encoded value for the desired + * VID codes. + * + * @param[in] HighVoltageVid VID code of the higher voltage. + * @param[in] LowVoltageVid VID code of the lower voltage. + * @param[in] CpuEarlyParams Service parameters + * @param[in] SlamTimeTable Look-up table of slam times. + * @param[in] StdHeader Config handle for library and services. + * + * @retval Encoded register value. + * + */ +UINT32 +F10GetSlamTimeEncoding ( + IN UINT8 HighVoltageVid, + IN UINT8 LowVoltageVid, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN CONST UINT32 *SlamTimeTable, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 SlamTime; + UINT32 EncodedSlamTime; + UINT32 VoltageDifference; + + ASSERT (LowVoltageVid >= HighVoltageVid); + ASSERT (CpuEarlyParams->PlatformConfig.VrmProperties.SlewRate != 0); + + // Calculate Slam Time + // VSSlamTime = 0.4us/mV (or 0.2us/mV) * Vhigh - Vlow + // In our case, we will scale the values by 100 to avoid + // decimals. + + VoltageDifference = (UINT32) ((LowVoltageVid - HighVoltageVid) * 12500); + SlamTime = (VoltageDifference / CpuEarlyParams->PlatformConfig.VrmProperties.SlewRate) + CpuEarlyParams->PlatformConfig.VrmProperties.AdditionalDelay; + if (VoltageDifference % CpuEarlyParams->PlatformConfig.VrmProperties.SlewRate) { + SlamTime++; + } + + // Now round up to nearest register setting + for (EncodedSlamTime = 0; EncodedSlamTime < 8; EncodedSlamTime++) { + if (SlamTime <= SlamTimeTable[EncodedSlamTime]) { + break; + } + } + + if (EncodedSlamTime > 7) { + // The VRMs are too slow for this CPU. Set to max, and fire an error trap. + IDS_ERROR_TRAP; + EncodedSlamTime = 7; + } + + return (EncodedSlamTime); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Calculates the power in milliWatts of the desired P-state. + * + * @CpuServiceMethod{::F_CPU_GET_PSTATE_POWER}. + * + * @param[in] FamilySpecificServices The current Family Specific 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 +F10GetPstatePower ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + OUT UINT32 *PowerInMw, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CpuVid; + UINT32 IddValue; + UINT32 IddDiv; + UINT32 Socket; + UINT32 Module; + UINT32 Ignored; + BOOLEAN PviFlag; + UINT32 V_x10000; + UINT32 Power; + PCI_ADDR PciAddress; + UINT32 TempVar_a; + UINT64 MsrRegister; + AGESA_STATUS IgnoredSts; + + ASSERT (StateNumber < NM_PS_REG); + LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &MsrRegister, StdHeader); + ASSERT (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1); + CpuVid = (UINT32) (((PSTATE_MSR *) &MsrRegister)->CpuVid); + IddValue = (UINT32) (((PSTATE_MSR *) &MsrRegister)->IddValue); + IddDiv = (UINT32) (((PSTATE_MSR *) &MsrRegister)->IddDiv); + + IdentifyCore (StdHeader, &Socket, &Module, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + + PciAddress.Address.Function = FUNC_3; + PciAddress.Address.Register = POWER_CTRL_MISCELLANEOUS_REG; + LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_a, StdHeader); + if ((TempVar_a & 0x00000100) != 0) { + PviFlag = TRUE; + } else { + PviFlag = FALSE; + } + if (PviFlag) { + // Set CpuVid value in case CPU is in PVI mode + if (CpuVid > 0x5D) { + CpuVid = 0x3F; + } else if (CpuVid > 0x3E) { + CpuVid = CpuVid - 0x1F; + } else { + CpuVid = (CpuVid >> 1); + } + + // PVI Encoding + if (CpuVid >= 0x20) { + V_x10000 = 7625L - (125L * (CpuVid - 0x20)); + } else { + V_x10000 = 15500L - (250L * CpuVid); + } + } else { + if (CpuVid >= 0x7C) { + V_x10000 = 0; + } else { + V_x10000 = 15500L - (125L * CpuVid); + } + } + + Power = V_x10000 * IddValue; + + switch (IddDiv) { + case 0: + *PowerInMw = Power / 10L; + break; + case 1: + *PowerInMw = Power / 100L; + break; + case 2: + *PowerInMw = Power / 1000L; + 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; + } + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Calculates the frequency in megahertz of the desired P-state. + * + * @CpuServiceMethod{::F_CPU_GET_PSTATE_FREQ}. + * + * @param[in] FamilySpecificServices The current Family Specific 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 +F10GetPstateFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 TempValue; + UINT32 CpuDid; + UINT32 CpuFid; + UINT64 MsrRegister; + + ASSERT (StateNumber < NM_PS_REG); + LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &MsrRegister, StdHeader); + ASSERT (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1); + CpuDid = (UINT32) (((PSTATE_MSR *) &MsrRegister)->CpuDid); + CpuFid = (UINT32) (((PSTATE_MSR *) &MsrRegister)->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); + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10DisablePstate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrRegister; + + ASSERT (StateNumber < NM_PS_REG); + LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &MsrRegister, StdHeader); + ((PSTATE_MSR *) &MsrRegister)->PsEnable = 0; + LibAmdMsrWrite (PS_REG_BASE + (UINT32) StateNumber, &MsrRegister, 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 +F10TransitionPstate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN BOOLEAN WaitForTransition, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrRegister; + + ASSERT (StateNumber < NM_PS_REG); + LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &MsrRegister, StdHeader); + ASSERT (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1); + LibAmdMsrRead (MSR_PSTATE_CTL, &MsrRegister, StdHeader); + ((PSTATE_CTRL_MSR *) &MsrRegister)->PstateCmd = (UINT64) StateNumber; + LibAmdMsrWrite (MSR_PSTATE_CTL, &MsrRegister, StdHeader); + if (WaitForTransition) { + do { + LibAmdMsrRead (MSR_PSTATE_STS, &MsrRegister, StdHeader); + } while (((PSTATE_STS_MSR *) &MsrRegister)->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 +F10GetTscRate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 Ignored; + UINT64 MsrRegister; + PCI_ADDR PciAddress; + AGESA_STATUS IgnoredSts; + + LibAmdMsrRead (0xC0010015, &MsrRegister, StdHeader); + if ((MsrRegister & 0x01000000) != 0) { + return (FamilySpecificServices->GetPstateFrequency (FamilySpecificServices, 0, FrequencyInMHz, StdHeader)); + } else { + IdentifyCore (StdHeader, &Socket, &Module, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); + return (FamilySpecificServices->GetNbFrequency (FamilySpecificServices, &PciAddress, FrequencyInMHz, &Ignored, StdHeader)); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Determines the NB clock on the desired node. + * + * @CpuServiceMethod{::F_CPU_GET_NB_FREQ}. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PciAddress The northbridge to query + * @param[out] FrequencyInMHz Northbridge clock frequency in MHz. + * @param[out] VoltageInuV Northbridge voltage in uV. + * @param[in] StdHeader Header for library and services + * + * @retval AGESA_UNSUPPORTED Unknown revs of F10 will return unsupported. + */ +AGESA_STATUS +F10GetNbFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT UINT32 *FrequencyInMHz, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + // This was called by an unknown rev of F10 CPU. + return (AGESA_UNSUPPORTED); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +F10LaunchApCore ( + 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 PciRegister; + PCI_ADDR PciAddress; + BOOLEAN LaunchFlag; + AGESA_STATUS Ignored; + + // Code Start + LaunchFlag = FALSE; + NodeRelativeCoreNum = CoreNum - PrimaryCoreNum; + GetPciAddress (StdHeader, SocketNum, ModuleNum, &PciAddress, &Ignored); + PciAddress.Address.Function = FUNC_0; + + switch (NodeRelativeCoreNum) { + case 0: + PciAddress.Address.Register = HT_INIT_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if ((PciRegister & HT_INIT_CTRL_REQ_DIS) != 0) { + PciRegister &= ~HT_INIT_CTRL_REQ_DIS; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + LaunchFlag = TRUE; + } else { + LaunchFlag = FALSE; + } + break; + + case 1: + PciAddress.Address.Register = HT_TRANS_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if ((PciRegister & HT_TRANS_CTRL_CPU1_EN) == 0) { + PciRegister |= HT_TRANS_CTRL_CPU1_EN; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + LaunchFlag = TRUE; + } else { + LaunchFlag = FALSE; + } + break; + + case 2: + PciAddress.Address.Register = ECS_HT_TRANS_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + + if ((PciRegister & ECS_HT_TRANS_CTRL_CPU2_EN) == 0) { + PciRegister |= ECS_HT_TRANS_CTRL_CPU2_EN; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, + StdHeader); + LaunchFlag = TRUE; + } else { + LaunchFlag = FALSE; + } + break; + + case 3: + PciAddress.Address.Register = ECS_HT_TRANS_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if ((PciRegister & ECS_HT_TRANS_CTRL_CPU3_EN) == 0) { + PciRegister |= ECS_HT_TRANS_CTRL_CPU3_EN; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + LaunchFlag = TRUE; + } else { + LaunchFlag = FALSE; + } + break; + + case 4: + PciAddress.Address.Register = ECS_HT_TRANS_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if ((PciRegister & ECS_HT_TRANS_CTRL_CPU4_EN) == 0) { + PciRegister |= ECS_HT_TRANS_CTRL_CPU4_EN; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + LaunchFlag = TRUE; + } else { + LaunchFlag = FALSE; + } + break; + + case 5: + PciAddress.Address.Register = ECS_HT_TRANS_CTRL; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + if ((PciRegister & ECS_HT_TRANS_CTRL_CPU5_EN) == 0) { + PciRegister |= ECS_HT_TRANS_CTRL_CPU5_EN; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + LaunchFlag = TRUE; + } else { + LaunchFlag = FALSE; + } + break; + + + default: + break; + } + + return (LaunchFlag); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will return the CpuFid and CpuDid in MHz, using the formula + * described in the BKDG MSRC001_00[68:64] P-State [4:0] Registers:bit 8:0 + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] PStateNumber P-state number to check. + * @param[in] Frequency Leveled target frequency for PStateNumber. + * @param[out] *CpuFidPtr New leveled FID. + * @param[out] *CpuDidPtr1 New leveled DID info 1. + * @param[out] *CpuDidPtr2 New leveled DID info 2. + * @param[in] *StdHeader Header for library and services. + * + * @retval AGESA_WARNING This P-State does not need to be modified. + * @retval AGESA_SUCCESS This P-State must be modified to be level. + */ +AGESA_STATUS +F10GetFrequencyXlatRegInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 PStateNumber, + IN UINT32 Frequency, + OUT UINT32 *CpuFidPtr, + OUT UINT32 *CpuDidPtr1, + OUT UINT32 *CpuDidPtr2, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 i; + UINT32 j; + AGESA_STATUS Status; + UINT32 FrequencyInMHz; + + FrequencyInMHz = 0; + *CpuDidPtr2 = 0xFFFF; + + Status = AGESA_SUCCESS; + + FamilySpecificServices->GetPstateFrequency (FamilySpecificServices, PStateNumber, &FrequencyInMHz, StdHeader); + if (FrequencyInMHz == Frequency) { + Status |= AGESA_WARNING; + } + + // CPU Frequency = 100 MHz * (CpuFid + 10h) / (2^CpuDid) + // In this for loop i = 2^CpuDid + + + for (i = 1; i < 17; (i += i)) { + for (j = 0; j < 64; j++) { + if (Frequency == ((100 * (j + 0x10)) / i )) { + *CpuFidPtr = j; + if (i == 1) { + *CpuDidPtr1 = 0; + } else if (i == 2) { + *CpuDidPtr1 = 1; + } else if (i == 4) { + *CpuDidPtr1 = 2; + } else if (i == 8) { + *CpuDidPtr1 = 3; + } else if (i == 16) { + *CpuDidPtr1 = 4; + } else { + *CpuFidPtr = 0xFFFF; + *CpuDidPtr1 = 0xFFFF; + } + // Success + return Status; + } + } + } + + // Error Condition + *CpuFidPtr = 0x00FF; + *CpuDidPtr1 = 0x00FF; + *CpuDidPtr2 = 0x00FF; + + return AGESA_ERROR; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * This function sets the Pstate MSR to each APs base on Pstate Buffer. + * + * @CpuServiceMethod{::F_CPU_SET_PSTATE_LEVELING_REG}. + * + * This function should be called for every core in the system. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CpuAmdPState Gathered P-state data structure for whole system. + * @param[in] StdHeader Config for library and services. + * + * @retval AGESA_STATUS @todo document return *values*. + * + */ +AGESA_STATUS +F10PstateLevelingCoreMsrModify ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN S_CPU_AMD_PSTATE *CpuAmdPState, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 i; + UINT32 Ignored; + UINT32 k; + UINT32 TempVar_d; + UINT32 TempVar_e; + UINT32 TempVar_f; + UINT64 MsrValue; + AGESA_STATUS Status; + UINT32 Socket; + UINT32 Module; + UINT32 Core; + PSTATE_LEVELING *PStateBufferPtr; + PSTATE_LEVELING *PStateBufferPtrTmp; + S_CPU_AMD_PSTATE *CpuAmdPstatePtr; + UINT32 LogicalSocketCount; + PCI_ADDR PciAddress; + UINT32 PciRegister; + + Ignored = 0; + CpuAmdPstatePtr = (S_CPU_AMD_PSTATE *) CpuAmdPState; + PStateBufferPtrTmp = CpuAmdPstatePtr->PStateLevelingStruc; + PStateBufferPtr = CpuAmdPstatePtr->PStateLevelingStruc; + LogicalSocketCount = CpuAmdPstatePtr->TotalSocketInSystem; + PciAddress.AddressValue = 0; + + // + //Try to find the Pstate buffer specific to this core(socket). + // + IdentifyCore (StdHeader, &Socket, &Module, &Core, &Status); + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, CpuAmdPstatePtr, i, StdHeader); + if (PStateBufferPtrTmp->SocketNumber == Socket) { + break; + } + } + + if (PStateBufferPtr[0].OnlyOneEnabledPState) { + // + //If all processors have only 1 enabled P-state, the following sequence should be performed on all cores: + // + + //1. Write the appropriate CpuFid value resulting from the matched CPU COF to MSRC001_0064[CpuFid]. + LibAmdMsrRead (MSR_PSTATE_0, &MsrValue, StdHeader); + Status = F10GetFrequencyXlatRegInfo (FamilySpecificServices, 0, PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].CoreFreq, &TempVar_d, &TempVar_e, &Ignored, StdHeader); + // Bits 5:0 + ((PSTATE_MSR *) &MsrValue)->CpuFid = TempVar_d; + // Bits 8:6 + ((PSTATE_MSR *) &MsrValue)->CpuDid = TempVar_e; + // Bits 39:32 + ((PSTATE_MSR *) &MsrValue)->IddValue = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddValue; + // Bits 41:40 + ((PSTATE_MSR *) &MsrValue)->IddDiv = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddDiv; + // Enable the P-State + ((PSTATE_MSR *) &MsrValue)->PsEnable = 1; + LibAmdMsrWrite (MSR_PSTATE_0, &MsrValue, StdHeader); + + //2. Copy MSRC001_0064 to MSRC001_0065. + LibAmdMsrWrite (MSR_PSTATE_1, &MsrValue, StdHeader); + + //3. Write 001b to F3xDC[PstatemaxVal]. + GetPciAddress (StdHeader, Socket, Module, &PciAddress, &Status); + PciAddress.Address.Register = CPTC2_REG; + PciAddress.Address.Function = FUNC_3; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal = 1; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + + //4. Write 001b to MSRC001_0062[PstateCmd]. + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 1, (BOOLEAN) FALSE, StdHeader); + + //5. Wait for MSRC001_0071[CurCpuFid] = MSRC001_0065[CpuFid]. + do { + LibAmdMsrRead (MSR_COFVID_STS, &MsrValue, StdHeader); + } while (((COFVID_STS_MSR *) &MsrValue)->CurCpuFid != TempVar_d); + + //6. Write 000b to MSRC001_0062[PstateCmd]. + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) FALSE, StdHeader); + + //7. Wait for MSRC001_0071[CurCpuFid] = MSRC001_0064[CpuFid]. + do { + LibAmdMsrRead (MSR_COFVID_STS, &MsrValue, StdHeader); + } while (((COFVID_STS_MSR *) &MsrValue)->CurCpuFid != TempVar_d); + + //8. Write 0b to MSRC001_0065[PstateEn]. + LibAmdMsrRead (MSR_PSTATE_1, &MsrValue, StdHeader); + ((PSTATE_MSR *) &MsrValue)->PsEnable = 0; + LibAmdMsrWrite (MSR_PSTATE_1, &MsrValue, StdHeader); + + //9. Write 000b to F3xDC[PstateMaxVal] and exit the sequence (no further steps are required). + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal = 0; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + + } else { + TempVar_f = MSR_PSTATE_0; + + for (k = 0; k <= PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; k++, TempVar_f++) { + // If pState is not disabled then do update + LibAmdMsrRead (TempVar_f, &MsrValue, StdHeader); + + if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable == 1) { + Status = F10GetFrequencyXlatRegInfo (FamilySpecificServices, (UINT8) k, PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].CoreFreq, &TempVar_d, &TempVar_e, &Ignored, StdHeader); + if (Status != AGESA_ERROR) { + // Bits 5:0 + ((PSTATE_MSR *) &MsrValue)->CpuFid = TempVar_d; + // Bits 8:6 + ((PSTATE_MSR *) &MsrValue)->CpuDid = TempVar_e; + } + + // Bits 39:32 + ((PSTATE_MSR *) &MsrValue)->IddValue = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].IddValue; + // Bits 41:40 + ((PSTATE_MSR *) &MsrValue)->IddDiv = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].IddDiv; + // Enable the P-State + ((PSTATE_MSR *) &MsrValue)->PsEnable = 1; + LibAmdMsrWrite (TempVar_f, &MsrValue, StdHeader); + } else { + // Disable the P-State + ((PSTATE_MSR *) &MsrValue)->PsEnable = 0; + LibAmdMsrWrite (TempVar_f, &MsrValue, StdHeader); + } + } + } + return AGESA_SUCCESS; +} + +/** + *--------------------------------------------------------------------------------------- + * + * F10GetPowerStepValueInTime + * + * Description: + * Convert power step value in time + * + * Parameters: + * @param[out] *PowerStepPtr + * + * @retval VOID + * + *--------------------------------------------------------------------------------------- + **/ +STATIC VOID +F10GetPowerStepValueInTime ( + IN OUT UINT32 *PowerStepPtr + ) +{ + UINT32 TempVar_a; + + 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); + } +} + + +/** + *--------------------------------------------------------------------------------------- + * + * F10GetPllValueInTime + * + * Description: + * Convert PLL Value in time + * + * Parameters: + * @param[out] *PllLockTimePtr + * + * @retval VOID + * + *--------------------------------------------------------------------------------------- + **/ +STATIC VOID +F10GetPllValueInTime ( + IN OUT UINT32 *PllLockTimePtr + ) +{ + if (*PllLockTimePtr < 4) { + *PllLockTimePtr = *PllLockTimePtr + 1; + } else if (*PllLockTimePtr == 4) { + *PllLockTimePtr = 8; + } else if (*PllLockTimePtr == 5) { + *PllLockTimePtr = 16; + } else + *PllLockTimePtr = 0; +} +/*---------------------------------------------------------------------------------------*/ +/** + * Get Pstate Transition Latency. + * + * @CpuServiceMethod{::F_CPU_PSTATE_TRANSITION_LATENCY}. + * + * Calculate TransitionLatency by power step value and pll value. + * + * @param[in] FamilySpecificServices The current Family Specific 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 +F10GetPstateTransLatency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PSTATE_LEVELING *PStateLevelingBufferStructPtr, + IN PCI_ADDR *PciAddress, + OUT UINT32 *TransitionLatency, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TempVar_b; + UINT32 TempVar_c; + UINT32 TempVar_d; + UINT32 TempVar8_a; + UINT32 TempVar8_b; + UINT32 Ignored; + UINT32 k; + UINT32 CpuFidSameFlag; + UINT8 PStateMaxValueOnCurrentCore; + UINT32 TransAndBusMastLatency; + + CpuFidSameFlag = 1; + + F10GetFrequencyXlatRegInfo ( + FamilySpecificServices, + 0, + PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[0].CoreFreq, + &TempVar_b, + &TempVar_c, + &Ignored, + StdHeader + ); + + TempVar_d = TempVar_b; + PStateMaxValueOnCurrentCore = PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue; + + // + //Check if MSRC001_00[68:64][CpuFid] is the same value for all P-states where + //MSRC001_00[68:64][PstateEn]=1 + // + for (k = 1; k <= PStateMaxValueOnCurrentCore; k++) { + if (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].PStateEnable != 0) { + F10GetFrequencyXlatRegInfo ( + FamilySpecificServices, + (UINT8) k, + PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq, + &TempVar_b, + &TempVar_c, + &Ignored, + StdHeader + ); + } + + if (TempVar_d != TempVar_b) { + CpuFidSameFlag = 0; + break; + } + } + + PciAddress->Address.Register = 0xD4; + PciAddress->Address.Function = FUNC_3; + LibAmdPciRead (AccessWidth32, *PciAddress, &TempVar_d, StdHeader); + + // PowerStepDown - Bits 20:23 + TempVar8_a = (TempVar_d & 0x00F00000) >> 20; + + // PowerStepUp - Bits 24:27 + TempVar8_b = (TempVar_d & 0x0F000000) >> 24; + + // Convert the raw numbers in TempVar8_a and TempVar8_b into time + F10GetPowerStepValueInTime (&TempVar8_a); + F10GetPowerStepValueInTime (&TempVar8_b); + + // + //(12 * (F3xD4[PowerStepDown] + F3xD4[PowerStepUp]) /1000) us + // + TransAndBusMastLatency = + (12 * (TempVar8_a + TempVar8_b) + 999) / 1000; + + if (CpuFidSameFlag == 0) { + // + //+ F3xA0[PllLockTime] + // + PciAddress->Address.Register = 0xA0; + LibAmdPciRead (AccessWidth32, *PciAddress, &TempVar_d, StdHeader); + + TempVar8_a = (0x00003800 & TempVar_d) >> 11; + F10GetPllValueInTime (&TempVar8_a); + TransAndBusMastLatency += TempVar8_a; + } + + *TransitionLatency = TransAndBusMastLatency; + + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get CPU pstate register Informations. + * + * @CpuServiceMethod{::F_CPU_GET_PSTATE_REGISTER_INFO}. + * + * This function will check if PState is Enabled by reading MSR. + * This function also returns the MSR Value, that contains IddValue, IddDiv. + * + * @param[in] FamilySpecificServices The current Family Specific 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[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F10GetPstateRegisterInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 PState, + OUT BOOLEAN *PStateEnabled, + IN OUT UINT32 *IddVal, + IN OUT UINT32 *IddDiv, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrRegister; + + ASSERT (PState < NM_PS_REG); + + // Read PSTATE MSRs + LibAmdMsrRead (PS_REG_BASE + (UINT32) PState, &MsrRegister, StdHeader); + + if (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1) { + // PState enable = bit 63 + *PStateEnabled = TRUE; + } else { + *PStateEnabled = FALSE; + } + + // Bits 39:32 (high 32 bits [7:0]) + *IddVal = (UINT32) ((PSTATE_MSR *) &MsrRegister)->IddValue; + // Bits 41:40 (high 32 bits [9:8]) + *IddDiv = (UINT32) ((PSTATE_MSR *) &MsrRegister)->IddDiv; + + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get CPU pstate max state. + * + * @CpuServiceMethod{::F_CPU_GET_PSTATE_MAX_STATE}. + * + * This function returns the MaxPStateNumber. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] MaxPStateNumber Boolean flag return pstate enable. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F10GetPstateMaxState ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *MaxPStateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrValue; + + // + // 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); + + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get CPU Specific Platform Type Info. + * + * @CpuServiceMethod{::F_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO}. + * + * This function returns Returns the platform features. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in,out] Features The Features supported by this platform. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + * @retval AGESA_SUCCESS Always succeeds. + */ +AGESA_STATUS +F10GetPlatformTypeSpecificInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT PLATFORM_FEATS *Features, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return (AGESA_SUCCESS); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Provide the features of the given HT link. + * + * @CpuServiceMethod{::F_GET_HT_LINK_FEATURES}. + * + * 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[out] Link The link number, for accessing non-capability set registers. + * @param[in] LinkBase The base HT Host capability PCI address for the link. + * @param[out] HtHostFeats The link's features. + * @param[in] StdHeader Standard Head Pointer + */ +VOID +F10GetHtLinkFeatures ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINTN *Link, + IN PCI_ADDR *LinkBase, + OUT HT_HOST_FEATS *HtHostFeats, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCI_ADDR PciAddress; + UINT32 RegValue; + UINT32 ExtendedFreq; + UINTN LinkOffset; + + ASSERT (FamilySpecificServices != NULL); + + // No features present unless link is good and connected. + HtHostFeats->HtHostValue = 0; + + // Compute link number + *Link = (((LinkBase->Address.Function == 4) ? 4 : 0) + ((LinkBase->Address.Register - 0x80) >> 5)); + + // Check coherency (HTHOST_LINK_TYPE_REG = 0x18) + PciAddress = *LinkBase; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_TYPE_REG_OFFSET; + LibAmdPciReadBits (PciAddress, 4, 0, &RegValue, StdHeader); + if (RegValue == 3) { + HtHostFeats->HtHostFeatures.Coherent = 1; + } else if (RegValue == 7) { + HtHostFeats->HtHostFeatures.NonCoherent = 1; + } + + // If link was not connected, don't check other attributes, make sure + // to return zero, no match. + if ((HtHostFeats->HtHostFeatures.Coherent == 1) || (HtHostFeats->HtHostFeatures.NonCoherent == 1)) { + // Check gen3 + PciAddress = *LinkBase; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_EXTENDED_FREQ; + LibAmdPciRead (AccessWidth32, PciAddress, &ExtendedFreq, StdHeader); + PciAddress = *LinkBase; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_FREQ_OFFSET; + LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader); + RegValue = (((ExtendedFreq & 0x1) << 4) | ((RegValue & 0x00000F00) >> 8)); + if (RegValue > 6) { + HtHostFeats->HtHostFeatures.Ht3 = 1; + } else { + HtHostFeats->HtHostFeatures.Ht1 = 1; + } + // Check ganged. + LinkOffset = (*Link) * 4; + PciAddress = *LinkBase; + PciAddress.Address.Function = 0; + PciAddress.Address.Register = ((UINT32)LinkOffset + 0x170); + LibAmdPciReadBits (PciAddress, 0, 0, &RegValue, StdHeader); + if (RegValue == 0) { + HtHostFeats->HtHostFeatures.UnGanged = 1; + } else { + HtHostFeats->HtHostFeatures.Ganged = 1; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Checks to see if the HT phy register table entry should be applied + * + * @CpuServiceMethod{::F_DOES_LINK_HAVE_HTFPY_FEATS}. + * + * This function determines if the link type field matches the HT link + * passed in. + * + * This method will match for sublink 1 if the link is ganged and sublink 0 matches. + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CapabilitySet Address of the HT capability block + * @param[in] Link Zero based HT link to check + * @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 Link does not match + * + */ +BOOLEAN +F10DoesLinkHaveHtPhyFeats ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR CapabilitySet, + IN UINT32 Link, + IN HT_PHY_LINK_FEATS *HtPhyLinkType, + OUT BOOLEAN *MatchedSublink1, + OUT HT_FREQUENCIES *Frequency0, + OUT HT_FREQUENCIES *Frequency1, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 RegValue; + UINT32 ExtendedFreq; + PCI_ADDR PciAddress; + PCI_ADDR SubLink1Address; + HT_PHY_LINK_FEATS LinkType; + BOOLEAN IsReallyCheckingBoth; + + ASSERT (Link < 4); + ASSERT (HtPhyLinkType != NULL); + // error checks: No unknown link type bits set and not a "match none" + ASSERT ((HtPhyLinkType->HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0); + ASSERT (HtPhyLinkType->HtPhyLinkValue != 0); + + *Frequency0 = 0; + *Frequency1 = 0; + IsReallyCheckingBoth = FALSE; + *MatchedSublink1 = FALSE; + LinkType.HtPhyLinkValue = 0; + + // Set the link indicators. This assumes each sublink set is contiguous, that is, links 3, 2, 1, 0 and 7, 6, 5, 4. + LinkType.HtPhyLinkValue |= (HTPHY_LINKTYPE_SL0_LINK0 << Link); + LinkType.HtPhyLinkValue |= (HTPHY_LINKTYPE_SL1_LINK4 << Link); + + // if ganged, don't read sublink 1, but use sublink 0 to check. + SubLink1Address = CapabilitySet; + + // Check ganged. Since we got called for sublink 0, sublink 1 is implemented also, + // but only access it if it is also unganged. + Link *= 4; + PciAddress = CapabilitySet; + PciAddress.Address.Function = 0; + PciAddress.Address.Register = (Link + 0x170); + LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader); + RegValue = (RegValue & 0x01); + if (RegValue == 0) { + // Then really read sublink1, rather than using sublink0 + SubLink1Address.Address.Function = 4; + IsReallyCheckingBoth = TRUE; + } + + // Checks for Sublink 0 + + // Check coherency (HTHOST_LINK_TYPE_REG = 0x18) + PciAddress = CapabilitySet; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_TYPE_REG_OFFSET; + LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader); + if ((RegValue & 0x1F) == 3) { + LinkType.HtPhyLinkFeatures.HtPhySL0Coh = 1; + } else if ((RegValue & 0x1F) == 7) { + LinkType.HtPhyLinkFeatures.HtPhySL0NonCoh = 1; + } + + // If link was not connected, don't check other attributes, make sure + // to return zero, no match. (Phy may be powered off.) + if ((LinkType.HtPhyLinkFeatures.HtPhySL0Coh) || (LinkType.HtPhyLinkFeatures.HtPhySL0NonCoh)) { + // Check gen3 + PciAddress = CapabilitySet; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_EXTENDED_FREQ; + LibAmdPciRead (AccessWidth32, PciAddress, &ExtendedFreq, StdHeader); + PciAddress = CapabilitySet; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_FREQ_OFFSET; + LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader); + RegValue = (((ExtendedFreq & 0x1) << 4) | ((RegValue & 0x00000F00) >> 8)); + *Frequency0 = RegValue; + if (RegValue > 6) { + LinkType.HtPhyLinkFeatures.HtPhySL0Ht3 = 1; + } else { + LinkType.HtPhyLinkFeatures.HtPhySL0Ht1 = 1; + } + } else { + LinkType.HtPhyLinkValue &= ~(HTPHY_LINKTYPE_SL0_ALL); + } + + // Checks for Sublink 1 + // Check coherency (HTHOST_LINK_TYPE_REG = 0x18) + PciAddress = SubLink1Address; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_TYPE_REG_OFFSET; + LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader); + if ((RegValue & 0x1F) == 3) { + LinkType.HtPhyLinkFeatures.HtPhySL1Coh = 1; + } else if ((RegValue & 0x1F) == 7) { + LinkType.HtPhyLinkFeatures.HtPhySL1NonCoh = 1; + } + + if ((LinkType.HtPhyLinkFeatures.HtPhySL1Coh) || (LinkType.HtPhyLinkFeatures.HtPhySL1NonCoh)) { + // Check gen3 + PciAddress = SubLink1Address; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_EXTENDED_FREQ; + LibAmdPciRead (AccessWidth32, PciAddress, &ExtendedFreq, StdHeader); + PciAddress = SubLink1Address; + PciAddress.Address.Register = PciAddress.Address.Register + HT_LINK_FREQ_OFFSET; + LibAmdPciRead (AccessWidth32, PciAddress, &RegValue, StdHeader); + RegValue = (((ExtendedFreq & 0x1) << 4) | ((RegValue & 0x00000F00) >> 8)); + *Frequency1 = RegValue; + if (RegValue > 6) { + LinkType.HtPhyLinkFeatures.HtPhySL1Ht3 = 1; + } else { + LinkType.HtPhyLinkFeatures.HtPhySL1Ht1 = 1; + } + } else { + LinkType.HtPhyLinkValue &= ~(HTPHY_LINKTYPE_SL1_ALL); + } + + // For Deemphasis checking, indicate whether it was actually sublink 1 that matched. + // If the link is ganged or only sublink 0 matched, or the link features didn't match, this is false. + if ((LinkType.HtPhyLinkValue & HtPhyLinkType->HtPhyLinkValue) != 0) { + if (IsReallyCheckingBoth && + (((LinkType.HtPhyLinkValue & HtPhyLinkType->HtPhyLinkValue) & (HTPHY_LINKTYPE_SL1_ALL)) != 0)) { + *MatchedSublink1 = TRUE; + } + return TRUE; // Link matches at least one of the desired characteristics + } else { + return FALSE; // Link does not match any criteria + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Applies an HT Phy read-modify-write based on an HT Phy register table entry. + * + * @CpuServiceMethod{::F_SET_HT_PHY_REGISTER}. + * + * This function performs the necessary sequence of PCI reads, writes, and waits + * necessary to program an HT Phy register. + * + * @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). + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +F10SetHtPhyRegister ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN HT_PHY_TYPE_ENTRY_DATA *HtPhyEntry, + IN PCI_ADDR CapabilitySet, + IN UINT32 Link, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Temp; + UINT32 PhyReg; + PCI_ADDR PhyBase; + + // Determine the PCI config address of the HT Phy portal + PhyBase = CapabilitySet; + PhyBase.Address.Function = FUNC_4; + PhyBase.Address.Register = ((Link << 3) + REG_HT4_PHY_OFFSET_BASE_4X180); + + LibAmdPciRead (AccessWidth32, PhyBase, &PhyReg, StdHeader); + + // Handle direct map registers if needed + PhyReg &= ~(HTPHY_DIRECT_OFFSET_MASK); + if (HtPhyEntry->Address > 0x1FF) { + PhyReg |= HTPHY_DIRECT_MAP; + } + + PhyReg |= (HtPhyEntry->Address); + // Ask the portal to read the HT Phy Register contents + LibAmdPciWrite (AccessWidth32, PhyBase, &PhyReg, StdHeader); + do + { + LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader); + } while (!(Temp & HTPHY_IS_COMPLETE_MASK)); + + // Get the current register contents and do the update requested by the table + PhyBase.AddressValue += 4; + LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader); + Temp &= ~(HtPhyEntry->Mask); + Temp |= (HtPhyEntry->Data); + LibAmdPciWrite (AccessWidth32, PhyBase, &Temp, StdHeader); + + PhyBase.AddressValue -= 4; + // Ask the portal to write our updated value to the HT Phy + PhyReg |= HTPHY_WRITE_CMD; + LibAmdPciWrite (AccessWidth32, PhyBase, &PhyReg, StdHeader); + do + { + LibAmdPciRead (AccessWidth32, PhyBase, &Temp, StdHeader); + } while (!(Temp & HTPHY_IS_COMPLETE_MASK)); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Set the HT Link Token Count registers (F3X1[54,50,4C,48]). + * + * @TableEntryTypeMethod{::HtTokenPciRegister}. + * + * Make the current core's PCI address with the function and register for the entry. + * For all HT links, check the link's feature set for a match to the entry. + * Read - Modify - Write the PCI register, clearing masked bits, and setting the data bits. + * + * @param[in] Entry The Link Token register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +F10SetRegisterForHtLinkTokenEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN Link; + UINTN LinkCount; + UINT32 MySocket; + UINT32 MyModule; + AGESA_STATUS IgnoredStatus; + UINT32 Ignored; + CPU_LOGICAL_ID CpuFamilyRevision; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + PCI_ADDR CapabilitySet; + HT_HOST_FEATS HtHostFeats; + PERFORMANCE_PROFILE_FEATS PlatformProfile; + UINTN ProcessorCount; + UINT32 RegisterData; + PCI_ADDR PciAddress; + + // 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->HtTokenEntry.LinkFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0) && + ((Entry->HtTokenEntry.PerformanceFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0) && + (Entry->HtTokenEntry.Mask != 0)); + + HtHostFeats.HtHostValue = 0; + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus); + GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus); + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetCpuServicesFromLogicalId (&CpuFamilyRevision, &FamilySpecificServices, StdHeader); + + // Check if the actual processor count is in either range. + ProcessorCount = GetNumberOfProcessors (StdHeader); + if (IsEitherCountInRange (ProcessorCount, ProcessorCount, Entry->HtTokenEntry.ProcessorCounts.ProcessorCountRanges)) { + // Check for any performance profile features. + GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, + Entry->HtTokenEntry.PerformanceFeats.PerformanceProfileValue)) { + // Check the link features. + LinkCount = 0; + while (LinkCount < 4) { + if (FindHtHostCapability (LinkCount, &CapabilitySet, StdHeader)) { + FamilySpecificServices->GetHtLinkFeatures (FamilySpecificServices, &Link, &CapabilitySet, &HtHostFeats, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (HtHostFeats.HtHostValue, Entry->HtTokenEntry.LinkFeats.HtHostValue)) { + // Do the HT Host PCI register update. + PciAddress = CapabilitySet; + PciAddress.Address.Function = 3; + PciAddress.Address.Register = LINK_TO_XCS_TOKEN_COUNT_REG_3X148 + ((UINT32)Link * 4); + LibAmdPciRead (AccessWidth32, PciAddress, &RegisterData, StdHeader); + RegisterData = RegisterData & (~(Entry->HtTokenEntry.Mask)); + RegisterData = RegisterData | Entry->HtTokenEntry.Data; + LibAmdPciWrite (AccessWidth32, PciAddress, &RegisterData, StdHeader); + } + } else { + // No more Capabilities. + break; + } + LinkCount ++; + } + } + } +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Utilities.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Utilities.h new file mode 100755 index 0000000000..4b4a440d59 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Utilities.h @@ -0,0 +1,223 @@ +/** + * @file + * + * AMD Family_10 specific utility functions. + * + * Provides numerous utility functions specific to family 10h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_F10_UTILITES_H_ +#define _CPU_F10_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 + *--------------------------------------------------------------------------------------- + */ +VOID +F10PmSwVoltageTransition ( + IN UINT32 VidCode, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F10PmSwVoltageTransitionServerNb ( + IN UINT32 VidCode, + IN BOOLEAN SlamMode, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +F10SwVoltageTransitionServerNbCore ( + IN VOID *InputData, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F10WaitOutVoltageTransition ( + IN BOOLEAN SlamMode, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F10GetCurrentVsTimeInUsecs ( + OUT UINT32 *VsTimeUsecs, + IN BOOLEAN SlamMode, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +F10ProgramVSSlamTimeOnSocket ( + IN PCI_ADDR *PciAddress, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +F10GetSlamTimeEncoding ( + IN UINT8 HighVoltageVid, + IN UINT8 LowVoltageVid, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN CONST UINT32 *SlamTimeTable, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10GetPstatePower ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + OUT UINT32 *PowerInMw, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10GetPstateFrequency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10DisablePstate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10TransitionPstate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 StateNumber, + IN BOOLEAN WaitForTransition, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10GetTscRate ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *FrequencyInMHz, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +F10LaunchApCore ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 SocketNum, + IN UINT32 ModuleNum, + IN UINT32 CoreNum, + IN UINT32 PrimaryCoreNum, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10GetFrequencyXlatRegInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT8 PStateNumber, + IN UINT32 Frequency, + OUT UINT32 *CpuFidPtr, + OUT UINT32 *CpuDidPtr1, + OUT UINT32 *CpuDidPtr2, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10PstateLevelingCoreMsrModify ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN S_CPU_AMD_PSTATE *CpuAmdPState, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10GetPstateTransLatency ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PSTATE_LEVELING *PStateLevelingBufferStructPtr, + IN PCI_ADDR *PciAddress, + OUT UINT32 *TransitionLatency, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10GetPstateRegisterInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 PState, + OUT BOOLEAN *PStateEnabled, + IN OUT UINT32 *IddVal, + IN OUT UINT32 *IddDiv, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10GetPstateMaxState ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *MaxPStateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +F10GetPlatformTypeSpecificInfo ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN OUT PLATFORM_FEATS *Features, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_F10_UTILITES_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10WheaInitDataTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10WheaInitDataTables.c new file mode 100755 index 0000000000..387038152e --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10WheaInitDataTables.c @@ -0,0 +1,124 @@ +/** + * @file + * + * AMD Family_10 WHEA initial Data + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6436 $ @e \$Date: 2008-06-18 05:49:23 -0500 (Wed, 18 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuLateInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FAMILY_0X10_CPUF10WHEAINITDATATABLES_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 + *---------------------------------------------------------------------------------------- + */ +VOID +GetF10WheaInitData ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **F10WheaInitDataPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AMD_HEST_BANK_INIT_DATA F10HestBankInitData[] = { + {0xFFFFFFFF,0xFFFFFFFF,0x400,0x401,0x402,0x403}, + {0xFFFFFFFF,0xFFFFFFFF,0x404,0x405,0x406,0x407}, + {0xFFFFFFFF,0xFFFFFFFF,0x408,0x409,0x40A,0x40B}, + {0xFFFFFFFF,0xFFFFFFFF,0x40C,0x40D,0x40E,0x40F}, + {0xFFFFFFFF,0xFFFFFFFF,0x410,0x411,0x412,0x413}, + {0xFFFFFFFF,0xFFFFFFFF,0x414,0x415,0x416,0x417}, +}; + +AMD_WHEA_INIT_DATA F10WheaInitData = { + 0x000000000, // AmdGlobCapInitDataLsd + 0x000000000, // AmdGlobCapInitDataMsd + 0x00000003F, // AmdGlobCtrlInitDataLsd + 0x000000000, // AmdGlobCtrlInitDataMsd + 0x00, // AmdMcbClrStatusOnInit + 0x02, // AmdMcbStatusDataFormat + 0x00, // AmdMcbConfWriteEn + (sizeof (F10HestBankInitData) / sizeof (F10HestBankInitData[0])), // HestBankNum + &F10HestBankInitData[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] F10WheaInitDataPtr Points to the family 10h WHEA properties. + * @param[out] NumberOfElements Will be one to indicate one structure. + * @param[in] StdHeader Header for library and services. + * + */ +VOID +GetF10WheaInitData ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **F10WheaInitDataPtr, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *NumberOfElements = 1; + *F10WheaInitDataPtr = &F10WheaInitData; +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/cpuFamRegisters.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/cpuFamRegisters.h new file mode 100755 index 0000000000..4a027a8254 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Family/cpuFamRegisters.h @@ -0,0 +1,180 @@ +/** + * @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: 6459 $ @e \$Date: 2008-06-19 17:56:21 -0700 (Thu, 19 Jun 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#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 10h equates +#define AMD_FAMILY_10_RB 0x0000000000000001ull +#define AMD_FAMILY_10_BL 0x0000000000000002ull +#define AMD_FAMILY_10_DA 0x0000000000000004ull +#define AMD_FAMILY_10_HY 0x0000000000000008ull +#define AMD_FAMILY_10_C32 AMD_FAMILY_10_HY + +#define AMD_FAMILY_10 (AMD_FAMILY_10_RB | AMD_FAMILY_10_BL | AMD_FAMILY_10_DA | AMD_FAMILY_10_HY) +#define AMD_FAMILY_GH (AMD_FAMILY_10) + +// Family 12h equates +#define AMD_FAMILY_12_LN 0x0000000000000010ull +#define AMD_FAMILY_12 (AMD_FAMILY_12_LN) +#define AMD_FAMILY_LN (AMD_FAMILY_12_LN) + +// Family 14h equates +#define AMD_FAMILY_14_ON 0x0000000000000020ull +#define AMD_FAMILY_14 (AMD_FAMILY_14_ON) +#define AMD_FAMILY_ON (AMD_FAMILY_14_ON) + +// Family 15h equates +#define AMD_FAMILY_15 0x0000000000000040ull +#define AMD_FAMILY_OR (AMD_FAMILY_15) + +// Family 16h equates +#define AMD_FAMILY_16 0x0000000000000080ull +#define AMD_FAMILY_WF (AMD_FAMILY_16) + +// Family Unknown +#define AMD_FAMILY_UNKNOWN 0x8000000000000000ull + +// Family Group equates +#define AMD_FAMILY_GE_12 (AMD_FAMILY_12 | AMD_FAMILY_14 | AMD_FAMILY_15 | AMD_FAMILY_16) + +// Family 10h CPU_LOGICAL_ID.Revision equates + // Family 10h RB steppings +#define AMD_F10_RB_C0 0x0000000000000001ull +#define AMD_F10_RB_C1 0x0000000000000002ull +#define AMD_F10_RB_C2 0x0000000000000004ull +#define AMD_F10_RB_C3 0x0000000000000008ull + // Family 10h BL steppings +#define AMD_F10_BL_C2 0x0000000000000010ull +#define AMD_F10_BL_C3 0x0000000000000020ull + // Family 10h DA steppings +#define AMD_F10_DA_C2 0x0000000000000040ull +#define AMD_F10_DA_C3 0x0000000000000080ull + // Family 10h HY SCM steppings +#define AMD_F10_HY_SCM_D0 0x0000000000000100ull +#define AMD_F10_HY_SCM_D1 0x0000000000000400ull + // Family 10h HY MCM steppings +#define AMD_F10_HY_MCM_D0 0x0000000000000200ull +#define AMD_F10_HY_MCM_D1 0x0000000000000800ull + + // Family 10h Unknown stepping +#define AMD_F10_UNKNOWN 0x8000000000000000ull + + // Family 10h Miscellaneous equates +#define AMD_F10_C0 (AMD_F10_RB_C0) +#define AMD_F10_C1 (AMD_F10_RB_C1) +#define AMD_F10_C2 (AMD_F10_RB_C2 | AMD_F10_DA_C2 | AMD_F10_BL_C2) +#define AMD_F10_C3 (AMD_F10_RB_C3 | AMD_F10_DA_C3 | AMD_F10_BL_C3) +#define AMD_F10_Cx (AMD_F10_C0 | AMD_F10_C1 | AMD_F10_C2 | AMD_F10_C3) + +#define AMD_F10_RB_ALL (AMD_F10_RB_C0 | AMD_F10_RB_C1 | AMD_F10_RB_C2 | AMD_F10_RB_C3) + +#define AMD_F10_BL_ALL (AMD_F10_BL_C2 | AMD_F10_BL_C3) +#define AMD_F10_BL_Cx (AMD_F10_BL_C2 | AMD_F10_BL_C3) + +#define AMD_F10_DA_ALL (AMD_F10_DA_C2 | AMD_F10_DA_C3) +#define AMD_F10_DA_Cx (AMD_F10_DA_C2 | AMD_F10_DA_C3) + +#define AMD_F10_D0 (AMD_F10_HY_SCM_D0 | AMD_F10_HY_MCM_D0) +#define AMD_F10_D1 (AMD_F10_HY_SCM_D1 | AMD_F10_HY_MCM_D1) +#define AMD_F10_Dx (AMD_F10_D0 | AMD_F10_D1) + +#define AMD_F10_HY_ALL (AMD_F10_Dx) +#define AMD_F10_C32_ALL (AMD_F10_HY_SCM_D0 | AMD_F10_HY_SCM_D1) + +#define AMD_F10_GT_B0 (AMD_F10_Cx | AMD_F10_Dx) +#define AMD_F10_GT_Bx (AMD_F10_Cx | AMD_F10_Dx) +#define AMD_F10_GT_A2 (AMD_F10_Cx | AMD_F10_Dx) +#define AMD_F10_GT_Ax (AMD_F10_Cx | AMD_F10_Dx) +#define AMD_F10_GT_C0 ((AMD_F10_Cx & ~AMD_F10_C0) | AMD_F10_Dx) +#define AMD_F10_GT_D0 (AMD_F10_Dx & ~AMD_F10_D0) + +#define AMD_F10_ALL (AMD_F10_Cx | AMD_F10_Dx | AMD_F10_UNKNOWN) + +// Family 12h CPU_LOGICAL_ID.Revision equates + // Family 12h LN steppings +#define AMD_F12_LN_A0 0x0000000000000001ull + // Family 12h Unknown stepping +#define AMD_F12_UNKNOWN 0x8000000000000000ull + +#define AMD_F12_ALL (AMD_F12_LN_A0 | AMD_F12_UNKNOWN) + +// Family 14h CPU_LOGICAL_ID.Revision equates + // Family 14h ON steppings +#define AMD_F14_ON_A0 0x0000000000000001ull + // Family 14h Unknown stepping +#define AMD_F14_UNKNOWN 0x8000000000000000ull + +#define AMD_F14_ALL (AMD_F14_ON_A0 | AMD_F14_UNKNOWN) + +// Family 15h CPU_LOGICAL_ID.Revision equates +// TBD + +// Family 16h CPU_LOGICAL_ID.Revision equates +// TBD + +#endif // _CPU_FAM_REGISTERS_H_ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/PreserveMailbox.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/PreserveMailbox.c new file mode 100755 index 0000000000..995f48357c --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/PreserveMailbox.c @@ -0,0 +1,210 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "Topology.h" +#include "GeneralServices.h" +#include "OptionMultiSocket.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "PreserveMailbox.h" +#include "heapManager.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FEATURE_PRESERVEMAILBOX_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 PreserveMailboxFamilyServiceTable; + +/*---------------------------------------------------------------------------------------*/ +/** + * The contents of the mailbox registers should always be preserved. + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE Always TRUE + * + */ +BOOLEAN +STATIC +IsPreserveAroundMailboxEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return TRUE; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Save and Restore or Initialize the content of the mailbox registers. + * + * The registers used for AP mailbox should have the content related to their function + * preserved. + * + * @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 +PreserveMailboxes ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PRESERVE_MAILBOX_FAMILY_SERVICES *FamilySpecificServices; + UINT32 Socket; + UINT32 Module; + PCI_ADDR BaseAddress; + PCI_ADDR MailboxRegister; + PCI_ADDR *NextRegister; + AGESA_STATUS IgnoredStatus; + AGESA_STATUS HeapStatus; + UINT32 Value; + ALLOCATE_HEAP_PARAMS AllocateParams; + LOCATE_HEAP_PTR LocateParams; + UINT32 RegisterEntryIndex; + + BaseAddress.AddressValue = ILLEGAL_SBDFO; + + if (EntryPoint == CPU_FEAT_AFTER_COHERENT_DISCOVERY) { + AllocateParams.BufferHandle = PRESERVE_MAIL_BOX_HANDLE; + AllocateParams.RequestedBufferSize = (sizeof (UINT32) * (MAX_PRESERVE_REGISTER_ENTRIES * (MAX_SOCKETS * MAX_DIES))); + AllocateParams.Persist = HEAP_SYSTEM_MEM; + HeapStatus = HeapAllocateBuffer (&AllocateParams, StdHeader); + ASSERT ((HeapStatus == AGESA_SUCCESS) && (AllocateParams.BufferPtr != NULL)); + LibAmdMemFill (AllocateParams.BufferPtr, 0xFF, AllocateParams.RequestedBufferSize, StdHeader); + RegisterEntryIndex = 0; + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &BaseAddress, &IgnoredStatus)) { + GetFeatureServicesOfSocket (&PreserveMailboxFamilyServiceTable, Socket, (CONST VOID **)&FamilySpecificServices, StdHeader); + NextRegister = FamilySpecificServices->RegisterList; + while (NextRegister->AddressValue != ILLEGAL_SBDFO) { + ASSERT (RegisterEntryIndex < + (MAX_PRESERVE_REGISTER_ENTRIES * GetPlatformNumberOfSockets () * GetPlatformNumberOfModules ())); + MailboxRegister = BaseAddress; + MailboxRegister.Address.Function = NextRegister->Address.Function; + MailboxRegister.Address.Register = NextRegister->Address.Register; + LibAmdPciRead (AccessWidth32, MailboxRegister, &Value, StdHeader); + (* (MAILBOX_REGISTER_SAVE_ENTRY) AllocateParams.BufferPtr) [RegisterEntryIndex] = Value; + RegisterEntryIndex++; + NextRegister++; + } + } + } + } + } else if ((EntryPoint == CPU_FEAT_INIT_LATE_END) || (EntryPoint == CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) { + LocateParams.BufferHandle = PRESERVE_MAIL_BOX_HANDLE; + HeapStatus = HeapLocateBuffer (&LocateParams, StdHeader); + ASSERT ((HeapStatus == AGESA_SUCCESS) && (LocateParams.BufferPtr != NULL)); + RegisterEntryIndex = 0; + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &BaseAddress, &IgnoredStatus)) { + GetFeatureServicesOfSocket (&PreserveMailboxFamilyServiceTable, Socket, (CONST VOID **)&FamilySpecificServices, StdHeader); + NextRegister = FamilySpecificServices->RegisterList; + while (NextRegister->AddressValue != ILLEGAL_SBDFO) { + ASSERT (RegisterEntryIndex < + (MAX_PRESERVE_REGISTER_ENTRIES * GetPlatformNumberOfSockets () * GetPlatformNumberOfModules ())); + MailboxRegister = BaseAddress; + MailboxRegister.Address.Function = NextRegister->Address.Function; + MailboxRegister.Address.Register = NextRegister->Address.Register; + if (FamilySpecificServices->IsZeroOnCold && (!IsWarmReset (StdHeader))) { + Value = 0; + } else { + Value = (* (MAILBOX_REGISTER_SAVE_ENTRY) LocateParams.BufferPtr) [RegisterEntryIndex]; + } + LibAmdPciWrite (AccessWidth32, MailboxRegister, &Value, StdHeader); + RegisterEntryIndex++; + NextRegister++; + } + } + } + } + HeapStatus = HeapDeallocateBuffer (PRESERVE_MAIL_BOX_HANDLE, StdHeader); + } + return AGESA_SUCCESS; +} + + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeaturePreserveAroundMailbox = +{ + PreserveAroundMailbox, + (CPU_FEAT_AFTER_COHERENT_DISCOVERY | CPU_FEAT_INIT_LATE_END | CPU_FEAT_AFTER_RESUME_MTRR_SYNC), + IsPreserveAroundMailboxEnabled, + PreserveMailboxes +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/PreserveMailbox.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/PreserveMailbox.h new file mode 100755 index 0000000000..f23a12da78 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/PreserveMailbox.h @@ -0,0 +1,87 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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 + *---------------------------------------------------------------------------------------- + */ + +/** + * 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. + PCI_ADDR *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/f10/Proc/CPU/Feature/cpuC6State.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuC6State.c new file mode 100755 index 0000000000..12c6944f81 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuC6State.c @@ -0,0 +1,200 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuFamilyTranslation.h" +#include "OptionMultiSocket.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "cpuFeatures.h" +#include "cpuC6State.h" +#include "Filecode.h" +#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) { + ASSERT (PlatformConfig->CStatePlatformData < 0x10000); + ASSERT (PlatformConfig->CStatePlatformData != 0); + if ((PlatformConfig->CStatePlatformData != 0) && (PlatformConfig->CStatePlatformData <= 0xFFF8)) { + 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, 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 + ) +{ + AP_TASK TaskPtr; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + + 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); + + 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; + + GetFeatureServicesOfCurrentCore (&C6FamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + FamilyServices->InitializeC6 (FamilyServices, + *((UINT64 *) EntryPoint), + &CpuEarlyParams->PlatformConfig, + 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), + IsC6FeatureEnabled, + InitializeC6Feature +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuC6State.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuC6State.h new file mode 100755 index 0000000000..cbaf3ad8dc --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuC6State.h @@ -0,0 +1,198 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_C6_STATE_H_ +#define _CPU_C6_STATE_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration. +typedef struct _C6_FAMILY_SERVICES C6_FAMILY_SERVICES; + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +// Defines for CST ACPI 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 - 5) // 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_C2_TYPE 0x02 + +/*---------------------------------------------------------------------------------------- + * 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 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 BytePrefix; ///< Byte Prefix Opcode + UINT8 Type; ///< Type + UINT8 BytePrefix2; ///< Byte Prefix Opcode + UINT8 Latency; ///< Latency + UINT8 Power; ///< Power +} CST_BODY_STRUCT; +#define CST_BODY_SIZE 33 + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] 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 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 + ); + +typedef UINT32 F_C6_GET_CST_SIZE ( + IN VOID + ); + +typedef VOID F_C6_CREATE_CST ( + IN OUT VOID **PstateAcpiBufferPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_C6_INIT *PF_C6_INIT; +typedef F_C6_GET_CST_SIZE *PF_C6_GET_CST_SIZE; +typedef F_C6_CREATE_CST *PF_C6_CREATE_CST; + +/** + * 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_GET_CST_SIZE GetAcpiCstObj; ///< Method: Family specific call to return the size of ACPI CST objects. + PF_C6_CREATE_CST CreateAcpiCstObj; ///< Method: Family specific call to create ACPI CST object +}; + + +/*---------------------------------------------------------------------------------------- + * 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/f10/Proc/CPU/Feature/cpuCacheFlushOnHalt.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCacheFlushOnHalt.c new file mode 100755 index 0000000000..48e5a93568 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCacheFlushOnHalt.c @@ -0,0 +1,185 @@ +/** + * @file + * + * AMD CPU Cache Flush On Halt 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: 6626 $ @e \$Date: 2008-07-04 02:01:02 +0800 (Fri, 04 Jul 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "Filecode.h" +#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; + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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. + */ +STATIC AGESA_STATUS +InitializeCacheFlushOnHaltFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 AndMask; + UINT32 OrMask; + UINT32 PciRegister; + PCI_ADDR PciAddress; + PCI_ADDR CfohPciAddress; + AGESA_STATUS AgesaStatus; + CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices; + + ASSERT (IsBsp (StdHeader, &AgesaStatus)); + + FamilySpecificServices = NULL; + AndMask = 0xFFFFFFFF; + OrMask = 0x00000000; + PciRegister = 0; + AgesaStatus = AGESA_SUCCESS; + + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + + // Get services for the socket + GetFeatureServicesOfSocket (&CacheFlushOnHaltFamilyServiceTable, Socket, (CONST VOID **)&FamilySpecificServices, StdHeader); + if (FamilySpecificServices != NULL) { + FamilySpecificServices->GetCacheFlushOnHaltRegister (FamilySpecificServices, &CfohPciAddress, &AndMask, &OrMask, StdHeader); + + // Get the Or Mask value from IDS + IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, &OrMask, StdHeader); + + // Set Cache Flush On Halt register + for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) { + PciAddress.Address.Function = CfohPciAddress.Address.Function; + PciAddress.Address.Register = CfohPciAddress.Address.Register; + LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); + PciRegister &= AndMask; + PciRegister |= OrMask; + LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); + } + } + } + } + } + return AgesaStatus; +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureCacheFlushOnHalt = +{ + CacheFlushOnHalt, + (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC), + IsCFOHEnabled, + InitializeCacheFlushOnHaltFeature +};
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCacheInit.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCacheInit.c new file mode 100755 index 0000000000..10f4f5c4f1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCacheInit.c @@ -0,0 +1,541 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + + +/* + *---------------------------------------------------------------------------- + * 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" +#define FILECODE PROC_CPU_FEATURE_CPUCACHEINIT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * 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 +CalculateOccupyExeCache ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will setup ROM execution cache. + * + * This function should only be called once. The execution cache regions are passed + * in, the max number of execution cache regions are three. If the start address of + * all three regions are zero, then no execution cache is allocated. + * + * -1 available cache size is less than requested, the ROM execution cache + * region is reduced or eliminated. + * -2 at least one execution cache regions across the 1MB line, the ROM execution + * cache size is reduced. + * -3 at least one execution cache regions across the 4GB line, the ROM execution + * cache size is reduced. + * -4 the start address of a region is not at the boundary of cache size + * -5 execution cache start address less than D0000 + * -6 more than 2 execution cache regions are above 1MB + * + * @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; + * + * @todo on Tilapia, this routine returns AGESA_ERROR. + */ +AGESA_STATUS +AllocateExecutionCache ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN EXECUTION_CACHE_REGION *AmdExeAddrMapPtr + ) +{ + AGESA_STATUS AgesaStatus; + AMD_GET_EXE_SIZE_PARAMS AmdGetExeSize; + UINT64 MsrData; + UINT32 RemainingExecutionCacheSize; + UINT32 VariableMttrBase; + UINT32 AgesaInfo; + UINT32 StartAddr; + UINT32 ExeCacheSize; + UINT32 StartFixMtrr; + UINT32 CurrentMtrr; + UINT32 EndFixMtrr; + UINT32 CurrentAllocatedExeCacheSize; + UINT8 i; + UINT8 Ignored; + UINT64 OccupyExeCacheStartAddr; + UINT64 OccupExeCacheSize; + CACHE_INFO *CacheInfoPtr; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + // + // if start address of all three regions are zero, then the default values are used + // + if (AmdExeAddrMapPtr[0].ExeCacheStartAddr == 0) { + if (AmdExeAddrMapPtr[1].ExeCacheStartAddr == 0) { + if (AmdExeAddrMapPtr[2].ExeCacheStartAddr == 0) { + // No regions defined by the caller + return AGESA_SUCCESS; + } + } + } + + // turn on modification bit + LibAmdMsrRead (MSR_SYS_CFG, &MsrData, StdHeader); + MsrData |= 0x80000; + LibAmdMsrWrite (MSR_SYS_CFG, &MsrData, StdHeader); + + // get available L2 cache size for ROM execution + AmdGetExeSize.StdHeader = *StdHeader; + AgesaStatus = AmdGetAvailableExeCacheSize (&AmdGetExeSize); + RemainingExecutionCacheSize = AmdGetExeSize.AvailableExeCacheSize; + CurrentAllocatedExeCacheSize = CalculateOccupyExeCache (StdHeader); + if (CurrentAllocatedExeCacheSize >= RemainingExecutionCacheSize) { + RemainingExecutionCacheSize = 0; + } else { + RemainingExecutionCacheSize = RemainingExecutionCacheSize - CurrentAllocatedExeCacheSize; + } + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **)&CacheInfoPtr, &Ignored, StdHeader); + + // Setup MTTRs for region 0 to region 2 + VariableMttrBase = AMD_MTRR_VARIABLE_BASE6; + 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; + } + + // Calculate available execution cache size for region 0 to 2 + if (RemainingExecutionCacheSize >= AmdExeAddrMapPtr[i].ExeCacheSize) { + RemainingExecutionCacheSize = RemainingExecutionCacheSize - AmdExeAddrMapPtr[i].ExeCacheSize; + } else { + AgesaStatus = AGESA_WARNING; + AgesaInfo = AGESA_CACHE_SIZE_REDUCED; + AmdExeAddrMapPtr[i].ExeCacheSize = RemainingExecutionCacheSize; + RemainingExecutionCacheSize = 0; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR | (UINT8) AgesaInfo), + i, AmdExeAddrMapPtr[i].ExeCacheStartAddr, AmdExeAddrMapPtr[i].ExeCacheSize, 0, StdHeader); + } + + // Align starting addresses on 32K boundary + AmdExeAddrMapPtr[i].ExeCacheStartAddr = + AmdExeAddrMapPtr[i].ExeCacheStartAddr & 0xFFFF8000; + + // Boundary alignment check mechanism + if ((AmdExeAddrMapPtr[i].ExeCacheStartAddr % AmdExeAddrMapPtr[i].ExeCacheSize) != 0) { + AgesaStatus = AGESA_ERROR; + AgesaInfo = AGESA_REGION_NOT_ALIGNED_ON_BOUNDARY; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR | (UINT8) AgesaInfo), + i, AmdExeAddrMapPtr[i].ExeCacheStartAddr, AmdExeAddrMapPtr[i].ExeCacheSize, 0, StdHeader); + break; + } + + // Check start address + if (AmdExeAddrMapPtr[i].ExeCacheStartAddr < 0xD0000) { + AgesaStatus = AGESA_ERROR; + AgesaInfo = AGESA_CACHE_START_ADDRESS_LESS_D0000; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR | (UINT8) AgesaInfo), + i, AmdExeAddrMapPtr[i].ExeCacheStartAddr, AmdExeAddrMapPtr[i].ExeCacheSize, 0, StdHeader); + break; + } + + StartAddr = AmdExeAddrMapPtr[i].ExeCacheStartAddr; + ExeCacheSize = AmdExeAddrMapPtr[i].ExeCacheSize; + + ExeCacheSize --; + + if (StartAddr < 0x100000) { + // Region below 1MB + // Fixed MTTR region + if ((StartAddr + ExeCacheSize) > 0xFFFFF) { + ExeCacheSize = 0xFFFFF - StartAddr; + AgesaStatus = AGESA_WARNING; + AgesaInfo = AGESA_CACHE_REGIONS_ACROSS_1MB; + AmdExeAddrMapPtr[i].ExeCacheSize = ExeCacheSize + 1; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR | (UINT8) AgesaInfo), + i, StartAddr, ExeCacheSize, 0, StdHeader); + } + + // Find start and end of MTTR + StartFixMtrr = AMD_MTRR_FIX4K_BASE + ((StartAddr >> 15) & 0x7); + EndFixMtrr = AMD_MTRR_FIX4K_BASE + (((StartAddr + ExeCacheSize) >> 15) & 0x7); + + // + //Check Mtrr before we use it, if Mtrr has been used, we need to add RemainingExecutionCacheSize back. + // + for (CurrentMtrr = StartFixMtrr; CurrentMtrr <= EndFixMtrr; CurrentMtrr++) { + LibAmdMsrRead (CurrentMtrr, &MsrData, StdHeader); + if (MsrData != 0) { + RemainingExecutionCacheSize = RemainingExecutionCacheSize + 0x8000; + } + } + + // Setup MTTRs + MsrData = WP_IO; + for (CurrentMtrr = StartFixMtrr; CurrentMtrr <= EndFixMtrr; CurrentMtrr++) { + LibAmdMsrWrite (CurrentMtrr, &MsrData, StdHeader); + } + } else { + // Region above 1MB + // Variable MTTR region + if (VariableMttrBase > AMD_MTRR_VARIABLE_BASE7) { + AgesaStatus = AGESA_ERROR; + AgesaInfo = AGESA_THREE_CACHE_REGIONS_ABOVE_1MB; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR | (UINT8) AgesaInfo), + i, StartAddr, ExeCacheSize, 0, StdHeader); + continue; + } + if ((0xFFFFFFFF - StartAddr) < ExeCacheSize) { + ExeCacheSize = 0xFFFFFFFF - StartAddr; + AgesaStatus = AGESA_WARNING; + AgesaInfo = AGESA_CACHE_REGIONS_ACROSS_4GB; + AmdExeAddrMapPtr[i].ExeCacheSize = ExeCacheSize + 1; + PutEventLog (AgesaStatus, + (CPU_EVENT_EXECUTION_CACHE_ALLOCATION_ERROR | (UINT8) AgesaInfo), + i, StartAddr, ExeCacheSize, 0, StdHeader); + } + + // + //Check Mtrr before we use it. + // + LibAmdMsrRead (VariableMttrBase, &MsrData, StdHeader); + if (MsrData != 0) { + + // + //Check expanded + // + OccupyExeCacheStartAddr = MsrData & (0xFFFF8000); + LibAmdMsrRead ((VariableMttrBase + 1), &MsrData, StdHeader); + OccupExeCacheSize = (~((MsrData & (0xFFFF8000)) - 1))&0xFFFF8000; + + // + //Region below || Region above + // + if ( ((StartAddr + ExeCacheSize + 1) <= OccupyExeCacheStartAddr) || + (StartAddr >= (OccupyExeCacheStartAddr + OccupExeCacheSize)) ) { + // + //Not overlap the original one, but it need to re-process and set an pair of empty Mtrr + // + VariableMttrBase += 2; + RemainingExecutionCacheSize = RemainingExecutionCacheSize + AmdExeAddrMapPtr[i].ExeCacheSize; + // + //Resume loop count + // + i--; + continue; + } else if (OccupyExeCacheStartAddr == StartAddr) { + + // + //Overlap with same start address + // + if (OccupExeCacheSize > (ExeCacheSize + 1)) { + //AgesaInfo = AGESA_DEALLOCATE_CACHE_REGIONS; + break; + } + RemainingExecutionCacheSize = RemainingExecutionCacheSize + (UINT32)OccupExeCacheSize; + } else { + // + //Overlap with different start address + // + //AgesaInfo = AGESA_DEALLOCATE_CACHE_REGIONS; + break; + } + } + + MsrData = (UINT64) (StartAddr | (WP_IO & 0xFull)); + + LibAmdMsrWrite (VariableMttrBase, &MsrData, StdHeader); + MsrData = (UINT64) ( 0xFFFFFFFF00000000ull | ((0xFFFFFFFFull - ExeCacheSize) | 0x800ull)); + MsrData &= CacheInfoPtr->VariableMtrrMask; + LibAmdMsrWrite ((VariableMttrBase + 1), &MsrData, StdHeader); + VariableMttrBase += 2; + } + } + + // Turn on MTTR enable bit and turn off modification bit + LibAmdMsrRead (MSR_SYS_CFG, &MsrData, StdHeader); + MsrData &= 0xFFFFFFFFFFF7FFFFull; + LibAmdMsrWrite (MSR_SYS_CFG, &MsrData, StdHeader); + + 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 (&FamilySpecificServices, &AmdGetExeSizeParams->StdHeader); + + // 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; + + FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **)&CacheInfoPtr, &Ignored, &AmdGetExeSizeParams->StdHeader); + + // 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 + * + * @retval Value Allocated size in bytes + * + */ +UINT32 +STATIC +CalculateOccupyExeCache ( + 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; +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCacheInit.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCacheInit.h new file mode 100755 index 0000000000..c4f51b7db7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCacheInit.h @@ -0,0 +1,101 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_CACHE_INIT_H_ +#define _CPU_CACHE_INIT_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ +#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 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 +} CACHE_INFO; + +/*---------------------------------------------------------------------------- + * 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/f10/Proc/CPU/Feature/cpuCoreLeveling.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCoreLeveling.c new file mode 100755 index 0000000000..bdb26abce7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuCoreLeveling.c @@ -0,0 +1,283 @@ +/** + * @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: 6626 $ @e \$Date: 2008-07-04 02:01:02 +0800 (Fri, 04 Jul 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "AMD.h" +#include "amdlib.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "cpuEarlyInit.h" +#include "Filecode.h" +#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 + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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: + * -1 CORE_LEVEL_LOWEST Level to lowest common denominator + * -2 CORE_LEVEL_TWO Level to 2 cores + * -3 CORE_LEVEL_POWER_OF_TWO Level to 1,2,4 or 8 + * -4 CORE_LEVEL_NONE Do no leveling + * + * @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. + * + */ +STATIC AGESA_STATUS +CoreLevelingAtEarly ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 NumberOfSockets; + UINT32 NumberOfModules; + UINT32 MinCoreCountOnNode; + UINT32 MaxCoreCountOnNode; + UINT32 LowCore; + UINT32 HighCore; + UINT32 LeveledCores; + UINT32 RequestedCores; + UINT32 TotalEnabledCoresOnNode; + AP_MAIL_INFO ApMailboxInfo; + CORE_LEVELING_TYPE CoreLevelMode; + CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices; + + MaxCoreCountOnNode = 0; + MinCoreCountOnNode = 0xFFFFFFFF; + LeveledCores = 0; + + 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 + // Get the highest and lowest core count in all nodes + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + for (Module = 0; Module < NumberOfModules; Module++) { + if (GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader)) { + TotalEnabledCoresOnNode = HighCore - LowCore + 1; + if (TotalEnabledCoresOnNode < MinCoreCountOnNode) { + MinCoreCountOnNode = TotalEnabledCoresOnNode; + } + if (TotalEnabledCoresOnNode > MaxCoreCountOnNode) { + MaxCoreCountOnNode = TotalEnabledCoresOnNode; + } + } + } + } + } + + // Get LeveledCores + switch (CoreLevelMode) { + case CORE_LEVEL_LOWEST: + if (MinCoreCountOnNode == MaxCoreCountOnNode) { + return (AGESA_SUCCESS); + } + LeveledCores = MinCoreCountOnNode; + 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_ONE: + LeveledCores = 1; + 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: + RequestedCores = CoreLevelMode - CORE_LEVEL_THREE + 3; + LeveledCores = (RequestedCores + NumberOfModules - 1) / NumberOfModules; + LeveledCores = (LeveledCores <= MinCoreCountOnNode) ? LeveledCores : MinCoreCountOnNode; + if ((LeveledCores * NumberOfModules) != RequestedCores) { + PutEventLog ( + AGESA_WARNING, + CPU_WARNING_ADJUSTED_LEVELING_MODE, + RequestedCores, (LeveledCores * NumberOfModules), 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++) { + FamilySpecificServices->SetDownCoreRegister (FamilySpecificServices, &Socket, &Module, &LeveledCores, StdHeader); + } + } + } + } + + 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/f10/Proc/CPU/Feature/cpuDmi.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuDmi.c new file mode 100755 index 0000000000..9e7ea86ec0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuDmi.c @@ -0,0 +1,694 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "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" +#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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 +); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +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 + ); + +/*--------------------------------------------------------------------------------------- + * 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 DimmIndex; + UINT16 NumberOfDimm; + UINT32 PciData; + UINT64 MsrData; + UINT64 MsrRegister; + PCI_ADDR PciAddress; + AGESA_STATUS Flag; + AGESA_STATUS CalledStatus; + AP_EXE_PARAMS ApParams; + MEM_DMI_INFO *MemInfo; + DMI_T17_MEMORY_TYPE MemType; + DMI_INFO *DmiBufferPtr; + ALLOCATE_HEAP_PARAMS AllocateHeapParams; + LOCATE_HEAP_PTR LocateHeapParams; + + MsrData = 0; + Flag = TRUE; + DmiBufferPtr = *DmiTable; + 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; + } + // 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 { + NumberOfDimm = *((UINT16 *) (LocateHeapParams.BufferPtr)); + MemType = *((DMI_T17_MEMORY_TYPE *) ((UINT8 *) (LocateHeapParams.BufferPtr) + 2)); + MemInfo = (MEM_DMI_INFO *) ((UINT8 *) (LocateHeapParams.BufferPtr) + 2 + sizeof (DMI_T17_MEMORY_TYPE)); + // TYPE 16 + DmiBufferPtr->T16.Location = 0x03; + DmiBufferPtr->T16.Use = 0x03; + PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_2, 0x90); + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + if (PciData == 0) { + PciAddress.AddressValue = MAKE_SBDFO (0, 0 , PCI_DEV_BASE, FUNC_2, 0x190); + LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); + } + if ((PciData & 0x00080000) != 0) { + DmiBufferPtr->T16.MemoryErrorCorrection = 0x04; + } else { + DmiBufferPtr->T16.MemoryErrorCorrection = 0x03; + } + + LibAmdMsrRead (TOP_MEM2, &MsrData, StdHeader); + if (MsrData == 0) { + LibAmdMsrRead (TOP_MEM, &MsrData, StdHeader); + DmiBufferPtr->T16.MaximumCapacity = (UINT32) (MsrData >> 10); + } else { + DmiBufferPtr->T16.MaximumCapacity = (UINT32) (MsrData >> 10); + } + + DmiBufferPtr->T16.NumberOfMemoryDevices = NumberOfDimm; + + // TYPE 17 + for (DimmIndex = 0; DimmIndex < NumberOfDimm; DimmIndex++) { + Socket = (MemInfo + DimmIndex)->Socket; + Channel = (MemInfo + DimmIndex)->Channel; + Dimm = (MemInfo + DimmIndex)->Dimm; + + DmiBufferPtr->T17[Socket][Channel][Dimm].TotalWidth = (MemInfo + DimmIndex)->TotalWidth; + DmiBufferPtr->T17[Socket][Channel][Dimm].DataWidth = (MemInfo + DimmIndex)->DataWidth; + DmiBufferPtr->T17[Socket][Channel][Dimm].MemorySize = (MemInfo + DimmIndex)->MemorySize; + DmiBufferPtr->T17[Socket][Channel][Dimm].FormFactor = (MemInfo + DimmIndex)->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; + DmiBufferPtr->T17[Socket][Channel][Dimm].TypeDetail.Synchronous = 1; + DmiBufferPtr->T17[Socket][Channel][Dimm].Speed = (MemInfo + DimmIndex)->Speed; + + DmiBufferPtr->T17[Socket][Channel][Dimm].ManufacturerIdCode = (MemInfo + DimmIndex)->ManufacturerIdCode; + + IntToString (DmiBufferPtr->T17[Socket][Channel][Dimm].SerialNumber, (MemInfo + DimmIndex)->SerialNumber, (sizeof DmiBufferPtr->T17[Socket][Channel][Dimm].SerialNumber - 1) / 2); + + LibAmdMemCopy (&DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber, &(MemInfo + DimmIndex)->PartNumber, sizeof (DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber), StdHeader); + DmiBufferPtr->T17[Socket][Channel][Dimm].PartNumber[18] = 0; + + DmiBufferPtr->T17[Socket][Channel][Dimm].Attributes = (MemInfo + DimmIndex)->Attributes; + + //TYPE 20 + DmiBufferPtr->T20[Socket][Channel][Dimm].StartingAddr = (MemInfo + DimmIndex)->StartingAddr; + DmiBufferPtr->T20[Socket][Channel][Dimm].EndingAddr = (MemInfo + DimmIndex)->EndingAddr; + DmiBufferPtr->T20[Socket][Channel][Dimm].PartitionRowPosition = 0; + DmiBufferPtr->T20[Socket][Channel][Dimm].InterleavePosition = 0xFF; + DmiBufferPtr->T20[Socket][Channel][Dimm].InterleavedDataDepth = 0xFF; + } + + // TYPE 19 + DmiBufferPtr->T19.StartingAddr = 0; + + LibAmdMsrRead (TOP_MEM2, &MsrRegister, StdHeader); + if (MsrRegister == 0) { + LibAmdMsrRead (TOP_MEM, &MsrRegister, StdHeader); + DmiBufferPtr->T19.EndingAddr = (UINT32) (MsrRegister >> 10); + } else if (MsrRegister != 0) { + DmiBufferPtr->T19.EndingAddr = (UINT32) (MsrRegister >> 10); + } + + 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 CpuStepping; + UINT16 Index; + UINT32 SocketNum; + UINT32 CacheSize; + UINT32 IgnoredModule; + UINT32 IgnoredCore; + 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 + for (Index = 0; Index < ProcData->LenBrandList; Index++) { + if ((ProcData->DmiBrandList[Index].PackageType == 'x' || ProcData->DmiBrandList[Index].PackageType == CpuInfo.PackageType) && + (ProcData->DmiBrandList[Index].PgOfBrandId == 'x' || ProcData->DmiBrandList[Index].PgOfBrandId == CpuInfo.BrandId.Pg) && + (ProcData->DmiBrandList[Index].NumberOfCores == 'x' || ProcData->DmiBrandList[Index].NumberOfCores == CpuInfo.TotalCoreNumber) && + (ProcData->DmiBrandList[Index].String1ofBrandId == 'x' || ProcData->DmiBrandList[Index].String1ofBrandId == CpuInfo.BrandId.String1)) { + DmiBufferPtr->T4[SocketNum].T4ProcFamily = ProcData->DmiBrandList[Index].ValueSetToDmiTable; + break; + } + } + + 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); + + // Tyep4 Offset 0x12, External Clock + DmiBufferPtr->T4[SocketNum].T4ExternalClock = EXTERNAL_CLOCK; + + // 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 + + // 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 + // BaseModel ProcVersion + // 0~1 A + // 2~3 B + // 4~7 C + // 8~9 D + // A~ E + switch (CpuInfo.BaseModel) { + case 0: + case 1: + DmiBufferPtr->T4[SocketNum].T4ProcVersion[0] = 0x41; + break; + case 2: + case 3: + DmiBufferPtr->T4[SocketNum].T4ProcVersion[0] = 0x42; + break; + case 4: + case 5: + case 6: + case 7: + DmiBufferPtr->T4[SocketNum].T4ProcVersion[0] = 0x43; + break; + case 8: + case 9: + DmiBufferPtr->T4[SocketNum].T4ProcVersion[0] = 0x44; + break; + case 0xA: + DmiBufferPtr->T4[SocketNum].T4ProcVersion[0] = 0x45; + break; + default: + DmiBufferPtr->T4[SocketNum].T4ProcVersion[0] = 0x41; + } + + if (CpuInfo.Stepping >= 0xA) { + CpuStepping = CpuInfo.Stepping + 0x37; + } else { + CpuStepping = CpuInfo.Stepping + 0x30; + } + + DmiBufferPtr->T4[SocketNum].T4ProcVersion[1] = (CHAR8) CpuStepping; + DmiBufferPtr->T4[SocketNum].T4ProcVersion[2] = '\0'; + + //------------------------------ + // 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 + LibAmdCpuidRead (AMD_CPUID_TLB_L1Cache, &CpuId, &ApExeParams->StdHeader); + + // Maximum L1 cache size + CacheSize = (UINT32) (((UINT8) (CpuId.ECX_Reg >> 24) + (UINT8) (CpuId.EDX_Reg >> 24)) * (CpuInfo.EnabledCoreNumber + 1)); + DmiBufferPtr->T7L1[SocketNum].T7MaxCacheSize = AdjustGranularity (&CacheSize); + + // Installed L1 cache size + DmiBufferPtr->T7L1[SocketNum].T7InstallSize = DmiBufferPtr->T7L1[SocketNum].T7MaxCacheSize; + + // Maximum L2 cache size + LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuId, &ApExeParams->StdHeader); + CacheSize = (UINT32) ((UINT16) (CpuId.ECX_Reg >> 16) * (CpuInfo.EnabledCoreNumber + 1)); + DmiBufferPtr->T7L2[SocketNum].T7MaxCacheSize = AdjustGranularity (&CacheSize); + + // Installed L2 cache size + DmiBufferPtr->T7L2[SocketNum].T7InstallSize = DmiBufferPtr->T7L2[SocketNum].T7MaxCacheSize; + + // Maximum L3 cache size + CacheSize = ((CpuId.EDX_Reg >> 18) & 0x3FFF) * 512; + DmiBufferPtr->T7L3[SocketNum].T7MaxCacheSize = AdjustGranularity (&CacheSize); + + // 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 = ASSOCIATIVE_2_WAY; + DmiBufferPtr->T7L2[SocketNum].T7Associativity = ASSOCIATIVE_16_WAY; + if (((CpuId.EDX_Reg >> 12) & 0x0F) == ASSOCIATIVE_16_WAY) { + DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_16_WAY; + } else { + DmiBufferPtr->T7L3[SocketNum].T7Associativity = ASSOCIATIVE_OTHER; + } + return (Flag); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * 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/f10/Proc/CPU/Feature/cpuFeatureLeveling.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuFeatureLeveling.c new file mode 100755 index 0000000000..03780ed500 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuFeatureLeveling.c @@ -0,0 +1,262 @@ +/** + * @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: 6626 $ @e \$Date: 2008-07-04 02:01:02 +0800 (Fri, 04 Jul 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * 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" +#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 BscCore; + 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, &BscCore, &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 != BscCore)) { + 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 (&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 (&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 + ) +{ + UINT32 AddressValue; + + AddressValue = (UINT32)GLOBAL_CPU_FEATURE_LIST_TEMP_ADDR; + + *Address = (UINT64 *)(AddressValue); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuFeatures.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuFeatures.c new file mode 100755 index 0000000000..e3a0ef99b5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuFeatures.c @@ -0,0 +1,149 @@ +/** + * @file + * + * Implement general feature dispatcher. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "GeneralServices.h" +#include "cpuFeatures.h" +#include "Filecode.h" +#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[]; + +/** + * 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 + ) +{ + UINTN i; + + ASSERT (Feature < MaxCpuFeature); + + 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 + ) +{ + UINTN i; + AGESA_STATUS AgesaStatus; + AGESA_STATUS CalledStatus; + AGESA_STATUS IgnoredStatus; + + AgesaStatus = AGESA_SUCCESS; + + IDS_OPTION_HOOK (IDS_PLATFORMCFG_OVERRIDE, PlatformConfig, StdHeader); + + if (IsBsp (StdHeader, &IgnoredStatus)) { + for (i = 0; SupportedCpuFeatureList[i] != NULL; i++) { + if ((SupportedCpuFeatureList[i]->EntryPoint & EntryPoint) != 0) { + if (SupportedCpuFeatureList[i]->IsEnabled (PlatformConfig, StdHeader)) { + CalledStatus = SupportedCpuFeatureList[i]->InitializeFeature (EntryPoint, PlatformConfig, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + } + } + } + } + return AgesaStatus; +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuFeatures.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuFeatures.h new file mode 100755 index 0000000000..698eafdbc8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuFeatures.h @@ -0,0 +1,255 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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: + * <ul> + * <li> Any core in the system must be able to determine if the feature should be enabled or not. + * + * <ul> + * <li> MSRs cannot be read in multisocket systems in the 'IsEnabled' function. + * + * <li> Cores cannot be launched in the 'IsEnabled' function. + * </ul> + * </ul> + * + * @par Determine the Time Point at which the Feature Should be Enabled + * + * Factors to consider in making this determination: + * + * <ul> + * <li> Determine if there are any dependencies on other settings that require strict ordering. + * + * <li> Consider the state of the APs that you will need. + * + * <li> Remember that features enabled during AmdInitEarly will automatically be restored on S3 resume. + * </ul> + * + * @par Implementing a new feature + * + * Perform the following steps to implement a new feature: + * + * <ul> + * <li> Create a unique equate for your time point, @b if you cannot use an existing time point. + * + * <li> Create a new value in the DISPATCHABLE_CPU_FEATURES enum for your feature. + * + * <li> Add a new 'C' file to the Features folder for your feature. + * + * <ul> + * <li> The 'C' file must implement 2 functions -- 'IsEnabled' and 'Initialize' + * + * <li> The 'C' file must instantiate a CPU_FEATURE_DESCRIPTOR structure. + * </ul> + * + * <li> Add a new 'H' file to the Features folder for your feature. + * + * <ul> + * <li> The 'H' file declares whatever family specific functions required by the feature. + * + * <li> 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. + * </ul> + * + * <li> Create 'C' files in all applicable family folders. + * + * <ul> + * <li> Implement the required family specific functions. + * + * <li> Instantiate a family specific services structure. + * </ul> + * + * <li> Create \<feature name\>Install.h in the include folder. + * + * <ul> + * <li> Add logic to determine when your feature should be included in the build. + * + * <li> If the feature should be included, define OPTION_\<feature name\> to the address of your + * CPU_FEATURE_DESCRIPTOR instantiation. If not, define OPTION_\<feature name\> to be blank. + * + * <li> Create a family translation table pointing to all applicable instantiations of + * family specific function structures. + * </ul> + * + * <li> Modify OptionCpuFeaturesInstall.h in the include folder. + * + * <ul> + * <li> Include \<feature name\>Install.h. + * + * <li> Add OPTION_\<feature name\> to the SupportedCpuFeatureList array. + * </ul> + * + * <li> If a new time point was created, add a call to DispatchCpuFeatures at the desired location, + * passing your new time point equate. + * </ul> + * + */ + + +/*---------------------------------------------------------------------------------------- + * 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_AFTER_PM_INIT (0x0000000000000001ull) +#define CPU_FEAT_AFTER_POST_MTRR_SYNC (0x0000000000000002ull) +#define CPU_FEAT_INIT_MID_END (0x0000000000000004ull) +#define CPU_FEAT_INIT_LATE_END (0x0000000000000008ull) +#define CPU_FEAT_S3_LATE_RESTORE_END (0x0000000000000010ull) +#define CPU_FEAT_AFTER_RESUME_MTRR_SYNC (0x0000000000000020ull) +#define CPU_FEAT_AFTER_COHERENT_DISCOVERY (0x0000000000000040ull) +/** + * Enumerated list of supported features. + */ +typedef enum { + HardwareC1e, ///< Hardware C1e + HtAssist, ///< Probe filter + MsgBasedC1e, ///< Message-based C1e + CoreLeveling, ///< Core Leveling + C6Cstate, ///< C6 C-state + CacheFlushOnHalt, ///< Cache Flush On Halt + PreserveAroundMailbox, ///< Save-Restore the registers used for AP mailbox, to preserve their normal function. + 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 + *---------------------------------------------------------------------------------------- + */ + +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 + ); + +#endif // _CPU_FEATURES_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHtAssist.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHtAssist.c new file mode 100755 index 0000000000..1dead2cabb --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHtAssist.c @@ -0,0 +1,344 @@ +/** + * @file + * + * AMD CPU HT Assist Initialization functions. + * + * Contains code for doing probe filter initialization. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 7284 $ @e \$Date: 2008-08-08 23:29:33 +0800 (Fri, 08 Aug 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "amdlib.h" +#include "Topology.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuLateInit.h" +#include "cpuFamilyTranslation.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFeatures.h" +#include "cpuHtAssist.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FEATURE_CPUHTASSIST_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +extern CPU_FAMILY_SUPPORT_TABLE HtAssistFamilyServiceTable; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Should HT Assist be enabled + * + * @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 cannot be enabled. + * + */ +BOOLEAN +STATIC +IsHtAssistEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN IsEnabled; + UINT32 CpuCount; + UINT32 Socket; + AP_MAILBOXES ApMailboxes; + HT_ASSIST_FAMILY_SERVICES *FamilyServices; + + IsEnabled = FALSE; + if (PlatformConfig->PlatformProfile.UseHtAssist) { + CpuCount = GetNumberOfProcessors (StdHeader); + ASSERT (CpuCount != 0); + + if (CpuCount == 1) { + GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader); + if (ApMailboxes.ApMailInfo.Fields.ModuleType != 0) { + IsEnabled = TRUE; + } + } else if (CpuCount > 1) { + IsEnabled = TRUE; + } + if (IsEnabled) { + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&HtAssistFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); + if ((FamilyServices == NULL) || !FamilyServices->IsHtAssistSupported (FamilyServices, Socket, StdHeader)) { + IsEnabled = FALSE; + break; + } + } + } + } + } + return IsEnabled; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable the HT Assist feature. + * + * HT Assist initialization requires the following series of steps. + * -# Disable Cache on @b all cores. + * -# Initialize Probe Filter PCI regs + * -# Save L3 Scrub Rate + * -# On each node: + * -# Turn off L3Scrubber and Disable L3 cache + * -# On each node: + * -# Enable probe filter + * -# On each node: + * -# Enable L3 cache and turn on Scrubber. + * -# Restore L3 Scrub Rate + * -# Enable Cache on @b all cores. + * + * @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 HT Assist feature is running optimally. + * @retval AGESA_WARNING HT Assist feature is not running optimally. + * + */ +AGESA_STATUS +STATIC +InitializeHtAssistFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CpuCount; + UINT32 Socket; + AGESA_STATUS AgesaStatus; + AP_MAILBOXES ApMailboxes; + AP_EXE_PARAMS ApParams; + UINT32 Scrubbers[MAX_SOCKETS_SUPPORTED][L3_SCRUBBER_CONTEXT_ARRAY_SIZE]; + HT_ASSIST_FAMILY_SERVICES *FamilyServices[MAX_SOCKETS_SUPPORTED]; + + AgesaStatus = AGESA_SUCCESS; + + // There are many family service call outs. Initialize the family service array while + // cache is still enabled. + for (Socket = 0; Socket < MAX_SOCKETS_SUPPORTED; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&HtAssistFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices[Socket], StdHeader); + } else { + FamilyServices[Socket] = NULL; + } + } + + if (EntryPoint == CPU_FEAT_AFTER_POST_MTRR_SYNC) { + // Check for optimal settings + GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader); + CpuCount = GetNumberOfProcessors (StdHeader); + if (((CpuCount == 1) && (ApMailboxes.ApMailInfo.Fields.ModuleType == 1)) || + ((CpuCount == 2) && (ApMailboxes.ApMailInfo.Fields.ModuleType == 0))) { + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (FamilyServices[Socket] != NULL) { + if (FamilyServices[Socket]->IsNonOptimalConfig (FamilyServices[Socket], Socket, StdHeader)) { + // Non-optimal settings. Log an event. + AgesaStatus = AGESA_WARNING; + PutEventLog (AgesaStatus, CPU_WARNING_NONOPTIMAL_HT_ASSIST_CFG, 0, 0, 0, 0, StdHeader); + break; + } + } + } + } + } else { + // Disable the scrubbers. + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (FamilyServices[Socket] != NULL) { + FamilyServices[Socket]->GetL3ScrubCtrl (FamilyServices[Socket], Socket, &Scrubbers[Socket][0], StdHeader); + } + } + + // Wait for 40us + WaitMicroseconds ((UINT32) 40, StdHeader); + + // Run DisableAllCaches on AP cores. + ApParams.StdHeader = *StdHeader; + ApParams.FunctionNumber = AP_LATE_TASK_DISABLE_CACHE; + ApParams.RelatedDataBlock = NULL; + ApParams.RelatedBlockLength = 0; + RunLateApTaskOnAllAPs (&ApParams, StdHeader); + + // Run DisableAllCaches on core 0. + DisableAllCaches (&ApParams); + + // Family hook before initialization. + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (FamilyServices[Socket] != NULL) { + FamilyServices[Socket]->HookBeforeInit (FamilyServices[Socket], Socket, StdHeader); + } + } + + // Activate probe filter. + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (FamilyServices[Socket] != NULL) { + FamilyServices[Socket]->HtAssistInit (FamilyServices[Socket], Socket, StdHeader); + } + } + + // Family hook after initialization. + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (FamilyServices[Socket] != NULL) { + FamilyServices[Socket]->HookAfterInit (FamilyServices[Socket], Socket, StdHeader); + } + } + + // Run EnableAllCaches on core 0. + EnableAllCaches (&ApParams); + + // Run EnableAllCaches on every core. + ApParams.FunctionNumber = AP_LATE_TASK_ENABLE_CACHE; + RunLateApTaskOnAllAPs (&ApParams, StdHeader); + + // Restore the scrubbers. + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (FamilyServices[Socket] != NULL) { + FamilyServices[Socket]->SetL3ScrubCtrl (FamilyServices[Socket], Socket, &Scrubbers[Socket][0], StdHeader); + } + } + } + + return AgesaStatus; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Disable all the caches on current core. + * + * @param[in] ApExeParams Handle to config for library and services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +DisableAllCaches ( + IN AP_EXE_PARAMS *ApExeParams + ) +{ + UINT32 CR0Data; + HT_ASSIST_FAMILY_SERVICES *FamilyServices; + + GetFeatureServicesOfCurrentCore (&HtAssistFamilyServiceTable, (CONST VOID **)&FamilyServices, &ApExeParams->StdHeader); + + FamilyServices->HookDisableCache (FamilyServices, &ApExeParams->StdHeader); + + // Disable cache through CR0. + LibAmdReadCpuReg (0, &CR0Data); + CR0Data |= (0x60000000); + LibAmdWriteCpuReg (0, CR0Data); + + // Execute wbinvd + LibAmdWriteBackInvalidateCache (); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * + * Enable all the caches on current core. + * + * @param[in] ApExeParams Handle to config for library and services. + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +EnableAllCaches ( + IN AP_EXE_PARAMS *ApExeParams + ) +{ + UINT32 CR0Data; + HT_ASSIST_FAMILY_SERVICES *FamilyServices; + + // Enable cache through CR0. + LibAmdReadCpuReg (0, &CR0Data); + CR0Data &= ~(0x60000000); + LibAmdWriteCpuReg (0, CR0Data); + + GetFeatureServicesOfCurrentCore (&HtAssistFamilyServiceTable, (CONST VOID **)&FamilyServices, &ApExeParams->StdHeader); + + FamilyServices->HookEnableCache (FamilyServices, &ApExeParams->StdHeader); + + return AGESA_SUCCESS; +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureHtAssist = +{ + HtAssist, + (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_INIT_MID_END | CPU_FEAT_S3_LATE_RESTORE_END), + IsHtAssistEnabled, + InitializeHtAssistFeature +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHtAssist.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHtAssist.h new file mode 100755 index 0000000000..0ce6b17574 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHtAssist.h @@ -0,0 +1,278 @@ +/** + * @file + * + * AMD AGESA CPU HT Assist Function declarations. + * + * Contains code that declares the AGESA CPU Probe filter related APIs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Feature + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_HT_ASSIST_H_ +#define _CPU_HT_ASSIST_H_ + +#include "Filecode.h" +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration. +typedef struct _HT_ASSIST_FAMILY_SERVICES HT_ASSIST_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 (0x00000000 | PROC_CPU_FEATURE_CPUHTASSIST_FILECODE) +#define AP_LATE_TASK_ENABLE_CACHE (0x00010000 | PROC_CPU_FEATURE_CPUHTASSIST_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 HT Assist is supported. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] Socket Processor socket to check. + * @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 HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_IS_SUPPORTED *PF_HT_ASSIST_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific hook before HT Assist is initialized. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_HT_ASSIST_BEFORE_INIT ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_BEFORE_INIT *PF_HT_ASSIST_BEFORE_INIT; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to disable cache. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_HT_ASSIST_DISABLE_CACHE ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_DISABLE_CACHE *PF_HT_ASSIST_DISABLE_CACHE; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to disable cache. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] StdHeader Config Handle for library, services. + * + * @return Family specific error value. + * + */ +typedef VOID F_HT_ASSIST_ENABLE_CACHE ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_ENABLE_CACHE *PF_HT_ASSIST_ENABLE_CACHE; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to disable cache. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] Socket Processor socket to enable. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_HT_ASSIST_INIT ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + 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 disable cache. + * + * @param[in] HtAssistServices HT Assist family services. + * @param[in] Socket Processor socket to check. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_HT_ASSIST_AFTER_INIT ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_AFTER_INIT *PF_HT_ASSIST_AFTER_INIT; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to save the L3 scrubber. + * + * @param[in] HtAssistServices HT Assist 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_HT_ASSIST_GET_L3_SCRUB_CTRL ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE], + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_GET_L3_SCRUB_CTRL *PF_HT_ASSIST_GET_L3_SCRUB_CTRL; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to restore the L3 scrubber. + * + * @param[in] HtAssistServices HT Assist 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_HT_ASSIST_SET_L3_SCRUB_CTRL ( + IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE], + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_SET_L3_SCRUB_CTRL *PF_HT_ASSIST_SET_L3_SCRUB_CTRL; + + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to restore the L3 scrubber. + * + * @param[in] HtAssistServices HT Assist 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 HT_ASSIST_FAMILY_SERVICES *HtAssistServices, + IN UINT32 Socket, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HT_ASSIST_IS_NONOPTIMAL *PF_HT_ASSIST_IS_NONOPTIMAL; + + +/** + * Provide the interface to the HT Assist 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 _HT_ASSIST_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + 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_GET_L3_SCRUB_CTRL GetL3ScrubCtrl; ///< Method: Save/disable the L3 scrubber. + PF_HT_ASSIST_SET_L3_SCRUB_CTRL SetL3ScrubCtrl; ///< Method: Restore the L3 scrubber. + PF_HT_ASSIST_BEFORE_INIT HookBeforeInit; ///< Method: Hook before enabling HT Assist. + PF_HT_ASSIST_AFTER_INIT HookAfterInit; ///< Method: Hook after enabling HT Assist. + PF_HT_ASSIST_DISABLE_CACHE HookDisableCache; ///< Method: Core hook just before disabling cache. + PF_HT_ASSIST_ENABLE_CACHE HookEnableCache; ///< Method: Core hook just after enabling cache. + PF_HT_ASSIST_IS_NONOPTIMAL IsNonOptimalConfig; ///< Method: Check if HT Assist is running optimally. +}; + + +/*---------------------------------------------------------------------------------------- + * 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_HT_ASSIST_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHwC1e.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHwC1e.c new file mode 100755 index 0000000000..49fb9b00a4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHwC1e.c @@ -0,0 +1,166 @@ +/** + * @file + * + * AMD AGESA CPU HW C1e feature support code. + * + * 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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "Topology.h" +#include "cpuFeatures.h" +#include "cpuHwC1e.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FEATURE_CPUHWC1E_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 HwC1eFamilyServiceTable; + +/*---------------------------------------------------------------------------------------*/ +/** + * Should hardware C1e be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HW C1e is supported. + * @retval FALSE HW C1e cannot be enabled. + * + */ +BOOLEAN +STATIC +IsHwC1eFeatureEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + BOOLEAN IsEnabled; + AP_MAILBOXES ApMailboxes; + HW_C1E_FAMILY_SERVICES *FamilyServices; + + ASSERT (PlatformConfig->C1eMode < MaxC1eMode); + IsEnabled = FALSE; + if (PlatformConfig->C1eMode == C1eModeHardware) { + ASSERT (PlatformConfig->C1ePlatformData < 0x10000); + ASSERT (PlatformConfig->C1ePlatformData != 0); + if ((PlatformConfig->C1ePlatformData != 0) && (PlatformConfig->C1ePlatformData < 0xFFFE)) { + if (GetNumberOfProcessors (StdHeader) == 1) { + GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader); + if (ApMailboxes.ApMailInfo.Fields.ModuleType == 0) { + GetFeatureServicesOfCurrentCore (&HwC1eFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + if (FamilyServices != NULL) { + IsEnabled = FamilyServices->IsHwC1eSupported (FamilyServices, StdHeader); + } + } + } + } + } + return IsEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable Hardware C1e + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @return The most severe status of any family specific service. + * + */ +AGESA_STATUS +STATIC +InitializeHwC1eFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS CalledStatus; + AGESA_STATUS AgesaStatus; + HW_C1E_FAMILY_SERVICES *FamilyServices; + + AgesaStatus = AGESA_SUCCESS; + + if (IsWarmReset (StdHeader)) { + GetFeatureServicesOfCurrentCore (&HwC1eFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + CalledStatus = FamilyServices->InitializeHwC1e (FamilyServices, EntryPoint, PlatformConfig, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + } + return AgesaStatus; +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureHwC1e = +{ + HardwareC1e, + CPU_FEAT_AFTER_PM_INIT, + IsHwC1eFeatureEnabled, + InitializeHwC1eFeature +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHwC1e.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHwC1e.h new file mode 100755 index 0000000000..53226f7ff1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuHwC1e.h @@ -0,0 +1,125 @@ +/** + * @file + * + * AMD AGESA CPU HW 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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_HW_C1E_H_ +#define _CPU_HW_C1E_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration. +typedef struct _HW_C1E_FAMILY_SERVICES HW_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 hardware C1e is supported. + * + * @param[in] HwC1eServices Hardware C1e services. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE HW C1e is supported. + * @retval FALSE HW C1e is not supported. + * + */ +typedef BOOLEAN F_HW_C1E_IS_SUPPORTED ( + IN HW_C1E_FAMILY_SERVICES *HwC1eServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HW_C1E_IS_SUPPORTED *PF_HW_C1E_IS_SUPPORTED; + +/*---------------------------------------------------------------------------------------*/ +/** + * Family specific call to enable hardware C1e. + * + * @param[in] HwC1eServices 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_HW_C1E_INIT ( + IN HW_C1E_FAMILY_SERVICES *HwC1eServices, + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_HW_C1E_INIT *PF_HW_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 _HW_C1E_FAMILY_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_HW_C1E_IS_SUPPORTED IsHwC1eSupported; ///< Method: Family specific call to check if hardware C1e is supported. + PF_HW_C1E_INIT InitializeHwC1e; ///< 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_HW_C1E_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuMsgBasedC1e.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuMsgBasedC1e.c new file mode 100755 index 0000000000..1be14e2db8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuMsgBasedC1e.c @@ -0,0 +1,236 @@ +/** + * @file + * + * AMD AGESA CPU Message-based C1e feature support code. + * + * 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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "OptionMultiSocket.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuFeatures.h" +#include "cpuMsgBasedC1e.h" +#include "GeneralServices.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FEATURE_CPUMSGBASEDC1E_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 +EnableMsgC1eOnSocket ( + 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 MsgBasedC1eFamilyServiceTable; +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------------------*/ +/** + * Should message-based C1e be enabled + * + * @param[in] PlatformConfig Contains the runtime modifiable feature input data. + * @param[in] StdHeader Config Handle for library, services. + * + * @retval TRUE Message-based C1e is supported. + * @retval FALSE Message-based C1e cannot be enabled. + * + */ +BOOLEAN +STATIC +IsMsgBasedC1eFeatureEnabled ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN Link; + UINTN LinkCount; + UINT32 Socket; + UINT32 Module; + BOOLEAN IsEnabled; + PCI_ADDR PciAddress; + AGESA_STATUS AgesaStatus; + HT_HOST_FEATS HtHostFeats; + CPU_SPECIFIC_SERVICES *CpuServices; + MSG_BASED_C1E_FAMILY_SERVICES *FamilyServices; + + ASSERT (PlatformConfig->C1eMode < MaxC1eMode); + + IsEnabled = FALSE; + if (PlatformConfig->C1eMode == C1eModeMsgBased) { + ASSERT (PlatformConfig->C1ePlatformData < 0x10000); + ASSERT (PlatformConfig->C1ePlatformData != 0); + if ((PlatformConfig->C1ePlatformData != 0) && (PlatformConfig->C1ePlatformData < 0xFFFE)) { + IsEnabled = TRUE; + for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetFeatureServicesOfSocket (&MsgBasedC1eFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader); + if ((FamilyServices == NULL) || !FamilyServices->IsMsgBasedC1eSupported (FamilyServices, Socket, StdHeader)) { + IsEnabled = FALSE; + break; + } else { + // If the CPU revision supports message-based C1e, check whether the feature should + // be disabled based on the speed of ncHT links (HT1). + GetCpuServicesOfSocket (Socket, &CpuServices, StdHeader); + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) { + HtHostFeats.HtHostValue = 0; + for (LinkCount = 0; LinkCount < 8; LinkCount++) { + if (FindHtHostCapability (LinkCount, &PciAddress, StdHeader)) { + CpuServices->GetHtLinkFeatures (CpuServices, &Link, &PciAddress, &HtHostFeats, StdHeader); + if ((HtHostFeats.HtHostFeatures.NonCoherent == 1) && (HtHostFeats.HtHostFeatures.Ht1 == 1)) { + IsEnabled = FALSE; + break; + } + } + } + } + // Exit for (Module = 0; Module < GetPlatformNumberOfModules; Module++) + if (!IsEnabled) { + break; + } + } + } + } + // Exit for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) + if (!IsEnabled) { + break; + } + } + } + } + return IsEnabled; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Enable Message-based C1e + * + * @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 +InitializeMsgBasedC1eFeature ( + IN UINT64 EntryPoint, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + + if ((EntryPoint != CPU_FEAT_AFTER_PM_INIT) || (IsWarmReset (StdHeader))) { + CpuEarlyParams.PlatformConfig = *PlatformConfig; + + TaskPtr.FuncAddress.PfApTaskIC = EnableMsgC1eOnSocket; + 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 message-based C1e on it's socket. + * + * @param[in] EntryPoint Timepoint designator. + * @param[in] StdHeader Config Handle for library, services. + * @param[in] CpuEarlyParams Service parameters. + * + */ +VOID +STATIC +EnableMsgC1eOnSocket ( + IN VOID *EntryPoint, + IN AMD_CONFIG_PARAMS *StdHeader, + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams + ) +{ + MSG_BASED_C1E_FAMILY_SERVICES *FamilyServices; + + GetFeatureServicesOfCurrentCore (&MsgBasedC1eFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + FamilyServices->InitializeMsgBasedC1e (FamilyServices, + *((UINT64 *) EntryPoint), + &CpuEarlyParams->PlatformConfig, + StdHeader); +} + +CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureMsgBasedC1e = +{ + MsgBasedC1e, + (CPU_FEAT_AFTER_PM_INIT | CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC), + IsMsgBasedC1eFeatureEnabled, + InitializeMsgBasedC1eFeature +}; diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuMsgBasedC1e.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuMsgBasedC1e.h new file mode 100755 index 0000000000..4896622986 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuMsgBasedC1e.h @@ -0,0 +1,127 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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. +typedef struct _MSG_BASED_C1E_FAMILY_SERVICES 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/f10/Proc/CPU/Feature/cpuPstateGather.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateGather.c new file mode 100755 index 0000000000..766a623102 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateGather.c @@ -0,0 +1,382 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + + +/* + *---------------------------------------------------------------------------- + * 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 "cpuApicUtilities.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FEATURE_CPUPSTATEGATHER_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +extern OPTION_PSTATE_POST_CONFIGURATION OptionPstatePostConfiguration; // global user config record + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +VOID +PStateGather ( + IN OUT VOID *PStateBuffer, + IN AMD_CONFIG_PARAMS *StdHeader + ); +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 + ); + +/** + *--------------------------------------------------------------------------------------- + * + * 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. + * + * Note: This function should be called for every core in the system. + * + * Parameters: + * @param[in] *StdHeader + * @param[in, out] *PStateStrucPtr + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + **/ +AGESA_STATUS +PStateGatherData ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr + ) +{ + AGESA_TESTPOINT (TpProcCpuEntryPstateGather, StdHeader); + return (*(OptionPstatePostConfiguration.PstateGather)) (StdHeader, PStateStrucPtr); + // Note: Split config struct into PEI/DXE halves. This one is PEI. +} + +/**-------------------------------------------------------------------------------------- + * + * 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; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + UINT32 MaxState; + + ASSERT (IsBsp (StdHeader, &IgnoredSts)); + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + ASSERT (FamilySpecificServices != NULL); + + PopulatedSockets = 1; + PStateBufferPtr = PStateStrucPtr->PStateLevelingStruc; + + NumberOfSockets = GetPlatformNumberOfSockets (); + IdentifyCore (StdHeader, &BscSocket, &Ignored, &Ignored, &IgnoredSts); + + PStateStrucPtr->SizeOfBytes = sizeof (S_CPU_AMD_PSTATE); + + MaxState = 0; + FamilySpecificServices->GetPstateMaxState (FamilySpecificServices, &MaxState, 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; + PCI_ADDR PciAddress; + PSTATE_LEVELING *PStateBufferPtr; + BOOLEAN PStateEnabled; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + UINT32 Socket; + AGESA_STATUS IgnoredSts; + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + ASSERT (FamilySpecificServices != NULL); + + PStateBufferPtr = (PSTATE_LEVELING *) PStateBuffer; + TotalEnabledPStates = 0; + PStateEnabled = FALSE; + + // + /// 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; /// @todo need remove + + // + // We need to know the max pstate state in this socket. + // + FamilySpecificServices->GetPstateMaxState (FamilySpecificServices, &TempVar_c, StdHeader); + PStateBufferPtr->PStateCoreStruct[0].PStateMaxValue = (UINT8) TempVar_c; + + for (k = 0; k <= TempVar_c; k++) { + // Check if PState is enabled + FamilySpecificServices->GetPstateRegisterInfo (FamilySpecificServices, + k, + &PStateEnabled, + &IddVal, + &IddDiv, + StdHeader); + + LibAmdMemFill (&(PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k]), 0, sizeof (S_PSTATE_VALUES), StdHeader); + + if (PStateEnabled) { + + FamilySpecificServices->GetPstateFrequency ( + FamilySpecificServices, + (UINT8) k, + &(PStateBufferPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq), + StdHeader); + + FamilySpecificServices->GetPstatePower ( + FamilySpecificServices, + (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].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); + GetPciAddress (StdHeader, Socket, NodeNum, &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 + +} + + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateLeveling.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateLeveling.c new file mode 100755 index 0000000000..169a94f170 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateLeveling.c @@ -0,0 +1,1088 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + *---------------------------------------------------------------------------- + */ + + +/* + *---------------------------------------------------------------------------- + * 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 "cpuApicUtilities.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FEATURE_CPUPSTATELEVELING_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +extern OPTION_PSTATE_POST_CONFIGURATION OptionPstatePostConfiguration; // global user config record + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +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 + ); + +/*---------------------------------------------------------------------------- + * 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 + ); + + +/** + *--------------------------------------------------------------------------------------- + * + * 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]; + + BOOLEAN TempFlag1; + BOOLEAN TempFlag2; + BOOLEAN TempFlag3; + BOOLEAN TempFlag4; + BOOLEAN AllCoresHaveHtcCapEquToZeroFlag; + BOOLEAN AllCoreHaveMaxOnePStateFlag; + BOOLEAN PstateMaxValEquToPstateHtcLimitFlag; + BOOLEAN AtLeastOneCoreHasPstateHtcLimitEquToOneFlag; + BOOLEAN PstateMaxValMinusHtcPstateLimitLessThan2Flag; + PSTATE_LEVELING *PStateBufferPtr; + PSTATE_LEVELING *PStateBufferPtrTmp = NULL; + 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; + + // 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) { + // Check if core frequency and power are same across all sockets. + TempFlag1 = FALSE; + for (i = 0; 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 = 0; k <= MaxPstateInNode; k++) { + if ((PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[k].CoreFreq != + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].CoreFreq) || + (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[k].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 == 0) { + 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; + PStateBufferPtr[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[0].CoreFreq; + TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[0].Power; + TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[0].IddValue; + TempVar_b = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[0].IddDiv; + + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + if (TempVar_d > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].CoreFreq) { + TempVar_d = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].CoreFreq; + } + + if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].Power) { + TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].Power; + TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddValue; + TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddDiv; + } + } + + // Set P0 Frequency and Power for all CPUs + for (i = 0; i < LogicalSocketCount; i++) { + CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader); + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].CoreFreq = TempVar_d; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].Power = TempVar_e; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddValue = TempVar_a; + PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].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 = 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] != 0) { + while (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].PStateEnable == 0) { + TempSocketPiArray[0] = TempSocketPiArray[0] - 1; + if (TempSocketPiArray[0] == 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] != 0) { + while (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].PStateEnable == 0) { + TempSocketPiArray[i]--; + if (TempSocketPiArray[i] == 0) { + 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 > 0; 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 BscCore; + 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, &BscCore, &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) BscCore)) { + 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 + ) +{ + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + FamilySpecificServices = NULL; + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + + FamilySpecificServices->SetPStateLevelReg (FamilySpecificServices, (S_CPU_AMD_PSTATE *) CpuAmdPState, StdHeader); + +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * This function will set msr on all cores of all nodes. + * + * @param[in] CpuAmdPState @todo describe + * @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 BscCore; + 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, &BscCore, &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) BscCore)) { + 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 (&FamilySpecificServices, StdHeader); + + FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) FALSE, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c new file mode 100755 index 0000000000..ed4eb02144 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.c @@ -0,0 +1,821 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + + +/* + *---------------------------------------------------------------------------- + * 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 "cpuC6State.h" +#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 C6FamilyServiceTable; + +STATIC ACPI_TABLE_HEADER ROMDATA CpuSsdtHdrStruct = +{ + {'S','S','D','T'}, + 0, + 1, + 0, + {'A','M','D',' ',' ',' '}, + {'P','O','W','E','R','N','O','W'}, + 1, + {'A','M','D',' '}, + 1 +}; + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +AGESA_STATUS +PStateLevelingMain ( + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); +AGESA_STATUS +CreateAcpiTablesMain ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SsdtPtr + ); +AGESA_STATUS +CreateAcpiTablesStub ( + 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 + * + *--------------------------------------------------------------------------------------- + */ +STATIC UINT32 +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 CstObjSize; + PSTATE_LEVELING *PStateLevelingBufferStructPtr; + C6_FAMILY_SERVICES *C6FamilyServices; + + ScopeSize = sizeof (ACPI_TABLE_HEADER); + CstObjSize = 0; + C6FamilyServices = NULL; + + PStateLevelingBufferStructPtr = AmdPstatePtr->PStateLevelingStruc; + MaxSocketNumberInSystem = AmdPstatePtr->TotalSocketInSystem; + + if (IsFeatureEnabled (C6Cstate, PlatformConfig, StdHeader)) { + GetFeatureServicesOfCurrentCore (&C6FamilyServiceTable, (CONST VOID **)&C6FamilyServices, StdHeader); + CstObjSize = C6FamilyServices->GetAcpiCstObj (); + } + + for (SocketCount = 0; SocketCount < MaxSocketNumberInSystem; SocketCount++) { + MaxCoreNumberInCurrentSocket = PStateLevelingBufferStructPtr->TotalCoresInNode; + for (CoreCount = 0; CoreCount < MaxCoreNumberInCurrentSocket; CoreCount++) { + MaxPstateNumberInCurrentCore = PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue + 1; + 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) + (SCOPE_STRUCT_SIZE - 1) + + CstObjSize; + + } + 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; +} + +/** + *--------------------------------------------------------------------------------------- + * + * CreateAcpiTables + * + * Description: + * This function will populate the ACPI PState tables + * 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 table pointer + * + * @retval AGESA_STATUS + * + *--------------------------------------------------------------------------------------- + */ +AGESA_STATUS +CreateAcpiTables ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SsdtPtr + ) +{ + AGESA_TESTPOINT (TpProcCpuEntryPstate, StdHeader); + return ((*(OptionPstateLateConfiguration.PstateFeature)) (StdHeader, PlatformConfig, SsdtPtr)); + // Note: Split config struct into PEI/DXE halves. This one is DXE. +} + +/**-------------------------------------------------------------------------------------- + * + * CreateAcpiTablesStub + * + * 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 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 +CreateAcpiTablesStub ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SsdtPtr + ) +{ + return AGESA_UNSUPPORTED; +} + +/**-------------------------------------------------------------------------------------- + * + * CreateAcpiTablesMain + * + * Description: + * This is the common routine for creating the ACPI information tables. + * + * 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 +CreateAcpiTablesMain ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN OUT VOID **SsdtPtr + ) +{ + UINT32 i; + UINT32 j; + UINT32 k; + UINT32 TempVar8_a; + UINT32 PStateCount; + UINT32 CoreCount; + UINT32 CoreCount1; + UINT32 SocketCount; + UINT32 ScopeSize; + UINT32 TempVar_a; + UINT32 TempVar_b; + UINT32 TempVar_c; + UINT32 TempVar_d; + PCI_ADDR PciAddress; + UINT32 TransAndBusMastLatency; + UINT32 MaxCorePerNode; + UINT8 PStateMaxValueOnCurrentCore; + UINT8 *IntermediatePtr; + PSTATE_LEVELING *PStateLevelingBufferStructPtr; + AMD_CONFIG_PARAMS *AmdConfigParamsStructPtr; + SCOPE *ScopeAcpiTablesStructPtr; + SCOPE *ScopeAcpiTablesStructPtrTemp; + 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 *pPpcHeaderBodyAcpiTables; + AGESA_BUFFER_PARAMS AgesaBuffer; + LOCATE_HEAP_PTR LocateHeapParams; + S_CPU_AMD_PSTATE *AmdPstatePtr; + BOOLEAN PstateCapEnable; + UINT32 PstateCapInputMilliWatts; + UINT8 PstateCapLevelSupport; + BOOLEAN PstateCapLevelSupportDetermined; + UINT8 LocalApicId; + AGESA_STATUS AgesaStatus; + AGESA_STATUS IgnoredStatus; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + PSTATE_CPU_FAMILY_SERVICES *FamilyServices; + BOOLEAN IsPsdDependent; + C6_FAMILY_SERVICES *C6FamilyServices; + // + //Initialize local variables + // + AmdConfigParamsStructPtr = StdHeader; + PstateCapEnable = FALSE; + PstateCapInputMilliWatts = PlatformConfig->PowerCeiling; + PstateCapLevelSupport = DEFAULT_PERF_PRESENT_CAP; + PstateCapLevelSupportDetermined = TRUE; + LocalApicId = 0; + AgesaStatus = AGESA_SUCCESS; + TempVar_c = 0; + ScopeAcpiTablesStructPtrTemp = NULL; + TransAndBusMastLatency = 0; + PStateCount = 0; + IsPsdDependent = !(PlatformConfig->ForcePstateIndependent); + FamilyServices = NULL; + C6FamilyServices = NULL; + + ASSERT (IsBsp (StdHeader, &IgnoredStatus)); + + // + //Locate P-state gathered data heap. + // + 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; + + // + // Check if we need to create ACPI tables + // + if (PStateLevelingBufferStructPtr[0].CreateAcpiTables == 0) { + return AGESA_UNSUPPORTED; + } + + // + //Allocate rough buffer for AcpiTable, if AcpiPstateBufferPtr is NULL + // + if (*SsdtPtr == NULL) { + AgesaBuffer.StdHeader = *StdHeader; + // + //Do not know the actual size.. pre-calculate it. + // + AgesaBuffer.BufferLength = CalAcpiTablesSize (AmdPstatePtr, PlatformConfig, StdHeader); + AgesaBuffer.BufferHandle = AMD_PSTATE_ACPI_BUFFER_HANDLE; + + AGESA_TESTPOINT (TpProcCpuBeforeAllocateSsdtBuffer, StdHeader); + if (AgesaAllocateBuffer (0, &AgesaBuffer) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpProcCpuAfterAllocateSsdtBuffer, StdHeader); + *SsdtPtr = AgesaBuffer.BufferPointer; + } + + //SSDT header + LibAmdMemCopy (*SsdtPtr, (VOID *) &CpuSsdtHdrStruct, (UINTN) (sizeof (ACPI_TABLE_HEADER)), StdHeader); + + IntermediatePtr = (UINT8 *) *SsdtPtr; + ScopeAcpiTablesStructPtr = (SCOPE *) &IntermediatePtr[sizeof (ACPI_TABLE_HEADER)]; + + SocketCount = AmdPstatePtr->TotalSocketInSystem; + + // Initialize data variables + ScopeSize = 0; + CoreCount = 0; + for (i = 0; i < SocketCount; i++) { + + MaxCorePerNode = PStateLevelingBufferStructPtr->TotalCoresInNode; + + for (j = 0; j < MaxCorePerNode; j++) { + + // + //Check Pstate Capability enable + // + if (PstateCapInputMilliWatts != 0) { + PstateCapEnable = TRUE; + PstateCapLevelSupportDetermined = FALSE; + } + + PStateMaxValueOnCurrentCore = PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue; + + 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 + // + ScopeAcpiTablesStructPtr++; + pPctAcpiTables = (PCT_HEADER_BODY *) ScopeAcpiTablesStructPtr; + ScopeAcpiTablesStructPtr--; + ScopeAcpiTablesStructPtrTemp = ScopeAcpiTablesStructPtr; + ScopeAcpiTablesStructPtrTemp++; + + 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; + + // Set _PSS Table - START + //------------------------ + + // Increment and then typecast the pointer + pPctAcpiTables++; + TempVar_c += PCT_STRUCT_SIZE; + + ScopeAcpiTablesStructPtrTemp = (SCOPE *) pPctAcpiTables; + } // end of OptionPstateLateConfiguration.CfgPstatePct + + pPssHeaderAcpiTables = (PSS_HEADER *) pPctAcpiTables; + + if (OptionPstateLateConfiguration.CfgPstatePss) { + // + // Set _PSS Header + // Note: Set the 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++; + }// end of PSS Header if OptionPstateLateConfiguration.CfgPstatePss + + pPssBodyAcpiTables = (PSS_BODY *) pPssHeaderAcpiTables; + + if (OptionPstateLateConfiguration.CfgPstatePss) { + // Restore the pPssHeaderAcpiTables + pPssHeaderAcpiTables--; + + // Set _PSS Body + //--------------- + PStateCount = 0; + + // + //Calculate pci address for socket only + // + GetPciAddress (StdHeader, (UINT32) PStateLevelingBufferStructPtr->SocketNumber, 0, &PciAddress, &IgnoredStatus); + TransAndBusMastLatency = 0; + GetCpuServicesOfSocket ((UINT32) PStateLevelingBufferStructPtr->SocketNumber, &FamilySpecificServices, StdHeader); + ASSERT (FamilySpecificServices != NULL); + FamilySpecificServices->GetPstateLatency (FamilySpecificServices, + PStateLevelingBufferStructPtr, + &PciAddress, + &TransAndBusMastLatency, + StdHeader); + + for (k = 0; k <= PStateMaxValueOnCurrentCore; k++) { + if (PStateLevelingBufferStructPtr->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 = + PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq; + + pPssBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE; + + pPssBodyAcpiTables->Power = + PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].Power; + + if (PstateCapEnable && (!PstateCapLevelSupportDetermined) && (PstateCapInputMilliWatts >= pPssBodyAcpiTables->Power)) { + PstateCapLevelSupport = (UINT8) k; + 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 = k; + pPssBodyAcpiTables->DwordPrefixOpcode6 = DWORD_PREFIX_OPCODE; + pPssBodyAcpiTables->Status = k; + + 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; + if (TempVar_a > 63) { + TempVar_b = TempVar_a; + TempVar_d = ((TempVar_b << 4) & 0x0000FF00); + TempVar_d = TempVar_d | ((TempVar_b & 0x0000000F) | 0x00000040); + TempVar_a = (UINT16) TempVar_d; + } + + pPssHeaderAcpiTables->PssLength = (UINT16) TempVar_a; + pPssHeaderAcpiTables->NumOfItemsInPss = (UINT8) PStateCount; + TempVar_c += (PSS_HEADER_STRUCT_SIZE + (PStateCount * PSS_BODY_STRUCT_SIZE)); + + ScopeAcpiTablesStructPtrTemp = (SCOPE *) pPssBodyAcpiTables; + } // end of PSS Body if OptionPstateLateConfiguration.CfgPstatePss + + // + // Set XPSS Table - START + //------------------------ + // Typecast the pointer + pXpssHeaderAcpiTables = (XPSS_HEADER *) 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++; + }//end of XPSS header if OptionPstateLateConfiguration.CfgPstateXpss + + pXpssBodyAcpiTables = (XPSS_BODY *) pXpssHeaderAcpiTables; + + if (OptionPstateLateConfiguration.CfgPstateXpss) { + // Restore the pXpssHeaderAcpiTables + pXpssHeaderAcpiTables--; + + // Set XPSS Body + //--------------- + for (k = 0; k <= PStateMaxValueOnCurrentCore; k++) { + if (PStateLevelingBufferStructPtr->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 = + PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq; + + pXpssBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE; + + pXpssBodyAcpiTables->Power = + PStateLevelingBufferStructPtr->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 = k; + pXpssBodyAcpiTables->ControlHi = 0; + pXpssBodyAcpiTables->StatusBuffer = XPSS_ACPI_BUFFER; + pXpssBodyAcpiTables->StatusLo = k; + 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; + if (TempVar_a > 63) { + TempVar_b = TempVar_a; + TempVar_d = ((TempVar_b << 4) & 0x0000FF00); + TempVar_d = TempVar_d | ((TempVar_b & 0x0000000F) | 0x00000040); + TempVar_a = (UINT16) TempVar_d; + } + + pXpssHeaderAcpiTables->XpssLength = (UINT16) TempVar_a; + pXpssHeaderAcpiTables->NumOfItemsInXpss = (UINT8) PStateCount; + TempVar_c += (XPSS_HEADER_STRUCT_SIZE + (PStateCount * XPSS_BODY_STRUCT_SIZE)); + + ScopeAcpiTablesStructPtrTemp = (SCOPE *) pXpssBodyAcpiTables; + } //end of XPSS Body OptionPstateLateConfiguration.CfgPstateXpss + + // + // Set _PSD Table - START + //------------------------ + // Typecast the pointer + pPsdHeaderAcpiTables = (PSD_HEADER *) pXpssBodyAcpiTables; + + // + // Get Total Cores Per Node + /// @todo Maybe this should ask for single core Sockets not single core nodes? + if (GetActiveCoresInGivenSocket ((UINT32) PStateLevelingBufferStructPtr->SocketNumber, &CoreCount1, AmdConfigParamsStructPtr)) { + if ((CoreCount1 != 1) && (OptionPstateLateConfiguration.CfgPstatePsd)) { + // + // Set _PSD Header + //----------------- + pPsdHeaderAcpiTables->NameOpcode = NAME_OPCODE; + pPsdHeaderAcpiTables->PkgOpcode = PACKAGE_OPCODE; + pPsdHeaderAcpiTables->PsdLength = PSD_HEADER_LENGTH; + pPsdHeaderAcpiTables->Value1 = PSD_VALUE1; + + // Set _PSD Header + 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++; + TempVar_c += PSD_HEADER_STRUCT_SIZE; + } // end of PSD Header if (CoreCount1 != 1) && (OptionPstateLateConfiguration.CfgPstatePsd) + } + pPsdBodyAcpiTables = (PSD_BODY *) pPsdHeaderAcpiTables; + + if ((CoreCount1 != 1) && (OptionPstateLateConfiguration.CfgPstatePsd)) { + 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; + // + //Get ApicId from AMD CPU general service. + //Basically, DependencyDomain should be LocalApicId for each core PSD independent. + // + GetApicId (StdHeader, (UINT32) PStateLevelingBufferStructPtr->SocketNumber, j, &LocalApicId, &AgesaStatus); + + GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + if (FamilyServices != NULL) { + IsPsdDependent = FamilyServices->IsPstatePsdDependent (FamilyServices, PlatformConfig, StdHeader); + } + + if (IsPsdDependent) { + pPsdBodyAcpiTables->DependencyDomain = PSD_DEPENDENCY_DOMAIN; + pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_SW_ALL; + pPsdBodyAcpiTables->NumOfProcessors = CoreCount1; + } else { + pPsdBodyAcpiTables->DependencyDomain = LocalApicId; + pPsdBodyAcpiTables->CoordinationType = PSD_COORDINATION_TYPE_SW_ANY; + pPsdBodyAcpiTables->NumOfProcessors = PSD_NUM_OF_PROCESSORS; + } + + pPsdBodyAcpiTables->DwordPrefixOpcode2 = DWORD_PREFIX_OPCODE; + pPsdBodyAcpiTables->DwordPrefixOpcode3 = DWORD_PREFIX_OPCODE; + + pPsdBodyAcpiTables++; + ScopeAcpiTablesStructPtrTemp = (SCOPE *) pPsdBodyAcpiTables; + TempVar_c += PSD_BODY_STRUCT_SIZE; + }// end of PSD Body if (CoreCount1 != 1) || (OptionPstateLateConfiguration.CfgPstatePsd) + + // + // Set _PPC Table - START + //------------------------ + + // Typecast the pointer + + pPpcHeaderBodyAcpiTables = (PPC_HEADER_BODY *) pPsdBodyAcpiTables; + + // Set _PPC Header and Body + //-------------------------- + if (OptionPstateLateConfiguration.CfgPstatePpc) { + pPpcHeaderBodyAcpiTables->NameOpcode = NAME_OPCODE; + pPpcHeaderBodyAcpiTables->PpcName_a__ = PPC_NAME__; + pPpcHeaderBodyAcpiTables->PpcName_a_P = PPC_NAME_P; + pPpcHeaderBodyAcpiTables->PpcName_b_P = PPC_NAME_P; + pPpcHeaderBodyAcpiTables->PpcName_a_C = PPC_NAME_C; + pPpcHeaderBodyAcpiTables->Value1 = PPC_VALUE1; + + pPpcHeaderBodyAcpiTables->DefaultPerfPresentCap = PstateCapLevelSupport; + TempVar_c += PPC_HEADER_BODY_STRUCT_SIZE; + // Increment and typecast the pointer + pPpcHeaderBodyAcpiTables++; + ScopeAcpiTablesStructPtrTemp = (SCOPE *) pPpcHeaderBodyAcpiTables; + }// end of OptionPstateLateConfiguration.CfgPstatePpc + + // If C6 is enabled, generate the corresponding ACPI object for it + if (IsFeatureEnabled (C6Cstate, PlatformConfig, StdHeader)) { + GetFeatureServicesOfCurrentCore (&C6FamilyServiceTable, (CONST VOID **)&C6FamilyServices, StdHeader); + C6FamilyServices->CreateAcpiCstObj ((VOID *) &ScopeAcpiTablesStructPtrTemp, StdHeader); + TempVar_c += C6FamilyServices->GetAcpiCstObj (); + } + + // + // Now update the SCOPE Length field + // + { + TempVar_c += (SCOPE_STRUCT_SIZE - 1); + ScopeSize += TempVar_c; + + TempVar_d = ((TempVar_c << 4) & 0x0000FF00); + TempVar_d |= ((TempVar_c & 0x0000000F) | 0x00000040); + TempVar_a = TempVar_d; + ScopeAcpiTablesStructPtr->ScopeLength = (UINT16) TempVar_a; + TempVar_c = 0; + } + + // Increment and typecast the pointer + ScopeAcpiTablesStructPtr = ScopeAcpiTablesStructPtrTemp; + + } // for (j = 0; j < MPPSTATE_MAX_CORES_PER_NODE; j++) + + // + //Calculate next node buffer address + // + PStateLevelingBufferStructPtr = (PSTATE_LEVELING *) ((UINT8 *) PStateLevelingBufferStructPtr + (UINTN) sizeof (PSTATE_LEVELING) + (UINTN) (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue * sizeof (S_PSTATE_VALUES))); + + } // for (i = 0; i < NodeCount; i++) + + //Update SSDT header Checksum + ((ACPI_TABLE_HEADER *) *SsdtPtr)->TableLength = (ScopeSize + CoreCount + sizeof (ACPI_TABLE_HEADER)); + ChecksumAcpiTable ((ACPI_TABLE_HEADER *) *SsdtPtr, StdHeader); + + return AGESA_SUCCESS; +} + + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.h new file mode 100755 index 0000000000..af55edfd67 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuPstateTables.h @@ -0,0 +1,120 @@ +/** + * @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: 13766 $ @e \$Date: 2009-05-14 07:22:59 +0800 (Thu, 14 May 2009) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_PSTATE_TABLES_H_ +#define _CPU_PSTATE_TABLES_H_ + +/*---------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *---------------------------------------------------------------------------------------- + */ +// Forward declaration. +typedef struct _PSTATE_CPU_FAMILY_SERVICES 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 + *---------------------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------------------*/ +/** + * 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 set core TscFreqSel. + * + * @param[in] PstateCpuFamilyServices Pstate CPU services. + * @param[in] StdHeader Config Handle for library, services. + * + */ +typedef VOID F_PSTATE_SET_TSC_FREQ_SEL ( + IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_PSTATE_SET_TSC_FREQ_SEL *PF_PSTATE_SET_TSC_FREQ_SEL; + +/** + * Provide the interface to the PSD 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_DEPENDENT IsPstatePsdDependent; ///< Method: Family specific call to check if PSD is dependent. + PF_PSTATE_SET_TSC_FREQ_SEL CpuSetTscFreqSel; ///< Method: Family specific call to set core TscFreqSel. +}; + + +/*---------------------------------------------------------------------------------------- + * F U N C T I O N S P R O T O T Y P E + *---------------------------------------------------------------------------------------- + */ + +#endif // _CPU_PSTATE_TABLES_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuSlit.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuSlit.c new file mode 100755 index 0000000000..1447c450e9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuSlit.c @@ -0,0 +1,370 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------- + * 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 "Topology.h" +#include "Ids.h" +#include "cpuFeatures.h" +#include "Filecode.h" +#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, + {'A','M','D',' ',' ',' '}, + {'F','1','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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * + * 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; + ACPI_TABLE_HEADER *CpuSlitHeaderStructPtr; + AGESA_STATUS Flag; + ALLOCATE_HEAP_PARAMS AllocStruct; + + MaxHops = 0; + SocketTopologyPtr = NULL; + Flag = AGESA_ERROR; + + // find out the pointer to the BufferHandle which contains + // Node Topology information + AcpiSlitHBufferFind (StdHeader, &SocketTopologyPtr); + if (SocketTopologyPtr == 0) { + return (Flag); + } + + SocketNum = *SocketTopologyPtr; + + // 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; + BufferPtr = *SlitPtr; + + Flag = AGESA_SUCCESS; + // SLIT body + // check if is PfMode (Prober Filer Mode) + if (!IsFeatureEnabled (HtAssist, PlatformConfig, StdHeader)) { + // probe filter is disabled + + // 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 { + // probe filter is enabled + + // 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/f10/Proc/CPU/Feature/cpuSrat.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuSrat.c new file mode 100755 index 0000000000..bf136043d2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuSrat.c @@ -0,0 +1,614 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ***************************************************************************/ + + +/*---------------------------------------------------------------------------- + * 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 "cpuRegisters.h" +#include "cpuLateInit.h" +#include "Ids.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_FEATURE_CPUSRAT_FILECODE + +/*---------------------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + *---------------------------------------------------------------------------------------- + */ +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 + ); +/*---------------------------------------------------------------------------------------- + * 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 0x010000 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * 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, + {'A','M','D',' ',' ',' '}, + {'F','1','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 RegVal; + UINT32 tempVar_32; + AMD_APIC_PARAMS ApicParams; + PCI_ADDR PciAddress; + CPU_SRAT_HEADER *CpuSratHeaderStructPtr; + AGESA_BUFFER_PARAMS AllocParams; + + // Get Node count + PciAddress.AddressValue = MAKE_SBDFO (0, 0, LOW_NODE_DEVICEID, FUNC_0, NodeID); + LibAmdPciRead (AccessWidth32 , PciAddress, &RegVal, StdHeader); + NodeCount = (UINT8) (((RegVal >> 4) & 0x7) + 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)) + + (MAX_NUMBER_CORES * sizeof (CPU_SRAT_APIC_ENTRY)))); + + if (*SratPtr == NULL) { + // + // Allocate a buffer by callback function + // + AllocParams.StdHeader = *StdHeader; + AllocParams.BufferLength = tempVar_32; + AllocParams.BufferHandle = AMD_SRAT_INFO_BUFFER_HANDLE; + + AGESA_TESTPOINT (TpProcCpuBeforeAllocateSratBuffer, StdHeader); + if (AgesaAllocateBuffer (0, &AllocParams) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpProcCpuAfterAllocateSratBuffer, StdHeader); + + *SratPtr = AllocParams.BufferPointer; + } + + CpuSratHeaderStructPtr = (CPU_SRAT_HEADER *) *SratPtr; + BufferPtr = (UINT8 *) *SratPtr; + + // Copy acpiSRATHeader -> data buffer + LibAmdMemCopy (*SratPtr, (VOID *) &CpuSratHdrStruct, (UINTN) (sizeof (CPU_SRAT_HEADER)), 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/f10/Proc/CPU/Feature/cpuWhea.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuWhea.c new file mode 100755 index 0000000000..fb8930269e --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Feature/cpuWhea.c @@ -0,0 +1,276 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "OptionWhea.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "Ids.h" +#include "Filecode.h" +#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 + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +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 + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * + * 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; + AGESA_BUFFER_PARAMS AllocParams; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + FamilySpecificServices = NULL; + + // 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; + } + + HestMceTableSize = sizeof (AMD_HEST_MCE_TABLE) + BankNum * sizeof (AMD_HEST_BANK); + HestCmcTableSize = sizeof (AMD_HEST_CMC_TABLE) + BankNum * 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.StdHeader = *StdHeader; + AllocParams.BufferLength = (UINT32) (HestMceTableSize + HestCmcTableSize); + AllocParams.BufferHandle = AMD_WHEA_BUFFER_HANDLE; + + AGESA_TESTPOINT (TpProcCpuBeforeAllocateWheaBuffer, StdHeader); + if (AgesaAllocateBuffer (0, &AllocParams) != AGESA_SUCCESS) { + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpProcCpuAfterAllocateWheaBuffer, StdHeader); + + HestMceTablePtr = (AMD_HEST_MCE_TABLE *) AllocParams.BufferPointer; + HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) ((UINT8 *) (HestMceTablePtr + 1) + (BankNum * sizeof (AMD_HEST_BANK))); + } + + // step 3: fill in Hest MCE table + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetWheaInitData (FamilySpecificServices, (CONST VOID **)&WheaInitDataPtr, &Entries, StdHeader); + + ASSERT (BankNum <= WheaInitDataPtr->HestBankNum); + + HestMceTablePtr->TblLength = HestMceTableSize; + HestMceTablePtr->GlobCapInitDataLSD = WheaInitDataPtr->GlobCapInitDataLSD; + HestMceTablePtr->GlobCapInitDataMSD = WheaInitDataPtr->GlobCapInitDataMSD; + HestMceTablePtr->GlobCtrlInitDataLSD = WheaInitDataPtr->GlobCtrlInitDataLSD; + HestMceTablePtr->GlobCtrlInitDataMSD = WheaInitDataPtr->GlobCtrlInitDataMSD; + HestMceTablePtr->NumHWBanks = BankNum; + + HestBankPtr = (AMD_HEST_BANK *) (HestMceTablePtr + 1); + CreateHestBank (HestBankPtr, BankNum, WheaInitDataPtr); + + // step 4: fill in Hest CMC table + HestCmcTablePtr->NumHWBanks = BankNum; + HestCmcTablePtr->TblLength = HestCmcTableSize; + + HestBankPtr = (AMD_HEST_BANK *) (HestCmcTablePtr + 1); + CreateHestBank (HestBankPtr, BankNum, 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/f10/Proc/CPU/S3.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/S3.c new file mode 100755 index 0000000000..05a4827b21 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/S3.c @@ -0,0 +1,1166 @@ +/** + * @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: 7735 $ @e \$Date: 2008-08-27 14:49:19 -0500 (Wed, 27 Aug 2008) $ + * + */ +/***************************************************************************** + * + * 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 "Ids.h" +#include "mm.h" +#include "mn.h" +#include "S3.h" +#include "mfs3.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "Filecode.h" +#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 = (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 = (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; + default: + AndMask = RegisterHdr->RegisterList[i].AndMask; + RegSizeInBytes = 4; + AccessWidth = AccessS3SaveWidth32; + break; + } + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + LibAmdPciRead (AccessWidth, PciAddress, *OrMask, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, PciAddress, *OrMask, StdHeader); + } + **((UINT32 **) OrMask) &= AndMask; + 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; + default: + AndMask = RegisterHdr->RegisterList[i].AndMask; + RegSizeInBytes = 4; + AccessWidth = AccessS3SaveWidth32; + break; + } + if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { + LibAmdPciRead (AccessWidth, PciAddress, *OrMask, StdHeader); + } else { + SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, PciAddress, *OrMask, StdHeader); + } + **((UINT32 **) OrMask) &= AndMask; + 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; + 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); + } + + 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; + default: + AndMask = RegisterHdr->RegisterList[i].AndMask; + RegSizeInBytes = 4; + RegValueWrite = **(UINT32 **)OrMask; + AccessWidth = AccessS3SaveWidth32; + break; + } + 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; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, + PciAddress, + &RegValueRead, + StdHeader); + RegValueWrite |= RegValueRead & (~AndMask); + RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth, + PciAddress, + &RegValueWrite, + StdHeader); + } + IntermediatePtr = (UINT8 *) *OrMask; + *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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; + 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); + } + + 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; + default: + AndMask = RegisterHdr->RegisterList[i].AndMask; + RegSizeInBytes = 4; + RegValueWrite = **(UINT32 **)OrMask; + AccessWidth = AccessS3SaveWidth32; + break; + } + 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; + RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, + PciAddress, + &RegValueRead, + StdHeader); + RegValueWrite |= RegValueRead & (~AndMask); + RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth, + PciAddress, + &RegValueWrite, + StdHeader); + } + IntermediatePtr = (UINT8 *) *OrMask; + *OrMask = &IntermediatePtr[RegSizeInBytes]; + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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; + UINT16 i; + UINT64 RegValueRead; + UINT64 RegValueWrite; + 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++) { + 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; + UINT16 i; + UINT64 RegValueRead; + UINT64 RegValueWrite; + 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)) { + 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/f10/Proc/CPU/S3.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/S3.h new file mode 100755 index 0000000000..3e72774213 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/S3.h @@ -0,0 +1,394 @@ +/** + * @file + * + * ACPI S3 support definitions. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 7672 $ @e \$Date: 2008-08-25 21:30:52 -0500 (Mon, 25 Aug 2008) $ + * + */ +/* +***************************************************************************** +* +* 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. +* +* *************************************************************************** +* +*/ + +#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 + *--------------------------------------------------------------------------------------- + */ + + +/*--------------------------------------------------------------------------------------- + * 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 +} 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 +} 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 +} 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 +} 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 +} 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/f10/Proc/CPU/Table.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/Table.c new file mode 100755 index 0000000000..4f767b8f27 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Table.c @@ -0,0 +1,1576 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "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 "Filecode.h" +#define FILECODE PROC_CPU_TABLE_FILECODE + +extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration; + +/*---------------------------------------------------------------------------------------- + * 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 BUILD_OPT_CFG UserOptions; + +VOID +SetRegistersFromTablesAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * 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,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 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 < (TABLE_CORE_SELECTOR)TableEntryTypeMax); + + NextTable = *RegisterTableHandle; + if (NextTable == NULL) { + // Begin + NextTable = FamilySpecificServices->RegisterTableList; + } else { + NextTable++; + } + // skip if not selected + while ((*NextTable != NULL) && (*NextTable)->Selector != Selector) { + 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; + + Features->PerformanceProfileValue = 0; + // Reflect Probe Filter Configuration. + Features->PerformanceProfileFeatures.ProbeFilter = 0; + if (IsFeatureEnabled (HtAssist, 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.HiSpeedEnable) { + Features->PerformanceProfileFeatures.VrmHighSpeed = 1; + } + + // Get some family, model specific performance type info. + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + ASSERT (FamilySpecificServices != NULL); + + // Is the Northbridge P-State feature enabled + Features->PerformanceProfileFeatures.NbPstates = 0; + if (FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, 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; + + // 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)); + + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredSts); + GetPciAddress (StdHeader, MySocket, MyModule, &MyPciAddress, &IgnoredSts); + MyPciAddress.Address.Function = Entry->PciEntry.Address.Address.Function; + MyPciAddress.Address.Register = Entry->PciEntry.Address.Address.Register; + LibAmdPciRead (AccessWidth32, MyPciAddress, &TempVar32_a, StdHeader); + TempVar32_a = TempVar32_a & (~(Entry->PciEntry.Mask)); + TempVar32_a = TempVar32_a | Entry->PciEntry.Data; + LibAmdPciWrite (AccessWidth32, MyPciAddress, &TempVar32_a, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the Errata Workaround Register Entry. + * + * @TableEntryTypeMethod{::ErrataWorkaround}. + * + * 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 Errata Workaround register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForErrataWorkaroundEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + ASSERT (Entry->ErrataEntry.DoAction != NULL); + + Entry->ErrataEntry.DoAction (Entry->ErrataEntry.Data, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Finds the HT link capability set for a particular node/link. + * + * This function traverses the desired node's PCI capabilities searching + * for the HT capabilities associated with the desired HT link. If found, + * the PCI address of the capability block will be returned. + * + * @param[in] Link Zero based link number on Node + * @param[in,out] CapabilitySet PCI address of the link's capability block + * @param[in] StdHeader Config handle for library and services + * + * @retval TRUE Node/link capabilities found + * @retval FALSE Node/link capabilities not found + * + */ +BOOLEAN +FindHtHostCapability ( + IN UINTN Link, + IN OUT PCI_ADDR *CapabilitySet, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 CapabilityReg; + PCI_ADDR PciAddress; + BOOLEAN Result; + + Result = FALSE; + PciAddress = *CapabilitySet; + PciAddress.Address.Register = 0; + // Convert link from zero base to one base and adjust for sub link 0/1 split. + Link++; + PciAddress.Address.Function = ((Link > 4) ? 4 : 0); + Link = ((Link > 4) ? (Link - 4) : Link); + + // Until either all capabilities are done or until the desired link is found, + // keep looking for HT Host Capabilities. + while (Link != 0) { + 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 == 0) { + // If we found the link, update the caller's pointer and success. + *CapabilitySet = PciAddress; + Result = TRUE; + } + return Result ; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Program HT Phy PCI registers using BKDG values. + * + * @TableEntryTypeMethod{::HtPhyRegister}. + * + * + * @param[in] Entry 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. + * + */ +VOID +SetRegisterForHtPhyEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Link; + UINT32 MySocket; + UINT32 MyModule; + AGESA_STATUS IgnoredStatus; + UINT32 Ignored; + CPU_LOGICAL_ID CpuFamilyRevision; + PCI_ADDR CapabilitySet; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + BOOLEAN MatchedSublink1; + HT_FREQUENCIES Freq0; + HT_FREQUENCIES Freq1; + + // 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->InitialValues[4] == 0) && + ((Entry->HtPhyEntry.TypeFeats.HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0) && + (Entry->HtPhyEntry.Address < HTPHY_REGISTER_MAX)); + + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus); + GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus); + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetCpuServicesFromLogicalId (&CpuFamilyRevision, &FamilySpecificServices, StdHeader); + Link = 0; + while (Link < 4) { + if (FindHtHostCapability (Link, &CapabilitySet, StdHeader)) { + if (FamilySpecificServices->DoesLinkHaveHtPhyFeats ( + FamilySpecificServices, + CapabilitySet, + Link, + &Entry->HtPhyEntry.TypeFeats, + &MatchedSublink1, + &Freq0, + &Freq1, + StdHeader)) { + FamilySpecificServices->SetHtPhyRegister (FamilySpecificServices, &Entry->HtPhyEntry, CapabilitySet, Link, StdHeader); + } + } else { + // No more Capabilities, no more links present + break; + } + Link ++; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Program a range of HT Phy PCI registers using BKDG values. + * + * @TableEntryTypeMethod{::HtPhyRangeRegister}. + * + * + * @param[in] Entry 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. + * + */ +VOID +SetRegisterForHtPhyRangeEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Link; + UINT32 MySocket; + UINT32 MyModule; + AGESA_STATUS IgnoredStatus; + UINT32 Ignored; + CPU_LOGICAL_ID CpuFamilyRevision; + PCI_ADDR CapabilitySet; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + HT_PHY_TYPE_ENTRY_DATA CurrentHtPhyRegister; + BOOLEAN MatchedSublink1; + HT_FREQUENCIES Freq0; + HT_FREQUENCIES Freq1; + + // 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->HtPhyRangeEntry.TypeFeats.HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0) && + (Entry->HtPhyRangeEntry.LowAddress <= Entry->HtPhyRangeEntry.HighAddress) && + (Entry->HtPhyRangeEntry.HighAddress < HTPHY_REGISTER_MAX) && + (Entry->HtPhyRangeEntry.HighAddress != 0)); + + CurrentHtPhyRegister.Mask = Entry->HtPhyRangeEntry.Mask; + CurrentHtPhyRegister.Data = Entry->HtPhyRangeEntry.Data; + CurrentHtPhyRegister.TypeFeats = Entry->HtPhyRangeEntry.TypeFeats; + + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus); + GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus); + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetCpuServicesFromLogicalId (&CpuFamilyRevision, &FamilySpecificServices, StdHeader); + Link = 0; + while (Link < 4) { + if (FindHtHostCapability (Link, &CapabilitySet, StdHeader)) { + if (FamilySpecificServices->DoesLinkHaveHtPhyFeats ( + FamilySpecificServices, + CapabilitySet, + Link, + &Entry->HtPhyRangeEntry.TypeFeats, + &MatchedSublink1, + &Freq0, + &Freq1, + StdHeader)) { + for (CurrentHtPhyRegister.Address = Entry->HtPhyRangeEntry.LowAddress; + CurrentHtPhyRegister.Address <= Entry->HtPhyRangeEntry.HighAddress; + CurrentHtPhyRegister.Address++) { + FamilySpecificServices->SetHtPhyRegister (FamilySpecificServices, &CurrentHtPhyRegister, CapabilitySet, Link, StdHeader); + } + } + } else { + // No more Capabilities, no more links present + break; + } + Link ++; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * 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 +STATIC +IsDeemphasisLinkInternal ( + IN UINT32 PackageLink + ) +{ + return (BOOLEAN) ((PackageLink <= HT_LIST_MATCH_INTERNAL_LINK_2) && (PackageLink >= HT_LIST_MATCH_INTERNAL_LINK_0)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the Package Link number, for the current node and real link number. + * + * Based on the link to package link mapping from BKDG, look up package link for + * the input link on the internal node number corresponding to the current core's node. + * For single module processors, the northbridge link and package link are the same. + * + * @param[in] Link the link on the current node. + * @param[in] FamilySpecificServices CPU specific support interface. + * @param[in] StdHeader Config params for library, services. + * + * @return the Package Link, HT_LIST_TERMINAL Not connected in package, HT_LIST_MATCH_INTERNAL_LINK package internal link. + * + */ +UINT32 +STATIC +LookupPackageLink ( + IN UINT32 Link, + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 PackageLinkMapItem; + UINT32 PackageLink; + AP_MAIL_INFO ApMailbox; + + PackageLink = HT_LIST_TERMINAL; + + GetApMailbox (&ApMailbox.Info, StdHeader); + + if (ApMailbox.Fields.ModuleType != 0) { + ASSERT (FamilySpecificServices->PackageLinkMap != NULL); + // Use table to find this module's package link + PackageLinkMapItem = 0; + while ((*FamilySpecificServices->PackageLinkMap)[PackageLinkMapItem].Link != HT_LIST_TERMINAL) { + if (((*FamilySpecificServices->PackageLinkMap)[PackageLinkMapItem].Module == ApMailbox.Fields.Module) && + ((*FamilySpecificServices->PackageLinkMap)[PackageLinkMapItem].Link == Link)) { + PackageLink = (*FamilySpecificServices->PackageLinkMap)[PackageLinkMapItem].PackageLink; + break; + } + PackageLinkMapItem++; + } + } else { + PackageLink = Link; + } + return PackageLink; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Get the platform's specified deemphasis levels for the current link. + * + * Search the platform's list for a match to the current link and also matching frequency. + * If a match is found, use the specified deemphasis levels. + * + * @param[in] Socket The current Socket. + * @param[in] Link The link on that socket. + * @param[in] Frequency The frequency the link is set to. + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] FamilySpecificServices CPU specific support interface. + * @param[in] StdHeader Config params for library, services. + * + * @return The Deemphasis values for the link. + */ +UINT32 +STATIC +GetLinkDeemphasis ( + IN UINT32 Socket, + IN UINT32 Link, + IN HT_FREQUENCIES Frequency, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Result; + CPU_HT_DEEMPHASIS_LEVEL *Match; + UINT32 PackageLink; + + PackageLink = LookupPackageLink (Link, FamilySpecificServices, StdHeader); + // All External and Internal links have deemphasis level none as the default. + // However, it is expected that the platform BIOS will provide deemphasis levels for the external links. + Result = ((DCV_LEVEL_NONE) | (DEEMPHASIS_LEVEL_NONE)); + + if (PlatformConfig->PlatformDeemphasisList != NULL) { + Match = PlatformConfig->PlatformDeemphasisList; + while (Match->Socket != HT_LIST_TERMINAL) { + if (((Match->Socket == Socket) || (Match->Socket == HT_LIST_MATCH_ANY)) && + ((Match->Link == PackageLink) || + ((Match->Link == HT_LIST_MATCH_ANY) && (!IsDeemphasisLinkInternal (PackageLink))) || + ((Match->Link == HT_LIST_MATCH_INTERNAL_LINK) && (IsDeemphasisLinkInternal (PackageLink)))) && + ((Match->LoFreq <= Frequency) && (Match->HighFreq >= Frequency))) { + // Found a match, get the deemphasis value. + ASSERT ((MaxPlatformDeemphasisLevel > Match->DcvDeemphasis) | (MaxPlatformDeemphasisLevel > Match->ReceiverDeemphasis)); + Result = ((1 << Match->DcvDeemphasis) | (1 << Match->ReceiverDeemphasis)); + break; + } else { + Match++; + } + } + } + return Result; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Program Deemphasis registers using BKDG values, for the platform specified levels. + * + * @TableEntryTypeMethod{::DeemphasisRegister}. + * + * + * @param[in] Entry 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. + * + */ +VOID +SetRegisterForDeemphasisEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Link; + UINT32 MySocket; + UINT32 MyModule; + AGESA_STATUS IgnoredStatus; + UINT32 Ignored; + CPU_LOGICAL_ID CpuFamilyRevision; + PCI_ADDR CapabilitySet; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + BOOLEAN MatchedSublink1; + HT_FREQUENCIES Freq0; + HT_FREQUENCIES Freq1; + + // 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->DeemphasisEntry.Levels.DeemphasisValues & ~(VALID_DEEMPHASIS_LEVELS)) == 0) && + ((Entry->DeemphasisEntry.HtPhyEntry.TypeFeats.HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0) && + (Entry->DeemphasisEntry.HtPhyEntry.Address < HTPHY_REGISTER_MAX)); + + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus); + GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus); + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetCpuServicesFromLogicalId (&CpuFamilyRevision, &FamilySpecificServices, StdHeader); + Link = 0; + while (Link < 4) { + if (FindHtHostCapability (Link, &CapabilitySet, StdHeader)) { + if (FamilySpecificServices->DoesLinkHaveHtPhyFeats ( + FamilySpecificServices, + CapabilitySet, + Link, + &Entry->DeemphasisEntry.HtPhyEntry.TypeFeats, + &MatchedSublink1, + &Freq0, + &Freq1, + StdHeader)) { + if (DoesEntryTypeSpecificInfoMatch ( + GetLinkDeemphasis ( + MySocket, + (MatchedSublink1 ? (Link + 4) : Link), + (MatchedSublink1 ? Freq1 : Freq0), + PlatformConfig, + FamilySpecificServices, + StdHeader), + Entry->DeemphasisEntry.Levels.DeemphasisValues)) { + FamilySpecificServices->SetHtPhyRegister ( + FamilySpecificServices, + &Entry->DeemphasisEntry.HtPhyEntry, + CapabilitySet, + Link, + StdHeader + ); + } + } + } else { + // No more Capabilities, no more links present + break; + } + Link ++; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Program HT Phy PCI registers which have complex frequency dependencies. + * + * @TableEntryTypeMethod{::HtPhyFreqRegister}. + * + * + * @param[in] Entry 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. + * + */ +VOID +SetRegisterForHtPhyFreqEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Link; + UINT32 MySocket; + UINT32 MyModule; + AGESA_STATUS IgnoredStatus; + UINT32 Ignored; + CPU_LOGICAL_ID CpuFamilyRevision; + PCI_ADDR CapabilitySet; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + BOOLEAN MatchedSublink1; + HT_FREQUENCIES Freq0; + HT_FREQUENCIES Freq1; + BOOLEAN Temp; + UINT32 NbFreq; + + // Errors: 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->HtPhyFreqEntry.HtPhyEntry.TypeFeats.HtPhyLinkValue & ~(HTPHY_LINKTYPE_ALL)) == 0) && + (Entry->HtPhyFreqEntry.HtPhyEntry.Address < HTPHY_REGISTER_MAX)); + + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus); + GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus); + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetCpuServicesFromLogicalId (&CpuFamilyRevision, &FamilySpecificServices, StdHeader); + Link = 0; + while (Link < 4) { + if (FindHtHostCapability (Link, &CapabilitySet, StdHeader)) { + if (FamilySpecificServices->DoesLinkHaveHtPhyFeats ( + FamilySpecificServices, + CapabilitySet, + Link, + &Entry->HtPhyFreqEntry.HtPhyEntry.TypeFeats, + &MatchedSublink1, + &Freq0, + &Freq1, + StdHeader)) { + // Check the HT Frequency for match to the range. + if (IsEitherCountInRange ( + (MatchedSublink1 ? Freq1 : Freq0), + (MatchedSublink1 ? Freq1 : Freq0), + Entry->HtPhyFreqEntry.HtFreqCounts.HtFreqCountRanges)) { + // Get the NB Frequency, convert to 100's of MHz, then convert to equivalent HT encoding. This supports + // NB frequencies from 800 MHz to 2600 MHz, which is currently greater than any processor supports. + OptionMultiSocketConfiguration.GetSystemNbCof (&NbFreq, &Temp, StdHeader); + NbFreq = (NbFreq / 100); + NbFreq = (NbFreq / 2) + 1; + if (IsEitherCountInRange (NbFreq, NbFreq, Entry->HtPhyFreqEntry.NbFreqCounts.HtFreqCountRanges)) { + FamilySpecificServices->SetHtPhyRegister (FamilySpecificServices, &Entry->HtPhyFreqEntry.HtPhyEntry, CapabilitySet, Link, StdHeader); + } + } + } + } else { + // No more Capabilities, no more links present + break; + } + Link ++; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 HT Phy Performance Profile Register Entry. + * + * @TableEntryTypeMethod{::HtPhyProfileRegister}. + * + * @param[in] Entry The HT Phy register entry to perform + * @param[in] PlatformConfig Config handle for platform specific information + * @param[in] StdHeader Config handle for library and services. + * + */ +VOID +SetRegisterForHtPhyProfileEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PERFORMANCE_PROFILE_FEATS PlatformProfile; + TABLE_ENTRY_DATA HtPhyEntry; + + // 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->HtPhyProfileEntry.TypeFeats.PerformanceProfileValue & ~((PERFORMANCE_PROFILE_ALL) | (PERFORMANCE_AND))) == 0) && + (Entry->InitialValues[5] == 0)); + + GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, + Entry->HtPhyProfileEntry.TypeFeats.PerformanceProfileValue)) { + LibAmdMemFill (&HtPhyEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + HtPhyEntry.HtPhyEntry = Entry->HtPhyProfileEntry.HtPhyEntry; + SetRegisterForHtPhyEntry (&HtPhyEntry, PlatformConfig, StdHeader); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the HT Host PCI Register Entry. + * + * @TableEntryTypeMethod{::HtHostPciRegister}. + * + * Make the current core's PCI address with the function and register for the entry. + * For all HT links, check the link's feature set for a match to 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 +SetRegisterForHtHostEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN Link; + UINTN LinkCount; + UINT32 MySocket; + UINT32 MyModule; + AGESA_STATUS IgnoredStatus; + UINT32 Ignored; + CPU_LOGICAL_ID CpuFamilyRevision; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + PCI_ADDR CapabilitySet; + HT_HOST_FEATS HtHostFeats; + UINT32 RegisterData; + + // 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->InitialValues[4] == 0) && + ((Entry->HtHostEntry.TypeFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0) && + (Entry->HtHostEntry.Address.Address.Register < HT_LINK_HOST_CAP_MAX)); + + HtHostFeats.HtHostValue = 0; + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus); + GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus); + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetCpuServicesFromLogicalId (&CpuFamilyRevision, &FamilySpecificServices, StdHeader); + LinkCount = 0; + while (LinkCount < 8) { + if (FindHtHostCapability (LinkCount, &CapabilitySet, StdHeader)) { + FamilySpecificServices->GetHtLinkFeatures (FamilySpecificServices, &Link, &CapabilitySet, &HtHostFeats, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (HtHostFeats.HtHostValue, Entry->HtHostEntry.TypeFeats.HtHostValue)) { + // Do the HT Host PCI register update. + CapabilitySet.Address.Register += Entry->HtHostEntry.Address.Address.Register; + LibAmdPciRead (AccessWidth32, CapabilitySet, &RegisterData, StdHeader); + RegisterData = RegisterData & (~(Entry->HtHostEntry.Mask)); + RegisterData = RegisterData | Entry->HtHostEntry.Data; + LibAmdPciWrite (AccessWidth32, CapabilitySet, &RegisterData, StdHeader); + } + } else { + // No more Capabilities. Switch to sublink 1's if we are just done with sublink 0's. + // (This case handles less than 4 links are implemented in the processor.) + if (CapabilitySet.Address.Function == 0) { + CapabilitySet.Address.Function = 4; + LinkCount = 3; + } else { + break; + } + } + LinkCount ++; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the Core Counts Performance PCI Register Entry. + * + * @TableEntryTypeMethod{::CoreCountsPciRegister}. + * + * 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 +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}. + * + * 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 +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 Processor Token Counts PCI Register Entry. + * + * @TableEntryTypeMethod{::TokenPciRegister}. + * + * The table criteria then 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) + * + * @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 +SetRegisterForTokenPciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PERFORMANCE_PROFILE_FEATS PlatformProfile; + UINTN SystemDegree; + 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)); + + GetPerformanceFeatures (&PlatformProfile, PlatformConfig, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (PlatformProfile.PerformanceProfileValue, Entry->TokenPciEntry.TypeFeats.PerformanceProfileValue)) { + SystemDegree = GetSystemDegree (StdHeader); + // Check if the system degree is in the range. + if (IsEitherCountInRange (SystemDegree, SystemDegree, Entry->TokenPciEntry.ConnectivityCount.ConnectivityCountRanges)) { + LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + PciEntry.PciEntry = Entry->TokenPciEntry.PciEntry; + SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader); + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the HT Link Feature PCI Register Entry. + * + * @TableEntryTypeMethod{::HtFeatPciRegister}. + * + * Set a single field (that is, the register field is not in HT Host capability or a + * set of per link registers) in PCI config, based on HT link features and package type. + * This code is used for two cases: single link processors and multilink processors. + * For single link cases, the link will be tested for a match to the HT Features for the link. + * For multilink processors, the entry will match if @b any link is found which matches. + * For example, a setting can be applied based on coherent HT3 by matching coherent AND HT3. + * + * Make the core's PCI address. Check the package type (currently more important to the single link case), + * and if matching, iterate through all links checking for an HT feature match until found or exhausted. + * If a match was found, pass the PCI entry data to the implementer for writing for the current core. + * + * @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 +SetRegisterForHtFeaturePciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN Link; + UINTN LinkCount; + UINT32 MySocket; + UINT32 MyModule; + AGESA_STATUS IgnoredStatus; + UINT32 Ignored; + CPU_LOGICAL_ID CpuFamilyRevision; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + PCI_ADDR CapabilitySet; + HT_HOST_FEATS HtHostFeats; + UINT32 ProcessorPackageType; + BOOLEAN IsMatch; + 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->HtFeatPciEntry.PciEntry.Mask != 0) && + ((Entry->HtFeatPciEntry.LinkFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0)); + + HtHostFeats.HtHostValue = 0; + LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + PciEntry.PciEntry = Entry->HtFeatPciEntry.PciEntry; + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus); + GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus); + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetCpuServicesFromLogicalId (&CpuFamilyRevision, &FamilySpecificServices, StdHeader); + + ASSERT ((Entry->HtFeatPciEntry.PackageType.PackageTypeValue & ~(PACKAGE_TYPE_ALL)) == 0); + + ProcessorPackageType = LibAmdGetPackageType (StdHeader); + if (DoesEntryTypeSpecificInfoMatch (ProcessorPackageType, Entry->HtFeatPciEntry.PackageType.PackageTypeValue)) { + IsMatch = FALSE; + for (LinkCount = 0; LinkCount < 8; LinkCount++) { + if (FindHtHostCapability (LinkCount, &CapabilitySet, StdHeader)) { + FamilySpecificServices->GetHtLinkFeatures (FamilySpecificServices, &Link, &CapabilitySet, &HtHostFeats, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (HtHostFeats.HtHostValue, Entry->HtFeatPciEntry.LinkFeats.HtHostValue)) { + IsMatch = TRUE; + break; + } + } else { + break; + } + } + if (IsMatch) { + // Do the PCI register update. + SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader); + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Perform the HT Link PCI Register Entry. + * + * @TableEntryTypeMethod{::HtLinkPciRegister}. + * + * Make the current core's PCI address with the function and register for the entry. + * Registers are processed for match per link, assuming sequential PCI address per link. + * Read - Modify - Write each matching link's 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 +SetRegisterForHtLinkPciEntry ( + IN TABLE_ENTRY_DATA *Entry, + IN PLATFORM_CONFIGURATION *PlatformConfig, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINTN Link; + UINTN LinkCount; + UINT32 MySocket; + UINT32 MyModule; + AGESA_STATUS IgnoredStatus; + UINT32 Ignored; + CPU_LOGICAL_ID CpuFamilyRevision; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + PCI_ADDR CapabilitySet; + HT_HOST_FEATS HtHostFeats; + 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->HtLinkPciEntry.PciEntry.Mask != 0) && + ((Entry->HtLinkPciEntry.LinkFeats.HtHostValue & ~((HT_HOST_FEATURES_ALL) | (HT_HOST_AND))) == 0)); + + HtHostFeats.HtHostValue = 0; + LibAmdMemFill (&PciEntry, 0, sizeof (TABLE_ENTRY_DATA), StdHeader); + PciEntry.PciEntry = Entry->HtLinkPciEntry.PciEntry; + IdentifyCore (StdHeader, &MySocket, &MyModule, &Ignored, &IgnoredStatus); + GetPciAddress (StdHeader, MySocket, MyModule, &CapabilitySet, &IgnoredStatus); + GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); + GetCpuServicesFromLogicalId (&CpuFamilyRevision, &FamilySpecificServices, StdHeader); + + LinkCount = 0; + while (LinkCount < 8) { + if (FindHtHostCapability (LinkCount, &CapabilitySet, StdHeader)) { + FamilySpecificServices->GetHtLinkFeatures (FamilySpecificServices, &Link, &CapabilitySet, &HtHostFeats, StdHeader); + if (DoesEntryTypeSpecificInfoMatch (HtHostFeats.HtHostValue, Entry->HtLinkPciEntry.LinkFeats.HtHostValue)) { + // Do the update to the link's non-Host PCI register, based on the entry address. + PciEntry.PciEntry.Address = Entry->HtLinkPciEntry.PciEntry.Address; + PciEntry.PciEntry.Address.Address.Register = PciEntry.PciEntry.Address.Address.Register + ((UINT32)Link * 4); + SetRegisterForPciEntry (&PciEntry, PlatformConfig, StdHeader); + } + } else { + // No more Capabilities. Switch to sublink 1's if we are just done with sublink 0's. + // (This case handles less than 4 links are implemented in the processor.) + if (CapabilitySet.Address.Function == 0) { + CapabilitySet.Address.Function = 4; + LinkCount = 3; + } else { + break; + } + } + LinkCount ++; + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * 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 (&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 == 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] StdHeader Config handle for library and services. + * + */ +VOID +SetRegistersFromTables ( + IN PLATFORM_CONFIGURATION *PlatformConfig, + 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, &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, &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, &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 +SetRegistersFromTablesAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_TESTPOINT (TpProcCpuProcessRegisterTables, StdHeader); + SetRegistersFromTables (&EarlyParams->PlatformConfig, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/Table.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/Table.h new file mode 100755 index 0000000000..475272d65c --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/Table.h @@ -0,0 +1,1174 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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. + * <ul> + * <li> Add a member to the enum TABLE_ENTRY_TYPE which is a descriptive name of the entry's purpose + * or distinct characteristics. + * + * <li> 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. + * + * <li> 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! + * + * <li> 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: + * + * <ul> + * <li> 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". + * + * <li> 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. + * </ul> + * + * <li> Add the descriptor that will link table entries of your data type to an implementation for it. + * <ul> + * <li> Find the options file which instantiates the CPU_SPECIFIC_SERVICES for each logical model that will + * support the new entry type. + * + * <li> 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. + * </ul> + * + * <li> 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 + * + * </ul> + * + * @par Adding a new Register Table + * + * To add a new register table for a logical CPU model follow the steps below. + * + * <ul> + * <li> Find the options file which instantiates the CPU_SPECIFIC_SERVICES for the logical model that + * should include the table. + * + * <li> From there find the instantiation of its REGISTER_TABLE list. Add the name of the new register table. + * </ul> + * + */ + +/*------------------------------------------------------------------------------------------*/ +/* + * 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. + ErrataWorkaround, ///< Processor Errata 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). + 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. + 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. + 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. + 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; + +// 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 +// bit 15 is reserved + +// 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 +// bit 31 is reserved + +#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) +#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) +#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 :(15 - 7); ///< Ht Phy Sub-link 0 Pad + 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 HtPhySL0Link4:1; ///< Ht Phy Sub-link 1 specifically for node link 4. + UINT32 HtPhySL0Link5:1; ///< Ht Phy Sub-link 1 specifically for node link 5. + UINT32 HtPhySL0Link6:1; ///< Ht Phy Sub-link 1 specifically for node link 6. + UINT32 HtPhySL0Link7:1; ///< Ht Phy Sub-link 1 specifically for node link 7. + UINT32 :(31 - 23); ///< Ht Phy Sub-link 1 Pad +} 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 VALID_DEEMPHASIS_LEVELS (DEEMPHASIS_LEVEL_NONE | \ + DEEMPHASIS_LEVEL__3 | \ + DEEMPHASIS_LEVEL__6 | \ + DEEMPHASIS_LEVEL__8 | \ + DEEMPHASIS_LEVEL__11 | \ + DEEMPHASIS_LEVEL__11_8 | \ + 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) + +/** + * 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 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) + +/** + * 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; + +/** + * 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 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 { + PROCESSOR_COUNTS ProcessorCounts; ///< Specify a processor count range. + PERFORMANCE_PROFILE_FEATS PerformanceFeats; ///< Performance Profile features. + HT_HOST_FEATS LinkFeats; ///< Link Features. + 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; + +/** + * 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; + +/** + * An Errata Workaround method. + * + * \@TableTypeErrataInstances. + * + * 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_ERRATA_WORKAROUND ( + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a method. +typedef F_ERRATA_WORKAROUND *PF_ERRATA_WORKAROUND; + +/** + * Table Entry Data for Errata 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_ERRATA_WORKAROUND DoAction; ///< A function implementing the workaround. + UINT32 Data; ///< This data is passed to DoAction(). +} ERRATA_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. + ERRATA_WORKAROUND_TYPE_ENTRY_DATA ErrataEntry; ///< Errata 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_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. + 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. +} 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 + 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 Errata Workaround data. + * + * This ensures the entry data is the same size as TABLE_ENTRY_DATA. + */ +typedef union { + ERRATA_WORKAROUND_TYPE_ENTRY_DATA ErrataInitializer; ///< 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. +} ERRATA_WORKAROUND_DATA_INITIALIZER; + +/** + * A type suitable for an initializer for Errata 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. + ERRATA_WORKAROUND_DATA_INITIALIZER EntryData; ///< Special union accepts errata workaround data initializer. +} ERRATA_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 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 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 Errata Workaround Register Entry. + */ +VOID +SetRegisterForErrataWorkaroundEntry ( + 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 + ); + +/** + * Finds the HT link capability set for a particular node/link. + */ +BOOLEAN +FindHtHostCapability ( + IN UINTN Link, + IN OUT PCI_ADDR *CapabilitySet, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_TABLE_H_ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cahalt.asm b/src/vendorcode/amd/agesa/f10/Proc/CPU/cahalt.asm new file mode 100755 index 0000000000..0b796c8510 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cahalt.asm @@ -0,0 +1,319 @@ +;/** +; * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. +; +;***************************************************************************** + + .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 +; +;====================================================================== +ExecuteFinalHltInstruction PROC NEAR C PUBLIC + + pop esi ; StdHeader + pop esi ; pointer to ApMtrrSettingsList, set through build configuration + + mov eax, CR0 ; Make sure cache is disabled for all APs + or eax, CR0_CD OR CR0_NW ; Disable cache + mov cr0, eax ; Write back to CR0 + + ; 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, MtrrVarDramEn ; Disable + bts eax, MtrrFixDramModEn ; Enable + btr eax, MtrrFixDramEn ; Disable + bts eax, SysUcLockEn + _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) + 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 + + ; restore variable MTTR6 and MTTR7 to default states + mov ecx, AMD_MTRR_VARIABLE_BASE6 ; clear MTRRPhysBase6 MTRRPhysMask6 + xor eax, eax ; and MTRRPhysBase7 MTRRPhysMask7 + xor edx, edx + .while (cl < 010h) + _WRMSR + inc cl + .endw + + ; Enable fixed-range and variable-range MTRRs + mov ecx, AMD_MTRR_DEFTYPE + _RDMSR + or ax, 0C00h ; Set Fixed-Range Enable (FE) and MTRR Enable (E) bits + _WRMSR + + ; Enable Top-of-Memory setting + ; Enable use of RdMem/WrMem bits attributes + mov ecx, MTRR_SYS_CFG + _RDMSR + bts eax, MtrrVarDramEn ; Enable + btr eax, MtrrFixDramModEn ; Disable + bts eax, MtrrFixDramEn ; Enable + _WRMSR + + ; Enable the self modifying code check buffer and Enable hardware prefetches + mov ecx, 0C0011022h + _RDMSR + btr eax, DC_DIS_SPEC_TLB_RLD ; Disable speculative TLB reloads bit + btr eax, DIS_CLR_WBTOL2_SMC_HIT ; Disable the self modifying code check buffer bit + btr eax, DIS_HW_PF ; Disable hardware prefetches bit + _WRMSR + + dec cx ; MSRC001_1021 Instruction Cache Configuration Register (IC_CFG) + _RDMSR + btr eax, IC_DIS_SPEC_TLB_RLD ; turn on Disable speculative TLB reloads bit + _WRMSR + + AMD_DISABLE_STACK_FAMILY_HOOK ; Re-Enable L3 cache to accept clear lines + + xor eax, eax + +@@: + cli + hlt + jmp @B ;ExecuteHltInstruction +ExecuteFinalHltInstruction ENDP + +;====================================================================== +; ExecuteHltInstruction: Performs a hlt instruction. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; eax, ebx, ecx, edx, esp +; +;====================================================================== +ExecuteHltInstruction PROC NEAR C PUBLIC + cli + hlt + ret +ExecuteHltInstruction ENDP + +;====================================================================== +; NmiHandler: Simply performs an IRET. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +NmiHandler PROC NEAR C PUBLIC + iretd +NmiHandler ENDP + +;====================================================================== +; GetCsSelector: Returns the current protected mode CS selector. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +GetCsSelector PROC NEAR C PUBLIC, 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 +; +; WARNING: This routine has a mirror routine in the PREMEM segment. +; These two routines MUST be sync'd for content. +;====================================================================== +FarCallGetCs PROC FAR PRIVATE + + mov ax, ss:[esp + 4] + retf + +FarCallGetCs ENDP + +;====================================================================== +; SetIdtr: +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; none +; +; WARNING: This routine has a mirror routine in the PREMEM segment. +; These two routines MUST be sync'd for content. +;====================================================================== +SetIdtr PROC NEAR C PUBLIC USES EBX, IdtPtr:PTR + mov ebx, IdtPtr + lidt fword ptr ss:[ebx] + ret +SetIdtr ENDP + +;====================================================================== +; ExecuteWbinvdInstruction: Performs a wbinvd instruction. +; +; In: +; None +; +; Out: +; None +; +; Destroyed: +; None +; +;====================================================================== +ExecuteWbinvdInstruction PROC NEAR C PUBLIC + wbinvd ; Write back the cache tag RAMs + ret +ExecuteWbinvdInstruction ENDP + +END diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cahalt.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cahalt.c new file mode 100755 index 0000000000..2421bb9570 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cahalt.c @@ -0,0 +1,309 @@ +/* $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 "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 AP_MTRR_SETTINGS *ApMtrrSettingsList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +SetIdtr ( + IN IDT_BASE_LIMIT *IdtInfo, + IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr + ); + +VOID +GetCsSelector ( + IN UINT16 *Selector, + IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr + ); + +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 + *---------------------------------------------------------------------------------------- + */ + + +//---------------------------------------------------------------------------- + +STATIC +VOID +PrimaryCoreFunctions (AP_MTRR_SETTINGS *ApMtrrSettingsList) + { + UINT64 data; + UINT32 msrno; + // 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 + + data = __readmsr (0xC0010010); // MTRR_SYS_CFG + data &= ~(1 << 18); // MtrrFixDramEn + data &= ~(1 << 20); // MtrrVarDramEn + data |= (1 << 19); // MtrrFixDramModEn + data |= (1 << 17); // SysUcLockEn + __writemsr (0xC0010010, data); + + // Set 7FFFh-00000h and 9FFFFh-80000h as WB DRAM + __writemsr (0x250, 0x1E1E1E1E1E1E1E1Eull); // AMD_MTRR_FIX64k_00000 + __writemsr (0x258, 0x1E1E1E1E1E1E1E1Eull); // AMD_MTRR_FIX16k_80000 + + // Set BFFFFh-A0000h, DFFFFh-C0000h as Uncacheable Memory-mapped IO + __writemsr (0x259, 0); // AMD_AP_MTRR_FIX16k_A0000 + __writemsr (0x268, 0); // AMD_MTRR_FIX4k_C0000 + __writemsr (0x269, 0); // AMD_MTRR_FIX4k_C8000 + __writemsr (0x26A, 0); // AMD_MTRR_FIX4k_D0000 + __writemsr (0x26B, 0); // AMD_MTRR_FIX4k_D8000 + + // Set FFFFFh-E0000h as Uncacheable Memory + for (msrno = 0x26C; msrno <= 0x26F; msrno++) + __writemsr (msrno, 0x1818181818181818ull); + + // If IBV provided settings for Fixed-Sized MTRRs, + // overwrite the default settings. + if ((uintptr_t) ApMtrrSettingsList != 0 && (uintptr_t) ApMtrrSettingsList != 0xFFFFFFFF) + { + int index; + for (index = 0; ApMtrrSettingsList [index].MsrAddr != CPU_LIST_TERMINAL; index++) + __writemsr (ApMtrrSettingsList [index].MsrAddr, ApMtrrSettingsList [index].MsrData); + } + + // restore variable MTTR6 and MTTR7 to default states + for (msrno = 0x20F; msrno <= 0x20C; msrno--) // decrement so that the pair is disable before the base is cleared + __writemsr (msrno, 0); + + // Enable fixed-range and variable-range MTRRs + // Set Fixed-Range Enable (FE) and MTRR Enable (E) bits + __writemsr (0x2FF, __readmsr (0x2FF) | 0xC00); + + // Enable Top-of-Memory setting + // Enable use of RdMem/WrMem bits attributes + data = __readmsr (0xC0010010); // MTRR_SYS_CFG + data |= (1 << 18); // MtrrFixDramEn + data |= (1 << 20); // MtrrVarDramEn + data &= ~(1 << 19); // MtrrFixDramModEn + __writemsr (0xC0010010, data); + } + +//---------------------------------------------------------------------------- + +VOID +ExecuteFinalHltInstruction ( + IN AP_MTRR_SETTINGS *ApMtrrSettingsList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + int abcdRegs [4]; + UINT32 cr0val; + UINT64 data; + + cr0val = __readcr0 (); + //Make sure cache is disabled for all APs + __writecr0 (cr0val | 0x60000000); + + //Configure the MTRRs on the AP so when it runs remote code it will execute + //out of RAM instead of ROM. + PrimaryCoreFunctions (ApMtrrSettingsList); + + // Make sure not to touch any Shared MSR from this point on + + // Restore settings that were temporarily overridden for the cache as ram phase + data = __readmsr (0xC0011022); // MSR_DC_CFG + data &= ~(1 << 4); // DC_DIS_SPEC_TLB_RLD + data &= ~(1 << 8); // DIS_CLR_WBTOL2_SMC_HIT + data &= ~(1 << 13); // DIS_HW_PF + __writemsr (0xC0011022, data); + + data = __readmsr (0xC0011021); // MSR_IC_CFG - C001_1021 + data &= ~(1 << 9); // IC_DIS_SPEC_TLB_RLD + __writemsr (0xC0011021, data); + + // AMD_DISABLE_STACK_FAMILY_HOOK + __cpuid (abcdRegs, 1); + if ((abcdRegs [0] >> 20) == 1) //-----family 10h (Hydra) only----- + { + data = __readmsr (0xC0011022); + data &= ~(1 << 4); + data &= ~(1 << 8); + data &= ~(1 << 13); + __writemsr (0xC0011022, data); + + data = __readmsr (0xC0011021); + data &= ~(1 << 14); + data &= ~(1 << 9); + __writemsr (0xC0011021, data); + + data = __readmsr (0xC001102A); + data &= ~(1 << 15); + data &= ~(1ull << 35); + __writemsr (0xC001102A, data); + } + else if ((abcdRegs [0] >> 20) == 6) //-----family 15h (Orochi) only----- + { + data = __readmsr (0xC0011020); + data &= ~(1 << 28); + __writemsr (0xC0011020, data); + + data = __readmsr (0xC0011021); + data &= ~(1 << 9); + __writemsr (0xC0011021, data); + + data = __readmsr (0xC0011022); + data &= ~(1 << 4); + data &= ~(1l << 13); + __writemsr (0xC0011022, data); + } + + for (;;) + { + _disable (); + __halt (); + } + } + +//---------------------------------------------------------------------------- + +/// 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/f10/Proc/CPU/cpuApicUtilities.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuApicUtilities.c new file mode 100755 index 0000000000..8565084605 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuApicUtilities.c @@ -0,0 +1,1474 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "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" +#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 0x00000001 +#define AP_TASK_HAS_OUTPUT 0x00000002 +#define AP_RETURN_PARAMS 0x00000004 +#define AP_END_AT_HLT 0x00000008 +#define AP_PASS_EARLY_PARAMS 0x00000010 + +#define SEG_DESC_PRESENT 0x80 + +#define SEG_DESC_TYPE_LDT 0x02 +#define SEG_DESC_TYPE_CALL16 0x04 +#define SEG_DESC_TYPE_TASK 0x05 +#define SEG_DESC_TYPE_INT16 0x06 +#define SEG_DESC_TYPE_TRAP16 0x07 +#define SEG_DESC_TYPE_CALL32 0x0C +#define SEG_DESC_TYPE_INT32 0x0E +#define SEG_DESC_TYPE_TRAP32 0x0F + +/*---------------------------------------------------------------------------------------- + * 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; + +/// 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; + +#include "cpuRegisters.h" +#if 0 +/// 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; +#endif + +/*---------------------------------------------------------------------------------------- + * 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 UINT8 Socket, + IN UINT8 Core, + 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 UINT8 Socket, + IN UINT8 Core, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +ApUtilReceivePointer ( + IN UINT8 Socket, + IN UINT8 Core, + OUT VOID **ReturnPointer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +ApUtilTransmitPointer ( + IN UINT8 Socket, + IN UINT8 Core, + IN VOID **Pointer, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +PerformFinalHalt ( + 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 +GetCsSelector ( + IN UINT16 *Selector, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +extern +VOID +NmiHandler ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +extern +VOID +SetIdtr ( + IN IDT_BASE_LIMIT *IdtInfo, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +extern +VOID +ExecuteFinalHltInstruction ( + IN AP_MTRR_SETTINGS *ApMtrrSettingsList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +extern BUILD_OPT_CFG UserOptions; + +VOID +LocalApicInitializationAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * 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. + * + */ +STATIC 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; + 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); + + /** + * print the debug information. + * For MCM processor: + * Node 0x00 Core 0x00 is intenal Node 0 Core 0 + * Node 0x01 Core 0x04 is intenal Node 1 Core 0 + */ + printk(BIOS_DEBUG, "Node: 0x%02lx Core: 0x%02lx, Apicid = 0x%02lx\n", + CurrentNodeNum, CurrentCore, TempVar_a >> APIC20_ApicId); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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; + AP_FUNCTION_PTR FuncAddress; + IDT_DESCRIPTOR IdtDesc; + 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); + + // Determine the BSC's socket number + GetSocketModuleOfNode ((UINT32) 0x00000000, &BscSocket, &Ignored, StdHeader); + + // Setup Interrupt Descriptor Table for sleep mode + ApUtilSetupIdtForHlt (&IdtDesc, 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; + } + + // 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 (SourceSocket, 0, StdHeader); + if (RemoteCmd == CommandStart) { + ApFlags = ApUtilReadRemoteDataDword (SourceSocket, 0, StdHeader); + + ApUtilReceivePointer (SourceSocket, 0, (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; + 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] Socket Socket number of the desired core + * @param[in] Core Core number of the desired core + * @param[in] StdHeader Configuration parameters pointer + * + * @return The current value of the remote cores control byte + * + */ +UINT8 +ApUtilReadRemoteControlByte ( + IN UINT8 Socket, + IN UINT8 Core, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 ControlByte; + UINT32 ApicRegister; + + ApicRegister = ApUtilRemoteRead (Socket, Core, 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] Socket Socket number of the desired core + * @param[in] Core Core number of the desired core + * @param[in] StdHeader Configuration parameters pointer + * + * @return The current value of the remote core's data dword + * + */ +UINT32 +ApUtilReadRemoteDataDword ( + IN UINT8 Socket, + IN UINT8 Core, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + return (ApUtilRemoteRead (Socket, Core, 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; + AP_WAIT_FOR_STATUS WaitForStatus; + + ApFlags = 0; + ReturnCode = 0; + + CoreId = ApUtilCalculateUniqueId (Socket, Core, 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 (Socket, Core, &WaitForStatus, StdHeader); + + if (CurrentStatus != CORE_UNAVAILABLE) { + ApUtilWriteDataDword (ApFlags, StdHeader); + ApUtilWriteControlByte (CoreId, StdHeader); + + if (CurrentStatus == CORE_IDLE_HLT) { + ApUtilFireDirectedNmi (Socket, Core, StdHeader); + } + + ApUtilTransmitPointer (Socket, Core, (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 (Socket, Core, &WaitForStatus, StdHeader); + if ((ApFlags & AP_TASK_HAS_OUTPUT) != 0) { + ReturnCode = ApUtilReadRemoteDataDword (Socket, Core, 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] Socket + * @param[in] Core + * @param[in] WaitParamsPtr + * @param[in] StdHeader + * + * @return The current value of the remote core's control byte + * + */ +UINT8 +ApUtilWaitForCoreStatus ( + IN UINT8 Socket, + IN UINT8 Core, + 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 (Socket, Core, 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 = (UINT32) NmiHandler; + NmiIdtDescPtr->OffsetLo = (UINT16) HandlerOffset & 0xFFFF; + NmiIdtDescPtr->OffsetHi = (UINT16) (HandlerOffset >> 16); + GetCsSelector (&NmiIdtDescPtr->Selector, StdHeader); + NmiIdtDescPtr->Flags = SEG_DESC_PRESENT | SEG_DESC_TYPE_INT32; + NmiIdtDescPtr->Rsvd = 0; + NmiIdtDescPtr->Offset64 = (UINT32) (HandlerOffset >> 32); + NmiIdtDescPtr->Rsvd64 = 0; + IdtInfo.Limit = (UINT16) ((DescSize * 3) - 1); + IdtInfo.Base = (UINT32) NmiIdtDescPtr - (DescSize * 2); + 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; + AP_WAIT_FOR_STATUS WaitForStatus; + AGESA_STATUS IgnoredSts; + + 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 (Socket, Core, &WaitForStatus, StdHeader); + ApUtilWriteDataDword (BufferInfo->DataTransferFlags, StdHeader); + + ApUtilWriteControlByte (CORE_DATA_FLAGS_READY, StdHeader); + WaitForStatus.WaitForStatusFlags = 0; + ApUtilWaitForCoreStatus (Socket, Core, &WaitForStatus, StdHeader); + if ((BufferInfo->DataTransferFlags & DATA_IN_MEMORY) != 0) { + ApUtilTransmitPointer (Socket, Core, (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 (Socket, Core, &WaitForStatus, StdHeader); + WaitForStatus.WaitForStatusFlags = 0; + CurrentPtr = (UINT32 *) BufferInfo->DataPtr; + for (i = 0; i < BufferInfo->DataSizeInDwords; ++i) { + ApUtilWriteDataDword (*CurrentPtr++, StdHeader); + ApUtilWriteControlByte (CurrentStatus, StdHeader); + ApUtilWaitForCoreStatus (Socket, Core, &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; + 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); + + WaitForStatus.Status = &MyUniqueId; + WaitForStatus.NumberOfElements = 1; + WaitForStatus.RetryCount = WAIT_INFINITELY; + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + + ApUtilWaitForCoreStatus (Socket, Core, &WaitForStatus, StdHeader); + TransactionSize = ApUtilReadRemoteDataDword (Socket, Core, 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 = (UINT16) (TransactionSize << 2); + if (HeapAllocateBuffer (&HeapMalloc, StdHeader) == AGESA_SUCCESS) { + BufferInfo->DataPtr = (UINT32 *) HeapMalloc.BufferPtr; + BufferInfo->DataSizeInDwords = HeapMalloc.RequestedBufferSize >> 2; + } 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 (Socket, Core, &WaitForStatus, StdHeader); + BufferInfo->DataTransferFlags = ApUtilReadRemoteDataDword (Socket, Core, StdHeader); + ApUtilWriteControlByte (CORE_DATA_FLAGS_ACKNOWLEDGE, StdHeader); + if ((BufferInfo->DataTransferFlags & DATA_IN_MEMORY) != 0) { + if (BufferInfo->DataPtr != NULL) { + ReturnStatus = AGESA_ALERT; + } + ApUtilReceivePointer (Socket, Core, (VOID **) &BufferInfo->DataPtr, StdHeader); + } else { + CurrentStatus = CORE_STS_DATA_READY_1; + ApUtilWaitForCoreStatus (Socket, Core, &WaitForStatus, StdHeader); + CurrentStatus = CORE_STS_DATA_READY_0; + ApUtilWriteControlByte (CurrentStatus, StdHeader); + CurrentPtr = BufferInfo->DataPtr; + for (i = 0; i < TransactionSize; ++i) { + ApUtilWaitForCoreStatus (Socket, Core, &WaitForStatus, StdHeader); + *CurrentPtr++ = ApUtilReadRemoteDataDword (Socket, Core, 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 BscCore; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + 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, &BscCore, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCore)) { + 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 + ) +{ + ApUtilWriteControlByte (CORE_UNAVAILABLE, StdHeader); + ExecuteFinalHltInstruction (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] Socket Socket number of remote core + * @param[in] Core Core number of remote 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 UINT8 Socket, + IN UINT8 Core, + IN UINT8 RegAddr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 ApicRegister; + UINT32 TargetApicId; + UINT64 ApicBase; + UINT64 ApicAddr; + + ApUtilGetLocalApicBase (&ApicBase, StdHeader); + GetLocalApicIdForCore ((UINT32) Socket, (UINT32) Core, &TargetApicId, 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] Socket Socket number of remote core to wake up + * @param[in] Core Socket-relative core number of the remote core to wake up + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilFireDirectedNmi ( + IN UINT8 Socket, + IN UINT8 Core, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 TargetApicId; + + GetLocalApicIdForCore ((UINT32) Socket, (UINT32) Core, &TargetApicId, 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] Socket Socket number of the remote core + * @param[in] Core Core number of the remote core + * @param[out] ReturnPointer Pointer passed from remote core + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilReceivePointer ( + IN UINT8 Socket, + IN UINT8 Core, + 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 (Socket, Core, &WaitForStatus, StdHeader); + *AddressScratchPtr++ = ApUtilReadRemoteDataDword (Socket, Core, StdHeader); + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); + WaitForStatus.WaitForStatusFlags = 0; + ApUtilWaitForCoreStatus (Socket, Core, &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] Socket Socket number of the remote core + * @param[in] Core Core number of the remote core + * @param[out] Pointer Pointer passed from remote core + * @param[in] StdHeader Configuration parameters pointer + * + */ +VOID +STATIC +ApUtilTransmitPointer ( + IN UINT8 Socket, + IN UINT8 Core, + 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 (Socket, Core, &WaitForStatus, StdHeader); + ApUtilWriteDataDword (*AddressScratchPtr++, StdHeader); + ApUtilWriteControlByte (CORE_STS_DATA_READY_0, StdHeader); + WaitForStatus.WaitForStatusFlags = 0; + ApUtilWaitForCoreStatus (Socket, Core, &WaitForStatus, StdHeader); + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuApicUtilities.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuApicUtilities.h new file mode 100755 index 0000000000..1762aac6ff --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuApicUtilities.h @@ -0,0 +1,260 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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 0x30000 +#define CMD_REG_REMOTE_DELIVERY_PENDING 0x10000 +#define CMD_REG_REMOTE_DELIVERY_DONE 0x20000 +#define CMD_REG_TO_NMI 0x400 + +// ExeFlags bits +#define WAIT_FOR_CORE 0x00000001 +#define TASK_HAS_OUTPUT 0x00000002 +#define RETURN_PARAMS 0x00000004 +#define END_AT_HLT 0x00000008 +#define PASS_EARLY_PARAMS 0x00000010 + +// 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)) + +/*--------------------------------------------------------------------------------------- + * 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; + +#define WAIT_STATUS_EQUALITY 0x00000001 +#define WAIT_INFINITELY 0 + +// Data Transfer Flags +#define DATA_IN_MEMORY 0x00000001 + + +/*--------------------------------------------------------------------------------------- + * 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 UINT8 Socket, + IN UINT8 Core, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +ApUtilWriteControlByte ( + IN UINT8 Value, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +ApUtilReadRemoteDataDword ( + IN UINT8 Socket, + IN UINT8 Core, + 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 UINT8 Socket, + IN UINT8 Core, + 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 + ); + +#endif /* _CPU_APIC_UTILITIES_H_ */ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuBist.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuBist.c new file mode 100755 index 0000000000..931f92018a --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuBist.c @@ -0,0 +1,168 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuApicUtilities.h" +#include "Filecode.h" +#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 BscCore; + 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, BscCore and NumberOfSockets in the system + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCore, &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 != BscCore)) { + 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) { + 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); +}
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuBrandId.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuBrandId.c new file mode 100755 index 0000000000..3541c03556 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuBrandId.c @@ -0,0 +1,311 @@ +/** + * @file + * + * AMD CPU BrandId related functions. + * + * Contains code that provides CPU BrandId information + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "OptionPstate.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuEarlyInit.h" +#include "cpuRegisters.h" +#include "heapManager.h" +#include "GeneralServices.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_CPUBRANDID_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 CHAR8 ROMDATA strEngSample[] = "AMD Engineering Sample"; +CONST CHAR8 ROMDATA strTtkSample[] = "AMD Thermal Test Kit"; +CONST CHAR8 ROMDATA strUnknown[] = "AMD Processor Model Unknown"; + +CONST AMD_CPU_BRAND ROMDATA EngSample_Str = {0, 0, 0, SOCKET_IGNORE, strEngSample, sizeof (strEngSample)}; +CONST AMD_CPU_BRAND ROMDATA TtkSample_Str = {0, 1, 0, SOCKET_IGNORE, strTtkSample, sizeof (strTtkSample)}; +CONST AMD_CPU_BRAND ROMDATA Dflt_Str1 = {0, 0, 0, SOCKET_IGNORE, strUnknown, sizeof (strUnknown)}; +CONST AMD_CPU_BRAND ROMDATA Dflt_Str2 = {0, 0, 0, SOCKET_IGNORE, DR_NO_STRING, DR_NO_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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +SetBrandIdRegistersAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------*/ +/** + * Program BrandID registers (CPUIDNameStringPtr[0-5]) + * + * This function determines the appropriate brand string for the executing + * core, and programs the namestring MSRs. + * + * @param[in,out] StdHeader Config handle for library and services. + * + */ +VOID +SetBrandIdRegisters ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 SocketIndex; + UINT8 SuffixStatus; + UINT8 TableElements; + UINT8 TableEntryCount; + UINT8 TableEntryIndex; + CHAR8 TempChar; + CHAR8 *NameStringPtr; + CHAR8 *SuffixStringPtr; + CHAR8 *BrandStringPtr; + CHAR8 *TempNameCharPtr; + UINT32 MsrIndex; + UINT32 Quotient; + UINT32 Remainder; + UINT64 *MsrNameStringPtrPtr; + CPUID_DATA CpuId; + CPU_LOGICAL_ID CpuLogicalId; + CPU_BRAND_TABLE *SocketTableEntry; + CPU_BRAND_TABLE **SocketTableEntry1; + AMD_CPU_BRAND *SocketTablePtr; + AMD_CPU_BRAND_DATA Data; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + SuffixStatus = 0; + FamilySpecificServices = NULL; + SocketTablePtr = NULL; + SocketTableEntry = NULL; + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + // Step1: Allocate 48 bytes from Heap space + AllocHeapParams.RequestedBufferSize = CPU_BRAND_ID_LENGTH; + AllocHeapParams.BufferHandle = AMD_BRAND_ID_BUFFER_HANDLE; + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + // Clear NameBuffer + BrandStringPtr = (CHAR8 *) AllocHeapParams.BufferPtr; + LibAmdMemFill (BrandStringPtr, 0, CPU_BRAND_ID_LENGTH, StdHeader); + } else { + PutEventLog ( + AGESA_ERROR, + CPU_ERROR_BRANDID_HEAP_NOT_AVAILABLE, + 0, 0, 0, 0, StdHeader + ); + return; + } + + // Step2: Get brandid from model number and model string + LibAmdCpuidRead (AMD_CPUID_FMF, &CpuId, StdHeader); + + // @todo: BrandId should be the common routine. Read from CPUID should move to Cpu Family Specific Service... + // Step3: Figure out Socket/Page/Model/String1/String2/Core Number + Data.String2 = (UINT8) (CpuId.EBX_Reg & 0x0f); + Data.Model = (UINT8) ((CpuId.EBX_Reg >> 4) & 0x7f); + Data.String1 = (UINT8) ((CpuId.EBX_Reg >> 11) & 0x0f); + Data.Page = (UINT8) ((CpuId.EBX_Reg >> 15) & 0x01); + Data.Socket = (UINT8) ((CpuId.EBX_Reg >> 28) & 0x0f); + Data.Cores = FamilySpecificServices->GetNumberOfCoresForBrandstring (FamilySpecificServices, StdHeader); + + // Step4: If NN = 0, we have an engineering sample, no suffix; then jump to Step6 + if (Data.Model == 0) { + if (Data.Page == 0) { + SocketTablePtr = (AMD_CPU_BRAND *)&EngSample_Str; + } else { + SocketTablePtr = (AMD_CPU_BRAND *)&TtkSample_Str; + } + } else { + + // Model is not equal to zero, so decrement it + // For family 10 if PkgType[3:0] is greater than or equal to 2h and families >= 12h + GetLogicalIdOfCurrentCore (&CpuLogicalId, StdHeader); + if ((((CpuLogicalId.Family & AMD_FAMILY_10) != 0) && (Data.Socket >= DR_SOCKET_S1G3)) || + ((CpuLogicalId.Family & AMD_FAMILY_GE_12) != 0)) { + Data.Model--; + } + + // Step5: Search for String1 (there can be only 1) + FamilySpecificServices->GetBrandString1 (FamilySpecificServices, (CONST VOID **) &SocketTableEntry, &TableEntryCount, StdHeader); + SocketTableEntry1 = (CPU_BRAND_TABLE **) SocketTableEntry; + for (TableEntryIndex = 0; ((TableEntryIndex < TableEntryCount) + && (SuffixStatus == 0)); TableEntryIndex++, SocketTableEntry1++) { + if (*SocketTableEntry1 == NULL) { + break; + } + SocketTablePtr = (AMD_CPU_BRAND *) (*SocketTableEntry1)->Table; + TableElements = (*SocketTableEntry1)->NumberOfEntries; + for (SocketIndex = 0; (SocketIndex < TableElements) + && SuffixStatus == 0; SocketIndex++) { + if ((SocketTablePtr->Page == Data.Page) && + (SocketTablePtr->Index == Data.String1) && + (SocketTablePtr->Socket == Data.Socket) && + (SocketTablePtr->Cores == Data.Cores)) { + SuffixStatus = 1; + } else { + SocketTablePtr++; + } + } + } + if (SuffixStatus == 0) { + SocketTablePtr = (AMD_CPU_BRAND *)&Dflt_Str1; // We did not find one, make 'Unknown' + } + } + + // Step6: Copy String into NameBuffer + // We now have data structure pointing to correct type in (*SocketTablePtr) + LibAmdMemCopy (BrandStringPtr, + (CHAR8 *)SocketTablePtr->Stringstart, + SocketTablePtr->Stringlength, + StdHeader); + + // Step7: Get suffix, determine addition to BRANDSPEED + if (SuffixStatus != 0) { + // Turn our value into a decimal string + // We have a value like 37d which we need to turn into '3' '7' + // Divide by 10, store remainder as an ASCII char on stack, repeat until Quotient is 0 + NameStringPtr = BrandStringPtr + SocketTablePtr->Stringlength - 1; + TempNameCharPtr = NameStringPtr; + Quotient = Data.Model; + do { + Remainder = Quotient % 10; + Quotient = Quotient / 10; + *TempNameCharPtr++ = (CHAR8) (Remainder + '0'); // Put suffix into our NameBuffer + } while (Quotient != 0); + if (Data.Model < 10) { + *TempNameCharPtr++ = '0'; + } + + // Step8: Reverse the string sequence and copy into NameBuffer + SuffixStringPtr = TempNameCharPtr--; + while (NameStringPtr < TempNameCharPtr) { + TempChar = *NameStringPtr; + *NameStringPtr = *TempNameCharPtr; + *TempNameCharPtr = TempChar; + NameStringPtr++; + TempNameCharPtr--; + } + + // Step9: Search for String2 + SuffixStatus = 0; + FamilySpecificServices->GetBrandString2 (FamilySpecificServices, (CONST VOID **) &SocketTableEntry, &TableEntryCount, StdHeader); + SocketTableEntry1 = (CPU_BRAND_TABLE **) SocketTableEntry; + for (TableEntryIndex = 0; ((TableEntryIndex < TableEntryCount) + && (SuffixStatus == 0)); TableEntryIndex++, SocketTableEntry1++) { + if (*SocketTableEntry1 == NULL) { + break; + } + SocketTablePtr = (AMD_CPU_BRAND *) (*SocketTableEntry1)->Table; + TableElements = (*SocketTableEntry1)->NumberOfEntries; + for (SocketIndex = 0; (SocketIndex < TableElements) + && SuffixStatus == 0; SocketIndex++) { + if ((SocketTablePtr->Page == Data.Page) && + (SocketTablePtr->Index == Data.String2) && + (SocketTablePtr->Socket == Data.Socket) && + (SocketTablePtr->Cores == Data.Cores)) { + SuffixStatus = 1; + } else { + SocketTablePtr++; + } + } + } + if (SuffixStatus == 0) { + SocketTablePtr = (AMD_CPU_BRAND *)&Dflt_Str2; + } + + // Step10: Copy String2 into our NameBuffer + if (SocketTablePtr->Stringlength != 0) { + LibAmdMemCopy (SuffixStringPtr, + (CHAR8 *)SocketTablePtr->Stringstart, + SocketTablePtr->Stringlength, + StdHeader); + } + } + + // Step11: Put values into name MSRs, Always write the full 48 bytes + MsrNameStringPtrPtr = (UINT64 *) BrandStringPtr; + for (MsrIndex = MSR_CPUID_NAME_STRING0; MsrIndex <= MSR_CPUID_NAME_STRING5; MsrIndex++) { + LibAmdMsrWrite (MsrIndex, MsrNameStringPtrPtr, StdHeader); + MsrNameStringPtrPtr++; + } + HeapDeallocateBuffer (AMD_BRAND_ID_BUFFER_HANDLE, StdHeader); +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Program BrandID registers (CPUIDNameStringPtr[0-5]) + * + * This function acts as a wrapper for calling the SetBrandIdRegisters + * 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 +SetBrandIdRegistersAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_TESTPOINT (TpProcCpuSetBrandID, StdHeader); + SetBrandIdRegisters (StdHeader); +}
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEarlyInit.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEarlyInit.c new file mode 100755 index 0000000000..905fa01fef --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEarlyInit.c @@ -0,0 +1,363 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "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" +#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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +VOID +McaInitializationAtEarly ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*------------------------------------------------------------------------------------*/ +/** + * 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 + */ +STATIC 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 j; + UINT8 StartCore; + UINT8 EndCore; + UINT32 NodeNum; + UINT32 PrimaryCore; + UINT32 SocketNum; + UINT32 ModuleNum; + UINT32 HighCore; + UINT32 ApHeapIndex; + AP_WAIT_FOR_STATUS WaitForStatus; + AGESA_STATUS Status; + AGESA_STATUS CalledStatus; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + AMD_CPU_EARLY_PARAMS CpuEarlyParams; + PF_PERFORM_EARLY_INIT_ON_CORE *EarlyTableOnCore; + + Status = AGESA_SUCCESS; + CalledStatus = AGESA_SUCCESS; + + AmdCpuEarlyInitializer (StdHeader, PlatformConfig, &CpuEarlyParams); + ASSERT (CpuEarlyParams.PlatformConfig.VrmProperties.CurrentLimit >= CpuEarlyParams.PlatformConfig.VrmProperties.LowPowerThreshold); + + IDS_OPTION_HOOK (IDS_CPU_Early_Override, &CpuEarlyParams, StdHeader); + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + EarlyTableOnCore = NULL; + FamilySpecificServices->GetEarlyInitOnCoreTable (FamilySpecificServices, (CONST PF_PERFORM_EARLY_INIT_ON_CORE **)&EarlyTableOnCore, &CpuEarlyParams, StdHeader); + if (EarlyTableOnCore != NULL) { + for (i = 0; EarlyTableOnCore[i] != NULL; i++) { + EarlyTableOnCore[i] (FamilySpecificServices, &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)) { + + // 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, &SocketNum, &ModuleNum, StdHeader); + GetCpuServicesOfSocket (SocketNum, &FamilySpecificServices, StdHeader); + FamilySpecificServices->SetApCoreNumber (FamilySpecificServices, SocketNum, ModuleNum, 0, StdHeader); + FamilySpecificServices->TransferApCoreNumber (FamilySpecificServices, StdHeader); + + // Clear BSP's Status Byte + ApUtilWriteControlByte (CORE_ACTIVE, StdHeader); + + NodeNum = 1; + ApHeapIndex = 1; + for (i = 0; i < 2; i++) { + while (NodeNum < MAX_NODES && + GetSocketModuleOfNode (NodeNum, &SocketNum, &ModuleNum, StdHeader)) { + GetCpuServicesOfSocket (SocketNum, &FamilySpecificServices, StdHeader); + GetGivenModuleCoreRange (SocketNum, ModuleNum, &PrimaryCore, &HighCore, StdHeader); + if (i == 0) { + StartCore = (UINT8) PrimaryCore; + EndCore = (UINT8) PrimaryCore; + } else { + StartCore = (UINT8) PrimaryCore + 1; + EndCore = (UINT8) HighCore; + } + for (j = StartCore; j <= EndCore; j++) { + FamilySpecificServices->SetApCoreNumber (FamilySpecificServices, SocketNum, ModuleNum, ApHeapIndex, StdHeader); + if (FamilySpecificServices->LaunchApCore (FamilySpecificServices, SocketNum, ModuleNum, j, PrimaryCore, StdHeader)) { + WaitStatus = CORE_IDLE; + WaitForStatus.Status = &WaitStatus; + WaitForStatus.NumberOfElements = 1; + WaitForStatus.RetryCount = WAIT_INFINITELY; + WaitForStatus.WaitForStatusFlags = WAIT_STATUS_EQUALITY; + ApUtilWaitForCoreStatus ( + (UINT8) SocketNum, + j, + &WaitForStatus, + StdHeader + ); + ApHeapIndex++; + } + } + NodeNum++; + } + NodeNum = 0; + } + + // B S P P h a s e - 1 E N D + AGESA_TESTPOINT (TpProcCpuPowerMgmtInit, StdHeader); + CalledStatus = PmInitializationAtEarly (&CpuEarlyParams, StdHeader); + if (CalledStatus > Status) { + Status = CalledStatus; + } + + AGESA_TESTPOINT (TpProcCpuEarlyFeatureInit, StdHeader); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_AFTER_PM_INIT, PlatformConfig, StdHeader); + + // Sleep all APs + ApUtilWriteControlByte (CORE_IDLE_HLT, StdHeader); + } // if (amdIsBsp()) - END + 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 + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 + * + *--------------------------------------------------------------------------------------- + */ +STATIC 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); + } + } + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEarlyInit.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEarlyInit.h new file mode 100755 index 0000000000..48c7961fbf --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEarlyInit.h @@ -0,0 +1,228 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_EARLY_INIT_H_ +#define _CPU_EARLY_INIT_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ +typedef struct _CPU_CORE_LEVELING_FAMILY_SERVICES 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 + +/* 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_SIZE 2048 +/*--------------------------------------------------------------------------------------- + * 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 MicrocodePatchDataID; ///< Internal use only + UINT8 MicrocodePatchDataLength; ///< Internal use only + UINT8 InitializationFlag; ///< Internal use only + 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 MatchRegister0; ///< Internal use only + UINT32 MatchRegister1; ///< Internal use only + UINT32 MatchRegister2; ///< Internal use only + UINT32 MatchRegister3; ///< Internal use only + UINT32 MatchRegister4; ///< Internal use only + UINT32 MatchRegister5; ///< Internal use only + UINT32 MatchRegister6; ///< Internal use only + UINT32 MatchRegister7; ///< Internal use only + 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_SIZE]; ///< 2k UINT8 elements +} MICROCODE_PATCHES; + +/** + * 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] StdHeader Header for library and services. + * + */ +typedef VOID (F_CPU_SET_DOWN_CORE_REGISTER) ( + IN CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices, + IN UINT32 *Socket, + IN UINT32 *Module, + IN UINT32 *LeveledCores, + 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 { + 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 +VOID +SetBrandIdRegisters ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PmInitializationAtEarly ( + IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +LoadMicrocodePatch ( + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); +#endif // _CPU_EARLY_INIT_H_ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEnvInit.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEnvInit.h new file mode 100755 index 0000000000..9d73d8f4cb --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEnvInit.h @@ -0,0 +1,73 @@ +/** + * @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: 8361 $ @e \$Date: 2008-09-19 21:22:28 +0800 (Fri, 19 Sep 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#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/f10/Proc/CPU/cpuEventLog.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEventLog.c new file mode 100755 index 0000000000..2d296d2d21 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuEventLog.c @@ -0,0 +1,379 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "heapManager.h" +#include "GeneralServices.h" +#include "Ids.h" +#include "Filecode.h" +#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); + 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; + + 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; + HeapLocateBuffer (&LocateHeapStruct, StdHeader); + *EventLog = (AGESA_STRUCT_BUFFER *)LocateHeapStruct.BufferPtr; +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuFamilyTranslation.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuFamilyTranslation.c new file mode 100755 index 0000000000..207af8457a --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuFamilyTranslation.c @@ -0,0 +1,481 @@ +/** + * @file + * + * AMD CPU Family Translation functions. + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Interface + * @e \$Revision: 6155 $ @e \$Date: 2008-05-27 04:48:33 -0500 (Tue, 27 May 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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 "Ids.h" +#include "cpuRegisters.h" +#include "CommonReturns.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#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_GET_PSTATE_POWER) CommonReturnAgesaSuccess, + (PF_CPU_GET_PSTATE_FREQ) CommonReturnAgesaSuccess, + (PF_CPU_DISABLE_PSTATE) CommonReturnAgesaSuccess, + (PF_CPU_TRANSITION_PSTATE) CommonReturnAgesaSuccess, + (PF_CPU_GET_IDD_MAX) CommonReturnFalse, + (PF_CPU_GET_TSC_RATE) CommonReturnAgesaSuccess, + (PF_CPU_PSTATE_TRANSITION_LATENCY) CommonReturnAgesaSuccess, + (PF_CPU_GET_PSTATE_REGISTER_INFO) CommonReturnAgesaSuccess, + (PF_CPU_GET_PSTATE_MAX_STATE) CommonReturnAgesaSuccess, + (PF_CPU_SET_PSTATE_LEVELING_REG) CommonReturnAgesaSuccess, + (PF_CPU_GET_NB_FREQ) CommonReturnAgesaSuccess, + (PF_CPU_IS_NBCOF_INIT_NEEDED) CommonReturnAgesaSuccess, + (PF_CPU_AP_INITIAL_LAUNCH) CommonReturnFalse, + (PF_CPU_NUMBER_OF_BRANDSTRING_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_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_DOES_LINK_HAVE_HTFPY_FEATS) CommonReturnFalse, + (PF_SET_HT_PHY_REGISTER) CommonVoid, + (PF_GET_HT_LINK_FEATURES) CommonVoid, + NULL, + NULL, + NULL, + (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 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 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 CPU_SPECIFIC_SERVICES **FunctionTable, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GetFeatureServicesFromLogicalId (&CpuSupportedFamiliesTable, + LogicalId, + (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[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/f10/Proc/CPU/cpuFamilyTranslation.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuFamilyTranslation.h new file mode 100755 index 0000000000..d34d4dac57 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuFamilyTranslation.h @@ -0,0 +1,1030 @@ +/** + * @file + * + * AMD CPU Family Translation functions. + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 6155 $ @e \$Date: 2008-05-27 04:48:33 -0500 (Tue, 27 May 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#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. + * <ul> + * <li> Create a typedef for the Method with the correct parameters and return type. + * + * <ul> + * <li> 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 <tt> typedef VOID (*PF_METHOD_NAME)(); </tt> @n + * + * <li> [Optionally make the type F_<name> and provide a separate: + * @n <tt> typedef F_METHOD_NAME *PF_METHOD_NAME> </tt> @n + * and provide a single line "///" doxygen comment brief description on the PF_ type.] + * </ul> + * + * <li> The first parameter to @b all Family Specific Service Methods is @b required to be a reference to + * their Family Service struct. + * @n <tt> IN CPU_SPECIFIC_SERVICES *FamilySpecificServices </tt> @n + * + * <li> 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 + * + * <li> Add to the ::CPU_SPECIFIC_SERVICES struct an item for the Method: + * @n <tt> PF_METHOD_NAME MethodName; ///< Method: description. </tt> @n + * </ul> + * + * @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 "cpuRegisters.h" +#include "cpuServices.h" +#include "Table.h" +#include "Ids.h" +#include "Topology.h" + +// Forward declaration. +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 + *--------------------------------------------------------------------------------------- + */ +/** + * Get the desired P-state's rated power in milliwatts. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific 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 CPU_SPECIFIC_SERVICES *FamilySpecificServices, + 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; + +/** + * Get the desired P-state's frequency in megahertz. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific 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 CPU_SPECIFIC_SERVICES *FamilySpecificServices, + 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; + +/** + * Disable the desired P-state. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] StateNumber 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 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 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; + +/** + * Get CPU pstate transition latency for current socket. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific 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 CPU_SPECIFIC_SERVICES *FamilySpecificServices, + 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; + +/** + * Get CPU pstate register Informations. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific 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[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_PSTATE_REGISTER_INFO ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN UINT32 PState, + OUT BOOLEAN *PStateEnabled, + IN OUT UINT32 *IddVal, + IN OUT UINT32 *IddDiv, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_PSTATE_REGISTER_INFO *PF_CPU_GET_PSTATE_REGISTER_INFO; + +/** + * Get CPU Pstate Max State. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[out] MaxPStateNumber The value return max pstate value current socket. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_PSTATE_MAX_STATE ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINT32 *MaxPStateNumber, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_PSTATE_MAX_STATE *PF_CPU_GET_PSTATE_MAX_STATE; + + +/** + * Set the system wide P-state settings on the current core. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific 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 CPU_SPECIFIC_SERVICES *FamilySpecificServices, + 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; + +/** + * 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[in] PciAddress The PCI address of the node in question. + * @param[out] FreqInMHz The desired node's frequency in megahertz. + * @param[out] VoltageInuV The desired node's voltage in microvolts. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef AGESA_STATUS F_CPU_GET_NB_FREQ ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR *PciAddress, + OUT UINT32 *FreqInMHz, + OUT UINT32 *VoltageInuV, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_GET_NB_FREQ *PF_CPU_GET_NB_FREQ; + +/** + * 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 processor cores for brandstring detection + * + * @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 cores on current processor + */ +typedef UINT8 F_CPU_NUMBER_OF_BRANDSTRING_CORES ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a Method. +typedef F_CPU_NUMBER_OF_BRANDSTRING_CORES *PF_CPU_NUMBER_OF_BRANDSTRING_CORES; + +/** + * 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; + +/** + * 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; + +/** + * 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] 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 AMD_CONFIG_PARAMS *StdHeader + ); + +/// Reference to a method +typedef F_IS_NB_PSTATE_ENABLED *PF_IS_NB_PSTATE_ENABLED; + +/** + * Checks to see if the HT phy register table entry type features match the link features. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in] CapabilitySet Address of the HT capability block + * @param[in] Link Zero based HT link to check + * @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 Link does not match + * + */ +typedef BOOLEAN F_DOES_LINK_HAVE_HTFPY_FEATS ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + IN PCI_ADDR CapabilitySet, + IN 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_DOES_LINK_HAVE_HTFPY_FEATS *PF_DOES_LINK_HAVE_HTFPY_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; + +/** + * 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 PF_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 given 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[out] Link The link number, for accessing non-capability set registers. + * @param[in] LinkBase The base HT Host capability PCI address for the link. + * @param[out] HtHostFeats The link's features. + * @param[in] StdHeader Standard Head Pointer + */ +typedef VOID F_GET_HT_LINK_FEATURES ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT UINTN *Link, + IN PCI_ADDR *LinkBase, + OUT HT_HOST_FEATS *HtHostFeats, + IN AMD_CONFIG_PARAMS *StdHeader + ); +/// Reference to a Method. +typedef F_GET_HT_LINK_FEATURES *PF_GET_HT_LINK_FEATURES; + +/*---------------------------------------------------------------------------------------*/ +/** + * Provide the interface to all cpu 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(). + * See CPU Family Specific Services Implementation Guide for adding new services. + */ +struct _CPU_SPECIFIC_SERVICES { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_CPU_GET_PSTATE_POWER GetPstatePower; ///< Method: Get the desired P-state's rated power in milliwatts. + PF_CPU_GET_PSTATE_FREQ GetPstateFrequency; ///< Method: Get the desired P-state's frequency in megahertz. + PF_CPU_DISABLE_PSTATE DisablePstate; ///< Method: Disable the desired P-state. + PF_CPU_TRANSITION_PSTATE TransitionPstate; ///< Method: Transition the current core to the desired P-state. + PF_CPU_GET_IDD_MAX GetProcIddMax; ///< Method: Gets P-state maximum current required + PF_CPU_GET_TSC_RATE GetTscRate; ///< Method: Returns the rate at which the current core's timestamp counter increments in megahertz. + PF_CPU_PSTATE_TRANSITION_LATENCY GetPstateLatency; ///< Method: Get pstate transition latency. + PF_CPU_GET_PSTATE_REGISTER_INFO GetPstateRegisterInfo; ///< Method: Get pstate register Informations. + PF_CPU_GET_PSTATE_MAX_STATE GetPstateMaxState; ///< Method: Get pstate max state number. + PF_CPU_SET_PSTATE_LEVELING_REG SetPStateLevelReg; ///< Method: Set the system wide P-state settings on the current core. + PF_CPU_GET_NB_FREQ GetNbFrequency; ///< Method: Returns the processor north bridge's clock rate in megahertz. + PF_CPU_IS_NBCOF_INIT_NEEDED IsNbCofInitNeeded; ///< Method: Returns whether or not the NB frequency initialization sequence is required to be performed by the BIOS. + PF_CPU_AP_INITIAL_LAUNCH LaunchApCore; ///< Method: Launches the desired core from the reset vector. + PF_CPU_NUMBER_OF_BRANDSTRING_CORES GetNumberOfCoresForBrandstring; ///< Method: Get the current core's number of cores used in the brandstring calculation. + PF_CPU_AMD_GET_AP_MAILBOX_FROM_HARDWARE GetApMailboxFromHardware; ///< Method: Get the AP's topology info from the hardware mailbox. + PF_CPU_SET_AP_CORE_NUMBER SetApCoreNumber; ///< Method: Set the AP's core number to the hardware mailbox. + PF_CPU_GET_AP_CORE_NUMBER GetApCoreNumber; ///< Method: Get the AP's core number from hardware. + PF_CPU_TRANSFER_AP_CORE_NUMBER TransferApCoreNumber; ///< Method: Move the AP's core number from the mailbox to hardware. + PF_CORE_ID_POSITION_IN_INITIAL_APIC_ID CoreIdPositionInInitialApicId; ///< Method: Which bits in initial APIC Id are the Core Id. + PF_CPU_SAVE_FEATURES SaveFeatures; ///< Method: Get least common features set of all CPUs and save them to CPU_FEATURES_LIST + PF_CPU_WRITE_FEATURES WriteFeatures; ///< Method: Get least common features from CPU_FEATURES_LIST and write them to CPU + PF_CPU_SET_WARM_RESET_FLAG SetWarmResetFlag; ///< Method: Set Warm Reset Flag + PF_CPU_GET_WARM_RESET_FLAG GetWarmResetFlag; ///< Method: Get Warm Reset Flag + PF_CPU_GET_FAMILY_SPECIFIC_ARRAY GetBrandString1; ///< Method: Get a Brand String table + PF_CPU_GET_FAMILY_SPECIFIC_ARRAY GetBrandString2; ///< Method: Get a Brand String table + PF_CPU_GET_FAMILY_SPECIFIC_ARRAY GetMicroCodePatchesStruct; ///< Method: Get microcode patches + PF_CPU_GET_FAMILY_SPECIFIC_ARRAY GetMicrocodeEquivalenceTable; ///< Method: Get CPU equivalence for loading microcode patches. + PF_CPU_GET_FAMILY_SPECIFIC_ARRAY GetCacheInfo; ///< Method: Get setup for cache use and initialization. + PF_CPU_GET_FAMILY_SPECIFIC_ARRAY GetSysPmTableStruct; ///< Method: Get Power Management settings. + PF_CPU_GET_FAMILY_SPECIFIC_ARRAY GetWheaInitData; ///< Method: Get Whea Initial Data. + PF_CPU_GET_PLATFORM_TYPE_SPECIFIC_INFO GetPlatformTypeSpecificInfo; ///< Method: Get Specific platform Type features. + PF_IS_NB_PSTATE_ENABLED IsNbPstateEnabled; ///< Method: Get whether Northbridge PStates feature is enabled. + PF_DOES_LINK_HAVE_HTFPY_FEATS DoesLinkHaveHtPhyFeats; ///< Method: Get Link features and match for HT Phy Table Entry. + PF_SET_HT_PHY_REGISTER SetHtPhyRegister; ///< Method: Set an Ht Phy register based on table entry. + PF_GET_HT_LINK_FEATURES GetHtLinkFeatures; ///< Method: Get the Ht link features for the HT Host capability. + REGISTER_TABLE **RegisterTableList; ///< Public Data: The available register tables. + TABLE_ENTRY_TYPE_DESCRIPTOR *TableEntryTypeDescriptors; ///< Public Data: implemented register table entry types. + PACKAGE_HTLINK_MAP PackageLinkMap; ///< Public Data: translate northbridge HT links to package level links, or NULL. + PF_GET_EARLY_INIT_TABLE GetEarlyInitOnCoreTable; ///< Method: Get the initialization steps needed at AmdInitEarly. +}; + +/** + * A Family Id and an interface to it's implementations of Family Specific Services. + * + * Note that this is a logical family id, which may specify family, model (or even stepping). + */ +typedef struct { + UINT64 Family; ///< The Family to which this interface belongs. + CONST VOID *TablePtr; ///< The interface to its Family Specific Services. +} CPU_SPECIFIC_SERVICES_XLAT; + +/** + * A collection of Family specific interfaces to Family Specific services. + */ +typedef struct { + UINT8 Elements; ///< The number of tables to search. + CONST CPU_SPECIFIC_SERVICES_XLAT *FamilyTable; ///< The family interfaces. +} CPU_FAMILY_SUPPORT_TABLE; + +/** + * Implement the translation of a logical CPU id to an id that can be used to get Family specific services. + */ +typedef struct { + UINT32 Family; ///< Provide translation for this family + CPU_LOGICAL_ID UnknownRevision; ///< In this family, unrecognized models (or steppings) are treated as though they were this model and stepping. + CONST PF_CPU_GET_SUBFAMILY_ID_ARRAY *SubFamilyIdTable; ///< Method: Get family specific model (and stepping) resolution. + UINT8 Elements; ///< The number of family specific model tables pointed to by SubFamilyIdTable +} CPU_LOGICAL_ID_FAMILY_XLAT; + +/** + * A collection of all available family id translations. + */ +typedef struct { + UINT8 Elements; ///< The number of family translation items to search. + CONST CPU_LOGICAL_ID_FAMILY_XLAT *FamilyIdTable; ///< The family translation items. +} CPU_FAMILY_ID_XLAT_TABLE; + +/*--------------------------------------------------------------------------------------- + * F U N C T I O N P R O T O T Y P E + *--------------------------------------------------------------------------------------- + */ + +/** + * Get a logical identifier for the specified processor, based on CPUID, but independent of CPUID formatting. + */ +VOID +GetLogicalIdOfSocket ( + IN UINT32 Socket, + OUT CPU_LOGICAL_ID *LogicalId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Get a logical identifier for the executing core, based on CPUID, but independent of CPUID formatting. + */ +VOID +GetLogicalIdOfCurrentCore ( + OUT CPU_LOGICAL_ID *LogicalId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Get a logical identifier for the specified CPUID value. + */ +VOID +GetLogicalIdFromCpuid ( + IN UINT32 RawCpuid, + OUT CPU_LOGICAL_ID *LogicalId, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Retrieves a pointer to the desired processor's family specific services structure. + */ +VOID +GetCpuServicesOfSocket ( + IN UINT32 Socket, + OUT CPU_SPECIFIC_SERVICES **FunctionTable, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Retrieves a pointer to the desired processor's family specific services structure. + */ +VOID +GetFeatureServicesOfSocket ( + IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable, + IN UINT32 Socket, + OUT CONST VOID **CpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Retrieves a pointer to the executing core's family specific services structure. + */ +VOID +GetCpuServicesOfCurrentCore ( + OUT CPU_SPECIFIC_SERVICES **FunctionTable, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Retrieves a pointer to the executing core's family specific services structure. + */ +VOID +GetFeatureServicesOfCurrentCore ( + IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable, + OUT CONST VOID **CpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Retrieves a pointer to the family specific services structure for a processor + * with the given logical ID. + */ +VOID +GetCpuServicesFromLogicalId ( + IN CPU_LOGICAL_ID *LogicalId, + OUT CPU_SPECIFIC_SERVICES **FunctionTable, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Retrieves a pointer to the family specific services structure for a processor + * with the given logical ID. + */ +VOID +GetFeatureServicesFromLogicalId ( + IN CPU_FAMILY_SUPPORT_TABLE *FamilyTable, + IN CPU_LOGICAL_ID *LogicalId, + OUT CONST VOID **CpuServices, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/** + * Used by logical families which don't need a certain register setting table or other data array. + */ +VOID +GetEmptyArray ( + IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, + OUT CONST VOID **Empty, + OUT UINT8 *NumberOfElements, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_FAMILY_TRANSLATION_H_ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuGeneralServices.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuGeneralServices.c new file mode 100755 index 0000000000..218813cfbf --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuGeneralServices.c @@ -0,0 +1,1050 @@ +/** + * @file + * + * Implement External, AGESA Common, and CPU component General Services. + * + * Contains implementation of the interfaces: General Services API in AGESA.h, + * GeneralServices.h, and cpuServices.h. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "Options.h" +#include "Topology.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuFamilyTranslation.h" +#include "cpuServices.h" +#include "heapManager.h" +#include "cpuApicUtilities.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_CPUGENERALSERVICES_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern OPTIONS_CONFIG_TOPOLOGY TopologyConfiguration; +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 - External General Services API + *---------------------------------------------------------------------------------------- + */ + +/** + * Get a specified Core's APIC ID. + * + * Invoke corresponding Cpu Service for external user. + * + * @param[in,out] AmdParamApic Our interface struct + * + * @return The most severe status of any called service. + */ +AGESA_STATUS +AmdGetApicId ( + IN OUT AMD_APIC_PARAMS *AmdParamApic + ) +{ + AGESA_STATUS AgesaStatus; + + AGESA_TESTPOINT (TpIfAmdGetApicIdEntry, &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->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); + + 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 () +{ + 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 () +{ + 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; + + ASSERT (Socket < MAX_SOCKETS); + Result = FALSE; + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + + // Get data block from heap + HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT (pSocketDieMap != NULL); + 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; + + Result = 0; + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + + // Get data block from heap + HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT (pSocketDieMap != NULL); + 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; + + Result = FALSE; + + ASSERT (Node < MAX_NODES); + + // Get Map from heap + SocketDieHeapDataBlock.BufferHandle = NODE_ID_MAP_HANDLE; + HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pNodeMap = (NODE_TO_SOCKET_DIE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT (pNodeMap != NULL); + *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; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 +ModifyCurrentSocketPci ( + IN PCI_ADDR *PciAddress, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT32 Module; + UINT32 Core; + UINT32 PciRegister; + AGESA_STATUS AgesaStatus; + PCI_ADDR Reg; + + IdentifyCore (StdHeader, &Socket, &Module, &Core, &AgesaStatus); + + for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &Reg, &AgesaStatus)) { + Reg.Address.Function = PciAddress->Address.Function; + Reg.Address.Register = PciAddress->Address.Register; + LibAmdPciRead (AccessWidth32, Reg, &PciRegister, StdHeader); + PciRegister &= Mask; + PciRegister |= Data; + LibAmdPciWrite (AccessWidth32, Reg, &PciRegister, StdHeader); + } + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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; +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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; + + ASSERT (Socket < MAX_SOCKETS); + ASSERT (Module < MAX_DIES); + Result = FALSE; + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + + // Get data block from heap + HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT (pSocketDieMap != NULL); + *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 (&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; + + Result = FALSE; + SocketDieHeapDataBlock.BufferHandle = SOCKET_DIE_MAP_HANDLE; + + // Get data block from heap + HeapLocateBuffer (&SocketDieHeapDataBlock, StdHeader); + pSocketDieMap = (SOCKET_DIE_TO_NODE_MAP)SocketDieHeapDataBlock.BufferPtr; + ASSERT (pSocketDieMap != NULL); + *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 + ) +{ + AGESA_STATUS Ignored; + LOCATE_HEAP_PTR LocalApMailboxCache; + CPU_SPECIFIC_SERVICES *FamilyServices; + AP_MAILBOXES ApMailboxes; + BOOLEAN IamBsp; + + IamBsp = IsBsp (StdHeader, &Ignored); + LocalApMailboxCache.BufferHandle = LOCAL_AP_MAIL_BOX_CACHE_HANDLE; + if (((StdHeader->HeapStatus == HEAP_LOCAL_CACHE) || IamBsp) && + (HeapLocateBuffer (&LocalApMailboxCache, StdHeader) == AGESA_SUCCESS)) { + // If during HEAP_LOCAL_CACHE stage, we always try to get ApMailbox from heap + // If we're not in HEAP_LOCAL_CACHE stage, only BSP can get ApMailbox from heap + *ApMailboxInfo = ((AP_MAILBOXES *) LocalApMailboxCache.BufferPtr)->ApMailInfo.Info; + } else if (!IamBsp) { + // If this is an AP, the hardware register should be good. + GetCpuServicesOfCurrentCore (&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + 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 + ) +{ + ALLOCATE_HEAP_PARAMS AllocHeapParams; + AP_MAILBOXES ApMailboxes; + CPU_SPECIFIC_SERVICES *FamilyServices; + + GetCpuServicesOfCurrentCore (&FamilyServices, StdHeader); + ASSERT (FamilyServices != NULL); + + // Get mailbox from hardware. + FamilyServices->GetApMailboxFromHardware (FamilyServices, &ApMailboxes, StdHeader); + + // Allocate heap for the info + AllocHeapParams.RequestedBufferSize = sizeof (AP_MAILBOXES); + AllocHeapParams.BufferHandle = LOCAL_AP_MAIL_BOX_CACHE_HANDLE; + AllocHeapParams.Persist = HEAP_SYSTEM_MEM; + if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) { + *(AP_MAILBOXES *)AllocHeapParams.BufferPtr = ApMailboxes; + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 + ) +{ + AP_MAILBOXES *ApMailboxes; + LOCATE_HEAP_PTR LocalApMailboxCache; + + // Get data block from heap + LocalApMailboxCache.BufferHandle = LOCAL_AP_MAIL_BOX_CACHE_HANDLE; + HeapLocateBuffer (&LocalApMailboxCache, StdHeader); + // non-Success handled by ASSERT not NULL below. + ApMailboxes = (AP_MAILBOXES *)LocalApMailboxCache.BufferPtr; + ASSERT (ApMailboxes != NULL); + return ApMailboxes->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 (&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; + } + +} +/*---------------------------------------------------------------------------------------*/ +/** + * + * 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 MsrRegister; + + // Make sure that Standard header is valid + ASSERT (StdHeader != NULL); + + if ((UserOptions.CfgPciMmioAddress != 0) && (UserOptions.CfgPciMmioSize != 0)) { + EncodedSize = LibAmdBitScanForward (UserOptions.CfgPciMmioSize); + MsrRegister = ((UserOptions.CfgPciMmioAddress | BIT0) | (EncodedSize << 2)); + LibAmdMsrWrite (MSR_MMIO_Cfg_Base, &MsrRegister, StdHeader); + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuInitEarlyTable.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuInitEarlyTable.c new file mode 100755 index 0000000000..db71d7d7f6 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuInitEarlyTable.c @@ -0,0 +1,120 @@ +/** + * @file + * + * Initialize the 'common' 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 + * @e \$Revision$ @e \$Date$ + * + */ +/* + ****************************************************************************** + * + * 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 "cpuFamilyTranslation.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_CPUINITEARLYTABLE_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 F_PERFORM_EARLY_INIT_ON_CORE McaInitializationAtEarly; +extern F_PERFORM_EARLY_INIT_ON_CORE SetRegistersFromTablesAtEarly; +extern F_PERFORM_EARLY_INIT_ON_CORE SetBrandIdRegistersAtEarly; +extern F_PERFORM_EARLY_INIT_ON_CORE LocalApicInitializationAtEarly; +extern F_PERFORM_EARLY_INIT_ON_CORE LoadMicrocodePatchAtEarly; + +CONST PF_PERFORM_EARLY_INIT_ON_CORE ROMDATA CommonEarlyInitOnCoreTable[] = +{ + McaInitializationAtEarly, + SetRegistersFromTablesAtEarly, + SetBrandIdRegistersAtEarly, + LocalApicInitializationAtEarly, + LoadMicrocodePatchAtEarly, + NULL +}; + +/*------------------------------------------------------------------------------------*/ +/** + * Initializer routine that may be invoked at AmdCpuEarly 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 +GetCommonEarlyInitOnCoreTable ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST PF_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ); +VOID +GetCommonEarlyInitOnCoreTable ( + IN CPU_SPECIFIC_SERVICES *FamilyServices, + OUT CONST PF_PERFORM_EARLY_INIT_ON_CORE **Table, + IN AMD_CPU_EARLY_PARAMS *EarlyParams, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + *Table = CommonEarlyInitOnCoreTable; +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuLateInit.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuLateInit.c new file mode 100755 index 0000000000..1e93f64357 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuLateInit.c @@ -0,0 +1,281 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuLateInit.h" +#include "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "Filecode.h" +#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 + * + * @retval AGESA_SUCCESS + * + */ +AGESA_STATUS +AmdCpuLate ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + 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 BscCore; + AGESA_STATUS CalledStatus; + AGESA_STATUS IgnoredStatus; + AGESA_STATUS AgesaStatus; + + ASSERT (IsBsp (StdHeader, &IgnoredStatus)); + + AgesaStatus = AGESA_SUCCESS; + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCore, &IgnoredStatus); + NumberOfSockets = GetPlatformNumberOfSockets (); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCore)) { + 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/f10/Proc/CPU/cpuLateInit.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuLateInit.h new file mode 100755 index 0000000000..8b461c9031 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuLateInit.h @@ -0,0 +1,797 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_LATE_INIT_H_ +#define _CPU_LATE_INIT_H_ + +#include "Filecode.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 + *---------------------------------------------------------------------------------------- + */ +//---------------------------------------------------------------------------- +// 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 200 +#define UNKNOWN 0x02 +#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 ASSOCIATIVE_2_WAY 0x04 +#define ASSOCIATIVE_16_WAY 0x08 +#define ASSOCIATIVE_OTHER 0x01 + +// Processor Upgrade Definition +#define P_UPGRADE_UNKNOWN 0x02 +#define P_UPGRADE_NONE 0x06 +#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_S1GX 0x1C + +//---------------------------------------------------------------------------- +// SRAT DEFINITIONS AND MACROS +// +//---------------------------------------------------------------------------- +#define NorthbridgeCapabilities 0xE8 +#define DRAMBase0 0x40 +#define MMIOBase0 0x80 +#define TOP_MEM 0xC001001A +#define LOW_NODE_DEVICEID 24 +#define LOW_APICID 0 + + +// Miscellaneous AMD related values +#define MAX_NUMBER_NODES 8 +#define MAX_NUMBER_CORES 6 // GH is 4 and RR is 6 + +// 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 + +//---------------------------------------------------------------------------- +// 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 0x0FFFF +#define INVALID_FREQ 0x0FFFFFFFF + +//------------------------- +// 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 PACKAGE_OPCODE 0x12 +#define BUFFER_OPCODE 0x11 +#define BYTE_PREFIX_OPCODE 0x0A +#define DWORD_PREFIX_OPCODE 0x0C +#define ACPI_BUFFER 0x080A0B11 + +// 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 0x11022C12 +#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 0xC0010062 +#define PCT_CONTROL_REG_HI 0x00 +#define PCT_VALUE4 0x14110079 +#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 0x080A0B11 + + +// Defines for PPC Header Table +// ---------------------------- +#define PPC_NAME__ '_' +#define PPC_NAME_P 'P' +#define PPC_NAME_C 'C' +#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_SW_ANY 0xFD +#define PSD_COORDINATION_TYPE_SW_ALL 0xFC +#define PSD_NUM_OF_PROCESSORS 0x01 + +#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__; ///< String "_" + UINT8 PpcName_a_P; ///< String "P" + UINT8 PpcName_b_P; ///< String "P" + UINT8 PpcName_a_C; ///< String "C" + UINT8 Value1; ///< Value + UINT8 DefaultPerfPresentCap; ///< Default Perf Present Cap +} PPC_HEADER_BODY; +#define PPC_HEADER_BODY_STRUCT_SIZE 7 // 7 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 + + +//typedef struct _S_PSTATE_ACPI_BUFFER { +// SCOPE AcpiScopeStruct; +// PCT_HEADER_BODY AcpiPctHeaderBodyStruct; +// PSS_HEADER AcpiPssHeaderStruct; +// PSS_BODY AcpiPssBodyStruct[MPPSTATE_MAXIMUM_STATES]; +// XPSS_HEADER AcpiXpssHeaderStruct; +// XPSS_BODY AcpiXpssBodyStruct[MPPSTATE_MAXIMUM_STATES]; +// PSD_HEADER AcpiPsdHeaderStruct; +// PSD_BODY AcpiPsdBodyStruct; +// PPC_HEADER_BODY AcpiPpcHeaderBodyStruct; +//} S_PSTATE_ACPI_BUFFER; + +//---------------------------------------------------------------------------- +// 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 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_TYPE_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 UINT8 OPTION_DMI_GET_VOLTAGE ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +typedef UINT16 OPTION_DMI_GET_MAX_SPEED ( + 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 +typedef struct { + UINT64 ProcessorFamily; ///< processor + OPTION_DMI_GET_CPU_INFO *DmiGetCpuInfo; ///< transfer vectors + OPTION_DMI_GET_VOLTAGE *DmiGetVoltage; ///< vector for reading voltage + OPTION_DMI_GET_MAX_SPEED *DmiGetMaxSpeed; ///< vector for reading speed + UINT8 LenBrandList; ///< size of brand table + CONST DMI_BRAND_ENTRY *DmiBrandList; ///< translate brand info to DMI identifier +} PROC_FAMILY_TABLE; + +//---------------------------------------------------------------------------- +// 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; + +/*---------------------------------------------------------------------------------------- + * 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 + ); + +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 + ); + +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/f10/Proc/CPU/cpuMicrocodePatch.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuMicrocodePatch.c new file mode 100755 index 0000000000..bd84e34d2a --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuMicrocodePatch.c @@ -0,0 +1,441 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "cpuEarlyInit.h" +#include "GeneralServices.h" +#include "Filecode.h" +#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 + ); + +BOOLEAN +STATIC +GetPatchEquivalentId ( + IN OUT UINT16 *ProcessorEquivalentId, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +STATIC +ValidateMicrocode ( + IN MICROCODE_PATCH *MicrocodePatchPtr, + IN UINT16 ProcessorEquivalentId, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +VOID +STATIC +GetMicrocodeVersion ( + OUT UINT32 *pMicrocodeVersion, + 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; + + // Get the patch pointer + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetMicroCodePatchesStruct (FamilySpecificServices, (CONST VOID **) &MicrocodePatchPtr, &TotalPatches, StdHeader); + + IDS_OPTION_HOOK (IDS_UCODE, &TotalPatches, StdHeader); + + // Get the processor microcode path equivalent ID + Status = GetPatchEquivalentId (&ProcessorEquivalentId, StdHeader); + if (!Status) { + return (Status); + } + + // parse the patch table to see if we have one for the current cpu + for (PatchNumber = 0; PatchNumber < TotalPatches; PatchNumber++) { + Status = ValidateMicrocode (MicrocodePatchPtr[PatchNumber], ProcessorEquivalentId, StdHeader); + if (Status) { + Status = LoadMicrocode (MicrocodePatchPtr[PatchNumber], StdHeader); + if (!Status) { + PutEventLog (AGESA_ERROR, + CPU_ERROR_MICRO_CODE_PATCH_IS_NOT_LOADED, + 0, 0, 0, 0, StdHeader); + } + return (Status); + } + } + + return (FALSE); +} + +/*--------------------------------------------------------------------------------------- + * 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 = (UINT32) MicrocodePatchPtr; + PatchLoaderMsr.BitFields.SBZ = 0; + LibAmdMsrWrite (MSR_PATCH_LOADER, &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 +STATIC +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 (&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 +STATIC +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 +STATIC +GetMicrocodeVersion ( + OUT UINT32 *pMicrocodeVersion, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 MsrData; + + MsrData = 0; + LibAmdMsrRead (MSR_PATCH_LEVEL, &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/f10/Proc/CPU/cpuPage.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPage.h new file mode 100755 index 0000000000..e2b2926668 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPage.h @@ -0,0 +1,60 @@ +/** + * @file + * + * Create outline and references for CPU Component mainpage documentation. + * + * Design guides, maintenance guides, and general documentation, are + * collected using this file onto the documentation mainpage. + * This file contains doxygen comment blocks, only. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Documentation + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +/** + * @page cpumain CPU Component Documentation + * + * Additional documentation for the CPU component consists of + * + * - Maintenance Guides: + * - @subpage cpuimplfss "CPU Family Specific Services Implementation Guide" + * - @subpage regtableimpl "Register Table Implementation Guide" + * - @subpage cpufeatimpl "CPU Generic Feature Implementation Guide" + * - add here >>> + * - Design Guides: + * - add here >>> + * + */ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPostInit.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPostInit.c new file mode 100755 index 0000000000..ea97e73dbb --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPostInit.c @@ -0,0 +1,480 @@ +/** + * @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: 6708 $ @e \$Date: 2008-07-10 18:04:19 -0500 (Thu, 10 Jul 2008) $ + * + */ +/* + **************************************************************************** + * AMD Generic Encapsulated Software Architecture + * + * Description: cpuPostInit.c - Cpu POST Initialization Functions. + * + ****************************************************************************** + * + * 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 "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" +#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 + ); + +VOID +STATIC +SetCoresTscFreqSel ( + 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 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); + CalledStatus = DispatchCpuFeatures (CPU_FEAT_AFTER_POST_MTRR_SYNC, PlatformConfig, StdHeader); + if (CalledStatus > AgesaStatus) { + AgesaStatus = CalledStatus; + } + // + // Feature Leveling + // + AGESA_TESTPOINT (TpProcCpuFeatureLeveling, StdHeader); + FeatureLeveling (StdHeader); + // + // P-state Gathered and set heap info + // + PstateCreateHeapInfo (StdHeader); + + // Set TscFreqSel at the rate specified by the core P0 after core frequency leveling. + SetCoresTscFreqSel (StdHeader); + + // Relinquish control of all APs to IBV. + 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 + * + */ +STATIC AGESA_STATUS +GetPstateGatherDataAddressAtPost ( + OUT UINT64 **Ptr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 AddressValue; + + AddressValue = (UINT32) P_STATE_DATA_GATHER_TEMP_ADDR; + + *Ptr = (UINT64 *)(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 + * + */ +STATIC 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 CreateAcpiTables to generate the + * final _PSS and XPSS objects. + * + * @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 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 (StdHeader, PStateBufferPtr); + 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 = (UINT16) (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 BscCore; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + AGESA_STATUS IgnoredSts; + + ASSERT (IsBsp (StdHeader, &IgnoredSts)); + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCore, &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 != BscCore)) { + 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; +} +/*---------------------------------------------------------------------------------------*/ +/** + * Set TSC Frequency Selection. + * + * This function set TSC Frequency Selection. + * + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +STATIC +SetTscFreqSel ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PSTATE_CPU_FAMILY_SERVICES *FamilyServices; + + FamilyServices = NULL; + + GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); + if (FamilyServices != NULL) { + FamilyServices->CpuSetTscFreqSel (FamilyServices, StdHeader); + } + +} + +/*---------------------------------------------------------------------------------------*/ +/** + * Set TSC Frequency Selection to all cores. + * + * This function set TscFreqSel to all cores in the system. + * + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +STATIC +SetCoresTscFreqSel ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AP_TASK TaskPtr; + UINT32 BscSocket; + UINT32 Ignored; + UINT32 BscCore; + UINT32 Core; + UINT32 Socket; + UINT32 NumberOfSockets; + UINT32 NumberOfCores; + AGESA_STATUS IgnoredSts; + + ASSERT (IsBsp (StdHeader, &IgnoredSts)); + + IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCore, &IgnoredSts); + NumberOfSockets = GetPlatformNumberOfSockets (); + + SetTscFreqSel (StdHeader); + + TaskPtr.FuncAddress.PfApTask = SetTscFreqSel; + TaskPtr.ExeFlags = WAIT_FOR_CORE; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + for (Core = 0; Core < NumberOfCores; Core++) { + if ((Socket != BscSocket) || (Core != BscCore)) { + ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, &TaskPtr, StdHeader); + } + } + } + } +}
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPostInit.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPostInit.h new file mode 100755 index 0000000000..2534e8d1b2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPostInit.h @@ -0,0 +1,234 @@ +/** + * @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: 6626 $ @e \$Date: 2008-07-03 13:01:02 -0500 (Thu, 03 Jul 2008) $ + * + */ +/* + ****************************************************************************** + * + * 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_POST_INIT_H_ +#define _CPU_POST_INIT_H_ + + +/*--------------------------------------------------------------------------------------- + * M I X E D (Definitions And Macros / Typedefs, Structures, Enums) + *--------------------------------------------------------------------------------------- + */ +typedef struct _CPU_CFOH_FAMILY_SERVICES 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 0x200000 ///< Fixed the row data at 2M memory address. +#define GLOBAL_CPU_FEATURE_LIST_TEMP_ADDR 0x200000 ///< 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 DE:1; ///< byte 1 bit 2 + UINT8 ExtApicSpace:1; ///< byte 1 bit 3 + UINT8 FFXSR:1; ///< byte 1 bit 4 + UINT8 FMA:1; ///< byte 1 bit 5 + UINT8 FPU:1; ///< byte 1 bit 6 + UINT8 FXSR:1; ///< byte 1 bit 7 + UINT8 HTT:1; ///< byte 2 bit 0 + UINT8 IBS:1; ///< byte 2 bit 1 + UINT8 LahfSahf:1; ///< byte 2 bit 2 + UINT8 LM:1; ///< byte 2 bit 3 + UINT8 MCA:1; ///< byte 2 bit 4 + UINT8 MCE:1; ///< byte 2 bit 5 + UINT8 MisAlignSse:1; ///< byte 2 bit 6 + UINT8 MMX:1; ///< byte 2 bit 7 + UINT8 MmxExt:1; ///< byte 3 bit 0 + UINT8 Monitor:1; ///< byte 3 bit 1 + UINT8 MSR:1; ///< byte 3 bit 2 + UINT8 MTRR:1; ///< byte 3 bit 3 + UINT8 NX:1; ///< byte 3 bit 4 + UINT8 OSVW:1; ///< byte 3 bit 5 + UINT8 OSXSAVE:1; ///< byte 3 bit 6 + UINT8 PAE:1; ///< byte 3 bit 7 + UINT8 Page1GB:1; ///< byte 4 bit 0 + UINT8 PAT:1; ///< byte 4 bit 1 + UINT8 PGE:1; ///< byte 4 bit 2 + UINT8 POPCNT:1; ///< byte 4 bit 3 + UINT8 PSE:1; ///< byte 4 bit 4 + UINT8 PSE36:1; ///< byte 4 bit 5 + UINT8 RDTSCP:1; ///< byte 4 bit 6 + UINT8 SKINIT:1; ///< byte 4 bit 7 + UINT8 SSE:1; ///< byte 5 bit 0 + UINT8 SSE2:1; ///< byte 5 bit 1 + UINT8 SSE3:1; ///< byte 5 bit 2 + UINT8 SSE4A:1; ///< byte 5 bit 3 + UINT8 SSE41:1; ///< byte 5 bit 4 + UINT8 SSE42:1; ///< byte 5 bit 5 + UINT8 SSE5:1; ///< byte 5 bit 6 + UINT8 SVM:1; ///< byte 5 bit 7 + UINT8 SysCallSysRet:1; ///< byte 6 bit 0 + UINT8 SysEnterSysExit:1; ///< byte 6 bit 1 + UINT8 ThreeDNow:1; ///< byte 6 bit 2 + UINT8 ThreeDNowExt:1; ///< byte 6 bit 3 + UINT8 ThreeDNowPrefetch:1; ///< byte 6 bit 4 + UINT8 TimeStampCounter:1; ///< byte 6 bit 5 + UINT8 VME:1; ///< byte 6 bit 6 + UINT8 WDT:1; ///< byte 6 bit 7 + UINT8 X2APIC:1; ///< byte 7 bit 0 + UINT8 XSAVE:1; ///< byte 7 bit 1 + UINT8 NodeId:1; ///< byte 7 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; + +/** + * Get Cache Flush On Halt Register. + * + * @CpuServiceInstances + * + * @param[in] FamilySpecificServices The current Family Specific Services. + * @param[in, out] PciAddress Pci address struct. + * @param[in, out] AndMask AND mask to be applied to the value before saving. + * @param[in, out] OrMask OR mask to be applied to the value before saving. + * @param[in] StdHeader Handle of Header for calling lib functions and services. + * + */ +typedef VOID (F_CPU_GET_CFOH_REG) ( + IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, + IN OUT PCI_ADDR *PciAddress, + IN OUT UINT32 *AndMask, + IN OUT UINT32 *OrMask, + IN AMD_CONFIG_PARAMS *StdHeader + ); + + /// Reference to a Method. +typedef F_CPU_GET_CFOH_REG *PF_CPU_GET_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 { + UINT16 Revision; ///< Interface version + // Public Methods. + PF_CPU_GET_CFOH_REG GetCacheFlushOnHaltRegister; ///< 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 +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 + ); + +AGESA_STATUS +PStateGatherData ( + IN AMD_CONFIG_PARAMS *StdHeader, + IN OUT S_CPU_AMD_PSTATE *PStateStrucPtr + ); + +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 + ); + +VOID +SyncApMsrsToBsc ( + IN OUT BSC_AP_MSR_SYNC *ApMsrSync, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +FinalizeAtPost ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif // _CPU_POST_INIT_H_ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmt.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmt.c new file mode 100755 index 0000000000..e686f71b87 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmt.c @@ -0,0 +1,243 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "OptionMultiSocket.h" +#include "cpuApicUtilities.h" +#include "cpuEarlyInit.h" +#include "cpuPowerMgmtSystemTables.h" +#include "cpuServices.h" +#include "Filecode.h" +#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; + + // 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) { + OptionMultiSocketConfiguration.BscRunCodeOnAllSystemCore0s (&TaskPtr, StdHeader, CpuEarlyParams); + } + + if (IsWarmReset (StdHeader)) { + TaskPtr.FuncAddress.PfApTaskC = GoToMemInitPstateCore0; + TaskPtr.DataTransfer.DataSizeInDwords = 0; + TaskPtr.ExeFlags = PASS_EARLY_PARAMS; + 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; + SYS_PM_TBL_STEP *FamilyTablePtr; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **)&FamilyTablePtr, &MyNumberOfSteps, StdHeader); + + if (*(UINT8 *)Step < MyNumberOfSteps) { + if (FamilyTablePtr[*(UINT8 *)Step].FuncPtr != NULL) { + if (!(BOOLEAN) (FamilyTablePtr[*(UINT8 *)Step].ExeFlags & PM_EXEFLAGS_WARM_ONLY) || + IsWarmReset (StdHeader)) { + FamilyTablePtr[*(UINT8 *)Step].FuncPtr (FamilySpecificServices, CpuEarlyParamsPtr, StdHeader); + } + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 (&FamilySpecificServices, StdHeader); + FamilySpecificServices->TransitionPstate (FamilySpecificServices, CpuEarlyParamsPtr->MemInitPState, (BOOLEAN) FALSE, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtMultiSocket.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtMultiSocket.c new file mode 100755 index 0000000000..795d148dd7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtMultiSocket.c @@ -0,0 +1,394 @@ +/** + * @file + * + * AMD CPU Power Management Multisocket Functions. + * + * Contains code for doing power management for multisocket CPUs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "GeneralServices.h" +#include "cpuServices.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "cpuPowerMgmtSystemTables.h" +#include "cpuPowerMgmtMultiSocket.h" +#include "GeneralServices.h" +#include "Filecode.h" +#define FILECODE PROC_CPU_CPUPOWERMGMTMULTISOCKET_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 +GetNextEvent ( + IN OUT VOID *EventLogEntryPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * Multisocket BSC call to start all system core 0s to perform a standard AP_TASK. + * + * This function loops through all possible socket locations, starting core 0 of + * each populated socket to perform the passed in AP_TASK. After starting all + * other core 0s, the BSC will perform the AP_TASK as well. 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 + * + */ +VOID +RunCodeOnAllSystemCore0sMulti ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ConfigParams + ) +{ + UINT32 BscSocket; + UINT32 BscModule; + UINT32 BscCore; + UINT8 Socket; + UINT32 NumberOfSockets; + AGESA_STATUS DummyStatus; + + ASSERT (IsBsp (StdHeader, &DummyStatus)); + + NumberOfSockets = GetPlatformNumberOfSockets (); + + IdentifyCore (StdHeader, &BscSocket, &BscModule, &BscCore, &DummyStatus); + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (Socket != BscSocket) { + if (IsProcessorPresent (Socket, StdHeader)) { + ApUtilRunCodeOnSocketCore (Socket, 0, TaskPtr, StdHeader); + } + } + } + ApUtilTaskOnExecutingCore (TaskPtr, StdHeader, ConfigParams); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Multisocket BSC call to determine the maximum number of steps that any single + * processor needs to execute. + * + * This function loops through all possible socket locations, gathering the number + * of power management steps each populated socket requires, and returns the + * highest number. + * + * @param[out] NumSystemSteps Maximum number of system steps required + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +GetNumberOfSystemPmStepsPtrMulti ( + OUT UINT8 *NumSystemSteps, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 NumberOfSteps; + UINT32 NumberOfSockets; + UINT32 Socket; + SYS_PM_TBL_STEP *Ignored; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + NumberOfSockets = GetPlatformNumberOfSockets (); + *NumSystemSteps = 0; + + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetCpuServicesOfSocket (Socket, &FamilySpecificServices, StdHeader); + FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **)&Ignored, &NumberOfSteps, StdHeader); + if (NumberOfSteps > *NumSystemSteps) { + *NumSystemSteps = NumberOfSteps; + } + } + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Multisocket call to determine the frequency that the northbridges must run. + * + * This function loops through all possible socket locations, comparing the + * maximum NB frequencies to determine the slowest. This function also + * determines if all coherent NB frequencies are equivalent. + * + * @param[out] SystemNbCof NB frequency for the system in MHz + * @param[out] SystemNbCofsMatch Whether or not all NB frequencies are equivalent + * @param[in] StdHeader Config handle for library and services + * + * @retval AGESA_SUCCESS Always succeeds. + * + */ +AGESA_STATUS +GetSystemNbCofMulti ( + OUT UINT32 *SystemNbCof, + OUT BOOLEAN *SystemNbCofsMatch, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Socket; + UINT8 Module; + UINT32 NumberOfSockets; + UINT32 CurrentNbCof; + UINT32 Ignored32; + BOOLEAN FirstCofNotFound; + PCI_ADDR PciAddress; + AGESA_STATUS ReturnCode; + AGESA_STATUS Ignored; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + ReturnCode = AGESA_SUCCESS; + + NumberOfSockets = GetPlatformNumberOfSockets (); + + // Find the slowest NB COF in the system & whether or not all are equivalent + *SystemNbCofsMatch = TRUE; + FirstCofNotFound = TRUE; + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetCpuServicesOfSocket (Socket, &FamilySpecificServices, StdHeader); + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &Ignored)) { + break; + } + } + if ((FamilySpecificServices->GetNbFrequency (FamilySpecificServices, &PciAddress, &CurrentNbCof, &Ignored32, StdHeader)) == AGESA_SUCCESS) { + if (FirstCofNotFound) { + *SystemNbCof = CurrentNbCof; + FirstCofNotFound = FALSE; + } else { + if (CurrentNbCof != *SystemNbCof) { + *SystemNbCofsMatch = FALSE; + if (CurrentNbCof < *SystemNbCof) { + *SystemNbCof = CurrentNbCof; + } + } + } + } + } + } + return (ReturnCode); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Multisocket call to determine if the BIOS is responsible for updating the + * northbridge operating frequency and voltage. + * + * This function loops through all possible socket locations, checking whether + * any populated sockets require 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 +GetSystemNbCofVidUpdateMulti ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 Module; + UINT32 Socket; + UINT32 NumberOfSockets; + BOOLEAN IgnoredBool; + BOOLEAN AtLeast1RequiresUpdate; + PCI_ADDR PciAddress; + AGESA_STATUS Ignored; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + NumberOfSockets = GetPlatformNumberOfSockets (); + + AtLeast1RequiresUpdate = FALSE; + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (IsProcessorPresent (Socket, StdHeader)) { + GetCpuServicesOfSocket (Socket, &FamilySpecificServices, StdHeader); + for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { + if (GetPciAddress (StdHeader, (UINT8) Socket, Module, &PciAddress, &Ignored)) { + break; + } + } + if (FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &IgnoredBool, StdHeader)) { + AtLeast1RequiresUpdate = TRUE; + break; + } + } + } + return AtLeast1RequiresUpdate; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Multisocket call to determine the most severe AGESA_STATUS return value after + * processing the power management initialization tables. + * + * This function loops through all possible socket locations, collecting any + * power management initialization errors that may have occurred. These errors + * are transferred from the core 0s of the socket in which the errors occurred + * to the BSC's heap. The BSC's heap is then searched for the most severe error + * that occurred, and returns it. 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 +GetEarlyPmErrorsMulti ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT16 i; + UINT32 BscSocket; + UINT32 BscModule; + UINT32 BscCore; + UINT32 Socket; + UINT32 NumberOfSockets; + AP_TASK TaskPtr; + AGESA_EVENT EventLogEntry; + AGESA_STATUS ReturnCode; + AGESA_STATUS DummyStatus; + + ASSERT (IsBsp (StdHeader, &ReturnCode)); + + ReturnCode = AGESA_SUCCESS; + EventLogEntry.EventClass = AGESA_SUCCESS; + EventLogEntry.EventInfo = 0; + EventLogEntry.DataParam1 = 0; + EventLogEntry.DataParam2 = 0; + EventLogEntry.DataParam3 = 0; + EventLogEntry.DataParam4 = 0; + + NumberOfSockets = GetPlatformNumberOfSockets (); + IdentifyCore (StdHeader, &BscSocket, &BscModule, &BscCore, &DummyStatus); + + TaskPtr.FuncAddress.PfApTaskI = GetNextEvent; + TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (AGESA_EVENT); + TaskPtr.DataTransfer.DataPtr = &EventLogEntry; + TaskPtr.DataTransfer.DataTransferFlags = 0; + TaskPtr.ExeFlags = WAIT_FOR_CORE | RETURN_PARAMS; + for (Socket = 0; Socket < NumberOfSockets; Socket++) { + if (Socket != BscSocket) { + if (IsProcessorPresent (Socket, StdHeader)) { + do { + ApUtilRunCodeOnSocketCore ((UINT8)Socket, (UINT8) 0, &TaskPtr, StdHeader); + if ((EventLogEntry.EventInfo & CPU_EVENT_PM_EVENT_MASK) == CPU_EVENT_PM_EVENT_CLASS) { + PutEventLog ( + EventLogEntry.EventClass, + EventLogEntry.EventInfo, + EventLogEntry.DataParam1, + EventLogEntry.DataParam2, + EventLogEntry.DataParam3, + EventLogEntry.DataParam4, + StdHeader + ); + } + } while (EventLogEntry.EventInfo != 0); + } + } + } + + 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); +} + +/*--------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *--------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------*/ +/** + * AP task to return the next event log entry to the BSC. + * + * This function calls to the event log manager to retrieve the next error out + * of the heap. + * + * @param[out] EventLogEntryPtr The AP's next event log entry + * @param[in] StdHeader Config handle for library and services + * + */ +VOID +STATIC +GetNextEvent ( + IN OUT VOID *EventLogEntryPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + GetEventLog ((AGESA_EVENT *) EventLogEntryPtr, StdHeader); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtMultiSocket.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtMultiSocket.h new file mode 100755 index 0000000000..e87155ba29 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtMultiSocket.h @@ -0,0 +1,101 @@ +/** + * @file + * + * AMD CPU Power Management Multisocket Functions. + * + * Contains code for doing power management for multisocket CPUs + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_POWER_MGMT_MULTI_SOCKET_H_ +#define _CPU_POWER_MGMT_MULTI_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 + *--------------------------------------------------------------------------------------- + */ +VOID +RunCodeOnAllSystemCore0sMulti ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ConfigParams + ); + +VOID +GetNumberOfSystemPmStepsPtrMulti ( + OUT UINT8 *NumSystemSteps, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GetSystemNbCofMulti ( + OUT UINT32 *SystemNbCof, + OUT BOOLEAN *SystemNbCofsMatch, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetSystemNbCofVidUpdateMulti ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GetEarlyPmErrorsMulti ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +#endif // _CPU_POWER_MGMT_MULTI_SOCKET_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtSingleSocket.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtSingleSocket.c new file mode 100755 index 0000000000..fda1e9f18b --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtSingleSocket.c @@ -0,0 +1,224 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "GeneralServices.h" +#include "cpuRegisters.h" +#include "cpuApicUtilities.h" +#include "cpuFamilyTranslation.h" +#include "cpuPowerMgmtSystemTables.h" +#include "cpuPowerMgmtSingleSocket.h" +#include "Filecode.h" +#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 + * + */ +VOID +RunCodeOnAllSystemCore0sSingle ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ConfigParams + ) +{ + ApUtilTaskOnExecutingCore (TaskPtr, StdHeader, ConfigParams); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 (&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[out] SystemNbCof NB frequency for the system in MHz + * @param[out] SystemNbCofsMatch Whether or not all NB frequencies are equivalent + * @param[in] StdHeader Config handle for library and services + * + * @retval AGESA_SUCCESS + * + */ +AGESA_STATUS +GetSystemNbCofSingle ( + OUT UINT32 *SystemNbCof, + OUT BOOLEAN *SystemNbCofsMatch, + IN OUT 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 (&FamilySpecificServices, StdHeader); + return (FamilySpecificServices->GetNbFrequency (FamilySpecificServices, &PciAddress, SystemNbCof, &Ignored, StdHeader)); +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 (&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); +} + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtSingleSocket.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtSingleSocket.h new file mode 100755 index 0000000000..8f00865564 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtSingleSocket.h @@ -0,0 +1,101 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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 + *--------------------------------------------------------------------------------------- + */ +VOID +RunCodeOnAllSystemCore0sSingle ( + IN AP_TASK *TaskPtr, + IN AMD_CONFIG_PARAMS *StdHeader, + IN VOID *ConfigParams + ); + +VOID +GetNumberOfSystemPmStepsPtrSingle ( + OUT UINT8 *NumSystemSteps, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GetSystemNbCofSingle ( + OUT UINT32 *SystemNbCof, + OUT BOOLEAN *SystemNbCofsMatch, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ); + +BOOLEAN +GetSystemNbCofVidUpdateSingle ( + 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/f10/Proc/CPU/cpuPowerMgmtSystemTables.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtSystemTables.h new file mode 100755 index 0000000000..124085850c --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuPowerMgmtSystemTables.h @@ -0,0 +1,92 @@ +/** + * @file + * + * Power Management Table declarations. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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 0x00000001 /* Skip step if set && cold reset */ +#define PM_EXEFLAGS_NOT_ON_S3 0x00000002 /* Skip step if S3 resume */ +#define PM_EXEFLAGS_SYSTEM_TASK 0x00000004 /* Future use */ +#define PM_EXEFLAGS_SERIAL_EXE 0x00000008 /* 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/f10/Proc/CPU/cpuRegisters.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuRegisters.h new file mode 100755 index 0000000000..6a280871a1 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuRegisters.h @@ -0,0 +1,359 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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 + * + *--------------------------------------------------------------- + */ + +#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 0x80000001 // Family Model Features information +#define AMD_CPUID_APICID_LPC_BID 0x00000001 // Local APIC ID, Logical Processor Count, Brand ID +#define AMD_CPUID_L2L3Cache_L2TLB 0x80000006 +#define AMD_CPUID_TLB_L1Cache 0x80000005 +#define AMD_CPUID_APM 0x80000007 +#define LOCAL_APIC_ID 24 +#define LOGICAL_PROCESSOR_COUNT 16 +#define AMD_CPUID_ASIZE_PCCOUNT 0x80000008 // 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 0x00000100 // bit 8 for MCG_CTL_P under MSRR +#define MSR_MCG_CAP 0x00000179 +#define MSR_MC0_CTL 0x00000400 + +#define MSR_APIC_BAR 0x0000001B +#define MSR_PATCH_LEVEL 0x0000008B + +#define CPUID_LONG_MODE_ADDR 0x80000008 +#define AMD_CPUID_FMF 0x80000001 + +#define MSR_EXTENDED_FEATURE_EN 0xC0000080 +#define MSR_MC_MISC_LINK_THRESHOLD 0xC0000408 +#define MSR_MC_MISC_L3_THRESHOLD 0xC0000409 +#define MSR_PATCH_LOADER 0xC0010020 + +/// 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 0xC0010010 // SYSCFG +#define MSR_TOM2 0xC001001D // TOP_MEM2 +#define MSR_MC4_CTL_MASK 0xC0010048 // MC4 Control Mask + +#define MSR_CPUID_FEATS 0xC0011004 // CPUID Features +#define MSR_CPUID_EXT_FEATS 0xC0011005 // CPUID Extended Features +#define MSR_HWCR 0xC0010015 +#define MSR_NB_CFG 0xC001001F // NB Config +#define ENABLE_CF8_EXT_CFG 0x00004000 // [46] +#define INIT_APIC_CPUID_LO 0x00400000 // [54] +#define MSR_LS_CFG 0xC0011020 +#define MSR_IC_CFG 0xC0011021 // ICache Config +#define MSR_DC_CFG 0xC0011022 +#define MSR_BU_CFG 0xC0011023 +#define MSR_DE_CFG 0xC0011029 +#define MSR_BU_CFG2 0xC001102A +#define MSR_BU_CFG3 0xC001102B +#define MSR_IBS_OP_DATA3 0xC0011037 +#define MSR_CPUID_NAME_STRING0 0xC0010030 // First CPUID namestring register +#define MSR_CPUID_NAME_STRING1 0xC0010031 +#define MSR_CPUID_NAME_STRING2 0XC0010032 +#define MSR_CPUID_NAME_STRING3 0xC0010033 +#define MSR_CPUID_NAME_STRING4 0xC0010034 +#define MSR_CPUID_NAME_STRING5 0xC0010035 // Last CPUID namestring register +#define MSR_MMIO_Cfg_Base 0xC0010058 // MMIO Configuration Base Address Register +#define MSR_BIST 0xC0010060 // BIST Results register +#define MSR_OSVW_ID_Length 0xC0010140 +#define MSR_OSVW_Status 0xC0010141 +#define MSR_PERF_CONTROL3 0xC0010003 // Perfromance control register number 3 +#define MSR_PERF_COUNTER3 0xC0010007 // Performance counter register number 3 +#define PERF_RESERVE_BIT_MASK 0x030FFFDFFFFFull // Mask of the Performance control Reserve bits +#define PERF_CAR_CORRUPTION_EVENT 0x040040F0E2ull // 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_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 HI_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 0x00000020 // [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 0x00000001 // [0] = CPU2 Enable +#define ECS_HT_TRANS_CTRL_CPU3_EN 0x00000002 // [1] = CPU3 Enable +#define ECS_HT_TRANS_CTRL_CPU4_EN 0x00000004 // [2] = CPU4 Enable +#define ECS_HT_TRANS_CTRL_CPU5_EN 0x00000008 // [3] = CPU5 Enable + +// 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 MULTI_NODE_CPU 29 +#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 0xE00001FF +#define HTPHY_WRITE_CMD 0x40000000 +#define HTPHY_IS_COMPLETE_MASK 0x80000000 +#define HTPHY_DIRECT_MAP 0x20000000 +#define HTPHY_DIRECT_OFFSET_MASK 0xE000FFFF + +// Misc. defines. +#define PCI_DEV_BASE 24 + +#define CPU_STEPPING 0x0000000F +#define CPU_MODEL 0x000000F0 +#define CPU_EMODEL 0x000F0000 +#define CPU_EFAMILY 0x00F00000 +#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 SOCKET_IGNORE 0xF + +#define LAPIC_BASE_ADDR_MASK 0x0000FFFFFFFFF000ull +#define APIC_EXT_BRDCST_MASK 0x000E0000 +#define APIC_ENABLE_BIT 0x00000800 +#define LOCAL_APIC_ADDR 0xFEE00000 +#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 CMD_REG_TO_READ_DATA 0x338 + +#define MAX_CORE_ID_SIZE 8 +#define MAX_CORE_ID_MASK ((1 << MAX_CORE_ID_SIZE) - 1) + +/*------------------------- + * Default definitions + *------------------------- + */ +#define DOWNCORE_MASK_SINGLE 0x3E +#define DOWNCORE_MASK_DUAL 0x3C +#define DOWNCORE_MASK_TRI 0x38 +#define DOWNCORE_MASK_FOUR 0x30 +#define DOWNCORE_MASK_FIVE 0x20 + +#define DELIVERY_STATUS BIT13 +#define REMOTE_READ_STAT_MASK 0x00030000 +#define REMOTE_DELIVERY_PENDING 0x00010000 +#define REMOTE_DELIVERY_DONE 0x00020000 + +/* + * -------------------------------------------------------------------------------------- + * + * 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; + +typedef struct { + UINT16 Limit; ///< Interrupt Descriptor Table size + UINT64 Base; ///< Interrupt Descriptor Table base address +} IDT_BASE_LIMIT; + + +#endif // _CPU_REGISTERS_H_ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuServices.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuServices.h new file mode 100755 index 0000000000..2eba7b7d52 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuServices.h @@ -0,0 +1,256 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#ifndef _CPU_SERVICES_H_ +#define _CPU_SERVICES_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 + *---------------------------------------------------------------------------------------- + */ +//---------------------------------------------------------------------------- +// 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 +typedef struct _WARM_RESET_REQUEST { + UINT8 RequestBit:1; ///< Request Bit + UINT8 StateBits:2; ///< State Bits + UINT8 Reserved:(8-3); ///< 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 + ); + +/** + * Writes to all nodes on the executing core's socket. + * + */ +VOID +ModifyCurrentSocketPci ( + IN PCI_ADDR *PciAddress, + IN UINT32 Mask, + IN UINT32 Data, + 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 + ); + +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 + ); + +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 + ); + +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 + ); + +#endif // _CPU_SERVICES_H_ diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuWarmReset.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuWarmReset.c new file mode 100755 index 0000000000..af4cb1b0e7 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/cpuWarmReset.c @@ -0,0 +1,188 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "cpuRegisters.h" +#include "cpuServices.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#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 (&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 (&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, Request); +} +/*---------------------------------------------------------------------------------------- + * 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 (&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, &Request); + + if (Request.StateBits >= PostStage) { + WarmReset = TRUE; + } else { + WarmReset = FALSE; + } + + return WarmReset; +} + +/*---------------------------------------------------------------------------------------- + * L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/heapManager.c b/src/vendorcode/amd/agesa/f10/Proc/CPU/heapManager.c new file mode 100755 index 0000000000..b5be972444 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/heapManager.c @@ -0,0 +1,593 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h" +#include "cpuRegisters.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "heapManager.h" +#include "cpuCacheInit.h" +#include "cpuFamilyTranslation.h" +#include "Filecode.h" +#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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +extern BUILD_OPT_CFG UserOptions; + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 (always succeeds) + * + */ +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; + UINT8 *HeapBufferPtr; + UINT32 *HeapDataPtr; + UINT64 MsrData; + UINT8 Ignored; + CACHE_INFO *CacheInfoPtr; + AGESA_STATUS IgnoredSts; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + + GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); + FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **)&CacheInfoPtr, &Ignored, StdHeader); + + if (!IsBsp (StdHeader, &IgnoredSts)) { + // APs must transfer their system core number from the mailbox to + // a local register while it is still valid. + FamilySpecificServices->TransferApCoreNumber (FamilySpecificServices, StdHeader); + } + + HeapBufferPtr = (UINT8 *) HeapGetCurrentBase (StdHeader); + // 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 & 0xFFFFFFFFFFFFFF00ull) == (UINT32) HeapBufferPtr) { + // 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 = (UINT32) HeapBufferPtr; + MsrData |= 0x06; + LibAmdMsrWrite (AMD_MTRR_VARIABLE_HEAP_BASE, &MsrData, StdHeader); + MsrData = CacheInfoPtr->VariableMtrrMask & AMD_HEAP_MTRR_MASK; + LibAmdMsrWrite (AMD_MTRR_VARIABLE_HEAP_MASK, &MsrData, 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 + HeapDataPtr = (UINT32 *) HeapBufferPtr; + for (HeapAlreadyInitSizeDword = 0; HeapAlreadyInitSizeDword < AMD_HEAP_SIZE_DWORD_PER_CORE; HeapAlreadyInitSizeDword++) { + *HeapDataPtr = 0; + HeapDataPtr++; + } + + // Save size of heap (which is contiguous right now) for later use + // Note: We are reserving the first 16 bytes for Heap Manager use + ((HEAP_MANAGER*) HeapBufferPtr)->AvailableSize = (AMD_HEAP_SIZE_PER_CORE - sizeof (HEAP_MANAGER)); + + 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 determines 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] AllocateHeapParamsPtr Structure 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 + * + */ +AGESA_STATUS +HeapAllocateBuffer ( + IN OUT ALLOCATE_HEAP_PARAMS *AllocateHeapParamsPtr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *HeapBufferPtr; + UINT8 *StartOfBufferPtr; + HEAP_MANAGER *HeapManagerPtr; + BUFFER_NODE *HeadNodePtr; + BUFFER_NODE *CurrentNodePtr; + BUFFER_NODE *NextNodePtr; + AGESA_BUFFER_PARAMS AgesaBuffer; + UINT32 AmdHeapRamAddress; + + AmdHeapRamAddress = (UINT32) UserOptions.CfgHeapDramAddress; + + // Buffer pointer is NULL unless we return a buffer. + AllocateHeapParamsPtr->BufferPtr = NULL; + + // check to see where the heap is + if (StdHeader->HeapStatus == HEAP_LOCAL_CACHE) { + HeapBufferPtr = (UINT8 *) HeapGetCurrentBase (StdHeader); + } else if (StdHeader->HeapStatus == HEAP_TEMP_MEM) { + HeapBufferPtr = (UINT8 *) AmdHeapRamAddress; + } else if (StdHeader->HeapStatus == HEAP_SYSTEM_MEM) { + AgesaBuffer.StdHeader = *StdHeader; + AgesaBuffer.BufferHandle = AllocateHeapParamsPtr->BufferHandle; + AgesaBuffer.BufferLength = AllocateHeapParamsPtr->RequestedBufferSize; + + AGESA_TESTPOINT (TpIfBeforeAllocateHeapBuffer, StdHeader); + if (AgesaAllocateBuffer (0, &AgesaBuffer) != AGESA_SUCCESS) { + AllocateHeapParamsPtr->BufferPtr = NULL; + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpIfAfterAllocateHeapBuffer, StdHeader); + + AllocateHeapParamsPtr->BufferPtr = (UINT8 *) (AgesaBuffer.BufferPointer); + return AGESA_SUCCESS; + } else if (StdHeader->HeapStatus == HEAP_S3_RESUME) { + HeapBufferPtr = (UINT8 *)(UINT32) StdHeader->HeapBasePtr; + } else { + AllocateHeapParamsPtr->BufferPtr = NULL; + // Heap buffer is not present. + return AGESA_BOUNDS_CHK; + } + + HeapManagerPtr = (HEAP_MANAGER *) HeapBufferPtr; + StartOfBufferPtr = HeapBufferPtr + sizeof (HEAP_MANAGER); + HeadNodePtr = (BUFFER_NODE *) StartOfBufferPtr; + CurrentNodePtr = HeadNodePtr; + + // Check if we can allocate space + if (AllocateHeapParamsPtr->RequestedBufferSize > (HeapManagerPtr->AvailableSize - sizeof (BUFFER_NODE) - 2 * SIZE_OF_SENTINEL)) { + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_IS_FULL, + AllocateHeapParamsPtr->BufferHandle, 0, 0, 0, StdHeader); + return AGESA_BOUNDS_CHK; + } + + if (HeadNodePtr->BufferSize == 0) { + NextNodePtr = CurrentNodePtr; + } else { + // locate the last heap, but if there already has been a heap with the incoming BufferHandle, we return AGESA_BOUNDS_CHK. + while (CurrentNodePtr->NextNodePtr != NULL) { + if (CurrentNodePtr->BufferHandle == AllocateHeapParamsPtr->BufferHandle) { + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_BUFFER_HANDLE_IS_ALREADY_USED, + AllocateHeapParamsPtr->BufferHandle, 0, 0, 0, StdHeader); + return AGESA_BOUNDS_CHK; + } + if (StdHeader->HeapStatus == HEAP_S3_RESUME) { + HeapBufferPtr = (UINT8 *) CurrentNodePtr; + CurrentNodePtr = (BUFFER_NODE *) &HeapBufferPtr[CurrentNodePtr->BufferSize + sizeof (BUFFER_NODE) + (2 * SIZE_OF_SENTINEL)]; + } else { + CurrentNodePtr = CurrentNodePtr->NextNodePtr; + } + } + if (CurrentNodePtr->BufferHandle == AllocateHeapParamsPtr->BufferHandle) { + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_BUFFER_HANDLE_IS_ALREADY_USED, + AllocateHeapParamsPtr->BufferHandle, 0, 0, 0, StdHeader); + return AGESA_BOUNDS_CHK; + } + + // Create a new node and link it with previous node + CurrentNodePtr->NextNodePtr = (BUFFER_NODE *) + (((UINT8 *) CurrentNodePtr) + + sizeof (BUFFER_NODE) + + CurrentNodePtr->BufferSize + + 2 * SIZE_OF_SENTINEL); + NextNodePtr = CurrentNodePtr->NextNodePtr; + } + NextNodePtr->BufferSize = AllocateHeapParamsPtr->RequestedBufferSize; + NextNodePtr->NextNodePtr = NULL; + NextNodePtr->BufferHandle = AllocateHeapParamsPtr->BufferHandle; + + // Debug feature + SET_SENTINEL_BEFORE (NextNodePtr); + SET_SENTINEL_AFTER (NextNodePtr); + + // Persist + if ((AllocateHeapParamsPtr->Persist == HEAP_TEMP_MEM) || (AllocateHeapParamsPtr->Persist == HEAP_SYSTEM_MEM)) { + NextNodePtr->Persist = AllocateHeapParamsPtr->Persist; + } else { + NextNodePtr->Persist = HEAP_LOCAL_CACHE; + } + + // Update global variables + HeapManagerPtr->AvailableSize -= NextNodePtr->BufferSize + sizeof (BUFFER_NODE) + 2 * SIZE_OF_SENTINEL; + + // Now fill in the incoming structure + AllocateHeapParamsPtr->BufferPtr = (UINT8 *) ((UINT8 *) NextNodePtr + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL); + Heap_Check (StdHeader); + + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * Deallocates a previously allocated buffer in the heap + * + * This function finds the buffer to deallocate, defragments the remaining + * heap, clears the new remainder, and updates the size of the heap. + * + * @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 + ) +{ + UINT16 AboveDeallocationHeapSize; + UINT16 DeallocationHeapSize; + UINT16 BelowDeallocationHeapSize; + UINT16 i; + UINT8 *HeapBufferPtr; + UINT8 *HeapDataPtr1; + UINT8 *HeapDataPtr2; + HEAP_MANAGER *HeapManagerPtr; + BUFFER_NODE *HeadNodePtr; + BUFFER_NODE *PreviousNodePtr; + BUFFER_NODE *CurrentNodePtr; + BUFFER_NODE *NextNodePtr; + AGESA_BUFFER_PARAMS AgesaBuffer; + UINT32 AmdHeapRamAddress; + + AmdHeapRamAddress = (UINT32) UserOptions.CfgHeapDramAddress; + + AboveDeallocationHeapSize = 0; + + // Step 1: locate the heap which is expected to be deallocated. + if (StdHeader->HeapStatus == HEAP_LOCAL_CACHE) { + HeapBufferPtr = (UINT8 *) HeapGetCurrentBase (StdHeader); + } else if (StdHeader->HeapStatus == HEAP_TEMP_MEM) { + HeapBufferPtr = (UINT8 *) AmdHeapRamAddress; + } else 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; + } else { + // Heap buffer is not present. + IDS_ERROR_TRAP; + return AGESA_BOUNDS_CHK; + } + + HeapManagerPtr = (HEAP_MANAGER *) HeapBufferPtr; + HeadNodePtr = (BUFFER_NODE *) ((HeapBufferPtr + sizeof (HEAP_MANAGER))); + CurrentNodePtr = HeadNodePtr; + PreviousNodePtr = CurrentNodePtr; + + while (CurrentNodePtr->BufferHandle != BufferHandle) { + AboveDeallocationHeapSize += (CurrentNodePtr->BufferSize) + sizeof (BUFFER_NODE) + 2 * SIZE_OF_SENTINEL; + PreviousNodePtr = CurrentNodePtr; + if (CurrentNodePtr->NextNodePtr == NULL) { + // If we are at the end of the heap and still unable to locate the buffer handle, return AGESA_BOUNDS_CHK + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_BUFFER_HANDLE_IS_NOT_PRESENT, + BufferHandle, 0, 0, 0, StdHeader); + return AGESA_BOUNDS_CHK; + } else { + CurrentNodePtr = CurrentNodePtr->NextNodePtr; + } + } + + // Step 2: defragment + + // Before: + // ------------------------ <- UINT8 * HeapBufferPtr + // | Heap Manager 16 Bytes| + // ------------------------ --- + // | Heap 1 | AboveDeallocationHeapSize + // | | + // ------------------------ --- + // | Heap 2 | <- Deallocate + // | | DeallocationHeapSize + // ------------------------ --- + // | Heap 3 | BelowDeallocationHeapSize + // | | + // ------------------------ --- + // | Unused | UnusedSize = HeapManagerPtr->AvailableSize + // ------------------------ --- + // After deallocating: shift all subsequent heap buffers up + // ------------------------ + // | Heap Manager 16 Bytes| + // ------------------------ + // | Heap 1 | + // | | + // ------------------------ + // | Heap 3 | + // | | + // ------------------------ + // | | + // | | + // | Unused | + // ------------------------ + DeallocationHeapSize = (CurrentNodePtr->BufferSize) + sizeof (BUFFER_NODE) + 2 * SIZE_OF_SENTINEL; + BelowDeallocationHeapSize = AMD_HEAP_SIZE_PER_CORE - sizeof (HEAP_MANAGER) + - HeapManagerPtr->AvailableSize + - AboveDeallocationHeapSize + - DeallocationHeapSize; + HeapDataPtr1 = (UINT8 *) CurrentNodePtr; + + // if this is the last Heap, then PreviousNodePtr->NextNodePtr = NULL and return + if (CurrentNodePtr->NextNodePtr == NULL) { + PreviousNodePtr->NextNodePtr = NULL; + } else { + HeapDataPtr2 = (UINT8 *) (CurrentNodePtr->NextNodePtr); + // subtract DeallocationHeapSize from all subsequent NextNodePtr + CurrentNodePtr = CurrentNodePtr->NextNodePtr; + while (CurrentNodePtr->NextNodePtr != NULL) { + NextNodePtr = CurrentNodePtr->NextNodePtr; + CurrentNodePtr->NextNodePtr = (BUFFER_NODE *) ((UINT8 *) (CurrentNodePtr->NextNodePtr) - DeallocationHeapSize); + CurrentNodePtr = NextNodePtr; + } + // shift subsequent heap buffers up + for (i = 0; i < BelowDeallocationHeapSize; i++) { + *HeapDataPtr1 = *HeapDataPtr2; + HeapDataPtr1++; + HeapDataPtr2++; + } + } + + // Step 3: clear remainder useless data + LibAmdMemFill (HeapDataPtr1, 0, DeallocationHeapSize, StdHeader); + + // Step 4: update unused size + HeapManagerPtr->AvailableSize = HeapManagerPtr->AvailableSize + DeallocationHeapSize; + return AGESA_SUCCESS; +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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] LocateHeapPtr 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 *LocateHeapPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 *HeapBufferPtr; + UINT8 *StartOfBufferPtr; + HEAP_MANAGER *HeapManagerPtr; + BUFFER_NODE *HeadNodePtr; + BUFFER_NODE *CurrentNodePtr; + BOOLEAN BufferHandleFlag; + AGESA_BUFFER_PARAMS AgesaBuffer; + UINT32 AmdHeapRamAddress; + + AmdHeapRamAddress = (UINT32) UserOptions.CfgHeapDramAddress; + + ASSERT (StdHeader != NULL); + + BufferHandleFlag = TRUE; + + if (StdHeader->HeapStatus == HEAP_LOCAL_CACHE) { + HeapBufferPtr = (UINT8 *) HeapGetCurrentBase (StdHeader); + } else if (StdHeader->HeapStatus == HEAP_TEMP_MEM) { + HeapBufferPtr = (UINT8 *) AmdHeapRamAddress; + } else if (StdHeader->HeapStatus == HEAP_SYSTEM_MEM) { + AgesaBuffer.StdHeader = *StdHeader; + AgesaBuffer.BufferHandle = LocateHeapPtr->BufferHandle; + + AGESA_TESTPOINT (TpIfBeforeLocateHeapBuffer, StdHeader); + if (AgesaLocateBuffer (0, &AgesaBuffer) != AGESA_SUCCESS) { + LocateHeapPtr->BufferPtr = NULL; + return AGESA_ERROR; + } + AGESA_TESTPOINT (TpIfAfterLocateHeapBuffer, StdHeader); + + LocateHeapPtr->BufferPtr = (UINT8 *) (AgesaBuffer.BufferPointer); + return AGESA_SUCCESS; + } else if (StdHeader->HeapStatus == HEAP_S3_RESUME) { + HeapBufferPtr = (UINT8 *) (UINT32) StdHeader->HeapBasePtr; + } else { + return AGESA_BOUNDS_CHK; + } + + HeapManagerPtr = (HEAP_MANAGER *) HeapBufferPtr; + StartOfBufferPtr = HeapBufferPtr + sizeof (HEAP_MANAGER); + HeadNodePtr = (BUFFER_NODE *) StartOfBufferPtr; + CurrentNodePtr = HeadNodePtr; + + while (CurrentNodePtr->BufferHandle != LocateHeapPtr->BufferHandle) { + if (CurrentNodePtr->NextNodePtr == NULL) { + BufferHandleFlag = FALSE; + break; + } else { + if (StdHeader->HeapStatus == HEAP_S3_RESUME) { + HeapBufferPtr = (UINT8 *) CurrentNodePtr; + CurrentNodePtr = (BUFFER_NODE *) &HeapBufferPtr[CurrentNodePtr->BufferSize + sizeof (BUFFER_NODE) + (2 * SIZE_OF_SENTINEL)]; + } else { + CurrentNodePtr = CurrentNodePtr->NextNodePtr; + } + } + } + + if (BufferHandleFlag) { + LocateHeapPtr->BufferPtr = (UINT8 *) ((UINT8 *) CurrentNodePtr + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL); + return AGESA_SUCCESS; + } else { + LocateHeapPtr->BufferPtr = NULL; + PutEventLog (AGESA_BOUNDS_CHK, + CPU_ERROR_HEAP_BUFFER_HANDLE_IS_NOT_PRESENT, + LocateHeapPtr->BufferHandle, 0, 0, 0, StdHeader); + return AGESA_BOUNDS_CHK; + } +} + + +/*---------------------------------------------------------------------------------------*/ +/** + * 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. + * + */ +VOID * +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 (&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 ((VOID *) (UINT32) ReturnPtr); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/CPU/heapManager.h b/src/vendorcode/amd/agesa/f10/Proc/CPU/heapManager.h new file mode 100755 index 0000000000..81f784ccb0 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/CPU/heapManager.h @@ -0,0 +1,221 @@ +/** + * @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: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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. + * + ****************************************************************************** + */ + +#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_END_OF_NODE 0x5F4F4E45 // _EON - END OF NODE +#define AMD_MTRR_VARIABLE_HEAP_BASE 0x20A +#define AMD_MTRR_VARIABLE_HEAP_MASK (AMD_MTRR_VARIABLE_HEAP_BASE + 1) + +#define AMD_HEAP_START_ADDRESS 0x400000 +#define AMD_HEAP_REGION_END_ADDRESS 0xBFFFFF +#define AMD_HEAP_SIZE_PER_CORE 0x010000 +#define AMD_HEAP_MTRR_MASK (((0xFFFFFFFFFFFFF800ull & ((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 0x20000000 // Set TOM to 512 MB (temporary value) +#define AMD_VAR_MTRR_ENABLE_BIT 0x100000 // bit 20 + +#define AMD_HEAP_RAM_ADDRESS 0xB0000 +#define AMD_HEAP_COPY_SIZE_DWORD AMD_HEAP_SIZE_PER_CORE / 4 + +#define MAX_CORES_PER_CPU 16 + +///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 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_FIX16K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull +#define AMD_MTRR_FIX16K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull +#define AMD_MTRR_FIX4K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull +#define AMD_MTRR_FIX4K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull + +/*--------------------------------------------------------------------------------------- + * 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 { + IN UINT16 RequestedBufferSize; ///< Size of buffer. + IN UINT32 BufferHandle; ///< An unique ID of buffer. + UINT8 Persist; ///< A flag. If marked, to be stored and passed to AmdInitLate. + OUT UINT8 *BufferPtr; ///< Pointer to buffer. +} ALLOCATE_HEAP_PARAMS; + +/// Locate Heap Parameters +typedef struct _LOCATE_HEAP_PTR { + UINT32 BufferHandle; ///< An unique ID of buffer. + UINT8 *BufferPtr; ///< Pointer to buffer. +} LOCATE_HEAP_PTR; + +/// Heap Node Header +typedef struct _BUFFER_NODE { + UINT32 BufferHandle; ///< An unique ID of buffer. + UINT16 BufferSize; ///< Size of buffer. + UINT8 Persist; ///< A flag. If marked, to be stored and passed to AmdInitLate. + struct _BUFFER_NODE *NextNodePtr; ///< Pointer to next Node. +} BUFFER_NODE; + +/// Heap Manager +typedef struct _HEAP_MANAGER { + UINT16 AvailableSize; ///< Available size of heap. + UINT16 Reserved1; ///< This space is reserved for future use. + UINT32 Reserved2; ///< This space is reserved for future use. + UINT64 Reserved3; ///< This space is reserved for future use. +} 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_UMA_INFO_HANDLE, ///< Assign 0x000A014 buffer handle to be used for Uma information + AMD_DMI_MEM_DEV_INFO_HANDLE, ///< Assign 0x000A015 buffer handle to DMI Type16 17 19 20 information + HT_STATE_DATA_HANDLE, ///< Assign 0x000A016 buffer handle to HT State Data + PRESERVE_MAIL_BOX_HANDLE, ///< Assign 0x000A017 buffer handle for Preserve Mailbox Feature. + EVENT_LOG_BUFFER_HANDLE, ///< Assign 0x000A018 buffer handle to Event Log + IDS_CONTROL_HANDLE, ///< Assign 0x000A019 buffer handle to AmdIds routine. + IDS_HT_DATA_HANDLE, ///< Assign 0x000A01A buffer handle to Ht IDS control + IDS_HDT_OUT_BUFFER_HANDLE, ///< Assign 0x000A01B buffer handle to be used for HDTOUT support. + IDS_CHECK_POINT_PERF_HANDLE, ///< Assign 0x000A01C buffer handle to Performance analysis + IDS_GRA_HANDLE, ///< Assign 0x000A01D buffer handle to be used for GRA support + AMD_PCIE_COMPLEX_DATA_HANDLE, ///< Assign 0x000A01E buffer handle to be used for PCIe support + AMD_GNB_SMU_CONFIG_HANDLE, ///< Assign 0x000A01F buffer handle to be used for GNB SMU configuration + AMD_PP_FUSE_TABLE_HANDLE, ///< Assign 0x000A020 buffer handle to be used for TT fuse table + AMD_GFX_PLATFORM_CONFIG_HANDLE, ///< Assign 0x000A021 buffer handle to be used for Gfx platform configuration + 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' + LOCAL_AP_MAIL_BOX_CACHE_HANDLE = 0x414D4258 ///< 'ambx' +} 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 *AllocateHeapParamsPtr, + 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 *LocateHeapPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +VOID * +HeapGetCurrentBase ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +EventLogInitialization ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +#endif // _HEAP_MANAGER_H_ |