From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web10.6747.1676694719854327353 for ; Fri, 17 Feb 2023 20:31:59 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=FX3pmVFf; spf=pass (domain: intel.com, ip: 134.134.136.65, mailfrom: andrei.warkentin@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676694719; x=1708230719; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=Y0TnYHN03aRRfilNUcw4obngw/FKbhjKCmLi2OHb4G0=; b=FX3pmVFf3RQscrtNA8QfnJdOg87zo5WTaxdQgl81i3tWG7YnVfeW2xVy SxPrw9AXbzc+9AZpVbfRhF9257l7vyzHqYWijL7Py98YrbbwIss1x/6WO rMvH8iM1CACBeah8U+Sd3BjjvZWY2RDXtJjDvYoeSeNL3UNJgKUzdVpd+ IL6q0JRbD1W1Jbkqc108ekXAbvqWEZBHFovsdHjabWx2iZSoCGGxcCMh4 Yr5s0qtgyJry+EA6ji+KtO3gFur566ICOGuu2UBErEamELLy94CN+l9zU bb0U4X8KysLZU7xr3KJGrqgYPMfLZmwpekciKtYVfFqGmqRDpgBkBnj2+ g==; X-IronPort-AV: E=McAfee;i="6500,9779,10624"; a="334340462" X-IronPort-AV: E=Sophos;i="5.97,306,1669104000"; d="scan'208";a="334340462" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2023 20:31:59 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10624"; a="703152920" X-IronPort-AV: E=Sophos;i="5.97,306,1669104000"; d="scan'208";a="703152920" Received: from awarkent-mobl1.amr.corp.intel.com ([10.213.189.88]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2023 20:31:58 -0800 From: "Andrei Warkentin" To: devel@edk2.groups.io Cc: Andrei Warkentin , Sunil V L , Daniel Schaefer Subject: [edk2 1/1] RiscV64 Timer: fix tick duration accounting Date: Fri, 17 Feb 2023 22:31:49 -0600 Message-Id: <20230218043149.1058-1-andrei.warkentin@intel.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable The TimerDxe implementation doesn't account for the physical time passed due to timer handler execution or (perhaps even more importantly) time spent with interrupts masked. Other implementations (e.g. like the Arm one) do. If the timer tick is always incremented at a fixed rate, then you can slow down UEFI's perception of time by running long sections of code in a critical section. Cc: Sunil V L Cc: Daniel Schaefer Signed-off-by: Andrei Warkentin --- UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c | 31 ++++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c b/UefiCpuPkg/CpuTimerDxe= RiscV64/Timer.c index 0ecefddf1f18..f65c64c296cd 100644 --- a/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c +++ b/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c @@ -41,6 +41,7 @@ STATIC EFI_TIMER_NOTIFY mTimerNotifyFunction; // The current period of the timer interrupt=0D //=0D STATIC UINT64 mTimerPeriod =3D 0;=0D +STATIC UINT64 mLastPeriodStart =3D 0;=0D =0D /**=0D Timer Interrupt Handler.=0D @@ -55,26 +56,32 @@ TimerInterruptHandler ( IN EFI_SYSTEM_CONTEXT SystemContext=0D )=0D {=0D - EFI_TPL OriginalTPL;=0D - UINT64 RiscvTimer;=0D + EFI_TPL OriginalTPL;=0D + UINT64 PeriodStart =3D RiscVReadTimer ();=0D =0D OriginalTPL =3D gBS->RaiseTPL (TPL_HIGH_LEVEL);=0D if (mTimerNotifyFunction !=3D NULL) {=0D - mTimerNotifyFunction (mTimerPeriod);=0D + //=0D + // For any number of reasons, the ticks could be coming=0D + // in slower than mTimerPeriod. For example, some code=0D + // is doing a *lot* of stuff inside an EFI_TPL_HIGH=0D + // critical section, and this should not cause the EFI=0D + // time to increment slower. So when we take an interrupt,=0D + // account for the actual time passed.=0D + //=0D + mTimerNotifyFunction (PeriodStart - mLastPeriodStart);=0D }=0D =0D - RiscVDisableTimerInterrupt (); // Disable SMode timer int=0D - RiscVClearPendingTimerInterrupt ();=0D if (mTimerPeriod =3D=3D 0) {=0D + RiscVDisableTimerInterrupt ();=0D gBS->RestoreTPL (OriginalTPL);=0D - RiscVDisableTimerInterrupt (); // Disable SMode timer int=0D return;=0D }=0D =0D - RiscvTimer =3D RiscVReadTimer ();=0D - SbiSetTimer (RiscvTimer +=3D mTimerPeriod);=0D + mLastPeriodStart =3D PeriodStart;=0D + SbiSetTimer (PeriodStart +=3D mTimerPeriod);=0D + RiscVEnableTimerInterrupt (); // enable SMode timer int=0D gBS->RestoreTPL (OriginalTPL);=0D - RiscVEnableTimerInterrupt (); // enable SMode timer int=0D }=0D =0D /**=0D @@ -154,8 +161,6 @@ TimerDriverSetTimerPeriod ( IN UINT64 TimerPeriod=0D )=0D {=0D - UINT64 RiscvTimer;=0D -=0D DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n", TimerPeriod));= =0D =0D if (TimerPeriod =3D=3D 0) {=0D @@ -165,8 +170,8 @@ TimerDriverSetTimerPeriod ( }=0D =0D mTimerPeriod =3D TimerPeriod / 10; // convert unit from 100ns to 1us=0D - RiscvTimer =3D RiscVReadTimer ();=0D - SbiSetTimer (RiscvTimer + mTimerPeriod);=0D + mLastPeriodStart =3D RiscVReadTimer ();=0D + SbiSetTimer (mLastPeriodStart + mTimerPeriod);=0D =0D mCpu->EnableInterrupt (mCpu);=0D RiscVEnableTimerInterrupt (); // enable SMode timer int=0D --=20 2.25.1