| @@ -1,43 +1,43 @@ | | | @@ -1,43 +1,43 @@ |
1 | /* $NetBSD: tsc.c,v 1.41 2020/04/21 02:56:37 msaitoh Exp $ */ | | 1 | /* $NetBSD: tsc.c,v 1.42 2020/04/23 20:38:33 ad Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * | | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. | | 26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.41 2020/04/21 02:56:37 msaitoh Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.42 2020/04/23 20:38:33 ad Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/systm.h> | | 33 | #include <sys/systm.h> |
34 | #include <sys/time.h> | | 34 | #include <sys/time.h> |
35 | #include <sys/timetc.h> | | 35 | #include <sys/timetc.h> |
36 | #include <sys/lwp.h> | | 36 | #include <sys/lwp.h> |
37 | #include <sys/atomic.h> | | 37 | #include <sys/atomic.h> |
38 | #include <sys/kernel.h> | | 38 | #include <sys/kernel.h> |
39 | #include <sys/cpu.h> | | 39 | #include <sys/cpu.h> |
40 | #include <sys/xcall.h> | | 40 | #include <sys/xcall.h> |
41 | | | 41 | |
42 | #include <machine/cpu_counter.h> | | 42 | #include <machine/cpu_counter.h> |
43 | #include <machine/cpuvar.h> | | 43 | #include <machine/cpuvar.h> |
| @@ -219,33 +219,37 @@ tsc_read_bp(struct cpu_info *ci, uint64_ | | | @@ -219,33 +219,37 @@ tsc_read_bp(struct cpu_info *ci, uint64_ |
219 | x86_pause(); | | 219 | x86_pause(); |
220 | } | | 220 | } |
221 | if (tsc_sync_cpu != NULL) { | | 221 | if (tsc_sync_cpu != NULL) { |
222 | panic("tsc_sync_bp: 2"); | | 222 | panic("tsc_sync_bp: 2"); |
223 | } | | 223 | } |
224 | | | 224 | |
225 | *bptscp = bptsc; | | 225 | *bptscp = bptsc; |
226 | *aptscp = tsc_sync_val; | | 226 | *aptscp = tsc_sync_val; |
227 | } | | 227 | } |
228 | | | 228 | |
229 | void | | 229 | void |
230 | tsc_sync_bp(struct cpu_info *ci) | | 230 | tsc_sync_bp(struct cpu_info *ci) |
231 | { | | 231 | { |
232 | uint64_t bptsc, aptsc; | | 232 | int64_t bptsc, aptsc, bsum = 0, asum = 0; |
233 | | | 233 | |
234 | tsc_read_bp(ci, &bptsc, &aptsc); /* discarded - cache effects */ | | 234 | tsc_read_bp(ci, &bptsc, &aptsc); /* discarded - cache effects */ |
235 | tsc_read_bp(ci, &bptsc, &aptsc); | | 235 | for (int i = 0; i < 8; i++) { |
| | | 236 | tsc_read_bp(ci, &bptsc, &aptsc); |
| | | 237 | bsum += bptsc; |
| | | 238 | asum += aptsc; |
| | | 239 | } |
236 | | | 240 | |
237 | /* Compute final value to adjust for skew. */ | | 241 | /* Compute final value to adjust for skew. */ |
238 | ci->ci_data.cpu_cc_skew = bptsc - aptsc; | | 242 | ci->ci_data.cpu_cc_skew = (bsum - asum) >> 3; |
239 | } | | 243 | } |
240 | | | 244 | |
241 | /* | | 245 | /* |
242 | * Called during startup of AP, by the AP itself. Interrupts are | | 246 | * Called during startup of AP, by the AP itself. Interrupts are |
243 | * disabled on entry. | | 247 | * disabled on entry. |
244 | */ | | 248 | */ |
245 | static void | | 249 | static void |
246 | tsc_post_ap(struct cpu_info *ci) | | 250 | tsc_post_ap(struct cpu_info *ci) |
247 | { | | 251 | { |
248 | uint64_t tsc; | | 252 | uint64_t tsc; |
249 | | | 253 | |
250 | /* Wait for go-ahead from primary. */ | | 254 | /* Wait for go-ahead from primary. */ |
251 | while ((ci->ci_flags & CPUF_SYNCTSC) == 0) { | | 255 | while ((ci->ci_flags & CPUF_SYNCTSC) == 0) { |
| @@ -260,27 +264,29 @@ tsc_post_ap(struct cpu_info *ci) | | | @@ -260,27 +264,29 @@ tsc_post_ap(struct cpu_info *ci) |
260 | /* Post result. Ensure the whole value goes out atomically. */ | | 264 | /* Post result. Ensure the whole value goes out atomically. */ |
261 | (void)atomic_swap_64(&tsc_sync_val, tsc); | | 265 | (void)atomic_swap_64(&tsc_sync_val, tsc); |
262 | | | 266 | |
263 | if (atomic_swap_ptr(&tsc_sync_cpu, NULL) != ci) { | | 267 | if (atomic_swap_ptr(&tsc_sync_cpu, NULL) != ci) { |
264 | panic("tsc_sync_ap"); | | 268 | panic("tsc_sync_ap"); |
265 | } | | 269 | } |
266 | } | | 270 | } |
267 | | | 271 | |
268 | void | | 272 | void |
269 | tsc_sync_ap(struct cpu_info *ci) | | 273 | tsc_sync_ap(struct cpu_info *ci) |
270 | { | | 274 | { |
271 | | | 275 | |
272 | tsc_post_ap(ci); | | 276 | tsc_post_ap(ci); |
273 | tsc_post_ap(ci); | | 277 | for (int i = 0; i < 8; i++) { |
| | | 278 | tsc_post_ap(ci); |
| | | 279 | } |
274 | } | | 280 | } |
275 | | | 281 | |
276 | static void | | 282 | static void |
277 | tsc_apply_cpu(void *arg1, void *arg2) | | 283 | tsc_apply_cpu(void *arg1, void *arg2) |
278 | { | | 284 | { |
279 | bool enable = arg1 != NULL; | | 285 | bool enable = arg1 != NULL; |
280 | if (enable) { | | 286 | if (enable) { |
281 | lcr4(rcr4() & ~CR4_TSD); | | 287 | lcr4(rcr4() & ~CR4_TSD); |
282 | } else { | | 288 | } else { |
283 | lcr4(rcr4() | CR4_TSD); | | 289 | lcr4(rcr4() | CR4_TSD); |
284 | } | | 290 | } |
285 | } | | 291 | } |
286 | | | 292 | |