1 /** @file
2   Definitions to install Multiple Processor PPI.
3 
4   Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
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 #ifndef _CPU_MP_PEI_H_
16 #define _CPU_MP_PEI_H_
17 
18 #include <PiPei.h>
19 
20 #include <Ppi/MpServices.h>
21 #include <Ppi/SecPlatformInformation.h>
22 #include <Ppi/SecPlatformInformation2.h>
23 #include <Ppi/EndOfPeiPhase.h>
24 
25 #include <Library/BaseLib.h>
26 #include <Library/DebugLib.h>
27 #include <Library/HobLib.h>
28 #include <Library/LocalApicLib.h>
29 #include <Library/PeimEntryPoint.h>
30 #include <Library/PeiServicesLib.h>
31 #include <Library/ReportStatusCodeLib.h>
32 #include <Library/CpuExceptionHandlerLib.h>
33 #include <Library/MpInitLib.h>
34 #include <Library/BaseMemoryLib.h>
35 
36 extern EFI_PEI_PPI_DESCRIPTOR   mPeiCpuMpPpiDesc;
37 
38 /**
39   This service retrieves the number of logical processor in the platform
40   and the number of those logical processors that are enabled on this boot.
41   This service may only be called from the BSP.
42 
43   This function is used to retrieve the following information:
44     - The number of logical processors that are present in the system.
45     - The number of enabled logical processors in the system at the instant
46       this call is made.
47 
48   Because MP Service Ppi provides services to enable and disable processors
49   dynamically, the number of enabled logical processors may vary during the
50   course of a boot session.
51 
52   If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
53   If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
54   EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
55   is returned in NumberOfProcessors, the number of currently enabled processor
56   is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
57 
58   @param[in]  PeiServices         An indirect pointer to the PEI Services Table
59                                   published by the PEI Foundation.
60   @param[in]  This                Pointer to this instance of the PPI.
61   @param[out] NumberOfProcessors  Pointer to the total number of logical processors in
62                                   the system, including the BSP and disabled APs.
63   @param[out] NumberOfEnabledProcessors
64                                   Number of processors in the system that are enabled.
65 
66   @retval EFI_SUCCESS             The number of logical processors and enabled
67                                   logical processors was retrieved.
68   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
69   @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL.
70                                   NumberOfEnabledProcessors is NULL.
71 **/
72 EFI_STATUS
73 EFIAPI
74 PeiGetNumberOfProcessors (
75   IN  CONST EFI_PEI_SERVICES    **PeiServices,
76   IN  EFI_PEI_MP_SERVICES_PPI   *This,
77   OUT UINTN                     *NumberOfProcessors,
78   OUT UINTN                     *NumberOfEnabledProcessors
79   );
80 
81 /**
82   Gets detailed MP-related information on the requested processor at the
83   instant this call is made. This service may only be called from the BSP.
84 
85   This service retrieves detailed MP-related information about any processor
86   on the platform. Note the following:
87     - The processor information may change during the course of a boot session.
88     - The information presented here is entirely MP related.
89 
90   Information regarding the number of caches and their sizes, frequency of operation,
91   slot numbers is all considered platform-related information and is not provided
92   by this service.
93 
94   @param[in]  PeiServices         An indirect pointer to the PEI Services Table
95                                   published by the PEI Foundation.
96   @param[in]  This                Pointer to this instance of the PPI.
97   @param[in]  ProcessorNumber     Pointer to the total number of logical processors in
98                                   the system, including the BSP and disabled APs.
99   @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
100 
101   @retval EFI_SUCCESS             Processor information was returned.
102   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
103   @retval EFI_INVALID_PARAMETER   ProcessorInfoBuffer is NULL.
104   @retval EFI_NOT_FOUND           The processor with the handle specified by
105                                   ProcessorNumber does not exist in the platform.
106 **/
107 EFI_STATUS
108 EFIAPI
109 PeiGetProcessorInfo (
110   IN  CONST EFI_PEI_SERVICES     **PeiServices,
111   IN  EFI_PEI_MP_SERVICES_PPI    *This,
112   IN  UINTN                      ProcessorNumber,
113   OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer
114   );
115 
116 /**
117   This service executes a caller provided function on all enabled APs. APs can
118   run either simultaneously or one at a time in sequence. This service supports
119   both blocking requests only. This service may only
120   be called from the BSP.
121 
122   This function is used to dispatch all the enabled APs to the function specified
123   by Procedure.  If any enabled AP is busy, then EFI_NOT_READY is returned
124   immediately and Procedure is not started on any AP.
125 
126   If SingleThread is TRUE, all the enabled APs execute the function specified by
127   Procedure one by one, in ascending order of processor handle number. Otherwise,
128   all the enabled APs execute the function specified by Procedure simultaneously.
129 
130   If the timeout specified by TimeoutInMicroSeconds expires before all APs return
131   from Procedure, then Procedure on the failed APs is terminated. All enabled APs
132   are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
133   and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its
134   content points to the list of processor handle numbers in which Procedure was
135   terminated.
136 
137   Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
138   to make sure that the nature of the code that is executed on the BSP and the
139   dispatched APs is well controlled. The MP Services Ppi does not guarantee
140   that the Procedure function is MP-safe. Hence, the tasks that can be run in
141   parallel are limited to certain independent tasks and well-controlled exclusive
142   code. PEI services and Ppis may not be called by APs unless otherwise
143   specified.
144 
145   In blocking execution mode, BSP waits until all APs finish or
146   TimeoutInMicroSeconds expires.
147 
148   @param[in] PeiServices          An indirect pointer to the PEI Services Table
149                                   published by the PEI Foundation.
150   @param[in] This                 A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
151   @param[in] Procedure            A pointer to the function to be run on enabled APs of
152                                   the system.
153   @param[in] SingleThread         If TRUE, then all the enabled APs execute the function
154                                   specified by Procedure one by one, in ascending order
155                                   of processor handle number. If FALSE, then all the
156                                   enabled APs execute the function specified by Procedure
157                                   simultaneously.
158   @param[in] TimeoutInMicroSeconds
159                                   Indicates the time limit in microseconds for APs to
160                                   return from Procedure, for blocking mode only. Zero
161                                   means infinity. If the timeout expires before all APs
162                                   return from Procedure, then Procedure on the failed APs
163                                   is terminated. All enabled APs are available for next
164                                   function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
165                                   or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
166                                   timeout expires in blocking mode, BSP returns
167                                   EFI_TIMEOUT.
168   @param[in] ProcedureArgument    The parameter passed into Procedure for all APs.
169 
170   @retval EFI_SUCCESS             In blocking mode, all APs have finished before the
171                                   timeout expired.
172   @retval EFI_DEVICE_ERROR        Caller processor is AP.
173   @retval EFI_NOT_STARTED         No enabled APs exist in the system.
174   @retval EFI_NOT_READY           Any enabled APs are busy.
175   @retval EFI_TIMEOUT             In blocking mode, the timeout expired before all
176                                   enabled APs have finished.
177   @retval EFI_INVALID_PARAMETER   Procedure is NULL.
178 **/
179 EFI_STATUS
180 EFIAPI
181 PeiStartupAllAPs (
182   IN  CONST EFI_PEI_SERVICES    **PeiServices,
183   IN  EFI_PEI_MP_SERVICES_PPI   *This,
184   IN  EFI_AP_PROCEDURE          Procedure,
185   IN  BOOLEAN                   SingleThread,
186   IN  UINTN                     TimeoutInMicroSeconds,
187   IN  VOID                      *ProcedureArgument      OPTIONAL
188   );
189 
190 /**
191   This service lets the caller get one enabled AP to execute a caller-provided
192   function. The caller can request the BSP to wait for the completion
193   of the AP. This service may only be called from the BSP.
194 
195   This function is used to dispatch one enabled AP to the function specified by
196   Procedure passing in the argument specified by ProcedureArgument.
197   The execution is in blocking mode. The BSP waits until the AP finishes or
198   TimeoutInMicroSecondss expires.
199 
200   If the timeout specified by TimeoutInMicroseconds expires before the AP returns
201   from Procedure, then execution of Procedure by the AP is terminated. The AP is
202   available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
203   EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
204 
205   @param[in] PeiServices          An indirect pointer to the PEI Services Table
206                                   published by the PEI Foundation.
207   @param[in] This                 A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
208   @param[in] Procedure            A pointer to the function to be run on enabled APs of
209                                   the system.
210   @param[in] ProcessorNumber      The handle number of the AP. The range is from 0 to the
211                                   total number of logical processors minus 1. The total
212                                   number of logical processors can be retrieved by
213                                   EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
214   @param[in] TimeoutInMicroseconds
215                                   Indicates the time limit in microseconds for APs to
216                                   return from Procedure, for blocking mode only. Zero
217                                   means infinity. If the timeout expires before all APs
218                                   return from Procedure, then Procedure on the failed APs
219                                   is terminated. All enabled APs are available for next
220                                   function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
221                                   or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
222                                   timeout expires in blocking mode, BSP returns
223                                   EFI_TIMEOUT.
224   @param[in] ProcedureArgument    The parameter passed into Procedure for all APs.
225 
226   @retval EFI_SUCCESS             In blocking mode, specified AP finished before the
227                                   timeout expires.
228   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
229   @retval EFI_TIMEOUT             In blocking mode, the timeout expired before the
230                                   specified AP has finished.
231   @retval EFI_NOT_FOUND           The processor with the handle specified by
232                                   ProcessorNumber does not exist.
233   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP or disabled AP.
234   @retval EFI_INVALID_PARAMETER   Procedure is NULL.
235 **/
236 EFI_STATUS
237 EFIAPI
238 PeiStartupThisAP (
239   IN  CONST EFI_PEI_SERVICES    **PeiServices,
240   IN  EFI_PEI_MP_SERVICES_PPI   *This,
241   IN  EFI_AP_PROCEDURE          Procedure,
242   IN  UINTN                     ProcessorNumber,
243   IN  UINTN                     TimeoutInMicroseconds,
244   IN  VOID                      *ProcedureArgument      OPTIONAL
245   );
246 
247 /**
248   This service switches the requested AP to be the BSP from that point onward.
249   This service changes the BSP for all purposes.   This call can only be performed
250   by the current BSP.
251 
252   This service switches the requested AP to be the BSP from that point onward.
253   This service changes the BSP for all purposes. The new BSP can take over the
254   execution of the old BSP and continue seamlessly from where the old one left
255   off.
256 
257   If the BSP cannot be switched prior to the return from this service, then
258   EFI_UNSUPPORTED must be returned.
259 
260   @param[in] PeiServices          An indirect pointer to the PEI Services Table
261                                   published by the PEI Foundation.
262   @param[in] This                 A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
263   @param[in] ProcessorNumber      The handle number of the AP. The range is from 0 to the
264                                   total number of logical processors minus 1. The total
265                                   number of logical processors can be retrieved by
266                                   EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
267   @param[in] EnableOldBSP         If TRUE, then the old BSP will be listed as an enabled
268                                   AP. Otherwise, it will be disabled.
269 
270   @retval EFI_SUCCESS             BSP successfully switched.
271   @retval EFI_UNSUPPORTED         Switching the BSP cannot be completed prior to this
272                                   service returning.
273   @retval EFI_UNSUPPORTED         Switching the BSP is not supported.
274   @retval EFI_SUCCESS             The calling processor is an AP.
275   @retval EFI_NOT_FOUND           The processor with the handle specified by
276                                   ProcessorNumber does not exist.
277   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the current BSP or a disabled
278                                   AP.
279   @retval EFI_NOT_READY           The specified AP is busy.
280 **/
281 EFI_STATUS
282 EFIAPI
283 PeiSwitchBSP (
284   IN  CONST EFI_PEI_SERVICES   **PeiServices,
285   IN  EFI_PEI_MP_SERVICES_PPI  *This,
286   IN  UINTN                    ProcessorNumber,
287   IN  BOOLEAN                  EnableOldBSP
288   );
289 
290 /**
291   This service lets the caller enable or disable an AP from this point onward.
292   This service may only be called from the BSP.
293 
294   This service allows the caller enable or disable an AP from this point onward.
295   The caller can optionally specify the health status of the AP by Health. If
296   an AP is being disabled, then the state of the disabled AP is implementation
297   dependent. If an AP is enabled, then the implementation must guarantee that a
298   complete initialization sequence is performed on the AP, so the AP is in a state
299   that is compatible with an MP operating system.
300 
301   If the enable or disable AP operation cannot be completed prior to the return
302   from this service, then EFI_UNSUPPORTED must be returned.
303 
304   @param[in] PeiServices          An indirect pointer to the PEI Services Table
305                                   published by the PEI Foundation.
306   @param[in] This                 A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
307   @param[in] ProcessorNumber      The handle number of the AP. The range is from 0 to the
308                                   total number of logical processors minus 1. The total
309                                   number of logical processors can be retrieved by
310                                   EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
311   @param[in] EnableAP             Specifies the new state for the processor for enabled,
312                                   FALSE for disabled.
313   @param[in] HealthFlag           If not NULL, a pointer to a value that specifies the
314                                   new health status of the AP. This flag corresponds to
315                                   StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo().
316                                   Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other
317                                   bits are ignored. If it is NULL, this parameter is
318                                   ignored.
319 
320   @retval EFI_SUCCESS             The specified AP was enabled or disabled successfully.
321   @retval EFI_UNSUPPORTED         Enabling or disabling an AP cannot be completed prior
322                                   to this service returning.
323   @retval EFI_UNSUPPORTED         Enabling or disabling an AP is not supported.
324   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
325   @retval EFI_NOT_FOUND           Processor with the handle specified by ProcessorNumber
326                                   does not exist.
327   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.
328 **/
329 EFI_STATUS
330 EFIAPI
331 PeiEnableDisableAP (
332   IN  CONST EFI_PEI_SERVICES    **PeiServices,
333   IN  EFI_PEI_MP_SERVICES_PPI   *This,
334   IN  UINTN                     ProcessorNumber,
335   IN  BOOLEAN                   EnableAP,
336   IN  UINT32                    *HealthFlag OPTIONAL
337   );
338 
339 /**
340   This return the handle number for the calling processor.  This service may be
341   called from the BSP and APs.
342 
343   This service returns the processor handle number for the calling processor.
344   The returned value is in the range from 0 to the total number of logical
345   processors minus 1. The total number of logical processors can be retrieved
346   with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be
347   called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
348   is returned. Otherwise, the current processors handle number is returned in
349   ProcessorNumber, and EFI_SUCCESS is returned.
350 
351   @param[in]  PeiServices         An indirect pointer to the PEI Services Table
352                                   published by the PEI Foundation.
353   @param[in]  This                A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
354   @param[out] ProcessorNumber     The handle number of the AP. The range is from 0 to the
355                                   total number of logical processors minus 1. The total
356                                   number of logical processors can be retrieved by
357                                   EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
358 
359   @retval EFI_SUCCESS             The current processor handle number was returned in
360                                   ProcessorNumber.
361   @retval EFI_INVALID_PARAMETER   ProcessorNumber is NULL.
362 **/
363 EFI_STATUS
364 EFIAPI
365 PeiWhoAmI (
366   IN  CONST EFI_PEI_SERVICES   **PeiServices,
367   IN  EFI_PEI_MP_SERVICES_PPI  *This,
368   OUT UINTN                    *ProcessorNumber
369   );
370 
371 /**
372   Collects BIST data from PPI.
373 
374   This function collects BIST data from Sec Platform Information2 PPI
375   or SEC Platform Information PPI.
376 
377   @param PeiServices         Pointer to PEI Services Table
378 
379 **/
380 VOID
381 CollectBistDataFromPpi (
382   IN CONST EFI_PEI_SERVICES             **PeiServices
383   );
384 
385 /**
386   Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
387 
388   @param  PeiServices                The pointer to the PEI Services Table.
389   @param  StructureSize              The pointer to the variable describing size of the input buffer.
390   @param  PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
391 
392   @retval EFI_SUCCESS                The data was successfully returned.
393   @retval EFI_BUFFER_TOO_SMALL       The buffer was too small. The current buffer size needed to
394                                      hold the record is returned in StructureSize.
395 
396 **/
397 EFI_STATUS
398 EFIAPI
399 SecPlatformInformation2 (
400   IN CONST EFI_PEI_SERVICES                   **PeiServices,
401   IN OUT UINT64                               *StructureSize,
402      OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
403   );
404 
405 #endif
406