Synchronize the TSCs of all CPUs early in the boot process, so system_time()

will return consistent values. This helps with debug measurements for the time
being. Obviously we'll have to think of something different when we support
speed-stepping on models with frequency-dependent TSCs.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30287 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-04-21 00:38:11 +00:00
parent 8c5cccce46
commit 8b3b05cbf9
2 changed files with 24 additions and 0 deletions

View File

@ -22,6 +22,7 @@
// MSR registers (possibly Intel specific)
#define IA32_MSR_TSC 0x10
#define IA32_MSR_APIC_BASE 0x1b
#define IA32_MSR_MTRR_CAPABILITIES 0xfe

View File

@ -78,6 +78,7 @@ bool gHasSSE = false;
static uint32 sCpuRendezvous;
static uint32 sCpuRendezvous2;
static vint32 sTSCSyncRendezvous;
segment_descriptor *gGDT = NULL;
@ -501,6 +502,28 @@ arch_cpu_preboot_init_percpu(kernel_args *args, int cpu)
x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU));
gX86SwapFPUFunc = i386_fnsave_swap;
// On SMP system we want to synchronize the CPUs' TSCs, so system_time()
// will return consistent values.
if (smp_get_num_cpus() > 1) {
// let the first CPU prepare the rendezvous point
if (cpu == 0)
sTSCSyncRendezvous = smp_get_num_cpus() - 1;
// One CPU after the other will drop out of this loop and be caught by
// the loop below, until the last CPU (0) gets there. Save for +/- a few
// cycles the CPUs should pass the second loop at the same time.
while (sTSCSyncRendezvous > cpu) {
}
sTSCSyncRendezvous = cpu - 1;
while (sTSCSyncRendezvous != -1) {
}
// reset TSC to 0
x86_write_msr(IA32_MSR_TSC, 0);
}
return B_OK;
}