From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by ml01.01.org (Postfix) with ESMTP id 28EC51A1DF1 for ; Wed, 10 Aug 2016 22:01:35 -0700 (PDT) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP; 10 Aug 2016 22:01:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,503,1464678000"; d="scan'208";a="747169898" Received: from orsmsx102.amr.corp.intel.com ([10.22.225.129]) by FMSMGA003.fm.intel.com with ESMTP; 10 Aug 2016 22:01:34 -0700 Received: from orsmsx111.amr.corp.intel.com (10.22.240.12) by ORSMSX102.amr.corp.intel.com (10.22.225.129) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 10 Aug 2016 22:01:34 -0700 Received: from orsmsx113.amr.corp.intel.com ([169.254.9.118]) by ORSMSX111.amr.corp.intel.com ([169.254.12.106]) with mapi id 14.03.0248.002; Wed, 10 Aug 2016 22:01:33 -0700 From: "Kinney, Michael D" To: "Zeng, Star" , "edk2-devel@lists.01.org" , "Kinney, Michael D" CC: "Gao, Liming" , "Lohr, Paul A" Thread-Topic: [PATCH] PcAtChipsetPkg AcpiTimerLib: Get more accurate TSC Frequency Thread-Index: AQHR83ll5NQDApcUzEyKTdKC2iGseKBDM8DQ Date: Thu, 11 Aug 2016 05:01:33 +0000 Message-ID: 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-ctpclassification: CTP_IC x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMDhkYjQxZGMtZjhlNS00YWM1LThjNTktYjlmNTA0OWZhZmE2IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE1LjkuNi42IiwiVHJ1c3RlZExhYmVsSGFzaCI6IkQ2WGNLajdjdEdvZGx4eEpaMEE3SGZyY2RDNFwvNGhoNU5MSm80SnU0MVQ4PSJ9 x-originating-ip: [10.22.254.140] 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 05:01:35 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: : Michael D Kinney > -----Original Message----- > From: Zeng, Star > Sent: Wednesday, August 10, 2016 7:38 PM > 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 Frequ= ency >=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 / 100= 00 > + 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 / 100= 00 > + 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 / 100= 00 > + 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