From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on0622.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe42::622]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2D05F81CE2 for ; Mon, 31 Oct 2016 12:43:13 -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=WIfM3XyTB2pKOPrxZI1xQKQlJAuU0uZPEJqnJWOFKrI=; b=isnFjakb5IhpogJ2YxDXlIi1aBrwxVgnpFeK7BLQ3ElOXm7IImTRAZr5dkeGNsh6kZDBqdyyqz8ZCBZ+DVAt0uyZxchJ37P3lUC+Cz+e6x/HP6Ta6/tsaNs6kTk7i768XREnQCDD0uX4os+Qcu7CAM40Qyk2YDXUBdu8B9NOGHE= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=leo.duran@amd.com; Received: from leduran-Precision-WorkStation-T5400.amd.com (165.204.77.1) by DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.679.12; Mon, 31 Oct 2016 19:43:10 +0000 From: Leo Duran To: CC: , , , , Leo Duran Date: Mon, 31 Oct 2016 14:42:57 -0500 Message-ID: <1477942977-25242-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.77.1] X-ClientProxiedBy: BLUPR01CA053.prod.exchangelabs.com (10.160.23.43) To DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) X-MS-Office365-Filtering-Correlation-Id: f3f9e63a-edd4-4aa8-9cc6-08d401c625ba X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 2:S1vuNNdMpPvftE6uSIeX0c6LodXq4mjjPxGuPX6Zc7Azk+GGzy9QUXyk/0cTFiuwA4a4eU/g4nq1XFDRNtikUQhh2iyXEurpTQK5pb9tixyQRfwZVNqoDwu2H1WbwXH4a/TW9zhPE2oK/h7GoH4EQWhRo78JpJAODm0iqkZq9TAze3ZrBuW5//ll5gsO84inDkvIIRilvSzXA6FPTofq2g==; 3:dHFBwQs0J/RC+DImBLmhaFMmCsi9q4iQqTFyeEzUevAA6dKJUUlwV8qskNBENKepBp0FgyF+bk/htmvtS4qBe6udfJsBo5VCAB80nhNuA2HEIHG939WG6dl+oNBdEuRnfmMMQHlqPdxAyDpAU+3lWg== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DM5PR12MB1243; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 25:u2v4urG82ry5oAYPniqtdlYuzokEsNtL4O7CtS5QIaz1JOgv6/uMTmnuUB6e5x8YuNNzgyRNl+dm98CLp21Halc5r64I3z/RL6tSSguC65+ISWgg8jsOhwyjl+J+vnt3CGF6cFQ2tEIwP1AE25bZ+zEti9cOBhQVoHHOV9vJCytWpA9P0q+F6EQx7B/ty1aRvvw229Hh1Uyilogh2UN5DD+s/7RsnzC47XMIo6Y7A9jqLG7j1GTMmzRA4sXMWtgOe+G2aRjMqe9YjpwRA54d9d3YsOnjpM5IUIt4LY5IiQqv9Wke7QzMS1S8WMrzmo7NKygAwH3ZKCE0zeL8wvY3w2DLMXjGSb+rUS7pKWql69mic/SRh5rppUetV6v6CU3x3qOPmSGTqjGeYxMyYSFnEl2Lr1lJW7DVQfA8wfx9Gpl36m5TdrjmlMtxtlk4tQflpc3jMJoUvjHPvKwd56Y1KnzSof/xjstCfZvAHCQgSTepd6yZG3ScYaOJ9UgH8u+2hqhTEfTCF7aqJXhsgIw9viQtjRKO8PaIMQxUefHWraFbLL/Kmdci+PJwmx2S1+CnIhG5zJX7Dn+1axWMNuorvBT+86UZlUPdRijDGIOULkBN8wVxloU1B5ZUZMBa3Rl7HfzUC72F+OZpgybk3AK7GpSElnr/YGD4zW9OAcfVXbWKyYgyCiWfyJ7vI3hbkzX9kc01reqkobbfxLqFZWkpnuVM3pbFg35WeMjDkW8Mxm8= X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 31:ln6qdWMmmQVYOnGy9IyToFn8m3i/8igjiuxX8vXIIzZwYHQUTIEegQcT/pGDToGDWdnioI+VEJWk11c+KaVWkyVPxjgbprUBHho/avI5u0b60RrVvWc+MJ9BLaKfNGnFFe8kX7y21zdc1UcGNF4ke4e4dxlE0gFLcKDmylSHytEBsEvCm0bIWIWpkIiu10uwlzQczSln6iIETVKsEvNIfEcPjA0dglk3He0otiP4iGZTYZtkAetjoqNK/VqdcmxmUG4WLFaMDYgbqndsB1JvIQ==; 20:kR6h4AoIEjiDolU29NhQMhM9QUbR40TFZRdugb/kL9qN1uPxq9T8ZW1p/ftkVrk8r0GU6jH+1sPWRdxYlxCGLY7/uk1UZ8pVeWfRgkDgN5IVKqcPBGUUBCrZbzudBHgQHdpz8VzTqVFF9B6ZB45NQKP2aCovdS2E0e4EN6EX1rUIrhDGXZHT9oRNyofpZFwu33jt5htWfm+YXT6HuwKvTjcNlN0VnCuAfiC/mPA/cxN5Jvuhu2aZVrNRDqM1FaSarHT+te42rQC7SjmDXmHmExHJHEJ/6y5V1x9xK8HMtQG2elZuWtnd6igwfdZAnjWHCtXpaWzzXCKoyIJFOb4marB5PH7uNFQfI4baKK8wzCdf8n/OvAgEcU2io1tVdoCw1zlxzFpeqABMoQnPjOXqYncff/35mBSAs4NnRutFznfTEqtfOVr+cjWNhVSyAadUUBeQM5JorM4NBNfE7npRQJ8QUkSGnYr3q53PWGAf22fV7NghgEP/KNKQunnVExUk 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)(10201501046)(3002001)(6055026); SRVR:DM5PR12MB1243; BCL:0; PCL:0; RULEID:; SRVR:DM5PR12MB1243; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 4:kIM5aTCI8bwB6MMJ1ZeEisuH/0aD3XKiQST/Q5DmxC9aP7uLR77sqQljhoMYdFgJyEqgVfgkptGiisiJtN3y7nuYn1dae/VT0NZ8hcRbyYT//D4WF+Lm2bD6sbRalCxXumNSRGq5sHbnacKLCEpZydKjnS6bmqV8MS1I3F/YBrA/sz5iI2Et9Mkax7WQozWO09k/kNECXJcXoRjmT17QUoHJCwhdehiweT+quGHhigonGYQ6fCyaFPjzq3deE0hSyXZnQEckwKQf1mxtknuTJcalXUpk2QhY4E7sO0jSdAeO5KhnQWVOgIS7TLbqeOSNO5UEFx//BtVEl6ItJ3yAYqUaV5ALlFiSwREhCPGtzJNyNeSIjkp0i+nTQQoJVES+IlbZNkQ/n/wL+KRzPltcmM18eBKAFZFN3ImpoblACXu48gpn0lvOKfJj4oFfPwUFuEzjszduCekRaNssvAJ3sw== X-Forefront-PRVS: 01128BA907 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(199003)(189002)(48376002)(97736004)(66066001)(110136003)(4326007)(2906002)(8676002)(81156014)(33646002)(7846002)(81166006)(7736002)(47776003)(105586002)(50226002)(50466002)(77096005)(189998001)(19580395003)(5660300001)(19580405001)(6916009)(68736007)(575784001)(42186005)(5003940100001)(6666003)(86362001)(50986999)(101416001)(586003)(6116002)(2351001)(229853001)(92566002)(3846002)(36756003)(106356001)(53416004)(305945005)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM5PR12MB1243; H:leduran-Precision-WorkStation-T5400.amd.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX: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; DM5PR12MB1243; 23:34mMpWldBJVgbCVqoEt54KsLPFKlI3OHE7iNacTVX?= =?us-ascii?Q?fsala1TQ4W5m+IyavjR57gU8RlP+f63GVNbSuy0Og5wVjYag2e6xC0wMfPmE?= =?us-ascii?Q?TYlLq6qqO/NYE452NmhUs/RgP1ULHMR9mkvhPKQwpnaxyNCzqRA8Jv7TVFF7?= =?us-ascii?Q?Gkm6IaAxHTY8fnmuKP3JGrJOBuBMXfOeqgeC42GDlmfv9RbchqBOBILlRBs4?= =?us-ascii?Q?2YC0POjMAAUOGA8ni7vpGr88HRfizI5Zf2QK/s7a+4ktnKgixsKkku4rJr1r?= =?us-ascii?Q?vFcEqpXzEDKJDAhXA5aXx4U8AnqpbizHPrr6oD3nnjsKPA74T2ER5jxSi6Qv?= =?us-ascii?Q?oVuG+Ac52eKXBLjU/QcP2O3Az96Kapx+oZndG0Xy3wcq/FPQY4MR7Ep14Axl?= =?us-ascii?Q?AP/UeRzhSYByV4sLREDkK+ktm8VA0XpXfFb8AGcGmXkUvob4ouSiS/6PBVy4?= =?us-ascii?Q?VIiwByKwCFaZQE9WzVRTbobY/IesEHav5Hgxuw1oYHALLuo2xcCXlWPMlacH?= =?us-ascii?Q?k7dMiSzpCsr9YoY3qfDy34Czyo3GaWzusV56qfK2xvUhb1CpTutKVQ/yW3Zr?= =?us-ascii?Q?3t6qg6tomfNnh6Rw0Fw3iNpCIBJCEm+0y/DmwzYoUuK045TjMmd4GKiDtFS2?= =?us-ascii?Q?AXK1L5Ai+lgIVOSzMWm1wrklIE+qFeMMOmZPWWy2G3EwpGIAHpv/WR7c8kFO?= =?us-ascii?Q?soyXhvcZBEKJVTdl+/D+o2jzJsZGEur/zdlOpRXm141kNTIRXeLMUi4EuCZB?= =?us-ascii?Q?XeCIakZnYO0O/7GDy9qObXMmx7jzsQdGbgi9QfAJzAMdyVx4e2FlxtvtZ5hk?= =?us-ascii?Q?Cu4GwhlsQ999vSGepicE6Jy6i4kRfpSSEEAArsBYCyd993tpiYMz3J/fhQtI?= =?us-ascii?Q?ikprBCMVwVZ8IKs8ofiI0+WBPco4EhR5C9WH43Arm+RwmafXcylg+SE0oV+9?= =?us-ascii?Q?XV+9huEViMO1wC3g9kqWfBf+YuobZfp/KRyZhFq3ucllgMfO+GOyG0wcSbWX?= =?us-ascii?Q?yCuS9ZhTBrAfh9VJMv0ZIS9FMQ5g2ryh7ifa1DBCtwq9w8dCHNghrbH6tBNC?= =?us-ascii?Q?EUJi0KoaPnjEUz54iNi2BMsVs/yODIlhEa549GlckZzX3bMMUa5kqTw++6LY?= =?us-ascii?Q?Lz34Ut373rgECDM0As2FhNTFYvZWqBFleUui8wIaeELcGevod2YhA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 6:tagNqnQLoabZuwn8sqnnLtMhds/P3Mu88dGzZz+J2PvcNVnGkXC/e+YFAuzjXznL9XXjboC/RaVFoOx5j4ynoKNoZuBwizJ2ldHiIjb1ZcUXiv3UxJDobz++rcIU1BVru0uBw00VJu2xzqLxtJzoFOjgEPJdgR5pEwm9c493aR5B6u021cv4Lpq3iPAnuHbFxgCuO2IG4NY9qzuD3epoyIwwZ96xcQ4mu92i6iWtgUS6wQojf/jGW43wnOo5TTYaC5ZIcM8PVhhqMjEI1TT92Z22PHGvPN4+bVJQHmJjXUyrFQZqi/31CqBp3ZKs5PLES7ygvjmFVW9G8pceby+u2OrrMwXYAMFVyA4YsYUaTUE=; 5:6P1V4qlq9sKC7NE6MFzLKRyQDS+oCWPVOi3aNHd8EaGsMM4a2hsJEIkElu2BrCsEAhZI1cBAVTWbY25B9SXUlG/KRQPedJkeUSiiiMvjPTC4XViyivu1sWXZkYW/mh8jWBCOsac/UUAVQLCfvzbDwadTL3mG/alQLq2RsXOpHhM=; 24:Lbdt63oVX2QJcwc5QL83BJPOgBaR2fboNisjWGIaKDMynMlyTNhBPta6wzK1kY0xkyqclvIbXuVkWdCG2uDX/ZR8JBfVdNeyhBg9elWFYXM= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 7:Rry4288uI65czx8A6VDA0W/rJcEoRwJHEEX9PuO2yUk/4P8apHP4UU+JS3NGVofnbntRJpy2aUVcyIKNfKCxGwnhzV1vyQj7IAtT12fbbJKCGrde04Zl/0V7HzYyvqAwu4c3wJUf4AWbXHc/dDJj96cDYGBUZ3HLDQ+ETQs1zniSGoPHPuJ1yRxtGmhJaLwZJNt4T+xBmAdl+Evyin0E1TmmF2026qxsIOImbxKd8PB9zoWU/2hCGbQ2D0XhhoJdT9ugamMQaZ3c0+eOPYWf6hoUB1iAIy8CX2znpqvtlX2u1vBlnTOaPHmY63f/rBUMz0Ux/M5ssxNlzyDNLDd0f8wwp0muOsZrfUs/ap4uJbE=; 20:v7f+4elN/xr22pIAoUfYt9ZxIeTikaHb7zdV5Eat524+yhprjikf79qCD94b2umtyy4xAEtuUiGONueq10o8fswT9tOHeSaNHvMiwvy3sGV+cbKiu/2iXTYOQYn696AKmNcVFXdnSKL8iu6O1pG95OdhF0aHHJNvkYRDs46mUps+/sbxjbZ+zYenfkNBW2wo5plZTOGx2PR0REWWdKX2G4qL6M16HDwUcIm6EtHRb+U1UzMDpbL046e/GmsTh8Ow X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Oct 2016 19:43:10.7356 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1243 Subject: [PATCH] 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: Mon, 31 Oct 2016 19:43:13 -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 | 20 +++ UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 146 +++++++++++++++++++++ .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 146 +++++++++++++++++++++ UefiCpuPkg/Library/MpInitLib/MpLib.c | 133 +------------------ UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c | 126 +----------------- 5 files changed, 324 insertions(+), 247 deletions(-) diff --git a/UefiCpuPkg/Include/Library/LocalApicLib.h b/UefiCpuPkg/Include/Library/LocalApicLib.h index cd4e613..179409e 100644 --- a/UefiCpuPkg/Include/Library/LocalApicLib.h +++ b/UefiCpuPkg/Include/Library/LocalApicLib.h @@ -410,6 +410,26 @@ 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[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +GetProcessorLocation( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ); #endif diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c index 8d0fb02..f32d287 100644 --- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c @@ -941,3 +941,149 @@ 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[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +GetProcessorLocation( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ) +{ + 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) { + if (Thread != NULL) { + *Thread = 0; + } + if (Core != NULL) { + *Core = 0; + } + if (Package != NULL) { + *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); } + + if (Thread != NULL) { + *Thread = InitialApicId & ((1 << ThreadBits) - 1); + } + if (Core != NULL) { + *Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); + } + if (Package != NULL) { + *Package = (InitialApicId >> (ThreadBits + CoreBits)); + } +} diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c index 4c42696..a34a272 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c @@ -1036,3 +1036,149 @@ 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[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +GetProcessorLocation( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ) +{ + 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) { + if (Thread != NULL) { + *Thread = 0; + } + if (Core != NULL) { + *Core = 0; + } + if (Package != NULL) { + *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); } + + if (Thread != NULL) { + *Thread = InitialApicId & ((1 << ThreadBits) - 1); + } + if (Core != NULL) { + *Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); + } + if (Package != NULL) { + *Package = (InitialApicId >> (ThreadBits + CoreBits)); + } +} diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index c3fe721..e48ff6a 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,12 @@ MpInitLibGetProcessorInfo ( // // Get processor location information // - ExtractProcessorLocation (CpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location); + GetProcessorLocation ( + CpuMpData->CpuData[ProcessorNumber].ApicId, + &ProcessorInfoBuffer->Location.Package, + &ProcessorInfoBuffer->Location.Core, + &ProcessorInfoBuffer->Location.Thread + ); if (HealthData != NULL) { HealthData->Uint32 = CpuMpData->CpuData[ProcessorNumber].Health; diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c index 40f2a17..f377a36 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,12 @@ 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.Package, + &gSmmCpuPrivate->ProcessorInfo[Index].Location.Core, + &gSmmCpuPrivate->ProcessorInfo[Index].Location.Thread + ); *ProcessorNumber = Index; gSmmCpuPrivate->Operation[Index] = SmmCpuAdd; -- 1.9.1