]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/PrePi/MainMPCore.c
ArmPkg/ArmCpuLib: Replaced complex functions ArmCpuSynchronizeWait & ArmCpuSynchroniz...
[mirror_edk2.git] / ArmPlatformPkg / PrePi / MainMPCore.c
1 /** @file
2 *
3 * Copyright (c) 2011, 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 // Enable the GIC Distributor
63 ArmGicEnableDistributor(PcdGet32(PcdGicDistributorBase));
64
65 // In some cases, the secondary cores are waiting for an SGI from the next stage boot loader toresume their initialization
66 if (!FixedPcdGet32(PcdSendSgiToBringUpSecondaryCores)) {
67 // Sending SGI to all the Secondary CPU interfaces
68 ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E);
69 }
70
71 PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp);
72
73 // We must never return
74 ASSERT(FALSE);
75 }
76
77 VOID
78 SecondaryMain (
79 IN UINTN MpId
80 )
81 {
82 EFI_STATUS Status;
83 ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
84 UINTN Index;
85 UINTN ArmCoreCount;
86 ARM_CORE_INFO *ArmCoreInfoTable;
87 UINT32 ClusterId;
88 UINT32 CoreId;
89 VOID (*SecondaryStart)(VOID);
90 UINTN SecondaryEntryAddr;
91
92 ClusterId = GET_CLUSTER_ID(MpId);
93 CoreId = GET_CORE_ID(MpId);
94
95 // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
96 Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi);
97 ASSERT_EFI_ERROR (Status);
98
99 ArmCoreCount = 0;
100 Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
101 ASSERT_EFI_ERROR (Status);
102
103 // Find the core in the ArmCoreTable
104 for (Index = 0; Index < ArmCoreCount; Index++) {
105 if ((ArmCoreInfoTable[Index].ClusterId == ClusterId) && (ArmCoreInfoTable[Index].CoreId == CoreId)) {
106 break;
107 }
108 }
109
110 // The ARM Core Info Table must define every core
111 ASSERT (Index != ArmCoreCount);
112
113 // Clear Secondary cores MailBox
114 MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue);
115
116 SecondaryEntryAddr = 0;
117 while (SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress), SecondaryEntryAddr == 0) {
118 ArmCallWFI ();
119 // Acknowledge the interrupt and send End of Interrupt signal.
120 ArmGicAcknowledgeSgiFrom (PcdGet32(PcdGicInterruptInterfaceBase), PRIMARY_CORE_ID);
121 }
122
123 // Jump to secondary core entry point.
124 SecondaryStart = (VOID (*)())SecondaryEntryAddr;
125 SecondaryStart();
126
127 // The secondaries shouldn't reach here
128 ASSERT(FALSE);
129 }