From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by ml01.01.org (Postfix) with ESMTP id 792AA1A1DED for ; Wed, 10 Aug 2016 19:42:31 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 10 Aug 2016 19:42:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,503,1464678000"; d="scan'208";a="1023424070" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga001.fm.intel.com with ESMTP; 10 Aug 2016 19:42:31 -0700 Received: from fmsmsx123.amr.corp.intel.com (10.18.125.38) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 10 Aug 2016 19:42:30 -0700 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by fmsmsx123.amr.corp.intel.com (10.18.125.38) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 10 Aug 2016 19:42:30 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.147]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.8]) with mapi id 14.03.0248.002; Thu, 11 Aug 2016 10:42:27 +0800 From: "Gao, Liming" To: "Zeng, Star" , "edk2-devel@lists.01.org" CC: "Kinney, Michael D" , "Lohr, Paul A" Thread-Topic: [PATCH] PcAtChipsetPkg AcpiTimerLib: Get more accurate TSC Frequency Thread-Index: AQHR83ln98twzjtMp0O+8jlGbqi0SqBDDQpQ Date: Thu, 11 Aug 2016 02:42:27 +0000 Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A1155E9AA0@shsmsx102.ccr.corp.intel.com> References: <1470883079-4472-1-git-send-email-star.zeng@intel.com> In-Reply-To: <1470883079-4472-1-git-send-email-star.zeng@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH] PcAtChipsetPkg AcpiTimerLib: Get more accurate TSC Frequency 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: Thu, 11 Aug 2016 02:42:31 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Liming Gao > -----Original Message----- > From: Zeng, Star > Sent: Thursday, August 11, 2016 10:38 AM > To: edk2-devel@lists.01.org > Cc: Zeng, Star ; Kinney, Michael D > ; Gao, Liming ; Lohr, > Paul A > Subject: [PATCH] PcAtChipsetPkg AcpiTimerLib: Get more accurate TSC > Frequency >=20 > Minimize the code overhead between the two TSC reads by adding > new internal API to calculate TSC Frequency instead of reusing > MicroSecondDelay (). >=20 > Cc: Michael D Kinney > Cc: Liming Gao > Cc: Paul A Lohr > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Star Zeng > --- > PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c | 56 > +++++++++++++++++++++- > .../Library/AcpiTimerLib/BaseAcpiTimerLib.c | 33 ++++++++----- > .../Library/AcpiTimerLib/DxeAcpiTimerLib.c | 31 ++++++++---- > 3 files changed, 99 insertions(+), 21 deletions(-) >=20 > diff --git a/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c > b/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c > index 806a4f7ce24c..e6fea231123d 100644 > --- a/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c > +++ b/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c > @@ -1,7 +1,7 @@ > /** @file > ACPI Timer implements one instance of Timer Library. >=20 > - Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
> + Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
> This program and the accompanying materials > are licensed and made available under the terms and conditions of the = BSD > License > which accompanies this distribution. The full text of the license may= be > found at > @@ -335,3 +335,57 @@ GetTimeInNanoSecond ( >=20 > return NanoSeconds; > } > + > +/** > + Calculate TSC frequency. > + > + The TSC counting frequency is determined by comparing how far it count= s > + 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 s= mall > + 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. > + > +**/ > +UINT64 > +InternalCalculateTscFrequency ( > + VOID > + ) > +{ > + UINT64 StartTSC; > + UINT64 EndTSC; > + UINT16 TimerAddr; > + UINT32 Ticks; > + UINT64 TscFrequency; > + BOOLEAN InterruptState; > + > + InterruptState =3D SaveAndDisableInterrupts (); > + > + TimerAddr =3D InternalAcpiGetAcpiTimerIoPort (); > + Ticks =3D IoRead32 (TimerAddr) + (ACPI_TIMER_FREQUENCY / 10000); // > Set Ticks to 100us in the future > + > + StartTSC =3D AsmReadTsc (); //= Get base value for the > TSC > + // > + // Wait until the ACPI timer has counted 100us. > + // Timer wrap-arounds are handled correctly by this function. > + // When the current ACPI timer value is greater than 'Ticks', the whil= e loop > will exit. > + // > + while (((Ticks - IoRead32 (TimerAddr)) & BIT23) =3D=3D 0) { > + CpuPause(); > + } > + EndTSC =3D AsmReadTsc (); //= TSC value 100us later > + > + TscFrequency =3D MultU64x32 ( > + (EndTSC - StartTSC), // N= umber of TSC counts in > 100us > + 10000 // N= umber of 100us in a second > + ); > + > + SetInterruptState (InterruptState); > + > + return TscFrequency; > +} > + > diff --git a/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c > b/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c > index 21fdb79908b8..8819ebcfccef 100644 > --- a/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c > +++ b/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c > @@ -1,7 +1,7 @@ > /** @file > ACPI Timer implements one instance of Timer Library. >=20 > - Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
> + Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
> This program and the accompanying materials > are licensed and made available under the terms and conditions of the = BSD > License > which accompanies this distribution. The full text of the license may= be > found at > @@ -17,6 +17,26 @@ > #include >=20 > /** > + Calculate TSC frequency. > + > + The TSC counting frequency is determined by comparing how far it count= s > + 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 s= mall > + 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. > + > +**/ > +UINT64 > +InternalCalculateTscFrequency ( > + VOID > + ); > + > +/** > Internal function to retrieves the 64-bit frequency in Hz. >=20 > Internal function to retrieves the 64-bit frequency in Hz. > @@ -29,14 +49,5 @@ InternalGetPerformanceCounterFrequency ( > VOID > ) > { > - BOOLEAN InterruptState; > - UINT64 Count; > - UINT64 Frequency; > - > - InterruptState =3D SaveAndDisableInterrupts (); > - Count =3D GetPerformanceCounter (); > - MicroSecondDelay (100); > - Frequency =3D MultU64x32 (GetPerformanceCounter () - Count, 10000); > - SetInterruptState (InterruptState); > - return Frequency; > + return InternalCalculateTscFrequency (); > } > diff --git a/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c > b/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c > index 6f5c07a4f0b4..7f7b0f8f6294 100644 > --- a/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c > +++ b/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c > @@ -1,7 +1,7 @@ > /** @file > ACPI Timer implements one instance of Timer Library. >=20 > - Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
> + Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
> This program and the accompanying materials > are licensed and made available under the terms and conditions of the = BSD > License > which accompanies this distribution. The full text of the license may= be > found at > @@ -16,6 +16,26 @@ > #include > #include >=20 > +/** > + Calculate TSC frequency. > + > + The TSC counting frequency is determined by comparing how far it count= s > + 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 s= mall > + 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. > + > +**/ > +UINT64 > +InternalCalculateTscFrequency ( > + VOID > + ); > + > // > // Cached performance counter frequency > // > @@ -34,15 +54,8 @@ InternalGetPerformanceCounterFrequency ( > VOID > ) > { > - BOOLEAN InterruptState; > - UINT64 Count; > - > if (mPerformanceCounterFrequency =3D=3D 0) { > - InterruptState =3D SaveAndDisableInterrupts (); > - Count =3D GetPerformanceCounter (); > - MicroSecondDelay (100); > - mPerformanceCounterFrequency =3D MultU64x32 > (GetPerformanceCounter () - Count, 10000); > - SetInterruptState (InterruptState); > + mPerformanceCounterFrequency =3D InternalCalculateTscFrequency (); > } > return mPerformanceCounterFrequency; > } > -- > 2.7.0.windows.1