version 1.37.4.2, 2020/04/21 18:42:12 |
version 1.38, 2020/02/21 00:26:22 |
Line 135 tsc_is_invariant(void) |
|
Line 135 tsc_is_invariant(void) |
|
x86_cpuid(0x80000000, descs); |
x86_cpuid(0x80000000, descs); |
if (descs[0] >= 0x80000007) { |
if (descs[0] >= 0x80000007) { |
x86_cpuid(0x80000007, descs); |
x86_cpuid(0x80000007, descs); |
invariant = (descs[3] & CPUID_APM_ITSC) != 0; |
invariant = (descs[3] & CPUID_APM_TSC) != 0; |
} |
} |
} |
} |
|
|
return invariant; |
return invariant; |
} |
} |
|
|
/* |
|
* Initialize timecounter(9) of TSC. |
|
* This function is called after all secondary processors were up and |
|
* calculated the drift. |
|
*/ |
|
void |
void |
tsc_tc_init(void) |
tsc_tc_init(void) |
{ |
{ |
Line 206 tsc_read_bp(struct cpu_info *ci, uint64_ |
|
Line 201 tsc_read_bp(struct cpu_info *ci, uint64_ |
|
|
|
/* Flag it and read our TSC. */ |
/* Flag it and read our TSC. */ |
atomic_or_uint(&ci->ci_flags, CPUF_SYNCTSC); |
atomic_or_uint(&ci->ci_flags, CPUF_SYNCTSC); |
bptsc = (rdtsc() >> 1); |
bptsc = cpu_counter_serializing() >> 1; |
|
|
/* Wait for remote to complete, and read ours again. */ |
/* Wait for remote to complete, and read ours again. */ |
while ((ci->ci_flags & CPUF_SYNCTSC) != 0) { |
while ((ci->ci_flags & CPUF_SYNCTSC) != 0) { |
__insn_barrier(); |
__insn_barrier(); |
} |
} |
bptsc += (rdtsc() >> 1); |
bptsc += (cpu_counter_serializing() >> 1); |
|
|
/* Wait for the results to come in. */ |
/* Wait for the results to come in. */ |
while (tsc_sync_cpu == ci) { |
while (tsc_sync_cpu == ci) { |
Line 251 tsc_post_ap(struct cpu_info *ci) |
|
Line 246 tsc_post_ap(struct cpu_info *ci) |
|
while ((ci->ci_flags & CPUF_SYNCTSC) == 0) { |
while ((ci->ci_flags & CPUF_SYNCTSC) == 0) { |
__insn_barrier(); |
__insn_barrier(); |
} |
} |
tsc = (rdtsc() >> 1); |
tsc = (cpu_counter_serializing() >> 1); |
|
|
/* Instruct primary to read its counter. */ |
/* Instruct primary to read its counter. */ |
atomic_and_uint(&ci->ci_flags, ~CPUF_SYNCTSC); |
atomic_and_uint(&ci->ci_flags, ~CPUF_SYNCTSC); |
tsc += (rdtsc() >> 1); |
tsc += (cpu_counter_serializing() >> 1); |
|
|
/* Post result. Ensure the whole value goes out atomically. */ |
/* Post result. Ensure the whole value goes out atomically. */ |
(void)atomic_swap_64(&tsc_sync_val, tsc); |
(void)atomic_swap_64(&tsc_sync_val, tsc); |