1 /** @file
2   This library implements the Extended SAL Library Class for use in boot services and runtime.
3 
4   Copyright (c) 2006 - 2012, 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 #include <PiDxe.h>
16 
17 #include <Protocol/ExtendedSalBootService.h>
18 #include <Protocol/ExtendedSalServiceClasses.h>
19 #include <Guid/EventGroup.h>
20 
21 #include <Library/ExtendedSalLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/UefiRuntimeServicesTableLib.h>
24 #include <Library/UefiRuntimeLib.h>
25 #include <Library/DebugLib.h>
26 
27 /**
28   Stores the virtual plabel of ESAL entrypoint.
29 
30   This assembly function stores the virtual plabel of ESAL entrypoint
31   where GetEsalEntryPoint() can easily retrieve.
32 
33   @param  EntryPoint  Virtual address of ESAL entrypoint
34   @param  Gp          Virtual GP of ESAL entrypoint
35 
36   @return r8 = EFI_SAL_SUCCESS
37 
38 **/
39 SAL_RETURN_REGS
40 EFIAPI
41 SetEsalVirtualEntryPoint (
42   IN  UINT64  EntryPoint,
43   IN  UINT64  Gp
44   );
45 
46 /**
47   Stores the physical plabel of ESAL entrypoint.
48 
49   This assembly function stores the physical plabel of ESAL entrypoint
50   where GetEsalEntryPoint() can easily retrieve.
51 
52   @param  EntryPoint  Physical address of ESAL entrypoint
53   @param  Gp          Physical GP of ESAL entrypoint
54 
55   @return r8 = EFI_SAL_SUCCESS
56 
57 **/
58 SAL_RETURN_REGS
59 EFIAPI
60 SetEsalPhysicalEntryPoint (
61   IN  UINT64  EntryPoint,
62   IN  UINT64  Gp
63   );
64 
65 /**
66   Retrieves plabel of ESAL entrypoint.
67 
68   This function retrives plabel of ESAL entrypoint stored by
69   SetEsalPhysicalEntryPoint().
70 
71   @return r8  = EFI_SAL_SUCCESS
72           r9  = Physical Plabel
73           r10 = Virtual Plabel
74           r11 = PSR
75 
76 **/
77 SAL_RETURN_REGS
78 EFIAPI
79 GetEsalEntryPoint (
80   VOID
81   );
82 
83 EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *mEsalBootService = NULL;
84 EFI_PLABEL                          mPlabel;
85 EFI_EVENT                           mEfiVirtualNotifyEvent;
86 
87 /**
88   Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE to set virtual plabel of
89   ESAL entrypoint.
90 
91   This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
92   It converts physical plabel of ESAL entrypoint to virtual plabel and stores it where
93   GetEsalEntryPoint() can easily retrieve.
94 
95   @param  Event        Event whose notification function is being invoked.
96   @param  Context      Pointer to the notification function's context
97 
98 **/
99 VOID
100 EFIAPI
ExtendedSalVirtualNotifyEvent(IN EFI_EVENT Event,IN VOID * Context)101 ExtendedSalVirtualNotifyEvent (
102   IN EFI_EVENT        Event,
103   IN VOID             *Context
104   )
105 {
106   UINT64  PhysicalEntryPoint;
107 
108   PhysicalEntryPoint = mPlabel.EntryPoint;
109 
110   gRT->ConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);
111 
112   mPlabel.GP += mPlabel.EntryPoint - PhysicalEntryPoint;
113 
114   SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
115 }
116 
117 /**
118   Gets Extended SAL Boot Service Protocol, and initializes physical plabel of
119   ESAL entrypoint.
120 
121   This function first locates Extended SAL Boot Service Protocol and caches it in global variable.
122   Then it initializes the physical plable of ESAL entrypoint, and stores
123   it where GetEsalEntryPoint() can easily retrieve.
124 
125   @retval  EFI_SUCCESS  Plable of ESAL entrypoint successfully stored.
126 
127 **/
128 EFI_STATUS
DxeSalLibInitialize(VOID)129 DxeSalLibInitialize (
130   VOID
131   )
132 {
133   EFI_PLABEL  *Plabel;
134   EFI_STATUS  Status;
135 
136   //
137   // The protocol contains a function pointer, which is an indirect procedure call.
138   // An indirect procedure call goes through a plabel, and pointer to a function is
139   // a pointer to a plabel. To implement indirect procedure calls that can work in
140   // both physical and virtual mode, two plabels are required (one physical and one
141   // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
142   // away. We cache it in a module global, so we can register the vitrual version.
143   //
144   Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);
145   ASSERT_EFI_ERROR (Status);
146 
147   Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;
148   mPlabel.EntryPoint  = Plabel->EntryPoint;
149   mPlabel.GP          = Plabel->GP;
150   //
151   // Stores the physical plabel of ESAL entrypoint where GetEsalEntryPoint() can easily retrieve.
152   //
153   SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
154 
155   return EFI_SUCCESS;
156 }
157 
158 /**
159   Constructor function to initializes physical plabel of ESAL entrypoint and register an event
160   for initialization of virtual plabel of ESAL entrypoint.
161 
162   This is the library constructor function to call a function to initialize physical plabel of ESAL entrypoint
163   and to register notification function for
164   EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which sets virtual plabel of ESAL entrypoint.
165 
166   @param  ImageHandle   The firmware allocated handle for the EFI image.
167   @param  SystemTable   A pointer to the EFI System Table.
168 
169   @retval EFI_SUCCESS   Notification function successfully registered.
170 
171 **/
172 EFI_STATUS
173 EFIAPI
DxeRuntimeExtendedSalLibConstruct(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)174 DxeRuntimeExtendedSalLibConstruct (
175   IN EFI_HANDLE           ImageHandle,
176   IN EFI_SYSTEM_TABLE     *SystemTable
177   )
178 {
179   EFI_STATUS  Status;
180 
181   //
182   // Register notify function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
183   //
184   ASSERT (gBS != NULL);
185 
186   DxeSalLibInitialize ();
187 
188   Status = gBS->CreateEventEx (
189                   EVT_NOTIFY_SIGNAL,
190                   TPL_NOTIFY,
191                   ExtendedSalVirtualNotifyEvent,
192                   NULL,
193                   &gEfiEventVirtualAddressChangeGuid,
194                   &mEfiVirtualNotifyEvent
195                   );
196 
197   ASSERT_EFI_ERROR (Status);
198 
199   return EFI_SUCCESS;
200 }
201 
202 /**
203   Destructor function to close the event created by the library constructor
204 
205   This is the library destructor function to close the event with type of
206   EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which is created by the library constructor.
207 
208   @param  ImageHandle   The firmware allocated handle for the EFI image.
209   @param  SystemTable   A pointer to the EFI System Table.
210 
211   @retval EFI_SUCCESS   Event successfully closed.
212 
213 **/
214 EFI_STATUS
215 EFIAPI
DxeRuntimeExtendedSalLibDeconstruct(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)216 DxeRuntimeExtendedSalLibDeconstruct (
217   IN EFI_HANDLE        ImageHandle,
218   IN EFI_SYSTEM_TABLE  *SystemTable
219   )
220 {
221   EFI_STATUS  Status;
222 
223   //
224   // Close SetVirtualAddressMap () notify function
225   //
226   ASSERT (gBS != NULL);
227   Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);
228   ASSERT_EFI_ERROR (Status);
229 
230   return EFI_SUCCESS;
231 }
232 
233 /**
234   Registers function of ESAL class and it's associated global.
235 
236   This function registers function of ESAL class, together with its associated global.
237   It is worker function for RegisterEsalClass().
238   It is only for boot time.
239 
240   @param  FunctionId     ID of function to register
241   @param  ClassGuidLo    GUID of ESAL class, lower 64-bits
242   @param  ClassGuidHi    GUID of ESAL class, upper 64-bits
243   @param  Function       Function to register with ClassGuid/FunctionId pair
244   @param  ModuleGlobal   Module global for the function.
245 
246   @return Status returned by RegisterExtendedSalProc() of Extended SAL Boot Service Protocol
247 
248 **/
249 EFI_STATUS
RegisterEsalFunction(IN UINT64 FunctionId,IN UINT64 ClassGuidLo,IN UINT64 ClassGuidHi,IN SAL_INTERNAL_EXTENDED_SAL_PROC Function,IN VOID * ModuleGlobal)250 RegisterEsalFunction (
251   IN  UINT64                                    FunctionId,
252   IN  UINT64                                    ClassGuidLo,
253   IN  UINT64                                    ClassGuidHi,
254   IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,
255   IN  VOID                                      *ModuleGlobal
256   )
257 {
258   return mEsalBootService->RegisterExtendedSalProc (
259                              mEsalBootService,
260                              ClassGuidLo,
261                              ClassGuidHi,
262                              FunctionId,
263                              Function,
264                              ModuleGlobal
265                              );
266 }
267 
268 /**
269   Registers ESAL Class and it's associated global.
270 
271   This function registers one or more Extended SAL services in a given
272   class along with the associated global context.
273   This function is only available prior to ExitBootServices().
274 
275   @param  ClassGuidLo          GUID of function class, lower 64-bits
276   @param  ClassGuidHi          GUID of function class, upper 64-bits
277   @param  ModuleGlobal         Module global for the class.
278   @param  ...                  List of Function/FunctionId pairs, ended by NULL
279 
280   @retval EFI_SUCCESS          The Extended SAL services were registered.
281   @retval EFI_UNSUPPORTED      This function was called after ExitBootServices().
282   @retval EFI_OUT_OF_RESOURCES There are not enough resources available to register one or more of the specified services.
283   @retval Other                ClassGuid could not be installed onto a new handle.
284 
285 **/
286 EFI_STATUS
287 EFIAPI
RegisterEsalClass(IN CONST UINT64 ClassGuidLo,IN CONST UINT64 ClassGuidHi,IN VOID * ModuleGlobal,OPTIONAL...)288 RegisterEsalClass (
289   IN  CONST UINT64    ClassGuidLo,
290   IN  CONST UINT64    ClassGuidHi,
291   IN  VOID            *ModuleGlobal,  OPTIONAL
292   ...
293   )
294 {
295   VA_LIST                         Args;
296   EFI_STATUS                      Status;
297   SAL_INTERNAL_EXTENDED_SAL_PROC  Function;
298   UINT64                          FunctionId;
299   EFI_HANDLE                      NewHandle;
300   EFI_GUID                        ClassGuid;
301 
302   VA_START (Args, ModuleGlobal);
303 
304   //
305   // Register all functions of the class to register.
306   //
307   Status = EFI_SUCCESS;
308   while (!EFI_ERROR (Status)) {
309     Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);
310     //
311     // NULL serves as the end mark of function list
312     //
313     if (Function == NULL) {
314       break;
315     }
316 
317     FunctionId  = VA_ARG (Args, UINT64);
318 
319     Status      = RegisterEsalFunction (FunctionId, ClassGuidLo, ClassGuidHi, Function, ModuleGlobal);
320   }
321 
322   VA_END (Args);
323 
324   if (EFI_ERROR (Status)) {
325     return Status;
326   }
327 
328   NewHandle = NULL;
329   *((UINT64 *)(&ClassGuid) + 0) = ClassGuidLo;
330   *((UINT64 *)(&ClassGuid) + 1) = ClassGuidHi;
331   return gBS->InstallProtocolInterface (
332                 &NewHandle,
333                 &ClassGuid,
334                 EFI_NATIVE_INTERFACE,
335                 NULL
336                 );
337 }
338 
339 /**
340   Calls an Extended SAL Class service that was previously registered with RegisterEsalClass().
341 
342   This function gets the entrypoint of Extended SAL, and calls an Extended SAL Class service
343   that was previously registered with RegisterEsalClass() through this entrypoint.
344 
345   @param  ClassGuidLo     GUID of function, lower 64-bits
346   @param  ClassGuidHi     GUID of function, upper 64-bits
347   @param  FunctionId      Function in ClassGuid to call
348   @param  Arg2            Argument 2 ClassGuid/FunctionId defined
349   @param  Arg3            Argument 3 ClassGuid/FunctionId defined
350   @param  Arg4            Argument 4 ClassGuid/FunctionId defined
351   @param  Arg5            Argument 5 ClassGuid/FunctionId defined
352   @param  Arg6            Argument 6 ClassGuid/FunctionId defined
353   @param  Arg7            Argument 7 ClassGuid/FunctionId defined
354   @param  Arg8            Argument 8 ClassGuid/FunctionId defined
355 
356   @retval EFI_SAL_SUCCESS ESAL procedure successfully called.
357   @retval EFI_SAL_ERROR   The address of ExtendedSalProc() can not be correctly
358                           initialized.
359   @retval Other           Status returned from ExtendedSalProc() service of
360                           EXTENDED_SAL_BOOT_SERVICE_PROTOCOL.
361 
362 **/
363 SAL_RETURN_REGS
364 EFIAPI
EsalCall(IN UINT64 ClassGuidLo,IN UINT64 ClassGuidHi,IN UINT64 FunctionId,IN UINT64 Arg2,IN UINT64 Arg3,IN UINT64 Arg4,IN UINT64 Arg5,IN UINT64 Arg6,IN UINT64 Arg7,IN UINT64 Arg8)365 EsalCall (
366   IN  UINT64    ClassGuidLo,
367   IN  UINT64    ClassGuidHi,
368   IN  UINT64    FunctionId,
369   IN  UINT64    Arg2,
370   IN  UINT64    Arg3,
371   IN  UINT64    Arg4,
372   IN  UINT64    Arg5,
373   IN  UINT64    Arg6,
374   IN  UINT64    Arg7,
375   IN  UINT64    Arg8
376   )
377 {
378   SAL_RETURN_REGS       ReturnReg;
379   EXTENDED_SAL_PROC     EsalProc;
380 
381   //
382   // Get the entrypoint of Extended SAL
383   //
384   ReturnReg = GetEsalEntryPoint ();
385   if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {
386     //
387     // The ESAL Entry Point could not be initialized
388     //
389     ReturnReg.Status = EFI_SAL_ERROR;
390     return ReturnReg;
391   }
392 
393   //
394   // Test PSR.it which is BIT36
395   //
396   if ((ReturnReg.r11 & BIT36) != 0) {
397     //
398     // Virtual mode plabel to entry point
399     //
400     EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r10;
401   } else {
402     //
403     // Physical mode plabel to entry point
404     //
405     EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r9;
406   }
407 
408   return EsalProc (
409            ClassGuidLo,
410            ClassGuidHi,
411            FunctionId,
412            Arg2,
413            Arg3,
414            Arg4,
415            Arg5,
416            Arg6,
417            Arg7,
418            Arg8
419            );
420 }
421 
422 /**
423   Wrapper for the EsalStallFunctionId service of Extended SAL Stall Services Class.
424 
425   This function is a wrapper for the EsalStallFunctionId service of Extended SAL
426   Stall Services Class. See EsalStallFunctionId of Extended SAL Specification.
427 
428   @param  Microseconds         The number of microseconds to delay.
429 
430   @retval EFI_SAL_SUCCESS               Call completed without error.
431   @retval EFI_SAL_INVALID_ARGUMENT      Invalid argument.
432   @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR Virtual address not registered
433 
434 **/
435 SAL_RETURN_REGS
436 EFIAPI
EsalStall(IN UINTN Microseconds)437 EsalStall (
438   IN UINTN  Microseconds
439   )
440 {
441   return EsalCall (
442            EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO,
443            EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI,
444            StallFunctionId,
445            Microseconds,
446            0,
447            0,
448            0,
449            0,
450            0,
451            0
452            );
453 }
454 
455 /**
456   Wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.
457 
458   This function is a wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL
459   PAL Services Services Class. See EsalSetNewPalEntryFunctionId of Extended SAL Specification.
460 
461   @param  PhysicalAddress        If TRUE, then PalEntryPoint is a physical address.
462                                  If FALSE, then PalEntryPoint is a virtual address.
463   @param  PalEntryPoint          The PAL Entry Point being set.
464 
465   @retval EFI_SAL_SUCCESS                The PAL Entry Point was set.
466   @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before
467                                          virtual mappings for the specified Extended SAL
468                                          Procedure are available.
469 
470 **/
471 SAL_RETURN_REGS
472 EFIAPI
EsalSetNewPalEntry(IN BOOLEAN PhysicalAddress,IN UINT64 PalEntryPoint)473 EsalSetNewPalEntry (
474   IN BOOLEAN  PhysicalAddress,
475   IN UINT64   PalEntryPoint
476   )
477 {
478   return EsalCall (
479            EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,
480            EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,
481            SetNewPalEntryFunctionId,
482            PhysicalAddress,
483            PalEntryPoint,
484            0,
485            0,
486            0,
487            0,
488            0
489            );
490 }
491 
492 /**
493   Wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.
494 
495   This function is a wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL
496   PAL Services Services Class. See EsalGetNewPalEntryFunctionId of Extended SAL Specification.
497 
498   @param  PhysicalAddress        If TRUE, then PalEntryPoint is a physical address.
499                                  If FALSE, then PalEntryPoint is a virtual address.
500 
501   @retval EFI_SAL_SUCCESS                The PAL Entry Point was retrieved and returned in
502                                          SAL_RETURN_REGS.r9.
503   @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before
504                                          virtual mappings for the specified Extended SAL
505                                          Procedure are available.
506   @return r9                             PAL entry point retrieved.
507 
508 **/
509 SAL_RETURN_REGS
510 EFIAPI
EsalGetNewPalEntry(IN BOOLEAN PhysicalAddress)511 EsalGetNewPalEntry (
512   IN BOOLEAN  PhysicalAddress
513   )
514 {
515   return EsalCall (
516            EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,
517            EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,
518            GetNewPalEntryFunctionId,
519            PhysicalAddress,
520            0,
521            0,
522            0,
523            0,
524            0,
525            0
526            );
527 }
528 
529 /**
530   Wrapper for the EsalGetStateBufferFunctionId service of Extended SAL MCA Log Services Class.
531 
532   This function is a wrapper for the EsalGetStateBufferFunctionId service of Extended SAL
533   MCA Log Services Class. See EsalGetStateBufferFunctionId of Extended SAL Specification.
534 
535   @param  McaType         See type parameter of SAL Procedure SAL_GET_STATE_INFO.
536   @param  McaBuffer             A pointer to the base address of the returned buffer.
537                                 Copied from SAL_RETURN_REGS.r9.
538   @param  BufferSize            A pointer to the size, in bytes, of the returned buffer.
539                                 Copied from SAL_RETURN_REGS.r10.
540 
541   @retval EFI_SAL_SUCCESS       The memory buffer to store error records was returned in r9 and r10.
542   @retval EFI_OUT_OF_RESOURCES  A memory buffer for string error records in not available
543   @return r9                    Base address of the returned buffer
544   @return r10                   Size of the returned buffer in bytes
545 
546 **/
547 SAL_RETURN_REGS
548 EFIAPI
EsalGetStateBuffer(IN UINT64 McaType,OUT UINT8 ** McaBuffer,OUT UINTN * BufferSize)549 EsalGetStateBuffer (
550   IN  UINT64  McaType,
551   OUT UINT8   **McaBuffer,
552   OUT UINTN   *BufferSize
553   )
554 {
555   SAL_RETURN_REGS Regs;
556 
557   Regs = EsalCall (
558            EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,
559            EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,
560            EsalGetStateBufferFunctionId,
561            McaType,
562            0,
563            0,
564            0,
565            0,
566            0,
567            0
568            );
569 
570   *McaBuffer  = (UINT8 *) Regs.r9;
571   *BufferSize = Regs.r10;
572 
573   return Regs;
574 }
575 
576 /**
577   Wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL MCA Log Services Class.
578 
579   This function is a wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL
580   MCA Log Services Class. See EsalSaveStateBufferFunctionId of Extended SAL Specification.
581 
582   @param  McaType         See type parameter of SAL Procedure SAL_GET_STATE_INFO.
583 
584   @retval EFI_SUCCESS  The memory buffer containing the error record was written to nonvolatile storage.
585 
586 **/
587 SAL_RETURN_REGS
588 EFIAPI
EsalSaveStateBuffer(IN UINT64 McaType)589 EsalSaveStateBuffer (
590   IN  UINT64  McaType
591   )
592 {
593   return EsalCall (
594            EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,
595            EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,
596            EsalSaveStateBufferFunctionId,
597            McaType,
598            0,
599            0,
600            0,
601            0,
602            0,
603            0
604            );
605 }
606 
607 /**
608   Wrapper for the EsalGetVectorsFunctionId service of Extended SAL Base Services Class.
609 
610   This function is a wrapper for the EsalGetVectorsFunctionId service of Extended SAL
611   Base Services Class. See EsalGetVectorsFunctionId of Extended SAL Specification.
612 
613   @param  VectorType         The vector type to retrieve.
614                              0 - MCA, 1 - BSP INIT, 2 - BOOT_RENDEZ, 3 - AP INIT.
615 
616   @retval EFI_SAL_SUCCESS          Call completed without error.
617   @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.
618   @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered
619                                    with the SAL Procedure SAL_SET_VECTORS.
620 
621 **/
622 SAL_RETURN_REGS
623 EFIAPI
EsalGetVectors(IN UINT64 VectorType)624 EsalGetVectors (
625   IN  UINT64  VectorType
626   )
627 {
628   return EsalCall (
629            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,
630            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,
631            EsalGetVectorsFunctionId,
632            VectorType,
633            0,
634            0,
635            0,
636            0,
637            0,
638            0
639            );
640 }
641 
642 /**
643   Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.
644 
645   This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL
646   Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.
647 
648   @param  ParamInfoType         The parameter type to retrieve.
649                                 1 - rendezvous interrupt
650                                 2 - wake up
651                                 3 - Corrected Platform Error Vector.
652 
653   @retval EFI_SAL_SUCCESS          Call completed without error.
654   @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.
655   @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered
656                                    with the SAL Procedure SAL_MC_SET_PARAMS.
657 
658 **/
659 SAL_RETURN_REGS
660 EFIAPI
EsalMcGetParams(IN UINT64 ParamInfoType)661 EsalMcGetParams (
662   IN  UINT64  ParamInfoType
663   )
664 {
665   return EsalCall (
666            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,
667            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,
668            EsalMcGetParamsFunctionId,
669            ParamInfoType,
670            0,
671            0,
672            0,
673            0,
674            0,
675            0
676            );
677 }
678 
679 /**
680   Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.
681 
682   This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL
683   Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.
684 
685   @retval EFI_SAL_SUCCESS          Call completed without error.
686   @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered
687                                    with the SAL Procedure SAL_MC_SET_PARAMS.
688 
689 **/
690 SAL_RETURN_REGS
691 EFIAPI
EsalMcGetMcParams(VOID)692 EsalMcGetMcParams (
693   VOID
694   )
695 {
696   return EsalCall (
697            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,
698            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,
699            EsalMcGetMcParamsFunctionId,
700            0,
701            0,
702            0,
703            0,
704            0,
705            0,
706            0
707            );
708 }
709 
710 /**
711   Wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL Base Services Class.
712 
713   This function is a wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL
714   Base Services Class. See EsalGetMcCheckinFlagsFunctionId of Extended SAL Specification.
715 
716   @param  CpuIndex         The index of the CPU of set of enabled CPUs to check.
717 
718   @retval EFI_SAL_SUCCESS  The checkin status of the requested CPU was returned.
719 
720 **/
721 SAL_RETURN_REGS
722 EFIAPI
EsalGetMcCheckinFlags(IN UINT64 CpuIndex)723 EsalGetMcCheckinFlags (
724   IN  UINT64  CpuIndex
725   )
726 {
727   return EsalCall (
728            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,
729            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,
730            EsalGetMcCheckinFlagsFunctionId,
731            CpuIndex,
732            0,
733            0,
734            0,
735            0,
736            0,
737            0
738            );
739 }
740 
741 /**
742   Wrapper for the EsalAddCpuDataFunctionId service of Extended SAL MP Services Class.
743 
744   This function is a wrapper for the EsalAddCpuDataFunctionId service of Extended SAL
745   MP Services Class. See EsalAddCpuDataFunctionId of Extended SAL Specification.
746 
747   @param  CpuGlobalId         The Global ID for the CPU being added.
748   @param  Enabled             The enable flag for the CPU being added.
749                               TRUE means the CPU is enabled.
750                               FALSE means the CPU is disabled.
751   @param  PalCompatibility    The PAL Compatibility value for the CPU being added.
752 
753   @retval EFI_SAL_SUCCESS             The CPU was added to the database.
754   @retval EFI_SAL_NOT_ENOUGH_SCRATCH  There are not enough resource available to add the CPU.
755 
756 **/
757 SAL_RETURN_REGS
758 EFIAPI
EsalAddCpuData(IN UINT64 CpuGlobalId,IN BOOLEAN Enabled,IN UINT64 PalCompatibility)759 EsalAddCpuData (
760   IN UINT64   CpuGlobalId,
761   IN BOOLEAN  Enabled,
762   IN UINT64   PalCompatibility
763   )
764 {
765   return EsalCall (
766            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
767            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
768            AddCpuDataFunctionId,
769            CpuGlobalId,
770            Enabled,
771            PalCompatibility,
772            0,
773            0,
774            0,
775            0
776            );
777 }
778 
779 /**
780   Wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL MP Services Class.
781 
782   This function is a wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL
783   MP Services Class. See EsalRemoveCpuDataFunctionId of Extended SAL Specification.
784 
785   @param  CpuGlobalId         The Global ID for the CPU being removed.
786 
787   @retval EFI_SAL_SUCCESS         The CPU was removed from the database.
788   @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.
789 
790 **/
791 SAL_RETURN_REGS
792 EFIAPI
EsalRemoveCpuData(IN UINT64 CpuGlobalId)793 EsalRemoveCpuData (
794   IN UINT64  CpuGlobalId
795   )
796 {
797   return EsalCall (
798            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
799            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
800            RemoveCpuDataFunctionId,
801            CpuGlobalId,
802            0,
803            0,
804            0,
805            0,
806            0,
807            0
808            );
809 }
810 
811 /**
812   Wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL MP Services Class.
813 
814   This function is a wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL
815   MP Services Class. See EsalModifyCpuDataFunctionId of Extended SAL Specification.
816 
817   @param  CpuGlobalId         The Global ID for the CPU being modified.
818   @param  Enabled             The enable flag for the CPU being modified.
819                               TRUE means the CPU is enabled.
820                               FALSE means the CPU is disabled.
821   @param  PalCompatibility    The PAL Compatibility value for the CPU being modified.
822 
823   @retval EFI_SAL_SUCCESS         The CPU database was updated.
824   @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.
825 
826 **/
827 SAL_RETURN_REGS
828 EFIAPI
EsalModifyCpuData(IN UINT64 CpuGlobalId,IN BOOLEAN Enabled,IN UINT64 PalCompatibility)829 EsalModifyCpuData (
830   IN UINT64   CpuGlobalId,
831   IN BOOLEAN  Enabled,
832   IN UINT64   PalCompatibility
833   )
834 {
835   return EsalCall (
836            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
837            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
838            ModifyCpuDataFunctionId,
839            CpuGlobalId,
840            Enabled,
841            PalCompatibility,
842            0,
843            0,
844            0,
845            0
846            );
847 }
848 
849 /**
850   Wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL MP Services Class.
851 
852   This function is a wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL
853   MP Services Class. See EsalGetCpuDataByIdFunctionId of Extended SAL Specification.
854 
855   @param  CpuGlobalId         The Global ID for the CPU being looked up.
856   @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.
857                               If FALSE, then the index of set of all CPUs of database is returned.
858 
859   @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.
860   @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.
861 
862 **/
863 SAL_RETURN_REGS
864 EFIAPI
EsalGetCpuDataById(IN UINT64 CpuGlobalId,IN BOOLEAN IndexByEnabledCpu)865 EsalGetCpuDataById (
866   IN UINT64   CpuGlobalId,
867   IN BOOLEAN  IndexByEnabledCpu
868   )
869 {
870   return EsalCall (
871            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
872            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
873            GetCpuDataByIDFunctionId,
874            CpuGlobalId,
875            IndexByEnabledCpu,
876            0,
877            0,
878            0,
879            0,
880            0
881            );
882 }
883 
884 /**
885   Wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL MP Services Class.
886 
887   This function is a wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL
888   MP Services Class. See EsalGetCpuDataByIndexFunctionId of Extended SAL Specification.
889 
890   @param  Index               The Global ID for the CPU being modified.
891   @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.
892                               If FALSE, then the index of set of all CPUs of database is returned.
893 
894   @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.
895   @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.
896 
897 **/
898 SAL_RETURN_REGS
899 EFIAPI
EsalGetCpuDataByIndex(IN UINT64 Index,IN BOOLEAN IndexByEnabledCpu)900 EsalGetCpuDataByIndex (
901   IN UINT64   Index,
902   IN BOOLEAN  IndexByEnabledCpu
903   )
904 {
905   return EsalCall (
906            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
907            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
908            GetCpuDataByIndexFunctionId,
909            Index,
910            IndexByEnabledCpu,
911            0,
912            0,
913            0,
914            0,
915            0
916            );
917 }
918 
919 /**
920   Wrapper for the EsalWhoAmIFunctionId service of Extended SAL MP Services Class.
921 
922   This function is a wrapper for the EsalWhoAmIFunctionId service of Extended SAL
923   MP Services Class. See EsalWhoAmIFunctionId of Extended SAL Specification.
924 
925   @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.
926                               If FALSE, then the index of set of all CPUs of database is returned.
927 
928   @retval EFI_SAL_SUCCESS         The Global ID for the calling CPU was returned.
929   @retval EFI_SAL_NO_INFORMATION  The calling CPU is not in the database.
930 
931 **/
932 SAL_RETURN_REGS
933 EFIAPI
EsalWhoAmI(IN BOOLEAN IndexByEnabledCpu)934 EsalWhoAmI (
935   IN BOOLEAN  IndexByEnabledCpu
936   )
937 {
938   return EsalCall (
939            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
940            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
941            CurrentProcInfoFunctionId,
942            IndexByEnabledCpu,
943            0,
944            0,
945            0,
946            0,
947            0,
948            0
949            );
950 }
951 
952 /**
953   Wrapper for the EsalNumProcessors service of Extended SAL MP Services Class.
954 
955   This function is a wrapper for the EsalNumProcessors service of Extended SAL
956   MP Services Class. See EsalNumProcessors of Extended SAL Specification.
957 
958   @retval EFI_SAL_SUCCESS    The information on the number of CPUs in the platform
959                              was returned.
960 
961 **/
962 SAL_RETURN_REGS
963 EFIAPI
EsalNumProcessors(VOID)964 EsalNumProcessors (
965   VOID
966   )
967 {
968   return EsalCall (
969            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
970            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
971            NumProcessorsFunctionId,
972            0,
973            0,
974            0,
975            0,
976            0,
977            0,
978            0
979            );
980 }
981 
982 /**
983   Wrapper for the EsalSetMinStateFnctionId service of Extended SAL MP Services Class.
984 
985   This function is a wrapper for the EsalSetMinStateFnctionId service of Extended SAL
986   MP Services Class. See EsalSetMinStateFnctionId of Extended SAL Specification.
987 
988   @param  CpuGlobalId       The Global ID for the CPU whose MINSTATE pointer is being set.
989   @param  MinStatePointer          The physical address of the MINSTATE buffer for the CPU
990                                    specified by CpuGlobalId.
991 
992   @retval EFI_SAL_SUCCESS          The MINSTATE pointer was set for the specified CPU.
993   @retval EFI_SAL_NO_INFORMATION   The specified CPU is not in the database.
994 
995 **/
996 SAL_RETURN_REGS
997 EFIAPI
EsalSetMinState(IN UINT64 CpuGlobalId,IN EFI_PHYSICAL_ADDRESS MinStatePointer)998 EsalSetMinState (
999   IN UINT64                CpuGlobalId,
1000   IN EFI_PHYSICAL_ADDRESS  MinStatePointer
1001   )
1002 {
1003   return EsalCall (
1004            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
1005            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
1006            SetMinStateFunctionId,
1007            CpuGlobalId,
1008            MinStatePointer,
1009            0,
1010            0,
1011            0,
1012            0,
1013            0
1014            );
1015 }
1016 
1017 /**
1018   Wrapper for the EsalGetMinStateFunctionId service of Extended SAL MP Services Class.
1019 
1020   This function is a wrapper for the EsalGetMinStateFunctionId service of Extended SAL
1021   MP Services Class. See EsalGetMinStateFunctionId of Extended SAL Specification.
1022 
1023   @param  CpuGlobalId   The Global ID for the CPU whose MINSTATE pointer is being retrieved.
1024 
1025   @retval EFI_SAL_SUCCESS        The MINSTATE pointer for the specified CPU was retrieved.
1026   @retval EFI_SAL_NO_INFORMATION The specified CPU is not in the database.
1027 
1028 **/
1029 SAL_RETURN_REGS
1030 EFIAPI
EsalGetMinState(IN UINT64 CpuGlobalId)1031 EsalGetMinState (
1032   IN UINT64  CpuGlobalId
1033   )
1034 {
1035   return EsalCall (
1036            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
1037            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
1038            GetMinStateFunctionId,
1039            CpuGlobalId,
1040            0,
1041            0,
1042            0,
1043            0,
1044            0,
1045            0
1046            );
1047 }
1048 
1049 /**
1050   Wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL MCA Services Class.
1051 
1052   This function is a wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL
1053   MCA Services Class. See EsalMcsGetStateInfoFunctionId of Extended SAL Specification.
1054 
1055   @param  CpuGlobalId               The Global ID for the CPU whose MCA state buffer is being retrieved.
1056   @param  StateBufferPointer        A pointer to the returned MCA state buffer.
1057   @param  RequiredStateBufferSize   A pointer to the size, in bytes, of the returned MCA state buffer.
1058 
1059   @retval EFI_SUCCESS               MINSTATE successfully got and size calculated.
1060   @retval EFI_SAL_NO_INFORMATION    Fail to get MINSTATE.
1061 
1062 **/
1063 SAL_RETURN_REGS
1064 EFIAPI
EsalMcaGetStateInfo(IN UINT64 CpuGlobalId,OUT EFI_PHYSICAL_ADDRESS * StateBufferPointer,OUT UINT64 * RequiredStateBufferSize)1065 EsalMcaGetStateInfo (
1066   IN  UINT64                CpuGlobalId,
1067   OUT EFI_PHYSICAL_ADDRESS  *StateBufferPointer,
1068   OUT UINT64                *RequiredStateBufferSize
1069   )
1070 {
1071   SAL_RETURN_REGS  Regs;
1072 
1073   Regs = EsalCall (
1074            EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,
1075            EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,
1076            McaGetStateInfoFunctionId,
1077            CpuGlobalId,
1078            0,
1079            0,
1080            0,
1081            0,
1082            0,
1083            0
1084            );
1085 
1086   *StateBufferPointer      = (EFI_PHYSICAL_ADDRESS) Regs.r9;
1087   *RequiredStateBufferSize = (UINT64) Regs.r10;
1088 
1089   return Regs;
1090 }
1091 
1092 /**
1093   Wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL MCA Services Class.
1094 
1095   This function is a wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL
1096   MCA Services Class. See EsalMcaRegisterCpuFunctionId of Extended SAL Specification.
1097 
1098   @param  CpuGlobalId          The Global ID for the CPU whose MCA state buffer is being set.
1099   @param  StateBufferPointer   A pointer to the MCA state buffer.
1100 
1101   @retval EFI_SAL_NO_INFORMATION   Cannot get the processor info with the CpuId
1102   @retval EFI_SUCCESS              Save the processor's state info successfully
1103 
1104 **/
1105 SAL_RETURN_REGS
1106 EFIAPI
EsalMcaRegisterCpu(IN UINT64 CpuGlobalId,IN EFI_PHYSICAL_ADDRESS StateBufferPointer)1107 EsalMcaRegisterCpu (
1108   IN UINT64                CpuGlobalId,
1109   IN EFI_PHYSICAL_ADDRESS  StateBufferPointer
1110   )
1111 {
1112   return EsalCall (
1113            EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,
1114            EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,
1115            McaRegisterCpuFunctionId,
1116            CpuGlobalId,
1117            StateBufferPointer,
1118            0,
1119            0,
1120            0,
1121            0,
1122            0
1123            );
1124 }
1125