]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/PrePi/MainMPCore.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ArmPlatformPkg / PrePi / MainMPCore.c
1 /** @file
2
3 Copyright (c) 2011-2014, ARM Limited. All rights reserved.
4
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "PrePi.h"
10
11 #include <Library/ArmGicLib.h>
12
13 #include <Ppi/ArmMpCoreInfo.h>
14
15 VOID
16 PrimaryMain (
17 IN UINTN UefiMemoryBase,
18 IN UINTN StacksBase,
19 IN UINT64 StartTimeStamp
20 )
21 {
22 // Enable the GIC Distributor
23 ArmGicEnableDistributor (PcdGet64 (PcdGicDistributorBase));
24
25 // In some cases, the secondary cores are waiting for an SGI from the next stage boot loader to resume their initialization
26 if (!FixedPcdGet32 (PcdSendSgiToBringUpSecondaryCores)) {
27 // Sending SGI to all the Secondary CPU interfaces
28 ArmGicSendSgiTo (PcdGet64 (PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));
29 }
30
31 PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
32
33 // We must never return
34 ASSERT (FALSE);
35 }
36
37 VOID
38 SecondaryMain (
39 IN UINTN MpId
40 )
41 {
42 EFI_STATUS Status;
43 ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
44 UINTN Index;
45 UINTN ArmCoreCount;
46 ARM_CORE_INFO *ArmCoreInfoTable;
47 UINT32 ClusterId;
48 UINT32 CoreId;
49
50 VOID (*SecondaryStart)(
51 VOID
52 );
53 UINTN SecondaryEntryAddr;
54 UINTN AcknowledgeInterrupt;
55 UINTN InterruptId;
56
57 ClusterId = GET_CLUSTER_ID (MpId);
58 CoreId = GET_CORE_ID (MpId);
59
60 // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
61 Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID **)&ArmMpCoreInfoPpi);
62 ASSERT_EFI_ERROR (Status);
63
64 ArmCoreCount = 0;
65 Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
66 ASSERT_EFI_ERROR (Status);
67
68 // Find the core in the ArmCoreTable
69 for (Index = 0; Index < ArmCoreCount; Index++) {
70 if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) &&
71 (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId))
72 {
73 break;
74 }
75 }
76
77 // The ARM Core Info Table must define every core
78 ASSERT (Index != ArmCoreCount);
79
80 // Clear Secondary cores MailBox
81 MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue);
82
83 do {
84 ArmCallWFI ();
85
86 // Read the Mailbox
87 SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
88
89 // Acknowledge the interrupt and send End of Interrupt signal.
90 AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), &InterruptId);
91 // Check if it is a valid interrupt ID
92 if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet64 (PcdGicDistributorBase))) {
93 // Got a valid SGI number hence signal End of Interrupt
94 ArmGicEndOfInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt);
95 }
96 } while (SecondaryEntryAddr == 0);
97
98 // Jump to secondary core entry point.
99 SecondaryStart = (VOID (*)()) SecondaryEntryAddr;
100 SecondaryStart ();
101
102 // The secondaries shouldn't reach here
103 ASSERT (FALSE);
104 }