From owner-svn-src-all@freebsd.org Wed Sep 25 13:36:57 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 4C0BF12766E; Wed, 25 Sep 2019 13:36:57 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46dfHF1NpVz3Q0m; Wed, 25 Sep 2019 13:36:57 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1315818744; Wed, 25 Sep 2019 13:36:57 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x8PDaueT022463; Wed, 25 Sep 2019 13:36:56 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x8PDauVJ022462; Wed, 25 Sep 2019 13:36:56 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201909251336.x8PDauVJ022462@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 25 Sep 2019 13:36:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r352684 - head/sys/x86/x86 X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/sys/x86/x86 X-SVN-Commit-Revision: 352684 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Sep 2019 13:36:57 -0000 Author: kib Date: Wed Sep 25 13:36:56 2019 New Revision: 352684 URL: https://svnweb.freebsd.org/changeset/base/352684 Log: x86: Fall back to leaf 0x16 if TSC frequency is obtained by CPUID and leaf 0x15 is not functional. This should improve automatic TSC frequency determination on Skylake/Kabylake/... families, where 0x15 exists but does not provide all necessary information. SDM contains relatively strong wording against such uses of 0x16, but Intel does not give us any other way to obtain the frequency. Linux did the same in the commit 604dc9170f2435d27da5039a3efd757dceadc684. Based on submission by: Neel Chauhan PR: 240475 Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D21777 Modified: head/sys/x86/x86/tsc.c Modified: head/sys/x86/x86/tsc.c ============================================================================== --- head/sys/x86/x86/tsc.c Wed Sep 25 13:29:56 2019 (r352683) +++ head/sys/x86/x86/tsc.c Wed Sep 25 13:36:56 2019 (r352684) @@ -134,7 +134,11 @@ tsc_freq_vmware(void) /* * Calculate TSC frequency using information from the CPUID leaf 0x15 - * 'Time Stamp Counter and Nominal Core Crystal Clock'. It should be + * 'Time Stamp Counter and Nominal Core Crystal Clock'. If leaf 0x15 + * is not functional, as it is on Skylake/Kabylake, try 0x16 'Processor + * Frequency Information'. Leaf 0x16 is described in the SDM as + * informational only, but if 0x15 did not work, and TSC calibration + * is disabled, it is the best we can get at all. It should still be * an improvement over the parsing of the CPU model name in * tsc_freq_intel(), when available. */ @@ -146,10 +150,20 @@ tsc_freq_cpuid(void) if (cpu_high < 0x15) return (false); do_cpuid(0x15, regs); - if (regs[0] == 0 || regs[1] == 0 || regs[2] == 0) + if (regs[0] != 0 && regs[1] != 0 && regs[2] != 0) { + tsc_freq = (uint64_t)regs[2] * regs[1] / regs[0]; + return (true); + } + + if (cpu_high < 0x16) return (false); - tsc_freq = (uint64_t)regs[2] * regs[1] / regs[0]; - return (true); + do_cpuid(0x16, regs); + if (regs[0] != 0) { + tsc_freq = (uint64_t)regs[0] * 1000000; + return (true); + } + + return (false); } static void