From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c09::22b; helo=mail-wm0-x22b.google.com; envelope-from=leif.lindholm@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm0-x22b.google.com (mail-wm0-x22b.google.com [IPv6:2a00:1450:400c:c09::22b]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2EB8F21CF58CE for ; Thu, 5 Oct 2017 13:11:43 -0700 (PDT) Received: by mail-wm0-x22b.google.com with SMTP id b189so4099948wmd.4 for ; Thu, 05 Oct 2017 13:15:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=+piGzPQIqsaeZS60YyMH6vryuy/yWdGuxLa/VtBh+L4=; b=SI1+KcXuAPCqjI7jv7Pjcwk6pmp5WDqQKJT9tLLNlwKGBCxhZ7B5Yl67JzcL/6Vfmi 7Od5SlFLnxeMCMAwMfzrux0iRWdgbxZ/85JHtAr54VipHX2BgF023p58yjaTYosPKELL Y3KU0cMLJ9ZGDJcGNhZPhmJCrDXzcMqm3bg4c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=+piGzPQIqsaeZS60YyMH6vryuy/yWdGuxLa/VtBh+L4=; b=QK+QG8IwlUgPufxQ9jjJk3GE69ZfU287Bd1NrfKi03vHXa3nFbIv5xCr5negy07dng vRqckY5mX+iJh7zbeHyIGWMcsPwkUfi7TT1bycmeSuF7ln9T0yM4zoGp6uplY6uKs8hC X9AOfZPKRmjvI20d+kUHqpcXmI3KFIet7gcHPWYME0+VuogrA70R44xttVlnWc6CV0mV 8BHwDNa0GqONbYCBrHxkkz6WzFBQA9yWAexPKWMMW+Y1oq8tqzsE58/eRZp+olPOAbQz vBnVXvDFAjwOPp9qKX7BAcIDnRhxLbwaFQMNlj43gMMmmCBcTikPbxkvwZuPa9bJg8W+ ovPg== X-Gm-Message-State: AMCzsaWv3xqm4lnNGKW0PyKjEsjs+94Cmag2iwSwH1eR2VDTJUooJ0ox idA4cQYOCqZVOUQizkx3fJNNkg== X-Google-Smtp-Source: AOwi7QCSjqlfaFlt+ZVP318ETprYNEwWmjGneLBHXxC82Qh7VIGWWbodZQrrNCCyUiHPh+/H6k/RAQ== X-Received: by 10.28.94.138 with SMTP id s132mr224825wmb.0.1507234505267; Thu, 05 Oct 2017 13:15:05 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id v80sm124653wmv.37.2017.10.05.13.15.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 05 Oct 2017 13:15:03 -0700 (PDT) Date: Thu, 5 Oct 2017 21:15:01 +0100 From: Leif Lindholm To: ard.biesheuvel@linaro.org Cc: edk2-devel@lists.01.org, evan.lloyd@arm.com, Matteo Carlini Message-ID: <20171005201501.hbdkecp3el5q4e3o@bivouac.eciton.net> References: <20170921162345.11724-1-evan.lloyd@arm.com> <20170921162345.11724-4-evan.lloyd@arm.com> MIME-Version: 1.0 In-Reply-To: <20170921162345.11724-4-evan.lloyd@arm.com> User-Agent: NeoMutt/20170113 (1.7.2) Subject: Re: [PATCH 3/4] ArmPkg/ArmGicDxe: Expose HardwareInterrupt2 protocol X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Oct 2017 20:11:44 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Sep 21, 2017 at 05:23:43PM +0100, evan.lloyd@arm.com wrote: > From: Ard Biesheuvel > > The existing HardwareInterrupt protocol lacked a means to configure the > level/edge properties of an interrupt. The new HardwareInterrupt2 > protocol introduced this capability. > This patch updates the GIC drivers to provide the new interfaces. > The changes comprise: > Update to use HardwareInterrupt2 protocol > Additions to register info in ArmGicLib.h > Added new functionality (GetTriggerType and SetTriggerType) > > The requirement for this change derives from a problem detected on ARM > Juno boards, but the change is of generic (ARM) relevance. > > This commit is in response to review on the mailing list and, as > suggested there, rolls Girish's updates onto Ard's original example. > > Contributed-under: TianoCore Contribution Agreement 1.0 This patch has lagged: Ard, are you happy to confirm this one could be updated to 1.1? / Leif > Signed-off-by: Ard Biesheuvel > Signed-off-by: Girish Pathak > Signed-off-by: Evan Lloyd > Tested-by: Girish Pathak > --- > > Notes: > 376_irqtype_v4 > [Leif Lindholm] > - Fixed continuation line indent > - Moved EFI_D_ERROR changes out > - Replaced MmioBitFieldRead32 > - Fixed indent and parentheses > > ArmPkg/Drivers/ArmGic/ArmGicDxe.inf | 3 +- > ArmPkg/Drivers/ArmGic/ArmGicDxe.h | 23 ++++ > ArmPkg/Include/Library/ArmGicLib.h | 11 +- > ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c | 43 ++++++ > ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c | 137 ++++++++++++++++++++ > ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c | 136 +++++++++++++++++++ > 6 files changed, 351 insertions(+), 2 deletions(-) > > diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf > index e554301c4b28022c805f69242cf6ee979d19abc2..d5921533fb68fa32c3e0705b05930700ee81da07 100644 > --- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf > +++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf > @@ -1,7 +1,7 @@ > #/** @file > # > # Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
> -# Copyright (c) 2012 - 2015, ARM Ltd. All rights reserved.
> +# Copyright (c) 2012 - 2017, ARM Ltd. All rights reserved.
> # > # This program and the accompanying materials > # are licensed and made available under the terms and conditions of the BSD License > @@ -48,6 +48,7 @@ [LibraryClasses] > > [Protocols] > gHardwareInterruptProtocolGuid > + gHardwareInterrupt2ProtocolGuid > gEfiCpuArchProtocolGuid > > [Pcd.common] > diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.h b/ArmPkg/Drivers/ArmGic/ArmGicDxe.h > index 76945282d9b9bbf6da872a408a56387ee321a3b5..610ffacc7eb025011f87ad5e6e457a610bd570a9 100644 > --- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.h > +++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.h > @@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > > #include > #include > +#include > > extern UINTN mGicNumInterrupts; > extern HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers; > @@ -32,6 +33,7 @@ extern HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers; > EFI_STATUS > InstallAndRegisterInterruptService ( > IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol, > + IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *Interrupt2Protocol, > IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler, > IN EFI_EVENT_NOTIFY ExitBootServicesEvent > ); > @@ -58,4 +60,25 @@ GicV3DxeInitialize ( > IN EFI_SYSTEM_TABLE *SystemTable > ); > > + > +// Shared code > + > +/** > + Calculate GICD_ICFGRn base address and corresponding bit > + field Int_config[1] of the GIC distributor register. > + > + @param Source Hardware source of the interrupt. > + @param RegAddress Corresponding GICD_ICFGRn base address. > + @param Config1Bit Bit number of F Int_config[1] bit in the register. > + > + @retval EFI_SUCCESS Source interrupt supported. > + @retval EFI_UNSUPPORTED Source interrupt is not supported. > +**/ > +EFI_STATUS > +GicGetDistributorIcfgBaseAndBit ( > + IN HARDWARE_INTERRUPT_SOURCE Source, > + OUT UINTN *RegAddress, > + OUT UINTN *Config1Bit > + ); > + > #endif > diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h > index a4ede82bc6c07733f880a12fff54001590a0518a..4b21ea9e4e76cb83c0c3421c1d9d88b456192687 100644 > --- a/ArmPkg/Include/Library/ArmGicLib.h > +++ b/ArmPkg/Include/Library/ArmGicLib.h > @@ -49,8 +49,17 @@ > #define ARM_GIC_ICDDCR_ARE (1 << 4) // Affinity Routing Enable (ARE) > #define ARM_GIC_ICDDCR_DS (1 << 6) // Disable Security (DS) > > +// GICD_ICDICFR bits > +#define ARM_GIC_ICDICFR_WIDTH 32 // ICDICFR is a 32 bit register > +#define ARM_GIC_ICDICFR_BYTES (ARM_GIC_ICDICFR_WIDTH / 8) > +#define ARM_GIC_ICDICFR_F_WIDTH 2 // Each F field is 2 bits > +#define ARM_GIC_ICDICFR_F_STRIDE 16 // (32/2) F fields per register > +#define ARM_GIC_ICDICFR_F_CONFIG1_BIT 1 // Bit number within F field > +#define ARM_GIC_ICDICFR_LEVEL_TRIGGERED 0x0 // Level triggered interrupt > +#define ARM_GIC_ICDICFR_EDGE_TRIGGERED 0x1 // Edge triggered interrupt > + > + > // GIC Redistributor > - > #define ARM_GICR_CTLR_FRAME_SIZE SIZE_64KB > #define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB > > diff --git a/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c b/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c > index 7ca3ca8f52afe52c827ca82b749b665184813fc1..bff8d983cf02f7fd1fa6165824cb6556cdea5c6f 100644 > --- a/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c > +++ b/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c > @@ -39,6 +39,46 @@ UINTN mGicNumInterrupts = 0; > > HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL; > > + > +/** > + Calculate GICD_ICFGRn base address and corresponding bit > + field Int_config[1] of the GIC distributor register. > + > + @param Source Hardware source of the interrupt. > + @param RegAddress Corresponding GICD_ICFGRn base address. > + @param Config1Bit Bit number of F Int_config[1] bit in the register. > + > + @retval EFI_SUCCESS Source interrupt supported. > + @retval EFI_UNSUPPORTED Source interrupt is not supported. > +**/ > +EFI_STATUS > +GicGetDistributorIcfgBaseAndBit ( > + IN HARDWARE_INTERRUPT_SOURCE Source, > + OUT UINTN *RegAddress, > + OUT UINTN *Config1Bit > + ) > +{ > + UINTN RegIndex; > + UINTN Field; > + > + if (Source >= mGicNumInterrupts) { > + ASSERT(Source < mGicNumInterrupts); > + return EFI_UNSUPPORTED; > + } > + > + RegIndex = Source / ARM_GIC_ICDICFR_F_STRIDE; // NOTE: truncation is significant > + Field = Source % ARM_GIC_ICDICFR_F_STRIDE; > + *RegAddress = PcdGet64 (PcdGicDistributorBase) > + + ARM_GIC_ICDICFR > + + (ARM_GIC_ICDICFR_BYTES * RegIndex); > + *Config1Bit = ((Field * ARM_GIC_ICDICFR_F_WIDTH) > + + ARM_GIC_ICDICFR_F_CONFIG1_BIT); > + > + return EFI_SUCCESS; > +} > + > + > + > /** > Register Handler for the specified interrupt source. > > @@ -84,6 +124,7 @@ RegisterInterruptSource ( > EFI_STATUS > InstallAndRegisterInterruptService ( > IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol, > + IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *Interrupt2Protocol, > IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler, > IN EFI_EVENT_NOTIFY ExitBootServicesEvent > ) > @@ -103,6 +144,8 @@ InstallAndRegisterInterruptService ( > &gHardwareInterruptHandle, > &gHardwareInterruptProtocolGuid, > InterruptProtocol, > + &gHardwareInterrupt2ProtocolGuid, > + Interrupt2Protocol, > NULL > ); > if (EFI_ERROR (Status)) { > diff --git a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c > index 3d5d034efbb1bf2e1e84841cab4175bc607845c2..7717ebe75330562db61a30ab4e5c5ad559c5f201 100644 > --- a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c > +++ b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c > @@ -29,6 +29,7 @@ Abstract: > #define ARM_GIC_DEFAULT_PRIORITY 0x80 > > extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol; > +extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol; > > STATIC UINT32 mGicInterruptInterfaceBase; > STATIC UINT32 mGicDistributorBase; > @@ -198,6 +199,141 @@ EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol = { > GicV2EndOfInterrupt > }; > > +/** > + Get interrupt trigger type of an interrupt > + > + @param This Instance pointer for this protocol > + @param Source Hardware source of the interrupt. > + @param TriggerType Returns interrupt trigger type. > + > + @retval EFI_SUCCESS Source interrupt supported. > + @retval EFI_UNSUPPORTED Source interrupt is not supported. > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +GicV2GetTriggerType ( > + IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, > + IN HARDWARE_INTERRUPT_SOURCE Source, > + OUT EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE *TriggerType > + ) > +{ > + UINTN RegAddress; > + UINTN Config1Bit; > + EFI_STATUS Status; > + > + Status = GicGetDistributorIcfgBaseAndBit ( > + Source, > + &RegAddress, > + &Config1Bit > + ); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if ((MmioRead32 (RegAddress) & (1 << Config1Bit)) == 0) { > + *TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH; > + } else { > + *TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Set interrupt trigger type of an interrupt > + > + @param This Instance pointer for this protocol > + @param Source Hardware source of the interrupt. > + @param TriggerType Interrupt trigger type. > + > + @retval EFI_SUCCESS Source interrupt supported. > + @retval EFI_UNSUPPORTED Source interrupt is not supported. > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +GicV2SetTriggerType ( > + IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, > + IN HARDWARE_INTERRUPT_SOURCE Source, > + IN EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE TriggerType > + ) > +{ > + UINTN RegAddress; > + UINTN Config1Bit; > + UINT32 Value; > + EFI_STATUS Status; > + BOOLEAN SourceEnabled; > + > + if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) > + && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) { > + DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \ > + TriggerType)); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + Status = GicGetDistributorIcfgBaseAndBit ( > + Source, > + &RegAddress, > + &Config1Bit > + ); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = GicV2GetInterruptSourceState ( > + (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, > + Source, > + &SourceEnabled > + ); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Value = (TriggerType == EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) > + ? ARM_GIC_ICDICFR_EDGE_TRIGGERED > + : ARM_GIC_ICDICFR_LEVEL_TRIGGERED; > + > + // Before changing the value, we must disable the interrupt, > + // otherwise GIC behavior is UNPREDICTABLE. > + if (SourceEnabled) { > + GicV2DisableInterruptSource ( > + (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, > + Source > + ); > + } > + > + MmioAndThenOr32 ( > + RegAddress, > + ~(0x1 << Config1Bit), > + Value << Config1Bit > + ); > + > + // Restore interrupt state > + if (SourceEnabled) { > + GicV2EnableInterruptSource ( > + (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, > + Source > + ); > + } > + > + return EFI_SUCCESS; > +} > + > +EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol = { > + (HARDWARE_INTERRUPT2_REGISTER)RegisterInterruptSource, > + (HARDWARE_INTERRUPT2_ENABLE)GicV2EnableInterruptSource, > + (HARDWARE_INTERRUPT2_DISABLE)GicV2DisableInterruptSource, > + (HARDWARE_INTERRUPT2_INTERRUPT_STATE)GicV2GetInterruptSourceState, > + (HARDWARE_INTERRUPT2_END_OF_INTERRUPT)GicV2EndOfInterrupt, > + GicV2GetTriggerType, > + GicV2SetTriggerType > +}; > + > /** > Shutdown our hardware > > @@ -321,6 +457,7 @@ GicV2DxeInitialize ( > > Status = InstallAndRegisterInterruptService ( > &gHardwareInterruptV2Protocol, > + &gHardwareInterrupt2V2Protocol, > GicV2IrqInterruptHandler, > GicV2ExitBootServicesEvent > ); > diff --git a/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c b/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c > index 50b51ffcf57b23b110899c7c55237cf85b61d196..01154848f4439af3e87e89cf796f3d69ce4a0c4a 100644 > --- a/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c > +++ b/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c > @@ -19,6 +19,7 @@ > #define ARM_GIC_DEFAULT_PRIORITY 0x80 > > extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol; > +extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V3Protocol; > > STATIC UINTN mGicDistributorBase; > STATIC UINTN mGicRedistributorsBase; > @@ -192,6 +193,140 @@ EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol = { > GicV3EndOfInterrupt > }; > > +/** > + Get interrupt trigger type of an interrupt > + > + @param This Instance pointer for this protocol > + @param Source Hardware source of the interrupt. > + @param TriggerType Returns interrupt trigger type. > + > + @retval EFI_SUCCESS Source interrupt supported. > + @retval EFI_UNSUPPORTED Source interrupt is not supported. > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +GicV3GetTriggerType ( > + IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, > + IN HARDWARE_INTERRUPT_SOURCE Source, > + OUT EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE *TriggerType > + ) > +{ > + UINTN RegAddress; > + UINTN Config1Bit; > + EFI_STATUS Status; > + > + Status = GicGetDistributorIcfgBaseAndBit ( > + Source, > + &RegAddress, > + &Config1Bit > + ); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if ((MmioRead32 (RegAddress) & (1 << Config1Bit)) == 0) { > + *TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH; > + } else { > + *TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Set interrupt trigger type of an interrupt > + > + @param This Instance pointer for this protocol > + @param Source Hardware source of the interrupt. > + @param TriggerType Interrupt trigger type. > + > + @retval EFI_SUCCESS Source interrupt supported. > + @retval EFI_UNSUPPORTED Source interrupt is not supported. > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +GicV3SetTriggerType ( > + IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, > + IN HARDWARE_INTERRUPT_SOURCE Source, > + IN EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE TriggerType > + ) > +{ > + UINTN RegAddress; > + UINTN Config1Bit; > + UINT32 Value; > + EFI_STATUS Status; > + BOOLEAN SourceEnabled; > + > + if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) > + && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH)) { > + DEBUG ((DEBUG_ERROR, "Invalid interrupt trigger type: %d\n", \ > + TriggerType)); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + Status = GicGetDistributorIcfgBaseAndBit ( > + Source, > + &RegAddress, > + &Config1Bit > + ); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = GicV3GetInterruptSourceState ( > + (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, > + Source, > + &SourceEnabled > + ); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Value = (TriggerType == EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING) > + ? ARM_GIC_ICDICFR_EDGE_TRIGGERED > + : ARM_GIC_ICDICFR_LEVEL_TRIGGERED; > + > + // Before changing the value, we must disable the interrupt, > + // otherwise GIC behavior is UNPREDICTABLE. > + if (SourceEnabled) { > + GicV3DisableInterruptSource ( > + (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, > + Source > + ); > + } > + > + MmioAndThenOr32 ( > + RegAddress, > + ~(0x1 << Config1Bit), > + Value << Config1Bit > + ); > + // Restore interrupt state > + if (SourceEnabled) { > + GicV3EnableInterruptSource ( > + (EFI_HARDWARE_INTERRUPT_PROTOCOL*)This, > + Source > + ); > + } > + > + return EFI_SUCCESS; > +} > + > +EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V3Protocol = { > + (HARDWARE_INTERRUPT2_REGISTER)RegisterInterruptSource, > + (HARDWARE_INTERRUPT2_ENABLE)GicV3EnableInterruptSource, > + (HARDWARE_INTERRUPT2_DISABLE)GicV3DisableInterruptSource, > + (HARDWARE_INTERRUPT2_INTERRUPT_STATE)GicV3GetInterruptSourceState, > + (HARDWARE_INTERRUPT2_END_OF_INTERRUPT)GicV3EndOfInterrupt, > + GicV3GetTriggerType, > + GicV3SetTriggerType > +}; > + > /** > Shutdown our hardware > > @@ -353,6 +488,7 @@ GicV3DxeInitialize ( > > Status = InstallAndRegisterInterruptService ( > &gHardwareInterruptV3Protocol, > + &gHardwareInterrupt2V3Protocol, > GicV3IrqInterruptHandler, > GicV3ExitBootServicesEvent > ); > -- > Guid("CE165669-3EF3-493F-B85D-6190EE5B9759") >