Print this page
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/i86pc/os/cpupm/turbo.c
+++ new/usr/src/uts/i86pc/os/cpupm/turbo.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
23 23 */
24 24 /*
25 25 * Copyright (c) 2009, Intel Corporation.
26 26 * All Rights Reserved.
27 27 */
28 28
29 29 #include <sys/x86_archext.h>
30 30 #include <sys/machsystm.h>
31 31 #include <sys/archsystm.h>
32 32 #include <sys/x_call.h>
33 -#include <sys/acpi/acpi.h>
33 +#include <acpica/include/acpi.h>
34 34 #include <sys/acpica.h>
35 35 #include <sys/speedstep.h>
36 36 #include <sys/cpu_acpi.h>
37 37 #include <sys/cpupm.h>
38 38 #include <sys/dtrace.h>
39 39 #include <sys/sdt.h>
40 40
41 41 typedef struct turbo_kstat_s {
42 42 struct kstat_named turbo_supported; /* turbo flag */
43 43 struct kstat_named t_mcnt; /* IA32_MPERF_MSR */
44 44 struct kstat_named t_acnt; /* IA32_APERF_MSR */
45 45 } turbo_kstat_t;
46 46
47 47 static int turbo_kstat_update(kstat_t *, int);
48 48 static void get_turbo_info(cpupm_mach_turbo_info_t *);
49 49 static void reset_turbo_info(void);
50 50 static void record_turbo_info(cpupm_mach_turbo_info_t *, uint32_t, uint32_t);
51 51 static void update_turbo_info(cpupm_mach_turbo_info_t *);
52 52
53 53 static kmutex_t turbo_mutex;
54 54
55 55 turbo_kstat_t turbo_kstat = {
56 56 { "turbo_supported", KSTAT_DATA_UINT32 },
57 57 { "turbo_mcnt", KSTAT_DATA_UINT64 },
58 58 { "turbo_acnt", KSTAT_DATA_UINT64 },
59 59 };
60 60
61 61 #define CPU_ACPI_P0 0
62 62 #define CPU_IN_TURBO 1
63 63
64 64 /*
65 65 * MSR for hardware coordination feedback mechanism
66 66 * - IA32_MPERF: increments in proportion to a fixed frequency
67 67 * - IA32_APERF: increments in proportion to actual performance
68 68 */
69 69 #define IA32_MPERF_MSR 0xE7
70 70 #define IA32_APERF_MSR 0xE8
71 71
72 72 /*
73 73 * kstat update function of the turbo mode info
74 74 */
75 75 static int
76 76 turbo_kstat_update(kstat_t *ksp, int flag)
77 77 {
78 78 cpupm_mach_turbo_info_t *turbo_info = ksp->ks_private;
79 79
80 80 if (flag == KSTAT_WRITE) {
81 81 return (EACCES);
82 82 }
83 83
84 84 /*
85 85 * update the count in case CPU is in the turbo
86 86 * mode for a long time
87 87 */
88 88 if (turbo_info->in_turbo == CPU_IN_TURBO)
89 89 update_turbo_info(turbo_info);
90 90
91 91 turbo_kstat.turbo_supported.value.ui32 =
92 92 turbo_info->turbo_supported;
93 93 turbo_kstat.t_mcnt.value.ui64 = turbo_info->t_mcnt;
94 94 turbo_kstat.t_acnt.value.ui64 = turbo_info->t_acnt;
95 95
96 96 return (0);
97 97 }
98 98
99 99 /*
100 100 * update the sum of counts and clear MSRs
101 101 */
102 102 static void
103 103 update_turbo_info(cpupm_mach_turbo_info_t *turbo_info)
104 104 {
105 105 ulong_t iflag;
106 106 uint64_t mcnt, acnt;
107 107
108 108 iflag = intr_clear();
109 109 mcnt = rdmsr(IA32_MPERF_MSR);
110 110 acnt = rdmsr(IA32_APERF_MSR);
111 111 wrmsr(IA32_MPERF_MSR, 0);
112 112 wrmsr(IA32_APERF_MSR, 0);
113 113 turbo_info->t_mcnt += mcnt;
114 114 turbo_info->t_acnt += acnt;
115 115 intr_restore(iflag);
116 116 }
117 117
118 118 /*
119 119 * Get count of MPERF/APERF MSR
120 120 */
121 121 static void
122 122 get_turbo_info(cpupm_mach_turbo_info_t *turbo_info)
123 123 {
124 124 ulong_t iflag;
125 125 uint64_t mcnt, acnt;
126 126
127 127 iflag = intr_clear();
128 128 mcnt = rdmsr(IA32_MPERF_MSR);
129 129 acnt = rdmsr(IA32_APERF_MSR);
130 130 turbo_info->t_mcnt += mcnt;
131 131 turbo_info->t_acnt += acnt;
132 132 intr_restore(iflag);
133 133 }
134 134
135 135 /*
136 136 * Clear MPERF/APERF MSR
137 137 */
138 138 static void
139 139 reset_turbo_info(void)
140 140 {
141 141 ulong_t iflag;
142 142
143 143 iflag = intr_clear();
144 144 wrmsr(IA32_MPERF_MSR, 0);
145 145 wrmsr(IA32_APERF_MSR, 0);
146 146 intr_restore(iflag);
147 147 }
148 148
149 149 /*
150 150 * sum up the count of one CPU_ACPI_P0 transition
151 151 */
152 152 void
153 153 cpupm_record_turbo_info(cpupm_mach_turbo_info_t *turbo_info,
154 154 uint32_t cur_state, uint32_t req_state)
155 155 {
156 156 if (!turbo_info->turbo_supported)
157 157 return;
158 158 /*
159 159 * enter P0 state
160 160 */
161 161 if (req_state == CPU_ACPI_P0) {
162 162 reset_turbo_info();
163 163 turbo_info->in_turbo = CPU_IN_TURBO;
164 164 }
165 165 /*
166 166 * Leave P0 state
167 167 */
168 168 else if (cur_state == CPU_ACPI_P0) {
169 169 turbo_info->in_turbo = 0;
170 170 get_turbo_info(turbo_info);
171 171 }
172 172 }
173 173
174 174 cpupm_mach_turbo_info_t *
175 175 cpupm_turbo_init(cpu_t *cp)
176 176 {
177 177 cpupm_mach_turbo_info_t *turbo_info;
178 178
179 179 turbo_info = kmem_zalloc(sizeof (cpupm_mach_turbo_info_t), KM_SLEEP);
180 180
181 181 turbo_info->turbo_supported = 1;
182 182 turbo_info->turbo_ksp = kstat_create("turbo", cp->cpu_id,
183 183 "turbo", "misc", KSTAT_TYPE_NAMED,
184 184 sizeof (turbo_kstat) / sizeof (kstat_named_t),
185 185 KSTAT_FLAG_VIRTUAL);
186 186
187 187 if (turbo_info->turbo_ksp == NULL) {
188 188 cmn_err(CE_NOTE, "kstat_create(turbo) fail");
189 189 } else {
190 190 turbo_info->turbo_ksp->ks_data = &turbo_kstat;
191 191 turbo_info->turbo_ksp->ks_lock = &turbo_mutex;
192 192 turbo_info->turbo_ksp->ks_update = turbo_kstat_update;
193 193 turbo_info->turbo_ksp->ks_data_size += MAXNAMELEN;
194 194 turbo_info->turbo_ksp->ks_private = turbo_info;
195 195
196 196 kstat_install(turbo_info->turbo_ksp);
197 197 }
198 198
199 199 return (turbo_info);
200 200 }
201 201
202 202 void
203 203 cpupm_turbo_fini(cpupm_mach_turbo_info_t *turbo_info)
204 204 {
205 205 if (turbo_info->turbo_ksp != NULL)
206 206 kstat_delete(turbo_info->turbo_ksp);
207 207 kmem_free(turbo_info, sizeof (cpupm_mach_turbo_info_t));
208 208 }
↓ open down ↓ |
165 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX