From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: redhat.com, ip: 209.132.183.28, mailfrom: lersek@redhat.com) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by groups.io with SMTP; Mon, 15 Apr 2019 07:08:07 -0700 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 738683002F44; Mon, 15 Apr 2019 14:08:06 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-121-136.rdu2.redhat.com [10.10.121.136]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3F9FA608C0; Mon, 15 Apr 2019 14:07:59 +0000 (UTC) Subject: Re: [edk2-devel] [PATCH v2 27/31] OvmfPkg/XenOvmf: Introduce XenTimerDxe To: devel@edk2.groups.io, anthony.perard@citrix.com Cc: Jordan Justen , Ard Biesheuvel , Julien Grall , xen-devel@lists.xenproject.org References: <20190409110844.14746-1-anthony.perard@citrix.com> <20190409110844.14746-28-anthony.perard@citrix.com> From: "Laszlo Ersek" Message-ID: <43e2eca8-99f3-dc3d-1ce9-0a2645cf8e46@redhat.com> Date: Mon, 15 Apr 2019 16:07:58 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <20190409110844.14746-28-anthony.perard@citrix.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Mon, 15 Apr 2019 14:08:06 +0000 (UTC) Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit On 04/09/19 13:08, Anthony PERARD wrote: > "PcAtChipsetPkg/8254TimerDxe" is replaced with a Xen-specific > EFI_TIMER_ARCH_PROTOCOL implementation. Also remove > 8259InterruptControllerDxe as it is not used anymore. > > This Timer uses the local APIC timer as time source as it can work on > both a Xen PVH guest and an HVM one. > > Based on the "PcAtChipsetPkg/8254TimerDxe" implementation. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Anthony PERARD > --- > > Notes: > v2: > - Use InitializeApicTimer instead of WriteLocalApicReg > - rework comments (remove many that don't apply) > - remove unused includes, and libs > - have a macro to the timervector. > - cleanup, copyright > - rework calculation of TimerCount, value to be use by the APIC timer > - check for overflow of TimerPeriod, with the apic timer, the period can > be up to about 42s on Xen (or even higher by changing the DivideValue). > > OvmfPkg/XenOvmf.dsc | 3 +- > OvmfPkg/XenOvmf.fdf | 3 +- > PcAtChipsetPkg/8254TimerDxe/8254Timer.inf => OvmfPkg/XenTimerDxe/XenTimerDxe.inf | 27 +++--- > PcAtChipsetPkg/8254TimerDxe/Timer.h => OvmfPkg/XenTimerDxe/XenTimerDxe.h | 32 +++---- > PcAtChipsetPkg/8254TimerDxe/Timer.c => OvmfPkg/XenTimerDxe/XenTimerDxe.c | 100 ++++++-------------- > 5 files changed, 55 insertions(+), 110 deletions(-) For OVMF in general, the primary residence of 8254TimerDxe is now under OvmfPkg, due to . However, as long as the module continues to exist under PcAtChipsetPkg (i.e. until is completed), I think it is OK as the copy-origin here. > > diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc > index 54601c697f..35af05715b 100644 > --- a/OvmfPkg/XenOvmf.dsc > +++ b/OvmfPkg/XenOvmf.dsc > @@ -560,10 +560,9 @@ [Components] > MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf > > MdeModulePkg/Universal/EbcDxe/EbcDxe.inf > - PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf > + OvmfPkg/XenTimerDxe/XenTimerDxe.inf > UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf > UefiCpuPkg/CpuDxe/CpuDxe.inf > - PcAtChipsetPkg/8254TimerDxe/8254Timer.inf > OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf > OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf > MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { > diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf > index f9e58befd6..d614bdce1d 100644 > --- a/OvmfPkg/XenOvmf.fdf > +++ b/OvmfPkg/XenOvmf.fdf > @@ -284,10 +284,9 @@ [FV.DXEFV] > INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf > INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf > INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf > -INF PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf > +INF OvmfPkg/XenTimerDxe/XenTimerDxe.inf > INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf > INF UefiCpuPkg/CpuDxe/CpuDxe.inf > -INF PcAtChipsetPkg/8254TimerDxe/8254Timer.inf > INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf > INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf > INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf > diff --git a/PcAtChipsetPkg/8254TimerDxe/8254Timer.inf b/OvmfPkg/XenTimerDxe/XenTimerDxe.inf > similarity index 64% > copy from PcAtChipsetPkg/8254TimerDxe/8254Timer.inf > copy to OvmfPkg/XenTimerDxe/XenTimerDxe.inf > index 46cf01de39..5ad80b9368 100644 > --- a/PcAtChipsetPkg/8254TimerDxe/8254Timer.inf > +++ b/OvmfPkg/XenTimerDxe/XenTimerDxe.inf > @@ -1,7 +1,9 @@ > ## @file > -# 8254 timer driver that provides Timer Arch protocol. > +# Local APIC timer driver that provides Timer Arch protocol. > +# > +# Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.
> +# Copyright (c) 2019, Citrix Systems, Inc. > # > -# Copyright (c) 2005 - 2018, 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 I'm sure this is well-intended (you simply created the patch before the Intel copyright notice was bumped under PcAtChipsetPkg), but now this diff appears a bit questionable, due to "downgrading" the Intel copyright. I understand it's technically correct (because the original code, being copied & customized here, matches the copyright notice too). (1) Still, could you please refresh this patch so that the Intel copyright is not touched in the "find-copies-harder" diff? (Covering all new files added in this patch.) ... Such a refresh would be justified by anyway -- we should preferably add new files only with SPDX license IDs now. Otherwise I'd be OK to ACK the patch. Thanks Laszlo > @@ -14,9 +16,8 @@ > > [Defines] > INF_VERSION = 0x00010005 > - BASE_NAME = Timer > - MODULE_UNI_FILE = Timer.uni > - FILE_GUID = f2765dec-6b41-11d5-8e71-00902707b35e > + BASE_NAME = XenTimerDxe > + FILE_GUID = 52fe8196-f9de-4d07-b22f-51f77a0e7c41 > MODULE_TYPE = DXE_DRIVER > VERSION_STRING = 1.0 > > @@ -25,24 +26,24 @@ [Defines] > [Packages] > MdePkg/MdePkg.dec > IntelFrameworkPkg/IntelFrameworkPkg.dec > + UefiCpuPkg/UefiCpuPkg.dec > + OvmfPkg/OvmfPkg.dec > > [LibraryClasses] > UefiBootServicesTableLib > BaseLib > DebugLib > UefiDriverEntryPoint > - IoLib > + LocalApicLib > > [Sources] > - Timer.h > - Timer.c > + XenTimerDxe.h > + XenTimerDxe.c > > [Protocols] > gEfiCpuArchProtocolGuid ## CONSUMES > - gEfiLegacy8259ProtocolGuid ## CONSUMES > gEfiTimerArchProtocolGuid ## PRODUCES > - > +[Pcd] > + gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES > [Depex] > - gEfiCpuArchProtocolGuid AND gEfiLegacy8259ProtocolGuid > -[UserExtensions.TianoCore."ExtraFiles"] > - TimerExtra.uni > + gEfiCpuArchProtocolGuid > diff --git a/PcAtChipsetPkg/8254TimerDxe/Timer.h b/OvmfPkg/XenTimerDxe/XenTimerDxe.h > similarity index 89% > copy from PcAtChipsetPkg/8254TimerDxe/Timer.h > copy to OvmfPkg/XenTimerDxe/XenTimerDxe.h > index 9d70e3aa19..747259c162 100644 > --- a/PcAtChipsetPkg/8254TimerDxe/Timer.h > +++ b/OvmfPkg/XenTimerDxe/XenTimerDxe.h > @@ -1,7 +1,9 @@ > /** @file > Private data structures > > -Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
> +Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
> +Copyright (c) 2019, Citrix Systems, Inc. > + > 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,34 +19,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > #include > > #include > -#include > #include > > +#include > + > #include > #include > #include > -#include > +#include > +#include > > -// > -// The PCAT 8253/8254 has an input clock at 1.193182 MHz and Timer 0 is > -// initialized as a 16 bit free running counter that generates an interrupt(IRQ0) > -// each time the counter rolls over. > -// > -// 65536 counts > -// ---------------- * 1,000,000 uS/S = 54925.4 uS = 549254 * 100 ns > -// 1,193,182 Hz > -// > - > -// > -// The maximum tick duration for 8254 timer > -// > -#define MAX_TIMER_TICK_DURATION 549254 > -// > // The default timer tick duration is set to 10 ms = 100000 100 ns units > // > #define DEFAULT_TIMER_TICK_DURATION 100000 > -#define TIMER_CONTROL_PORT 0x43 > -#define TIMER0_COUNT_PORT 0x40 > + > +// > +// The Timer Vector use for interrupt > +// > +#define LOCAL_APIC_TIMER_VECTOR 32 > > // > // Function Prototypes > diff --git a/PcAtChipsetPkg/8254TimerDxe/Timer.c b/OvmfPkg/XenTimerDxe/XenTimerDxe.c > similarity index 77% > copy from PcAtChipsetPkg/8254TimerDxe/Timer.c > copy to OvmfPkg/XenTimerDxe/XenTimerDxe.c > index 60799aadd3..fb39ce0cd3 100644 > --- a/PcAtChipsetPkg/8254TimerDxe/Timer.c > +++ b/OvmfPkg/XenTimerDxe/XenTimerDxe.c > @@ -1,7 +1,9 @@ > /** @file > Timer Architectural Protocol as defined in the DXE CIS > > -Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
> +Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
> +Copyright (c) 2019, Citrix Systems, Inc. > + > 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 > @@ -12,7 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > > **/ > > -#include "Timer.h" > +#include "XenTimerDxe.h" > > // > // The handle onto which the Timer Architectural Protocol will be installed > @@ -34,11 +36,6 @@ EFI_TIMER_ARCH_PROTOCOL mTimer = { > // > EFI_CPU_ARCH_PROTOCOL *mCpu; > > -// > -// Pointer to the Legacy 8259 Protocol instance > -// > -EFI_LEGACY_8259_PROTOCOL *mLegacy8259; > - > // > // The notification function to call on every timer interrupt. > // A bug in the compiler prevents us from initializing this here. > @@ -54,22 +51,7 @@ volatile UINT64 mTimerPeriod = 0; > // Worker Functions > // > /** > - Sets the counter value for Timer #0 in a legacy 8254 timer. > - > - @param Count The 16-bit counter value to program into Timer #0 of the legacy 8254 timer. > -**/ > -VOID > -SetPitCount ( > - IN UINT16 Count > - ) > -{ > - IoWrite8 (TIMER_CONTROL_PORT, 0x36); > - IoWrite8 (TIMER0_COUNT_PORT, (UINT8)(Count & 0xff)); > - IoWrite8 (TIMER0_COUNT_PORT, (UINT8)((Count >> 8) & 0xff)); > -} > - > -/** > - 8254 Timer #0 Interrupt Handler. > + Interrupt Handler. > > @param InterruptType The type of interrupt that occurred > @param SystemContext A pointer to the system context when the interrupt occurred > @@ -85,7 +67,7 @@ TimerInterruptHandler ( > > OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); > > - mLegacy8259->EndOfInterrupt (mLegacy8259, Efi8259Irq0); > + SendApicEoi(); > > if (mTimerNotifyFunction != NULL) { > // > @@ -187,49 +169,41 @@ TimerDriverSetTimerPeriod ( > ) > { > UINT64 TimerCount; > + UINT32 TimerFrequency; > + UINTN DivideValue = 1; > > - // > - // The basic clock is 1.19318 MHz or 0.119318 ticks per 100 ns. > - // TimerPeriod * 0.119318 = 8254 timer divisor. Using integer arithmetic > - // TimerCount = (TimerPeriod * 119318)/1000000. > - // > - // Round up to next highest integer. This guarantees that the timer is > - // equal to or slightly longer than the requested time. > - // TimerCount = ((TimerPeriod * 119318) + 500000)/1000000 > - // > - // Note that a TimerCount of 0 is equivalent to a count of 65,536 > - // > - // Since TimerCount is limited to 16 bits for IA32, TimerPeriod is limited > - // to 20 bits. > - // > if (TimerPeriod == 0) { > // > // Disable timer interrupt for a TimerPeriod of 0 > // > - mLegacy8259->DisableIrq (mLegacy8259, Efi8259Irq0); > + DisableApicTimerInterrupt(); > } else { > + TimerFrequency = PcdGet32(PcdFSBClock) / DivideValue; > > // > - // Convert TimerPeriod into 8254 counts > + // Convert TimerPeriod into local APIC counts > // > - TimerCount = DivU64x32 (MultU64x32 (119318, (UINT32) TimerPeriod) + 500000, 1000000); > + // TimerPeriod is in 100ns > + // TimerPeriod/10000000 will be in seconds. > + TimerCount = DivU64x32 (MultU64x32 (TimerPeriod, TimerFrequency), > + 10000000); > > - // > // Check for overflow > - // > - if (TimerCount >= 65536) { > - TimerCount = 0; > - TimerPeriod = MAX_TIMER_TICK_DURATION; > + if (TimerCount > MAX_UINT32) { > + TimerCount = MAX_UINT32; > + /* TimerPeriod = (MAX_UINT32 / TimerFrequency) * 10000000; */ > + TimerPeriod = 429496730; > } > + > // > - // Program the 8254 timer with the new count value > + // Program the timer with the new count value > // > - SetPitCount ((UINT16) TimerCount); > + InitializeApicTimer(DivideValue, TimerCount, TRUE, LOCAL_APIC_TIMER_VECTOR); > > // > // Enable timer interrupt > // > - mLegacy8259->EnableIrq (mLegacy8259, Efi8259Irq0, FALSE); > + EnableApicTimerInterrupt(); > } > // > // Save the new timer period > @@ -294,16 +268,9 @@ TimerDriverGenerateSoftInterrupt ( > IN EFI_TIMER_ARCH_PROTOCOL *This > ) > { > - EFI_STATUS Status; > - UINT16 IRQMask; > EFI_TPL OriginalTPL; > > - // > - // If the timer interrupt is enabled, then the registered handler will be invoked. > - // > - Status = mLegacy8259->GetMask (mLegacy8259, NULL, NULL, &IRQMask, NULL); > - ASSERT_EFI_ERROR (Status); > - if ((IRQMask & 0x1) == 0) { > + if (GetApicTimerInterruptState()) { > // > // Invoke the registered handler > // > @@ -343,7 +310,6 @@ TimerDriverInitialize ( > ) > { > EFI_STATUS Status; > - UINT32 TimerVector; > > // > // Initialize the pointer to our notify function. > @@ -361,12 +327,6 @@ TimerDriverInitialize ( > Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu); > ASSERT_EFI_ERROR (Status); > > - // > - // Find the Legacy8259 protocol. > - // > - Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &mLegacy8259); > - ASSERT_EFI_ERROR (Status); > - > // > // Force the timer to be disabled > // > @@ -374,16 +334,10 @@ TimerDriverInitialize ( > ASSERT_EFI_ERROR (Status); > > // > - // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver > + // Install interrupt handler for Local APIC Timer > // > - TimerVector = 0; > - Status = mLegacy8259->GetVector (mLegacy8259, Efi8259Irq0, (UINT8 *) &TimerVector); > - ASSERT_EFI_ERROR (Status); > - > - // > - // Install interrupt handler for 8254 Timer #0 (ISA IRQ0) > - // > - Status = mCpu->RegisterInterruptHandler (mCpu, TimerVector, TimerInterruptHandler); > + Status = mCpu->RegisterInterruptHandler (mCpu, LOCAL_APIC_TIMER_VECTOR, > + TimerInterruptHandler); > ASSERT_EFI_ERROR (Status); > > // >