]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuDxe/CpuMp.c
UefiCpuPkg/CpuDxe: introduce MP_SYSTEM_DATA for Mp Service Protocol
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuMp.c
CommitLineData
6022e28c
JJ
1/** @file\r
2 CPU DXE Module.\r
3\r
4 Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "CpuDxe.h"\r
16#include "CpuMp.h"\r
17\r
6a26a597
CF
18UINTN gMaxLogicalProcessorNumber;\r
19UINTN gApStackSize;\r
20\r
03673ae1
CF
21MP_SYSTEM_DATA mMpSystemData;\r
22\r
fab82c18
JJ
23VOID *mCommonStack = 0;\r
24VOID *mTopOfApCommonStack = 0;\r
6a26a597 25VOID *mApStackStart = 0;\r
fab82c18 26\r
003973d9
CF
27EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {\r
28 NULL, // GetNumberOfProcessors,\r
29 NULL, // GetProcessorInfo,\r
30 NULL, // StartupAllAPs,\r
31 NULL, // StartupThisAP,\r
32 NULL, // SwitchBSP,\r
33 NULL, // EnableDisableAP,\r
34 NULL // WhoAmI\r
35};\r
36\r
e343f8f7
CF
37/**\r
38 Application Processors do loop routine\r
39 after switch to its own stack.\r
40\r
41 @param Context1 A pointer to the context to pass into the function.\r
42 @param Context2 A pointer to the context to pass into the function.\r
43\r
44**/\r
45VOID\r
46ProcessorToIdleState (\r
47 IN VOID *Context1, OPTIONAL\r
48 IN VOID *Context2 OPTIONAL\r
49 )\r
50{\r
51 DEBUG ((DEBUG_INFO, "Ap apicid is %d\n", GetApicId ()));\r
52\r
53 AsmApDoneWithCommonStack ();\r
54\r
55 CpuSleep ();\r
56 CpuDeadLoop ();\r
57}\r
58\r
1535c888
JJ
59/**\r
60 Application Processor C code entry point.\r
61\r
62**/\r
63VOID\r
64EFIAPI\r
65ApEntryPointInC (\r
66 VOID\r
67 )\r
68{\r
03673ae1
CF
69 VOID* TopOfApStack;\r
70\r
71 FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);\r
72 TopOfApStack = (UINT8*)mApStackStart + gApStackSize;\r
73 mApStackStart = TopOfApStack;\r
74\r
75 mMpSystemData.NumberOfProcessors++;\r
e343f8f7
CF
76\r
77 SwitchStack (\r
78 (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,\r
79 NULL,\r
80 NULL,\r
03673ae1
CF
81 TopOfApStack);\r
82}\r
83\r
84/**\r
85 This function is called by all processors (both BSP and AP) once and collects MP related data.\r
86\r
87 @param Bsp TRUE if the CPU is BSP\r
88 @param ProcessorNumber The specific processor number\r
89\r
90 @retval EFI_SUCCESS Data for the processor collected and filled in\r
91\r
92**/\r
93EFI_STATUS\r
94FillInProcessorInformation (\r
95 IN BOOLEAN Bsp,\r
96 IN UINTN ProcessorNumber\r
97 )\r
98{\r
99 CPU_DATA_BLOCK *CpuData;\r
100 UINT32 ProcessorId;\r
101\r
102 CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
103 ProcessorId = GetApicId ();\r
104 CpuData->Info.ProcessorId = ProcessorId;\r
105 CpuData->Info.StatusFlag = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;\r
106 if (Bsp) {\r
107 CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;\r
108 }\r
109 CpuData->Info.Location.Package = ProcessorId;\r
110 CpuData->Info.Location.Core = 0;\r
111 CpuData->Info.Location.Thread = 0;\r
112 CpuData->State = Bsp ? CpuStateBuzy : CpuStateIdle;\r
113\r
114 CpuData->Procedure = NULL;\r
115 CpuData->Parameter = NULL;\r
116 InitializeSpinLock (&CpuData->CpuDataLock);\r
117\r
118 return EFI_SUCCESS;\r
1535c888
JJ
119}\r
120\r
03673ae1
CF
121/**\r
122 Prepare the System Data.\r
123\r
124 @retval EFI_SUCCESS the System Data finished initilization.\r
125\r
126**/\r
127EFI_STATUS\r
128InitMpSystemData (\r
129 VOID\r
130 )\r
131{\r
132 ZeroMem (&mMpSystemData, sizeof (MP_SYSTEM_DATA));\r
133\r
134 mMpSystemData.NumberOfProcessors = 1;\r
135 mMpSystemData.NumberOfEnabledProcessors = 1;\r
136\r
137 mMpSystemData.CpuDatas = AllocateZeroPool (sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber);\r
138 ASSERT(mMpSystemData.CpuDatas != NULL);\r
139\r
140 //\r
141 // BSP\r
142 //\r
143 FillInProcessorInformation (TRUE, 0);\r
144\r
145 return EFI_SUCCESS;\r
146}\r
1535c888 147\r
6022e28c
JJ
148/**\r
149 Initialize Multi-processor support.\r
150\r
151**/\r
152VOID\r
153InitializeMpSupport (\r
154 VOID\r
155 )\r
156{\r
6a26a597
CF
157 gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
158 if (gMaxLogicalProcessorNumber < 1) {\r
159 DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));\r
160 return;\r
161 }\r
162\r
163 if (gMaxLogicalProcessorNumber == 1) {\r
164 return;\r
165 }\r
166\r
167 gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize);\r
168 ASSERT ((gApStackSize & (SIZE_4KB - 1)) == 0);\r
169\r
170 mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));\r
171 ASSERT (mApStackStart != NULL);\r
6022e28c 172\r
6a26a597
CF
173 //\r
174 // the first buffer of stack size used for common stack, when the amount of AP\r
175 // more than 1, we should never free the common stack which maybe used for AP reset.\r
176 //\r
177 mCommonStack = mApStackStart;\r
178 mTopOfApCommonStack = (UINT8*) mApStackStart + gApStackSize;\r
179 mApStackStart = mTopOfApCommonStack;\r
180\r
03673ae1 181 InitMpSystemData ();\r
6a26a597 182\r
03673ae1 183 if (mMpSystemData.NumberOfProcessors == 1) {\r
6a26a597
CF
184 FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));\r
185 return;\r
186 }\r
187\r
03673ae1
CF
188 if (mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {\r
189 FreePages (mApStackStart, EFI_SIZE_TO_PAGES (\r
190 (gMaxLogicalProcessorNumber - mMpSystemData.NumberOfProcessors) *\r
191 gApStackSize));\r
6a26a597
CF
192 }\r
193}\r