]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/PrePi/MainMPCore.c
ArmPkg/ArmGicLib: Replaced 'ArmGicAcknowledgeSgiFrom' by 'ArmGicAcknowledgeInterrupt'
[mirror_edk2.git] / ArmPlatformPkg / PrePi / MainMPCore.c
1 /** @file
2 *
3 * Copyright (c) 2011-2012, ARM Limited. All rights reserved.
4 *
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
9 *
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.
12 *
13 **/
14
15 #include "PrePi.h"
16
17 #include <Library/ArmGicLib.h>
18
19 #include <Ppi/ArmMpCoreInfo.h>
20
21 EFI_STATUS
22 GetPlatformPpi (
23 IN EFI_GUID *PpiGuid,
24 OUT VOID **Ppi
25 )
26 {
27 UINTN PpiListSize;
28 UINTN PpiListCount;
29 EFI_PEI_PPI_DESCRIPTOR *PpiList;
30 UINTN Index;
31
32 PpiListSize = 0;
33 ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
34 PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR);
35 for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
36 if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) {
37 *Ppi = PpiList->Ppi;
38 return EFI_SUCCESS;
39 }
40 }
41
42 return EFI_NOT_FOUND;
43 }
44
45 VOID
46 PrimaryMain (
47 IN UINTN UefiMemoryBase,
48 IN UINTN StacksBase,
49 IN UINTN GlobalVariableBase,
50 IN UINT64 StartTimeStamp
51 )
52 {
53 // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
54 DEBUG_CODE_BEGIN();
55 EFI_STATUS Status;
56 ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
57
58 Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi);
59 ASSERT_EFI_ERROR (Status);
60 DEBUG_CODE_END();
61
62 // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0
63 DEBUG_CODE_BEGIN();
64 if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) {
65 DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n"));
66 }
67 DEBUG_CODE_END();
68
69 // Enable the GIC Distributor
70 ArmGicEnableDistributor(PcdGet32(PcdGicDistributorBase));
71
72 // In some cases, the secondary cores are waiting for an SGI from the next stage boot loader toresume their initialization
73 if (!FixedPcdGet32(PcdSendSgiToBringUpSecondaryCores)) {
74 // Sending SGI to all the Secondary CPU interfaces
75 ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));
76 }
77
78 PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp);
79
80 // We must never return
81 ASSERT(FALSE);
82 }
83
84 VOID
85 SecondaryMain (
86 IN UINTN MpId
87 )
88 {
89 EFI_STATUS Status;
90 ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
91 UINTN Index;
92 UINTN ArmCoreCount;
93 ARM_CORE_INFO *ArmCoreInfoTable;
94 UINT32 ClusterId;
95 UINT32 CoreId;
96 VOID (*SecondaryStart)(VOID);
97 UINTN SecondaryEntryAddr;
98 UINTN AcknowledgedCoreId;
99
100 ClusterId = GET_CLUSTER_ID(MpId);
101 CoreId = GET_CORE_ID(MpId);
102
103 // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
104 Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi);
105 ASSERT_EFI_ERROR (Status);
106
107 ArmCoreCount = 0;
108 Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
109 ASSERT_EFI_ERROR (Status);
110
111 // Find the core in the ArmCoreTable
112 for (Index = 0; Index < ArmCoreCount; Index++) {
113 if ((ArmCoreInfoTable[Index].ClusterId == ClusterId) && (ArmCoreInfoTable[Index].CoreId == CoreId)) {
114 break;
115 }
116 }
117
118 // The ARM Core Info Table must define every core
119 ASSERT (Index != ArmCoreCount);
120
121 // Clear Secondary cores MailBox
122 MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue);
123
124 do {
125 ArmCallWFI ();
126
127 // Read the Mailbox
128 SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
129
130 // Acknowledge the interrupt and send End of Interrupt signal.
131 ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), &AcknowledgedCoreId, NULL);
132 } while ((SecondaryEntryAddr == 0) && (AcknowledgedCoreId != PcdGet32 (PcdGicPrimaryCoreId)));
133
134 // Jump to secondary core entry point.
135 SecondaryStart = (VOID (*)())SecondaryEntryAddr;
136 SecondaryStart();
137
138 // The secondaries shouldn't reach here
139 ASSERT(FALSE);
140 }