From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by ml01.01.org (Postfix) with ESMTP id 596091A1DEF for ; Tue, 16 Aug 2016 19:26:51 -0700 (PDT) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga101.fm.intel.com with ESMTP; 16 Aug 2016 19:26:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,529,1464678000"; d="scan'208";a="866676327" Received: from shwdeopenpsi068.ccr.corp.intel.com ([10.239.9.9]) by orsmga003.jf.intel.com with ESMTP; 16 Aug 2016 19:26:49 -0700 From: Star Zeng To: edk2-devel@lists.01.org Cc: Star Zeng , Michael D Kinney , Liming Gao , Paolo Bonzini , Paul A Lohr Date: Wed, 17 Aug 2016 10:26:43 +0800 Message-Id: <1471400803-129280-1-git-send-email-star.zeng@intel.com> X-Mailer: git-send-email 2.7.0.windows.1 Subject: [PATCH] PcAtChipsetPkg AcpiTimerLib: Wait 363 ACPI timer counts to get TSC Freq X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Aug 2016 02:26:51 -0000 Compute the number of ticks to wait to measure TSC frequency. Instead of (ACPI_TIMER_FREQUENCY / 10000) = 357 and 357 * 10000 = 3570000, use 363 * 9861 = 3579543 Hz which is within 2 Hz of ACPI_TIMER_FREQUENCY. 363 counts is a calibration time of 101.4 uS. The idea comes from Michael and Paolo. Cc: Michael D Kinney Cc: Liming Gao Cc: Paolo Bonzini Cc: Paul A Lohr Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng --- PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c | 32 +++++++++++++--------- .../Library/AcpiTimerLib/BaseAcpiTimerLib.c | 14 +++++----- .../Library/AcpiTimerLib/DxeAcpiTimerLib.c | 14 +++++----- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c b/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c index e6fea231123d..020031e3f4a5 100644 --- a/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c +++ b/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c @@ -340,13 +340,13 @@ GetTimeInNanoSecond ( Calculate TSC frequency. The TSC counting frequency is determined by comparing how far it counts - during a 100us period as determined by the ACPI timer. The ACPI timer is - used because it counts at a known frequency. - The TSC is sampled, followed by waiting for ACPI_TIMER_FREQUENCY / 10000 - clocks of the ACPI timer, or 100us. The TSC is then sampled again. The - difference multiplied by 10000 is the TSC frequency. There will be a small - error because of the overhead of reading the ACPI timer. An attempt is - made to determine and compensate for this error. + during a 101.4 us period as determined by the ACPI timer. + The ACPI timer is used because it counts at a known frequency. + The TSC is sampled, followed by waiting 363 counts of the ACPI timer, + or 101.4 us. The TSC is then sampled again. The difference multiplied by + 9861 is the TSC frequency. There will be a small error because of the + overhead of reading the ACPI timer. An attempt is made to determine and + compensate for this error. @return The number of TSC counts per second. @@ -366,22 +366,28 @@ InternalCalculateTscFrequency ( InterruptState = SaveAndDisableInterrupts (); TimerAddr = InternalAcpiGetAcpiTimerIoPort (); - Ticks = IoRead32 (TimerAddr) + (ACPI_TIMER_FREQUENCY / 10000); // Set Ticks to 100us in the future + // + // Compute the number of ticks to wait to measure TSC frequency. + // Use 363 * 9861 = 3579543 Hz which is within 2 Hz of ACPI_TIMER_FREQUENCY. + // 363 counts is a calibration time of 101.4 uS. + // + Ticks = IoRead32 (TimerAddr) + 363; StartTSC = AsmReadTsc (); // Get base value for the TSC // - // Wait until the ACPI timer has counted 100us. + // Wait until the ACPI timer has counted 101.4 us. // Timer wrap-arounds are handled correctly by this function. - // When the current ACPI timer value is greater than 'Ticks', the while loop will exit. + // When the current ACPI timer value is greater than 'Ticks', + // the while loop will exit. // while (((Ticks - IoRead32 (TimerAddr)) & BIT23) == 0) { CpuPause(); } - EndTSC = AsmReadTsc (); // TSC value 100us later + EndTSC = AsmReadTsc (); // TSC value 101.4 us later TscFrequency = MultU64x32 ( - (EndTSC - StartTSC), // Number of TSC counts in 100us - 10000 // Number of 100us in a second + (EndTSC - StartTSC), // Number of TSC counts in 101.4 us + 9861 // Number of 101.4 us in a second ); SetInterruptState (InterruptState); diff --git a/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c b/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c index 8819ebcfccef..29521f8b220b 100644 --- a/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c +++ b/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c @@ -20,13 +20,13 @@ Calculate TSC frequency. The TSC counting frequency is determined by comparing how far it counts - during a 100us period as determined by the ACPI timer. The ACPI timer is - used because it counts at a known frequency. - The TSC is sampled, followed by waiting for ACPI_TIMER_FREQUENCY / 10000 - clocks of the ACPI timer, or 100us. The TSC is then sampled again. The - difference multiplied by 10000 is the TSC frequency. There will be a small - error because of the overhead of reading the ACPI timer. An attempt is - made to determine and compensate for this error. + during a 101.4 us period as determined by the ACPI timer. + The ACPI timer is used because it counts at a known frequency. + The TSC is sampled, followed by waiting 363 counts of the ACPI timer, + or 101.4 us. The TSC is then sampled again. The difference multiplied by + 9861 is the TSC frequency. There will be a small error because of the + overhead of reading the ACPI timer. An attempt is made to determine and + compensate for this error. @return The number of TSC counts per second. diff --git a/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c b/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c index 7f7b0f8f6294..b141c680fb82 100644 --- a/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c +++ b/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c @@ -20,13 +20,13 @@ Calculate TSC frequency. The TSC counting frequency is determined by comparing how far it counts - during a 100us period as determined by the ACPI timer. The ACPI timer is - used because it counts at a known frequency. - The TSC is sampled, followed by waiting for ACPI_TIMER_FREQUENCY / 10000 - clocks of the ACPI timer, or 100us. The TSC is then sampled again. The - difference multiplied by 10000 is the TSC frequency. There will be a small - error because of the overhead of reading the ACPI timer. An attempt is - made to determine and compensate for this error. + during a 101.4 us period as determined by the ACPI timer. + The ACPI timer is used because it counts at a known frequency. + The TSC is sampled, followed by waiting 363 counts of the ACPI timer, + or 101.4 us. The TSC is then sampled again. The difference multiplied by + 9861 is the TSC frequency. There will be a small error because of the + overhead of reading the ACPI timer. An attempt is made to determine and + compensate for this error. @return The number of TSC counts per second. -- 2.7.0.windows.1