From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: None (no SPF record) identity=mailfrom; client-ip=2a00:1450:4010:c07::243; helo=mail-lf0-x243.google.com; envelope-from=mw@semihalf.com; receiver=edk2-devel@lists.01.org Received: from mail-lf0-x243.google.com (mail-lf0-x243.google.com [IPv6:2a00:1450:4010:c07::243]) (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 AB834209831EA for ; Fri, 13 Jul 2018 01:12:32 -0700 (PDT) Received: by mail-lf0-x243.google.com with SMTP id m13-v6so26460453lfb.12 for ; Fri, 13 Jul 2018 01:12:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BQXNZX+tK0f0zTVaGvuugteuhhwYIf1zipypbi+gx9U=; b=IW7KitCze79TSZt0Jy9WoOSzymiBp1sIfXBLKrizcQAc38WnhzZbDHCH5CV6NnAb7e vURcoSCp3dvyH697zHaRPdsl/nClidc4Qe83XtAdalq6xQdXkXhbL048AW+BnmLVoe3h otd+3yt3drt6N2ZyPlQrXv+hyFhuBd9iEcpjO0RDDB86GVDcdhOzvxrvzi1qptvqix9O LRGx5HG7XYphy6j/cLbzgW7i/Z5for8mS69DJN/4DQS5SfZJRG+oAbo47ymg2Q083Fae uSPcUWnkdntE2hXWoEexsc0l1Ey5++5zrKtuc7ukF/cZDcfin8RoJSu1anhFgxhn9gQ4 dXDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BQXNZX+tK0f0zTVaGvuugteuhhwYIf1zipypbi+gx9U=; b=UhPvG1L5a3nzydqFL+UVJnprMN5M0khiNtmTKjcXtc6Js/TRdVtMjuGkjVDyztwwgK LenuEAtZ4fwGze1wlzrggAWxybBPT+dyTkajaydroFfuSJ2iNulPFwOVtPOpI2N0NpyF Tz5fcnMXbklgNsLUfqTjvUWJwKQrLvWYc6/1/C+z0eHVa/TAnrL23VPLaXa2eHeVCtmy fmkUJtF/+wV+tSP5zCG5mfvGExq17WIpQ33F+0oWvg/9GOth+86KyaS+mDiqfXGnA75w REZ14a6w3MDWQOPVcWNYBBZeIktCx65HX2UM+fdYKTraEbt7LEAEkSPVUnMw9sgxu0cL JPrA== X-Gm-Message-State: AOUpUlET8ikiYUhsu9PFhZijrkJHWyFnXh4gUc+vGEUmhDjwkXSQyWpv gSUk0bHlDluHu2XZtSsWj6U53TxCZbw= X-Google-Smtp-Source: AAOMgpdWoHTuTmiQU9Tb/uDVaayzvWpez7wSNUAKOIYIwGu8mfqhKTGvJJ0pzlQkAx5OxPgTTc6Rwg== X-Received: by 2002:a19:9d92:: with SMTP id g140-v6mr4501726lfe.85.1531469550366; Fri, 13 Jul 2018 01:12:30 -0700 (PDT) Received: from gilgamesh.semihalf.com (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id m29-v6sm6485484lfj.45.2018.07.13.01.12.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 13 Jul 2018 01:12:29 -0700 (PDT) From: Marcin Wojtas To: edk2-devel@lists.01.org Cc: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, nadavh@marvell.com, hannah@marvell.com, mw@semihalf.com, jsd@semihalf.com, jaz@semihalf.com Date: Fri, 13 Jul 2018 10:12:12 +0200 Message-Id: <1531469533-31787-6-git-send-email-mw@semihalf.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1531469533-31787-1-git-send-email-mw@semihalf.com> References: <1531469533-31787-1-git-send-email-mw@semihalf.com> Subject: [platforms: PATCH v2 5/6] Marvell/Library: Implement common ArmadaIcuLib X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Jul 2018 08:12:33 -0000 ICU (Interrupt Consolidation Unit) is a mechanism, that allows to send-message based interrupts from the CP110 unit (South Bridge) to the Application Processor hardware block. After dispatching the interrupts in the GIC are generated. This patch adds a basic version of the library, that allows to configure a static mapping between CP110 interfaces and GICv2 of the Armada7k8k SoC family. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Marcin Wojtas --- Silicon/Marvell/Library/IcuLib/IcuLib.inf | 38 +++ Silicon/Marvell/Library/IcuLib/IcuLib.h | 47 +++ Silicon/Marvell/Library/IcuLib/IcuLib.c | 317 ++++++++++++++++++++ 3 files changed, 402 insertions(+) create mode 100644 Silicon/Marvell/Library/IcuLib/IcuLib.inf create mode 100644 Silicon/Marvell/Library/IcuLib/IcuLib.h create mode 100644 Silicon/Marvell/Library/IcuLib/IcuLib.c diff --git a/Silicon/Marvell/Library/IcuLib/IcuLib.inf b/Silicon/Marvell/Library/IcuLib/IcuLib.inf new file mode 100644 index 0000000..0010141 --- /dev/null +++ b/Silicon/Marvell/Library/IcuLib/IcuLib.inf @@ -0,0 +1,38 @@ +## @file +# +# Copyright (C) 2018, Marvell International Ltd. and its affiliates
+# +# 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 +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR +# IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = IcuLib + FILE_GUID = 0301c9cb-43e6-40a8-96bf-41bd0501e86d + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmadaIcuLib + +[Sources] + IcuLib.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Silicon/Marvell/Marvell.dec + +[LibraryClasses] + ArmadaSoCDescLib + DebugLib + IoLib + PcdLib + +[FixedPcd] + gMarvellTokenSpaceGuid.PcdMaxCpCount diff --git a/Silicon/Marvell/Library/IcuLib/IcuLib.h b/Silicon/Marvell/Library/IcuLib/IcuLib.h new file mode 100644 index 0000000..fba1115 --- /dev/null +++ b/Silicon/Marvell/Library/IcuLib/IcuLib.h @@ -0,0 +1,47 @@ +/** +* +* Copyright (C) 2018, Marvell International Ltd. and its affiliates. +* +* 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 +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +* Glossary - abbreviations used in Marvell SampleAtReset library implementation: +* ICU - Interrupt Consolidation Unit +* AP - Application Processor hardware block (Armada 7k8k incorporates AP806) +* CP - South Bridge hardware blocks (Armada 7k8k incorporates CP110) +* +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ICU_REG_BASE(Cp) ArmadaSoCDescCpBaseGet (CpIndex) + 0x1E0000 + +#define ICU_GROUP_REGISTER_BASE_OFFSET 0x10 +#define ICU_SET_SPI_AL(x) (0x10 + (ICU_GROUP_REGISTER_BASE_OFFSET * x)) +#define ICU_SET_SPI_AH(x) (0x14 + (ICU_GROUP_REGISTER_BASE_OFFSET * x)) +#define ICU_CLR_SPI_AL(x) (0x18 + (ICU_GROUP_REGISTER_BASE_OFFSET * x)) +#define ICU_CLR_SPI_AH(x) (0x1c + (ICU_GROUP_REGISTER_BASE_OFFSET * x)) +#define ICU_INT_CFG(x) (0x100 + (sizeof (UINT32) * x)) + +#define ICU_INT_ENABLE_OFFSET 24 +#define ICU_IS_EDGE_OFFSET 28 +#define ICU_GROUP_OFFSET 29 + +#define ICU_MAX_SUPPORTED_UNITS 2 +#define ICU_MAX_IRQS_PER_CP 64 + +#define MAX_ICU_IRQS 207 diff --git a/Silicon/Marvell/Library/IcuLib/IcuLib.c b/Silicon/Marvell/Library/IcuLib/IcuLib.c new file mode 100644 index 0000000..e88337c --- /dev/null +++ b/Silicon/Marvell/Library/IcuLib/IcuLib.c @@ -0,0 +1,317 @@ +/** +* +* Copyright (C) 2018, Marvell International Ltd. and its affiliates. +* +* 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 +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +* Glossary - abbreviations used in Marvell SampleAtReset library implementation: +* ICU - Interrupt Consolidation Unit +* AP - Application Processor hardware block (Armada 7k8k incorporates AP806) +* CP - South Bridge hardware blocks (Armada 7k8k incorporates CP110) +* +**/ + +#include "IcuLib.h" + +STATIC EFI_EVENT mEfiExitBootServicesEvent; + +STATIC CONST ICU_IRQ IrqMapNonSecure[] = { + {22, 0, IcuIrqTypeLevel}, /* PCIx4 INT A interrupt */ + {23, 1, IcuIrqTypeLevel}, /* PCIx1 INT A interrupt */ + {24, 2, IcuIrqTypeLevel}, /* PCIx1 INT A interrupt */ + {27, 3, IcuIrqTypeLevel}, /* SD/MMC */ + {33, 4, IcuIrqTypeLevel}, /* PPv2 DBG AXI monitor */ + {34, 4, IcuIrqTypeLevel}, /* HB1 AXI monitor */ + {35, 4, IcuIrqTypeLevel}, /* AP AXI monitor */ + {36, 4, IcuIrqTypeLevel}, /* PPv2 AXI monitor */ + {39, 5, IcuIrqTypeLevel}, /* PPv2 Irq */ + {40, 6, IcuIrqTypeLevel}, /* PPv2 Irq */ + {41, 7, IcuIrqTypeLevel}, /* PPv2 Irq */ + {43, 8, IcuIrqTypeLevel}, /* PPv2 Irq */ + {44, 9, IcuIrqTypeLevel}, /* PPv2 Irq */ + {45, 10, IcuIrqTypeLevel}, /* PPv2 Irq */ + {47, 11, IcuIrqTypeLevel}, /* PPv2 Irq */ + {48, 12, IcuIrqTypeLevel}, /* PPv2 Irq */ + {49, 13, IcuIrqTypeLevel}, /* PPv2 Irq */ + {51, 14, IcuIrqTypeLevel}, /* PPv2 Irq */ + {52, 15, IcuIrqTypeLevel}, /* PPv2 Irq */ + {53, 16, IcuIrqTypeLevel}, /* PPv2 Irq */ + {55, 17, IcuIrqTypeLevel}, /* PPv2 Irq */ + {56, 18, IcuIrqTypeLevel}, /* PPv2 Irq */ + {57, 19, IcuIrqTypeLevel}, /* PPv2 Irq */ + {59, 20, IcuIrqTypeLevel}, /* PPv2 Irq */ + {60, 21, IcuIrqTypeLevel}, /* PPv2 Irq */ + {61, 22, IcuIrqTypeLevel}, /* PPv2 Irq */ + {63, 23, IcuIrqTypeLevel}, /* PPv2 Irq */ + {64, 24, IcuIrqTypeLevel}, /* PPv2 Irq */ + {65, 25, IcuIrqTypeLevel}, /* PPv2 Irq */ + {67, 26, IcuIrqTypeLevel}, /* PPv2 Irq */ + {68, 27, IcuIrqTypeLevel}, /* PPv2 Irq */ + {69, 28, IcuIrqTypeLevel}, /* PPv2 Irq */ + {71, 29, IcuIrqTypeLevel}, /* PPv2 Irq */ + {72, 30, IcuIrqTypeLevel}, /* PPv2 Irq */ + {73, 31, IcuIrqTypeLevel}, /* PPv2 Irq */ + {78, 32, IcuIrqTypeLevel}, /* MG Irq */ + {79, 33, IcuIrqTypeLevel}, /* GPIO 56-63 */ + {80, 34, IcuIrqTypeLevel}, /* GPIO 48-55 */ + {81, 35, IcuIrqTypeLevel}, /* GPIO 40-47 */ + {82, 36, IcuIrqTypeLevel}, /* GPIO 32-39 */ + {83, 37, IcuIrqTypeLevel}, /* GPIO 24-31 */ + {84, 38, IcuIrqTypeLevel}, /* GPIO 16-23 */ + {85, 39, IcuIrqTypeLevel}, /* GPIO 8-15 */ + {86, 40, IcuIrqTypeLevel}, /* GPIO 0-7 */ + {88, 41, IcuIrqTypeLevel}, /* EIP-197 ring-0 */ + {89, 42, IcuIrqTypeLevel}, /* EIP-197 ring-1 */ + {90, 43, IcuIrqTypeLevel}, /* EIP-197 ring-2 */ + {91, 44, IcuIrqTypeLevel}, /* EIP-197 ring-3 */ + {92, 45, IcuIrqTypeLevel}, /* EIP-197 int */ + {95, 46, IcuIrqTypeLevel}, /* EIP-150 Irq */ + {102, 47, IcuIrqTypeLevel}, /* USB3 Device Irq */ + {105, 48, IcuIrqTypeLevel}, /* USB3 Host-1 Irq */ + {106, 49, IcuIrqTypeLevel}, /* USB3 Host-0 Irq */ + {107, 50, IcuIrqTypeLevel}, /* SATA Host-1 Irq */ + {109, 50, IcuIrqTypeLevel}, /* SATA Host-0 Irq */ + {115, 52, IcuIrqTypeLevel}, /* NAND Irq */ + {117, 53, IcuIrqTypeLevel}, /* SPI-1 Irq */ + {118, 54, IcuIrqTypeLevel}, /* SPI-0 Irq */ + {120, 55, IcuIrqTypeLevel}, /* I2C 0 Irq */ + {121, 56, IcuIrqTypeLevel}, /* I2C 1 Irq */ + {122, 57, IcuIrqTypeLevel}, /* UART 0 Irq */ + {123, 58, IcuIrqTypeLevel}, /* UART 1 Irq */ + {124, 59, IcuIrqTypeLevel}, /* UART 2 Irq */ + {125, 60, IcuIrqTypeLevel}, /* UART 3 Irq */ + {127, 61, IcuIrqTypeLevel}, /* GOP-3 Irq */ + {128, 62, IcuIrqTypeLevel}, /* GOP-2 Irq */ + {129, 63, IcuIrqTypeLevel}, /* GOP-0 Irq */ +}; + +/* + * SEI - System Error Interrupts + * Note: SPI ID 0-20 are reserved for North-Bridge + */ +STATIC ICU_IRQ IrqMapSei[] = { + {11, 21, IcuIrqTypeLevel}, /* SEI error CP-2-CP */ + {15, 22, IcuIrqTypeLevel}, /* PIDI-64 SOC */ + {16, 23, IcuIrqTypeLevel}, /* D2D error Irq */ + {17, 24, IcuIrqTypeLevel}, /* D2D Irq */ + {18, 25, IcuIrqTypeLevel}, /* NAND error */ + {19, 26, IcuIrqTypeLevel}, /* PCIx4 error */ + {20, 27, IcuIrqTypeLevel}, /* PCIx1_0 error */ + {21, 28, IcuIrqTypeLevel}, /* PCIx1_1 error */ + {25, 29, IcuIrqTypeLevel}, /* SDIO reg error */ + {75, 30, IcuIrqTypeLevel}, /* IOB error */ + {94, 31, IcuIrqTypeLevel}, /* EIP150 error */ + {97, 32, IcuIrqTypeLevel}, /* XOR-1 system error */ + {99, 33, IcuIrqTypeLevel}, /* XOR-0 system error */ + {108, 34, IcuIrqTypeLevel}, /* SATA-1 error */ + {110, 35, IcuIrqTypeLevel}, /* SATA-0 error */ + {114, 36, IcuIrqTypeLevel}, /* TDM-MC error */ + {116, 37, IcuIrqTypeLevel}, /* DFX server Irq */ + {117, 38, IcuIrqTypeLevel}, /* Device bus error */ + {147, 39, IcuIrqTypeLevel}, /* Audio error */ + {171, 40, IcuIrqTypeLevel}, /* PIDI Sync error */ +}; + +/* REI - RAM Error Interrupts */ +STATIC CONST ICU_IRQ IrqMapRei[] = { + {12, 0, IcuIrqTypeLevel}, /* REI error CP-2-CP */ + {26, 1, IcuIrqTypeLevel}, /* SDIO memory error */ + {87, 2, IcuIrqTypeLevel}, /* EIP-197 ECC error */ + {93, 3, IcuIrqTypeEdge}, /* EIP-150 RAM error */ + {96, 4, IcuIrqTypeLevel}, /* XOR-1 memory Irq */ + {98, 5, IcuIrqTypeLevel}, /* XOR-0 memory Irq */ + {100, 6, IcuIrqTypeEdge}, /* USB3 device tx parity */ + {101, 7, IcuIrqTypeEdge}, /* USB3 device rq parity */ + {103, 8, IcuIrqTypeEdge}, /* USB3H-1 RAM error */ + {104, 9, IcuIrqTypeEdge}, /* USB3H-0 RAM error */ +}; + +STATIC CONST ICU_CONFIG IcuInitialConfig = { + .NonSecure = { IrqMapNonSecure, ARRAY_SIZE (IrqMapNonSecure) }, + .Sei = { IrqMapSei, ARRAY_SIZE (IrqMapSei) }, + .Rei = { IrqMapRei, ARRAY_SIZE (IrqMapRei) }, +}; + +STATIC +VOID +IcuClearIrq ( + IN UINTN IcuBase, + IN UINTN Nr +) +{ + MmioWrite32 (IcuBase + ICU_INT_CFG (Nr), 0); +} + +STATIC +VOID +IcuSetIrq ( + IN UINTN IcuBase, + IN CONST ICU_IRQ *Irq, + IN UINTN SpiBase, + IN ICU_GROUP Group + ) +{ + UINT32 IcuInt; + + IcuInt = (Irq->SpiId + SpiBase) | (1 << ICU_INT_ENABLE_OFFSET); + IcuInt |= Irq->IrqType << ICU_IS_EDGE_OFFSET; + IcuInt |= Group << ICU_GROUP_OFFSET; + + MmioWrite32 (IcuBase + ICU_INT_CFG (Irq->IcuId), IcuInt); +} + +STATIC +VOID +IcuConfigure ( + IN UINTN CpIndex, + IN MV_SOC_ICU_DESC *IcuDesc, + IN CONST ICU_CONFIG *Config + ) +{ + UINTN IcuBase, Index, SpiOffset, SpiBase; + CONST ICU_IRQ *Irq; + ICU_MSI *Msi; + + /* Get ICU registers base address */ + IcuBase = ICU_REG_BASE (CpIndex); + /* Get the base of the GIC SPI ID in the MSI message */ + SpiBase = IcuDesc->IcuSpiBase; + /* Get multiple CP110 instances SPI ID shift */ + SpiOffset = CpIndex * ICU_MAX_IRQS_PER_CP; + /* Get MSI addresses per interrupt group */ + Msi = IcuDesc->IcuMsi; + + /* Set the address for SET_SPI and CLR_SPI registers in AP */ + for (Index = 0; Index < IcuGroupMax; Index++, Msi++) { + MmioWrite32 (IcuBase + ICU_SET_SPI_AL (Msi->Group), + Msi->SetSpiAddr & 0xFFFFFFFF); + MmioWrite32 (IcuBase + ICU_SET_SPI_AH (Msi->Group), Msi->SetSpiAddr >> 32); + MmioWrite32 (IcuBase + ICU_CLR_SPI_AL (Msi->Group), + Msi->ClrSpiAddr & 0xFFFFFFFF); + MmioWrite32 (IcuBase + ICU_CLR_SPI_AH (Msi->Group), Msi->ClrSpiAddr >> 32); + } + + /* Mask all ICU interrupts */ + for (Index = 0; Index < MAX_ICU_IRQS; Index++) { + IcuClearIrq (IcuBase, Index); + } + + /* Configure the ICU interrupt lines */ + Irq = Config->NonSecure.Map; + for (Index = 0; Index < Config->NonSecure.Size; Index++, Irq++) { + IcuSetIrq (IcuBase, Irq, SpiBase + SpiOffset, IcuGroupNsr); + } + + Irq = Config->Sei.Map; + for (Index = 0; Index < Config->Sei.Size; Index++, Irq++) { + IcuSetIrq (IcuBase, Irq, SpiBase, IcuGroupSei); + } + + Irq = Config->Rei.Map; + for (Index = 0; Index < Config->Rei.Size; Index++, Irq++) { + IcuSetIrq (IcuBase, Irq, SpiBase, IcuGroupRei); + } +} + +STATIC +VOID +IcuClearGicSpi ( + IN UINTN CpIndex, + IN MV_SOC_ICU_DESC *IcuDesc + ) +{ + CONST ICU_CONFIG *Config; + UINTN Index, SpiOffset, SpiBase; + CONST ICU_IRQ *Irq; + ICU_MSI *Msi; + + Config = &IcuInitialConfig; + + /* Get the base of the GIC SPI ID in the MSI message */ + SpiBase = IcuDesc->IcuSpiBase; + /* Get multiple CP110 instances SPI ID shift */ + SpiOffset = CpIndex * ICU_MAX_IRQS_PER_CP; + /* Get MSI addresses per interrupt group */ + Msi = IcuDesc->IcuMsi; + + /* Clear ICU-generated GIC SPI interrupts */ + Irq = Config->NonSecure.Map; + for (Index = 0; Index < Config->NonSecure.Size; Index++, Irq++) { + MmioWrite32 (Msi->ClrSpiAddr, Irq->SpiId + SpiBase + SpiOffset); + } +} + +VOID +EFIAPI +IcuCleanUp ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + MV_SOC_ICU_DESC *IcuDesc; + UINTN CpCount, CpIndex; + + IcuDesc = Context; + + CpCount = FixedPcdGet8 (PcdMaxCpCount); + if (CpCount > ICU_MAX_SUPPORTED_UNITS) { + CpCount = ICU_MAX_SUPPORTED_UNITS; + } + + for (CpIndex = 0; CpIndex < CpCount; CpIndex++) { + IcuClearGicSpi (CpIndex, IcuDesc); + } +} + +EFI_STATUS +EFIAPI +ArmadaIcuInitialize ( + ) +{ + MV_SOC_ICU_DESC *IcuDesc; + UINTN CpCount, CpIndex; + EFI_STATUS Status; + + /* + * Due to limited amount of interrupt lanes, only 2 units can be + * wired to the GIC. + */ + CpCount = FixedPcdGet8 (PcdMaxCpCount); + if (CpCount > ICU_MAX_SUPPORTED_UNITS) { + DEBUG ((DEBUG_ERROR, + "%a: Default ICU to GIC mapping is available for maximum %d CP110 units", + ICU_MAX_SUPPORTED_UNITS, + __FUNCTION__)); + CpCount = ICU_MAX_SUPPORTED_UNITS; + } + + /* Obtain SoC description of the ICU */ + Status = ArmadaSoCDescIcuGet (&IcuDesc); + if (EFI_ERROR (Status)) { + return Status; + } + + /* Configure default ICU to GIC interrupt mapping for each CP110 */ + for (CpIndex = 0; CpIndex < CpCount; CpIndex++) { + IcuConfigure (CpIndex, IcuDesc, &IcuInitialConfig); + } + + /* + * In order to be immune to the OS capability of clearing ICU-generated + * GIC interrupts, register ExitBootServices event, that will + * make sure they remain disabled during OS boot. + */ + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + IcuCleanUp, + IcuDesc, + &mEfiExitBootServicesEvent); + + return Status; +} -- 2.7.4