Tue Apr 21 07:08:12 2020 UTC ()
 Print "Hz".


(msaitoh)
diff -r1.1 -r1.2 src/sys/arch/x86/x86/identcpu_subr.c

cvs diff -r1.1 -r1.2 src/sys/arch/x86/x86/identcpu_subr.c (switch to unified diff)

--- src/sys/arch/x86/x86/identcpu_subr.c 2020/04/21 02:56:37 1.1
+++ src/sys/arch/x86/x86/identcpu_subr.c 2020/04/21 07:08:12 1.2
@@ -1,146 +1,146 @@ @@ -1,146 +1,146 @@
1/*- 1/*-
2 * Copyright (c) 2020 The NetBSD Foundation, Inc. 2 * Copyright (c) 2020 The NetBSD Foundation, Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This code is derived from software contributed to The NetBSD Foundation 5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Masanobu SAITOH. 6 * by Masanobu SAITOH.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE. 27 * POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30/* 30/*
31 * Subroutines for CPU. 31 * Subroutines for CPU.
32 * This file is shared between kernel and userland. 32 * This file is shared between kernel and userland.
33 * See src/usr.sbin/cpuctl/{Makefile, arch/i386.c}). 33 * See src/usr.sbin/cpuctl/{Makefile, arch/i386.c}).
34 */ 34 */
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: identcpu_subr.c,v 1.1 2020/04/21 02:56:37 msaitoh Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: identcpu_subr.c,v 1.2 2020/04/21 07:08:12 msaitoh Exp $");
37 37
38#ifdef _KERNEL_OPT 38#ifdef _KERNEL_OPT
39#include "lapic.h" 39#include "lapic.h"
40#endif 40#endif
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43 43
44#ifdef _KERNEL 44#ifdef _KERNEL
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <x86/cpuvar.h> 46#include <x86/cpuvar.h>
47#include <x86/apicvar.h> 47#include <x86/apicvar.h>
48#include <machine/cpufunc.h> 48#include <machine/cpufunc.h>
49#include <machine/cputypes.h> 49#include <machine/cputypes.h>
50#include <machine/specialreg.h> 50#include <machine/specialreg.h>
51#else 51#else
52#include <stdarg.h> 52#include <stdarg.h>
53#include <stdbool.h> 53#include <stdbool.h>
54#include <stdio.h> 54#include <stdio.h>
55#include <stdlib.h> 55#include <stdlib.h>
56#include <string.h> 56#include <string.h>
57#include "cpuctl.h" 57#include "cpuctl.h"
58#include "cpuctl_i386.h" 58#include "cpuctl_i386.h"
59#endif 59#endif
60 60
61uint64_t 61uint64_t
62cpu_tsc_freq_cpuid(struct cpu_info *ci) 62cpu_tsc_freq_cpuid(struct cpu_info *ci)
63{ 63{
64 uint64_t freq = 0, khz; 64 uint64_t freq = 0, khz;
65 uint32_t descs[4]; 65 uint32_t descs[4];
66 uint32_t denominator, numerator; 66 uint32_t denominator, numerator;
67 67
68 if (!((ci->ci_max_cpuid >= 0x15) && (cpu_vendor == CPUVENDOR_INTEL))) 68 if (!((ci->ci_max_cpuid >= 0x15) && (cpu_vendor == CPUVENDOR_INTEL)))
69 return 0; 69 return 0;
70  70
71 x86_cpuid(0x15, descs); 71 x86_cpuid(0x15, descs);
72 denominator = descs[0]; 72 denominator = descs[0];
73 numerator = descs[1]; 73 numerator = descs[1];
74 if ((denominator == 0) || numerator == 0) { 74 if ((denominator == 0) || numerator == 0) {
75 aprint_debug_dev(ci->ci_dev, 75 aprint_debug_dev(ci->ci_dev,
76 "TSC/core crystal clock ratio is not enumerated\n"); 76 "TSC/core crystal clock ratio is not enumerated\n");
77 } else { 77 } else {
78 khz = 0; 78 khz = 0;
79 if (descs[2] != 0) 79 if (descs[2] != 0)
80 khz = descs[2] / 1000; 80 khz = descs[2] / 1000;
81 else if (CPUID_TO_FAMILY(ci->ci_signature) == 6) { 81 else if (CPUID_TO_FAMILY(ci->ci_signature) == 6) {
82 /* 82 /*
83 * Table 18-85 Nominal Core Crystal Clock Frequency, 83 * Table 18-85 Nominal Core Crystal Clock Frequency,
84 * 18.7.3 Determining the Processor Base Frequency, 84 * 18.7.3 Determining the Processor Base Frequency,
85 * Intel SDM. 85 * Intel SDM.
86 */ 86 */
87 switch (CPUID_TO_MODEL(ci->ci_signature)) { 87 switch (CPUID_TO_MODEL(ci->ci_signature)) {
88 case 0x55: /* Xeon Scalable */ 88 case 0x55: /* Xeon Scalable */
89 case 0x5f: /* 89 case 0x5f: /*
90 * Atom Goldmont (Denverton). Right? 90 * Atom Goldmont (Denverton). Right?
91 * XXX Not documented! 91 * XXX Not documented!
92 */ 92 */
93 khz = 25000; /* 25.0 MHz */ 93 khz = 25000; /* 25.0 MHz */
94 break; 94 break;
95 case 0x4e: /* 7th gen Core (Skylake) */ 95 case 0x4e: /* 7th gen Core (Skylake) */
96 case 0x5e: /* 7th gen Core (Skylake) */ 96 case 0x5e: /* 7th gen Core (Skylake) */
97 case 0x8e: /* 8th gen Core (Kaby Lake) */ 97 case 0x8e: /* 8th gen Core (Kaby Lake) */
98 case 0x9e: /* 8th gen Core (Kaby Lake) */ 98 case 0x9e: /* 8th gen Core (Kaby Lake) */
99 khz = 24000; /* 24.0 MHz */ 99 khz = 24000; /* 24.0 MHz */
100 break; 100 break;
101 case 0x5c: /* Atom Goldmont */ 101 case 0x5c: /* Atom Goldmont */
102 khz = 19200; /* 19.2 MHz */ 102 khz = 19200; /* 19.2 MHz */
103 break; 103 break;
104 default: /* Unknown */ 104 default: /* Unknown */
105 break; 105 break;
106 } 106 }
107 } 107 }
108 freq = khz * 1000 * numerator / denominator; 108 freq = khz * 1000 * numerator / denominator;
109 if (ci->ci_max_cpuid >= 0x16) { 109 if (ci->ci_max_cpuid >= 0x16) {
110 x86_cpuid(0x16, descs); 110 x86_cpuid(0x16, descs);
111 if (descs[0] != 0) { 111 if (descs[0] != 0) {
112 aprint_verbose_dev(ci->ci_dev, 112 aprint_verbose_dev(ci->ci_dev,
113 "CPU base freq %" PRIu64 "\n", 113 "CPU base freq %" PRIu64 " Hz\n",
114 (uint64_t)descs[0] * 1000000); 114 (uint64_t)descs[0] * 1000000);
115 115
116 /* 116 /*
117 * If we couldn't get frequency from 117 * If we couldn't get frequency from
118 * CPUID 0x15, use CPUID 0x16 EAX. 118 * CPUID 0x15, use CPUID 0x16 EAX.
119 */ 119 */
120 if (freq == 0) { 120 if (freq == 0) {
121 khz = (uint64_t)descs[0] * 1000 121 khz = (uint64_t)descs[0] * 1000
122 * denominator / numerator; 122 * denominator / numerator;
123 freq = (uint64_t)descs[0] * 1000000; 123 freq = (uint64_t)descs[0] * 1000000;
124 } 124 }
125 } 125 }
126 if (descs[1] != 0) { 126 if (descs[1] != 0) {
127 aprint_verbose_dev(ci->ci_dev, 127 aprint_verbose_dev(ci->ci_dev,
128 "CPU max freq %" PRIu64 "\n", 128 "CPU max freq %" PRIu64 " Hz\n",
129 (uint64_t)descs[1] * 1000000); 129 (uint64_t)descs[1] * 1000000);
130 } 130 }
131 } 131 }
132#if defined(_KERNEL) && NLAPIC > 0 132#if defined(_KERNEL) && NLAPIC > 0
133 if ((khz != 0) && (lapic_per_second == 0)) { 133 if ((khz != 0) && (lapic_per_second == 0)) {
134 lapic_per_second = khz * 1000; 134 lapic_per_second = khz * 1000;
135 aprint_debug_dev(ci->ci_dev, 135 aprint_debug_dev(ci->ci_dev,
136 "lapic_per_second set to %" PRIu32 "\n", 136 "lapic_per_second set to %" PRIu32 "\n",
137 lapic_per_second); 137 lapic_per_second);
138 } 138 }
139#endif 139#endif
140 } 140 }
141 if (freq != 0) 141 if (freq != 0)
142 aprint_verbose_dev(ci->ci_dev, "TSC freq %" PRIu64 "\n", 142 aprint_verbose_dev(ci->ci_dev, "TSC freq %" PRIu64 " Hz\n",
143 freq); 143 freq);
144 144
145 return freq; 145 return freq;
146} 146}