diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index c41f04ad1a..10cc713ad8 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -146,6 +146,10 @@ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask|0xF03|UINT32|0x00000031 # The Primary Core is ClusterId[0] & CoreId[0] gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037 + # Number of the CPU Interface for the Primary Core (eg: The number for the CPU0 of + # Cluster1 might be 4 if the implementer had followed the convention: Cpu Interface + # = 4 * Cluster) + gArmTokenSpaceGuid.PcdGicPrimaryCoreId|0|UINT32|0x00000043 # # ARM L2x0 PCDs diff --git a/ArmPkg/Drivers/PL390Gic/PL390Gic.c b/ArmPkg/Drivers/PL390Gic/PL390Gic.c index 56c0fd9c4f..8a10d113f7 100644 --- a/ArmPkg/Drivers/PL390Gic/PL390Gic.c +++ b/ArmPkg/Drivers/PL390Gic/PL390Gic.c @@ -38,45 +38,33 @@ ArmGicSendSgiTo ( MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId); } -UINT32 +RETURN_STATUS EFIAPI -ArmGicAcknowledgeSgiFrom ( - IN INTN GicInterruptInterfaceBase, - IN INTN CoreId +ArmGicAcknowledgeInterrupt ( + IN UINTN GicDistributorBase, + IN UINTN GicInterruptInterfaceBase, + OUT UINTN *CoreId, + OUT UINTN *InterruptId ) { - INTN InterruptId; + UINT32 Interrupt; - InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR); + // Read the Interrupt Acknowledge Register + Interrupt = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR); - // Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID - if ((((CoreId & 0x7) << 10) | PcdGet32(PcdGicSgiIntId)) == InterruptId) { - // Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId); - return 1; + // Check if it is a valid interrupt ID + if ((Interrupt & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase)) { + // Got a valid SGI number hence signal End of Interrupt by writing to ICCEOIR + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Interrupt); + + if (CoreId) { + *CoreId = (Interrupt >> 10) & 0x7; + } + if (InterruptId) { + *InterruptId = Interrupt & 0x3FF; + } + return RETURN_SUCCESS; } else { - return 0; - } -} - -UINT32 -EFIAPI -ArmGicAcknowledgeSgi2From ( - IN INTN GicInterruptInterfaceBase, - IN INTN CoreId, - IN INTN SgiId - ) -{ - INTN InterruptId; - - InterruptId = MmioRead32(GicInterruptInterfaceBase + ARM_GIC_ICCIAR); - - // Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID - if((((CoreId & 0x7) << 10) | (SgiId & 0x3FF)) == (InterruptId & 0x1FFF)) { - // Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR - MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId); - return 1; - } else { - return 0; + return RETURN_INVALID_PARAMETER; } } diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h index d6ffc753c7..c115767bbf 100644 --- a/ArmPkg/Include/Library/ArmGicLib.h +++ b/ArmPkg/Include/Library/ArmGicLib.h @@ -117,19 +117,13 @@ ArmGicSendSgiTo ( IN INTN SgiId ); -UINT32 +RETURN_STATUS EFIAPI -ArmGicAcknowledgeSgiFrom ( - IN INTN GicInterruptInterfaceBase, - IN INTN CoreId - ); - -UINT32 -EFIAPI -ArmGicAcknowledgeSgi2From ( - IN INTN GicInterruptInterfaceBase, - IN INTN CoreId, - IN INTN SgiId +ArmGicAcknowledgeInterrupt ( + IN UINTN GicDistributorBase, + IN UINTN GicInterruptInterfaceBase, + OUT UINTN *CoreId, + OUT UINTN *InterruptId ); UINTN diff --git a/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c b/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c index 6992b4a609..471a42c1ab 100755 --- a/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c +++ b/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c @@ -38,7 +38,7 @@ NonSecureWaitForFirmware ( ArmCallWFI(); // Acknowledge the interrupt and send End of Interrupt signal. - ArmGicAcknowledgeSgiFrom (PcdGet32(PcdGicInterruptInterfaceBase), PRIMARY_CORE_ID); + ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), NULL, NULL); // Jump to secondary core entry point. secondary_start (); diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c index 01cb06f8e5..aeea8f5bda 100644 --- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c +++ b/ArmPlatformPkg/PrePeiCore/MainMPCore.c @@ -45,6 +45,7 @@ SecondaryMain ( UINT32 CoreId; VOID (*SecondaryStart)(VOID); UINTN SecondaryEntryAddr; + UINTN AcknowledgedCoreId; ClusterId = GET_CLUSTER_ID(MpId); CoreId = GET_CORE_ID(MpId); @@ -80,12 +81,15 @@ SecondaryMain ( // Clear Secondary cores MailBox MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue); - SecondaryEntryAddr = 0; - while (SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress), SecondaryEntryAddr == 0) { + do { ArmCallWFI (); + + // Read the Mailbox + SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress); + // Acknowledge the interrupt and send End of Interrupt signal. - ArmGicAcknowledgeSgiFrom (PcdGet32(PcdGicInterruptInterfaceBase), PRIMARY_CORE_ID); - } + ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), &AcknowledgedCoreId, NULL); + } while ((SecondaryEntryAddr == 0) && (AcknowledgedCoreId != PcdGet32 (PcdGicPrimaryCoreId))); // Jump to secondary core entry point. SecondaryStart = (VOID (*)())SecondaryEntryAddr; @@ -107,6 +111,13 @@ PrimaryMain ( UINTN TemporaryRamBase; UINTN TemporaryRamSize; + // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0 + DEBUG_CODE_BEGIN(); + if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) { + DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n")); + } + DEBUG_CODE_END(); + CreatePpiList (&PpiListSize, &PpiList); // Enable the GIC Distributor diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf index 39dd89e800..efdc4b7544 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf @@ -61,6 +61,7 @@ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask gArmTokenSpaceGuid.PcdArmPrimaryCore + gArmTokenSpaceGuid.PcdGicPrimaryCoreId gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c index e9a3ef56a0..2c18f9f3c3 100644 --- a/ArmPlatformPkg/PrePi/MainMPCore.c +++ b/ArmPlatformPkg/PrePi/MainMPCore.c @@ -59,6 +59,13 @@ PrimaryMain ( ASSERT_EFI_ERROR (Status); DEBUG_CODE_END(); + // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0 + DEBUG_CODE_BEGIN(); + if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) { + DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n")); + } + DEBUG_CODE_END(); + // Enable the GIC Distributor ArmGicEnableDistributor(PcdGet32(PcdGicDistributorBase)); @@ -88,6 +95,7 @@ SecondaryMain ( UINT32 CoreId; VOID (*SecondaryStart)(VOID); UINTN SecondaryEntryAddr; + UINTN AcknowledgedCoreId; ClusterId = GET_CLUSTER_ID(MpId); CoreId = GET_CORE_ID(MpId); @@ -113,12 +121,15 @@ SecondaryMain ( // Clear Secondary cores MailBox MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue); - SecondaryEntryAddr = 0; - while (SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress), SecondaryEntryAddr == 0) { + do { ArmCallWFI (); + + // Read the Mailbox + SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress); + // Acknowledge the interrupt and send End of Interrupt signal. - ArmGicAcknowledgeSgiFrom (PcdGet32(PcdGicInterruptInterfaceBase), PRIMARY_CORE_ID); - } + ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), &AcknowledgedCoreId, NULL); + } while ((SecondaryEntryAddr == 0) && (AcknowledgedCoreId != PcdGet32 (PcdGicPrimaryCoreId))); // Jump to secondary core entry point. SecondaryStart = (VOID (*)())SecondaryEntryAddr; diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf index 6337da1334..12789a3965 100755 --- a/ArmPlatformPkg/PrePi/PeiMPCore.inf +++ b/ArmPlatformPkg/PrePi/PeiMPCore.inf @@ -94,6 +94,7 @@ gArmPlatformTokenSpaceGuid.PcdClusterCount gArmTokenSpaceGuid.PcdArmPrimaryCoreMask gArmTokenSpaceGuid.PcdArmPrimaryCore + gArmTokenSpaceGuid.PcdGicPrimaryCoreId gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize