From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on062d.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe42::62d]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id EE15C81DD6 for ; Fri, 28 Oct 2016 10:39:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=gcbBXVreEtygBT23BD/EH50bjYI+f52Wf29hz9MJULA=; b=ls2AiM1b+4zIMKAhkaPyCfsy+A5Ok7GHKy4VdaVjPivjck3FfDqi5ZityNTEo9wXcRT3CPKszxEsAiMJZAdYPSeuvO66kxlmzaob7+SQ++GoMLOQqjoU8mEQJhR3MAJsUyusA/p7a788vwImeX1D3R8JYq1hzE6kW4GyWnhqtyY= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=leo.duran@amd.com; Received: from leduran-Precision-WorkStation-T5400.amd.com (165.204.78.1) by MWHPR12MB1247.namprd12.prod.outlook.com (10.169.205.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.679.12; Fri, 28 Oct 2016 17:38:58 +0000 From: Leo Duran To: CC: , , , , Leo Duran Date: Fri, 28 Oct 2016 12:38:45 -0500 Message-ID: <1477676325-18717-1-git-send-email-leo.duran@amd.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 X-Originating-IP: [165.204.78.1] X-ClientProxiedBy: SN2PR17CA0003.namprd17.prod.outlook.com (10.169.188.141) To MWHPR12MB1247.namprd12.prod.outlook.com (10.169.205.7) X-MS-Office365-Filtering-Correlation-Id: b1788f87-63b5-487d-d88f-08d3ff594c79 X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1247; 2:wxNDetVIs6K6B7hC6vvKct3AQ/4EO1ORx8mUwJVNTKIPMGQmZlesPo5MarZvz6pO2kiGOEhe6D344zDVoIOBp1uPAs+UWZoChhGsrs92uxUMWK/23tt542/Pcyrbw11DQAGo/g5c1RsdVVeNdmtLk9EwT4vr90ISFSfqjs/s8/zDzjfogZxSo1+Xhr42J/vloFM8gCfPbaiPxtcv5l8AuQ==; 3:z31DKpiDOvIg+ejINolXuhPT0IsSJBR4fDkYKlGgYK4Z0QcveeyD5SbzC1+c62UF2em7XLKIW2Cqad9fJXJosdhrcC+fB9OMU1Wmcehj/bxlXNDykCUkonNM2vhDSXfd3Zqo+Jq0HutLmKs33MYnvw==; 25:FAPEenIjcmJ0WEcMY2spXGyCp06n09hOCkCT407wGV6i6k2lIVflf8MpCO+BtmRUpMiROzhG6ropdJVly/aRujMtG1AcfZGS2Mb6Z/IjdrF7L/RQrAbPZlqxl+pqWmkYcxHTvhoHSQmRFoi0JSk65j2NwnaLVOkDMZzF7Xw93mLc6qxuoz7mpkwcO+SmXWPAmPzY4rZz1GtUBe++p+qJt7xIqBAqYRxBjXDiDwU3pV0cdbb0O8DC97kEfwaCKdysaOq8e28HvUpVgoh7tGDFc34l8mQ9RhXE7ERt9NUIeL33hIKRtxhqMX6Tm6MiI3kYEJeh4L7lXf8B2bEkoy6qR6YgeRVwL+v+Js8xFxZ2TdK1KoDgcaLdzYqq/483baMEzckxYlRx+71P+ATipmak6STGrpOzGDkTL2qZqQQXNG0KvuACCS9Ozu16ExkEjXeI X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:MWHPR12MB1247; X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1247; 31:+8jHd3LDhUISlzw7yReGlnHbV70wyMjAqAEWbnfuAwl8AoywN/465dsADyjDM6XA71OapCo0mPhDr1BaGtUoTCT8suBmyUcq8LeQa6JcQeV1apwM8jWAjXjpDq5EUDx9O95SaiPG1xpan+2xTkgsC0bEGuouKcbwDf3ztapFjm5P2hyVrSRGvZLi/jAH2lFjMtKy04HoMKF24uOUJYlY4ED7MhwQFOlDqKn3Elk/LzNqqAfNhh0FKXhsiuxL7UyJ; 20:ifNz9G2VNFoKf72XwfdZoNEJvMCHpNxJjyk5Aset30kdidqsNiZOPOuJ0Z0G5ClO+YpyJ/ClHsFXCjtbk4orTI/prAACKb8hGjoAi7EuWnHr0WM1ws1qIcXKaOo/T9rSlkEcVUuimedFmBphmGLAPdPYykSWDK6zqhu2D8/CRWjCEpI/O+BG2dYeDYz6KMAvjDEBXM/ugcBqkTPaTRqhI8o2r1jlkY0c84VZX7URKR7d70tExuyeyBExA1FVYykIfRs+fz6YRcDRvQoEO6Qv5+FyGzxzRDjC5O7/ZDeYjFGDFOg2matNWm11Sk/jHrLFmYqWUfaK6Mdn8QJfTQiiPVLQPrMPq02K4kPXTTsmZE0L07/aSf3q7nGwpLo4U9TKanJqFNLoiICbvEWUOVW6nf6m5OY/S6pL1Rvys7AMQL82mNI/OkeQDednjBHFsGZO4v2sjEca1akU2yGPioPttjEaJRX+PYdT0JsWaCfpF3F3eOyrO8Nv8YLGsZ6b2Lnr X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026); SRVR:MWHPR12MB1247; BCL:0; PCL:0; RULEID:; SRVR:MWHPR12MB1247; X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1247; 4:ndbN3j+X5njvQjdsca4wAGuJBexSdrLsv8xdjt+kPSN/gLAHaGCbmYxC3F19HWveKAM3irSokZsEro/h8vpBhQwVOvMC+ddhLltoCxjMzdgO7FL9k+JdzCZqOJzMxkq/maqPZbzeqgGK0KvYF91LgBgjHYlD5qtuIwCNS5i2lx0vuZtOIWgVEiycso+XmNKSYX7bkT7gBVrJlFZetf7cvJka8EUVgMeeKBhxMGuwJ1N8CQghJhwrNXiCJ2MFtQH5/zqW9lDyxPhf0lr0DuZ8oQZaNux4cCzvFVm5LjmyflM5Mnp+psawFxQZy/FH/c1TADxivpRJ5z/gfqWTbOydO52cDLmeD3Mz/HdR51Mnryl/v15DxxQgX4x5w3uWClt16JqOAHbr+wUOFIWtvctKMMYLvjdqUVAZfMFXHjBXZ6ZWnoCIf7+noQxHjvEUdAn1+VsvhBItl5K/aoxuAWBb4g== X-Forefront-PRVS: 0109D382B0 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(189002)(199003)(2351001)(229853001)(106356001)(53416004)(5003940100001)(42186005)(50226002)(189998001)(6666003)(105586002)(305945005)(4326007)(48376002)(47776003)(575784001)(7736002)(68736007)(50466002)(86362001)(97736004)(19580405001)(19580395003)(81166006)(81156014)(6916009)(3846002)(6116002)(7846002)(586003)(92566002)(101416001)(33646002)(36756003)(5660300001)(8676002)(2906002)(77096005)(50986999)(66066001)(110136003)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR12MB1247; H:leduran-Precision-WorkStation-T5400.amd.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; MWHPR12MB1247; 23:oKtUTL5Wjy+IJoXxqB9zSC2yBiOkdnOnvcmZvhx/N?= =?us-ascii?Q?XM3FV+GCHoW9Ji12tr/+/DqaeeI8rqCWzZoUY5QrY8SW/RYZzuB7UDAKgAkJ?= =?us-ascii?Q?I47rt6RlHnrADYB7rF4iC09/+f2z+Coqa56aMgjChZ2Sp0A3emCLacD5A0qK?= =?us-ascii?Q?wII/PkmE4ozvXGUzskdNUz9bvLrDBUd5rEe/uly/+jmzXIzJ6+SNwmRoAzCM?= =?us-ascii?Q?y6biosSRWq9cXKDYb7t8mONgg0bCyTlaqjsowJ1Wyo6ipIdrpAX/AoWDmwf1?= =?us-ascii?Q?fUAPws5vPOx9ODQ6kT1K+2sonvUOnSuFRLQMk4ufAWjqBqNkMCO82dqc/kRz?= =?us-ascii?Q?Mt1JBltYi62gv53ImBpxIVRQjqwutTFsuRFxR8717ib+pyzZ0q4O281UzV8I?= =?us-ascii?Q?IpXNcNBpZ7fDvFaoUoqeninVV96Yb7zfhXvEo19yq064fy3t9D/X906Q4G7n?= =?us-ascii?Q?Xp9dvVPtt0XiGkmwbJ9xbnJpzSv6kTDN4/0Hl8DmC0wuWtOcgwhI1b2RUWB9?= =?us-ascii?Q?KnEIepP7nJRQTHJFU8KPCXvT6WNrjvJYvsHJpJl53eP8ykz5tN/5dSDrV7ff?= =?us-ascii?Q?llr2A0zohfOgGd5+S2CpMyE9qeobosPAg0Ja5vjenew1IzqfbRGuWICsd4qq?= =?us-ascii?Q?IV6Zbp3uN+RJAahpVOM7uBTPC4YmvzPR+y3bGObAmaVEqz5B/v96toAYhjd+?= =?us-ascii?Q?7GITLCkceVkLDqYv2XUrh2ApvwJ073+39kZ4z94baf96/ZhYuGI+i4wjWzdo?= =?us-ascii?Q?71KFLbmNvSnYFuoepxME2Lrb/FEHh75rdTgJFGequpfQKgAXtkF5Ps/3q2sn?= =?us-ascii?Q?tgY7dH0IwtZboZ9qcVuFIt1MgqENWpMx0XaykNao2BzWxBcBHQL/CSC/vIDR?= =?us-ascii?Q?K2jR8Tg5ubTWIBTkbw/OZz1G5jatZWntfrPL9pIaWzfX9kG7zOyThCwaToRo?= =?us-ascii?Q?UOg56i4+BeHi+HbSHyEuR2g/xSIgDt57905V61zX41+IjP194ViE214q5oh0?= =?us-ascii?Q?aYpg5Atvxr/MnSCCA2Xq1Q+6bdbBNlx/eABMl4AgVsAzFsqDDCiU2YlYSx+G?= =?us-ascii?Q?kE6j5UA0DgnH+5u16F7LvSANY3+k+BgyU9xewhpBN55KrLF2rAsIGJ/fYShv?= =?us-ascii?Q?2rVxGzOkAQfrV+tI6OLlidtAS9SpVxBzpOYBiqXZz5rZZI8rww0Tg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1247; 6:7u7j9NS3Z/haedWj6vDLHCcfCM4YHxDjsW+czK8SDebSKekwtQsNkmEHerupRA/mqC9/6MvPba2i9Lv7EGdnmN3jskEnDdWETaPTMCYEASCrSSTUkBJF8kv4LeRCJorJGEaV0/rkpeTIDaPYwlTBD8K+wCaoM8hOnpG3+QXpb6eiqrc7R4KA/6M3D4We7lsxhlRMn3+JIYQ6yUG1EN6P6OSEgB7TR1KIUKBfzAwcjYehMuKZnH+WpaX9XUX1y8rin1MpwxX7BlHjCaYv9NT5EmWwyE3191tWhQBcp3cG244bNjGEJKTXjG7Egczzq7M0WI45Zio5w22hoDpzhq9nO3coY59B/VkFDrhBOy2Xrhw=; 5:SdDtf58W1uktkTqepgsvzzn2EwgAlt63dzJXHoxHZ+Lhe5GXoe9y8r9rh8FrJ82yVXn0dLOEpmjAM5bRyoONzvHo5M9b7uy/ltf3f11Szou+BrU4dFbrLYpM6j6r0zmol482dScKQFVxdqzTQsRi3g==; 24:XK9DX0EoTbmmY1Zje1nVOYozMBDnXyIg3iYS1Nf08QxIAXiHeLmhDXrMym/6zMsmW1Ook6mbRZ3oKJBhNsBFHhJvCpZd05jyrwtEyj/eHkw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1247; 7:eGbfqzPj2nTXPGVzXzYQv/3G36T2BVqUOpexBRFEYa96rQQo2cbRNb6mH79mhe2Luqng76sBaZiEqJhF91OWDAeN9nju6ecQBrJJ4HkN8pbLvC4Afi8a1JtsawdNRlBgzyQ3FTD8P3kDB0DdogxVBLwcXHtm6dWKqi9g47SC+dC4cIYix7C1pkPW9b7v/D+DRGQlCpEMIFmMPc77NoUfQkefvGpAw1M46WpyJx42RMeTCGLEfiu7Ega1Q2ALkcdthSbpSjlGMuhZIkgCWK4xaaOURGF2p3xzY5o0+f3WiOF8iemnURUItHRAQSaLTPfkzQ3R21mN6DmemQQEpO4W3Xln78Ad+nxGZoDWjyiGOsE=; 20:4EdP6yhMr2WTxDJNiVKsXmmJe6hYB9u3Q/V6t6VhbwNaVI38mAH7LkPMsI6NmF8ydgo1ugGpSWB6/wZ9CFegBeW/fotIUSOxvdOs9L4Zo/5baIUFNvGxRnha21nViuXVvre6jfGF+VXRecSMQGVRs/hV6DLnCJfenz4eNjdgbuipA6SYsUV9KQjiK+DSL066Ye3YXyKoIQts1/0VxX2AJBol8BG9F6B/xFFBw3MLVKAQ9YsMkm2tu+vef00c6x4w X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Oct 2016 17:38:58.3782 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1247 Subject: [v3] UefiCpuPkg: Move GetProcessorLocation() to LocalApicLib library X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Oct 2016 17:39:01 -0000 Content-Type: text/plain 1) Remove SmmGetProcessorLocation() from PiSmmCpuDxeSmm driver. 2) Remove ExtractProcessorLocation() from MpInitLib library. 3) Add GetProcessorLocation() to BaseXApicLib and BaseXApicX2ApicLib. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Leo Duran --- UefiCpuPkg/Include/Library/LocalApicLib.h | 18 +++ UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 130 +++++++++++++++++++++ .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 130 +++++++++++++++++++++ UefiCpuPkg/Library/MpInitLib/MpLib.c | 128 +------------------- UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c | 121 +------------------ 5 files changed, 280 insertions(+), 247 deletions(-) diff --git a/UefiCpuPkg/Include/Library/LocalApicLib.h b/UefiCpuPkg/Include/Library/LocalApicLib.h index cd4e613..4abf64c 100644 --- a/UefiCpuPkg/Include/Library/LocalApicLib.h +++ b/UefiCpuPkg/Include/Library/LocalApicLib.h @@ -21,6 +21,9 @@ #define LOCAL_APIC_MODE_XAPIC 0x1 ///< xAPIC mode. #define LOCAL_APIC_MODE_X2APIC 0x2 ///< x2APIC mode. +#include +#include + /** Retrieve the base address of local APIC. @@ -410,6 +413,21 @@ GetApicMsiValue ( IN BOOLEAN LevelTriggered, IN BOOLEAN AssertionLevel ); + +/** +Get Package ID/Core ID/Thread ID of a processor. + +The algorithm assumes the target system has symmetry across physical package boundaries +with respect to the number of logical processors per package, number of cores per package. + +@param InitialApicId Must be the initial APIC ID of the target logical processor. +@param Location Returns the processor location information. +**/ +VOID +GetProcessorLocation( + IN UINT32 InitialApicId, + OUT EFI_CPU_PHYSICAL_LOCATION *Location +); #endif diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c index 8d0fb02..219f99f 100644 --- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c @@ -941,3 +941,133 @@ GetApicMsiValue ( } return MsiData.Uint64; } + +/** +Get Package ID/Core ID/Thread ID of a processor. + +The algorithm assumes the target system has symmetry across physical package boundaries +with respect to the number of logical processors per package, number of cores per package. + +@param InitialApicId Must be the initial APIC ID of the target logical processor. +@param Location Returns the processor location information. +**/ +VOID +GetProcessorLocation( +IN UINT32 InitialApicId, +OUT EFI_CPU_PHYSICAL_LOCATION *Location +) +{ + BOOLEAN TopologyLeafSupported; + UINTN ThreadBits; + UINTN CoreBits; + CPUID_VERSION_INFO_EBX VersionInfoEbx; + CPUID_VERSION_INFO_EDX VersionInfoEdx; + CPUID_CACHE_PARAMS_EAX CacheParamsEax; + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + UINT32 MaxCpuIdIndex; + UINT32 SubIndex; + UINTN LevelType; + UINT32 MaxLogicProcessorsPerPackage; + UINT32 MaxCoresPerPackage; + + // + // Check if the processor is capable of supporting more than one logical processor. + // + AsmCpuid(CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); + if (VersionInfoEdx.Bits.HTT == 0) { + Location->Thread = 0; + Location->Core = 0; + Location->Package = 0; + return; + } + + ThreadBits = 0; + CoreBits = 0; + + // + // Assume three-level mapping of APIC ID: Package:Core:SMT. + // + + TopologyLeafSupported = FALSE; + // + // Get the max index of basic CPUID + // + AsmCpuid(CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); + + // + // If the extended topology enumeration leaf is available, it + // is the preferred mechanism for enumerating topology. + // + if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { + AsmCpuidEx( + CPUID_EXTENDED_TOPOLOGY, + 0, + &ExtendedTopologyEax.Uint32, + &ExtendedTopologyEbx.Uint32, + &ExtendedTopologyEcx.Uint32, + NULL + ); + // + // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for + // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not + // supported on that processor. + // + if (ExtendedTopologyEbx.Uint32 != 0) { + TopologyLeafSupported = TRUE; + + // + // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract + // the SMT sub-field of x2APIC ID. + // + LevelType = ExtendedTopologyEcx.Bits.LevelType; + ASSERT(LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT); + ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift; + + // + // Software must not assume any "level type" encoding + // value to be related to any sub-leaf index, except sub-leaf 0. + // + SubIndex = 1; + do { + AsmCpuidEx( + CPUID_EXTENDED_TOPOLOGY, + SubIndex, + &ExtendedTopologyEax.Uint32, + NULL, + &ExtendedTopologyEcx.Uint32, + NULL + ); + LevelType = ExtendedTopologyEcx.Bits.LevelType; + if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) { + CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits; + break; + } + SubIndex++; + } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); + } + } + + if (!TopologyLeafSupported) { + AsmCpuid(CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL); + MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors; + if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) { + AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL); + MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1; + } + else { + // + // Must be a single-core processor. + // + MaxCoresPerPackage = 1; + } + + ThreadBits = (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1); + CoreBits = (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); + } + + Location->Thread = InitialApicId & ((1 << ThreadBits) - 1); + Location->Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); + Location->Package = (InitialApicId >> (ThreadBits + CoreBits)); +} diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c index 4c42696..16395a3 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c @@ -1036,3 +1036,133 @@ GetApicMsiValue ( } return MsiData.Uint64; } + +/** +Get Package ID/Core ID/Thread ID of a processor. + +The algorithm assumes the target system has symmetry across physical package boundaries +with respect to the number of logical processors per package, number of cores per package. + +@param InitialApicId Must be the initial APIC ID of the target logical processor. +@param Location Returns the processor location information. +**/ +VOID +GetProcessorLocation( +IN UINT32 InitialApicId, +OUT EFI_CPU_PHYSICAL_LOCATION *Location +) +{ + BOOLEAN TopologyLeafSupported; + UINTN ThreadBits; + UINTN CoreBits; + CPUID_VERSION_INFO_EBX VersionInfoEbx; + CPUID_VERSION_INFO_EDX VersionInfoEdx; + CPUID_CACHE_PARAMS_EAX CacheParamsEax; + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + UINT32 MaxCpuIdIndex; + UINT32 SubIndex; + UINTN LevelType; + UINT32 MaxLogicProcessorsPerPackage; + UINT32 MaxCoresPerPackage; + + // + // Check if the processor is capable of supporting more than one logical processor. + // + AsmCpuid(CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); + if (VersionInfoEdx.Bits.HTT == 0) { + Location->Thread = 0; + Location->Core = 0; + Location->Package = 0; + return; + } + + ThreadBits = 0; + CoreBits = 0; + + // + // Assume three-level mapping of APIC ID: Package:Core:SMT. + // + + TopologyLeafSupported = FALSE; + // + // Get the max index of basic CPUID + // + AsmCpuid(CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); + + // + // If the extended topology enumeration leaf is available, it + // is the preferred mechanism for enumerating topology. + // + if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { + AsmCpuidEx( + CPUID_EXTENDED_TOPOLOGY, + 0, + &ExtendedTopologyEax.Uint32, + &ExtendedTopologyEbx.Uint32, + &ExtendedTopologyEcx.Uint32, + NULL + ); + // + // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for + // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not + // supported on that processor. + // + if (ExtendedTopologyEbx.Uint32 != 0) { + TopologyLeafSupported = TRUE; + + // + // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract + // the SMT sub-field of x2APIC ID. + // + LevelType = ExtendedTopologyEcx.Bits.LevelType; + ASSERT(LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT); + ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift; + + // + // Software must not assume any "level type" encoding + // value to be related to any sub-leaf index, except sub-leaf 0. + // + SubIndex = 1; + do { + AsmCpuidEx( + CPUID_EXTENDED_TOPOLOGY, + SubIndex, + &ExtendedTopologyEax.Uint32, + NULL, + &ExtendedTopologyEcx.Uint32, + NULL + ); + LevelType = ExtendedTopologyEcx.Bits.LevelType; + if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) { + CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits; + break; + } + SubIndex++; + } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); + } + } + + if (!TopologyLeafSupported) { + AsmCpuid(CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL); + MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors; + if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) { + AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL); + MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1; + } + else { + // + // Must be a single-core processor. + // + MaxCoresPerPackage = 1; + } + + ThreadBits = (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1); + CoreBits = (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); + } + + Location->Thread = InitialApicId & ((1 << ThreadBits) - 1); + Location->Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); + Location->Package = (InitialApicId >> (ThreadBits + CoreBits)); +} diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index c3fe721..f3380bb 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -58,132 +58,6 @@ IsBspExecuteDisableEnabled ( } /** - Get CPU Package/Core/Thread location information. - - @param[in] InitialApicId CPU APIC ID - @param[out] Location Pointer to CPU location information -**/ -VOID -ExtractProcessorLocation ( - IN UINT32 InitialApicId, - OUT EFI_CPU_PHYSICAL_LOCATION *Location - ) -{ - BOOLEAN TopologyLeafSupported; - UINTN ThreadBits; - UINTN CoreBits; - CPUID_VERSION_INFO_EBX VersionInfoEbx; - CPUID_VERSION_INFO_EDX VersionInfoEdx; - CPUID_CACHE_PARAMS_EAX CacheParamsEax; - CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; - CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; - CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; - UINT32 MaxCpuIdIndex; - UINT32 SubIndex; - UINTN LevelType; - UINT32 MaxLogicProcessorsPerPackage; - UINT32 MaxCoresPerPackage; - - // - // Check if the processor is capable of supporting more than one logical processor. - // - AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); - if (VersionInfoEdx.Bits.HTT == 0) { - Location->Thread = 0; - Location->Core = 0; - Location->Package = 0; - return; - } - - ThreadBits = 0; - CoreBits = 0; - - // - // Assume three-level mapping of APIC ID: Package:Core:SMT. - // - - TopologyLeafSupported = FALSE; - // - // Get the max index of basic CPUID - // - AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); - - // - // If the extended topology enumeration leaf is available, it - // is the preferred mechanism for enumerating topology. - // - if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { - AsmCpuidEx ( - CPUID_EXTENDED_TOPOLOGY, - 0, - &ExtendedTopologyEax.Uint32, - &ExtendedTopologyEbx.Uint32, - &ExtendedTopologyEcx.Uint32, - NULL - ); - // - // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for - // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not - // supported on that processor. - // - if (ExtendedTopologyEbx.Uint32 != 0) { - TopologyLeafSupported = TRUE; - - // - // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract - // the SMT sub-field of x2APIC ID. - // - LevelType = ExtendedTopologyEcx.Bits.LevelType; - ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT); - ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift; - - // - // Software must not assume any "level type" encoding - // value to be related to any sub-leaf index, except sub-leaf 0. - // - SubIndex = 1; - do { - AsmCpuidEx ( - CPUID_EXTENDED_TOPOLOGY, - SubIndex, - &ExtendedTopologyEax.Uint32, - NULL, - &ExtendedTopologyEcx.Uint32, - NULL - ); - LevelType = ExtendedTopologyEcx.Bits.LevelType; - if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) { - CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits; - break; - } - SubIndex++; - } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); - } - } - - if (!TopologyLeafSupported) { - AsmCpuid (CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL); - MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors; - if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) { - AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL); - MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1; - } else { - // - // Must be a single-core processor. - // - MaxCoresPerPackage = 1; - } - - ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1); - CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1); - } - - Location->Thread = InitialApicId & ((1 << ThreadBits) - 1); - Location->Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); - Location->Package = (InitialApicId >> (ThreadBits + CoreBits)); -} - -/** Worker function for SwitchBSP(). Worker function for SwitchBSP(), assigned to the AP which is intended @@ -1451,7 +1325,7 @@ MpInitLibGetProcessorInfo ( // // Get processor location information // - ExtractProcessorLocation (CpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location); + GetProcessorLocation (CpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location); if (HealthData != NULL) { HealthData->Uint32 = CpuMpData->CpuData[ProcessorNumber].Health; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c index 40f2a17..67cd0a0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c @@ -27,125 +27,6 @@ EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService = { }; /** - Get Package ID/Core ID/Thread ID of a processor. - - APIC ID must be an initial APIC ID. - - The algorithm below assumes the target system has symmetry across physical package boundaries - with respect to the number of logical processors per package, number of cores per package. - - @param ApicId APIC ID of the target logical processor. - @param Location Returns the processor location information. -**/ -VOID -SmmGetProcessorLocation ( - IN UINT32 ApicId, - OUT EFI_CPU_PHYSICAL_LOCATION *Location - ) -{ - UINTN ThreadBits; - UINTN CoreBits; - UINT32 RegEax; - UINT32 RegEbx; - UINT32 RegEcx; - UINT32 RegEdx; - UINT32 MaxCpuIdIndex; - UINT32 SubIndex; - UINTN LevelType; - UINT32 MaxLogicProcessorsPerPackage; - UINT32 MaxCoresPerPackage; - BOOLEAN TopologyLeafSupported; - - ASSERT (Location != NULL); - - ThreadBits = 0; - CoreBits = 0; - TopologyLeafSupported = FALSE; - - // - // Check if the processor is capable of supporting more than one logical processor. - // - AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx); - ASSERT ((RegEdx & BIT28) != 0); - - // - // Assume three-level mapping of APIC ID: Package:Core:SMT. - // - - // - // Get the max index of basic CPUID - // - AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); - - // - // If the extended topology enumeration leaf is available, it - // is the preferred mechanism for enumerating topology. - // - if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) { - AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, &RegEax, &RegEbx, &RegEcx, NULL); - // - // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for - // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not - // supported on that processor. - // - if ((RegEbx & 0xffff) != 0) { - TopologyLeafSupported = TRUE; - - // - // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract - // the SMT sub-field of x2APIC ID. - // - LevelType = (RegEcx >> 8) & 0xff; - ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT); - if ((RegEbx & 0xffff) > 1 ) { - ThreadBits = RegEax & 0x1f; - } else { - // - // HT is not supported - // - ThreadBits = 0; - } - - // - // Software must not assume any "level type" encoding - // value to be related to any sub-leaf index, except sub-leaf 0. - // - SubIndex = 1; - do { - AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, SubIndex, &RegEax, NULL, &RegEcx, NULL); - LevelType = (RegEcx >> 8) & 0xff; - if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) { - CoreBits = (RegEax & 0x1f) - ThreadBits; - break; - } - SubIndex++; - } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); - } - } - - if (!TopologyLeafSupported) { - AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL); - MaxLogicProcessorsPerPackage = (RegEbx >> 16) & 0xff; - if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) { - AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &RegEax, NULL, NULL, NULL); - MaxCoresPerPackage = (RegEax >> 26) + 1; - } else { - // - // Must be a single-core processor. - // - MaxCoresPerPackage = 1; - } - - ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1); - CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1); - } - - Location->Thread = ApicId & ~((-1) << ThreadBits); - Location->Core = (ApicId >> ThreadBits) & ~((-1) << CoreBits); - Location->Package = (ApicId >> (ThreadBits+ CoreBits)); -} - -/** Gets processor information on the requested processor at the instant this call is made. @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance. @@ -280,7 +161,7 @@ SmmAddProcessor ( gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) { gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = ProcessorId; gSmmCpuPrivate->ProcessorInfo[Index].StatusFlag = 0; - SmmGetProcessorLocation ((UINT32)ProcessorId, &gSmmCpuPrivate->ProcessorInfo[Index].Location); + GetProcessorLocation ((UINT32)ProcessorId, &gSmmCpuPrivate->ProcessorInfo[Index].Location); *ProcessorNumber = Index; gSmmCpuPrivate->Operation[Index] = SmmCpuAdd; -- 1.9.1