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:
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
|
|
||||||
// MSR registers (possibly Intel specific)
|
// MSR registers (possibly Intel specific)
|
||||||
|
#define IA32_MSR_TSC 0x10
|
||||||
#define IA32_MSR_APIC_BASE 0x1b
|
#define IA32_MSR_APIC_BASE 0x1b
|
||||||
|
|
||||||
#define IA32_MSR_MTRR_CAPABILITIES 0xfe
|
#define IA32_MSR_MTRR_CAPABILITIES 0xfe
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ bool gHasSSE = false;
|
|||||||
|
|
||||||
static uint32 sCpuRendezvous;
|
static uint32 sCpuRendezvous;
|
||||||
static uint32 sCpuRendezvous2;
|
static uint32 sCpuRendezvous2;
|
||||||
|
static vint32 sTSCSyncRendezvous;
|
||||||
|
|
||||||
segment_descriptor *gGDT = NULL;
|
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));
|
x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU));
|
||||||
gX86SwapFPUFunc = i386_fnsave_swap;
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user