3 * Copyright (c) 2011-2012, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/ArmGicLib.h>
19 #include <Ppi/ArmMpCoreInfo.h>
23 IN UINTN UefiMemoryBase
,
25 IN UINTN GlobalVariableBase
,
26 IN UINT64 StartTimeStamp
29 // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0
31 if ((PcdGet32(PcdArmPrimaryCore
) != 0) && (PcdGet32 (PcdGicPrimaryCoreId
) == 0)) {
32 DEBUG((EFI_D_WARN
,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n"));
36 // Enable the GIC Distributor
37 ArmGicEnableDistributor(PcdGet32(PcdGicDistributorBase
));
39 // In some cases, the secondary cores are waiting for an SGI from the next stage boot loader to resume their initialization
40 if (!FixedPcdGet32(PcdSendSgiToBringUpSecondaryCores
)) {
41 // Sending SGI to all the Secondary CPU interfaces
42 ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase
), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE
, 0x0E, PcdGet32 (PcdGicSgiIntId
));
45 PrePiMain (UefiMemoryBase
, StacksBase
, GlobalVariableBase
, StartTimeStamp
);
47 // We must never return
57 ARM_MP_CORE_INFO_PPI
*ArmMpCoreInfoPpi
;
60 ARM_CORE_INFO
*ArmCoreInfoTable
;
63 VOID (*SecondaryStart
)(VOID
);
64 UINTN SecondaryEntryAddr
;
65 UINTN AcknowledgedCoreId
;
67 ClusterId
= GET_CLUSTER_ID(MpId
);
68 CoreId
= GET_CORE_ID(MpId
);
70 // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
71 Status
= GetPlatformPpi (&gArmMpCoreInfoPpiGuid
, (VOID
**)&ArmMpCoreInfoPpi
);
72 ASSERT_EFI_ERROR (Status
);
75 Status
= ArmMpCoreInfoPpi
->GetMpCoreInfo (&ArmCoreCount
, &ArmCoreInfoTable
);
76 ASSERT_EFI_ERROR (Status
);
78 // Find the core in the ArmCoreTable
79 for (Index
= 0; Index
< ArmCoreCount
; Index
++) {
80 if ((ArmCoreInfoTable
[Index
].ClusterId
== ClusterId
) && (ArmCoreInfoTable
[Index
].CoreId
== CoreId
)) {
85 // The ARM Core Info Table must define every core
86 ASSERT (Index
!= ArmCoreCount
);
88 // Clear Secondary cores MailBox
89 MmioWrite32 (ArmCoreInfoTable
[Index
].MailboxClearAddress
, ArmCoreInfoTable
[Index
].MailboxClearValue
);
95 SecondaryEntryAddr
= MmioRead32 (ArmCoreInfoTable
[Index
].MailboxGetAddress
);
97 // Acknowledge the interrupt and send End of Interrupt signal.
98 ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase
), PcdGet32(PcdGicInterruptInterfaceBase
), &AcknowledgedCoreId
, NULL
);
99 } while ((SecondaryEntryAddr
== 0) && (AcknowledgedCoreId
!= PcdGet32 (PcdGicPrimaryCoreId
)));
101 // Jump to secondary core entry point.
102 SecondaryStart
= (VOID (*)())SecondaryEntryAddr
;
105 // The secondaries shouldn't reach here