2 Top level module for the EBC virtual machine implementation.
3 Provides auxilliary support routines for the VM. That is, routines
4 that are not particularly related to VM execution of EBC instructions.
6 Copyright (c) 2006, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "EbcExecute.h"
21 // We'll keep track of all thunks we create in a linked list. Each
22 // thunk is tied to an image handle, so we have a linked list of
23 // image handles, with each having a linked list of thunks allocated
24 // to that image handle.
26 typedef struct _EBC_THUNK_LIST
{
28 struct _EBC_THUNK_LIST
*Next
;
31 typedef struct _EBC_IMAGE_LIST
{
32 struct _EBC_IMAGE_LIST
*Next
;
33 EFI_HANDLE ImageHandle
;
34 EBC_THUNK_LIST
*ThunkList
;
41 IN EFI_EBC_PROTOCOL
*This
,
42 IN EFI_HANDLE ImageHandle
49 IN EFI_EBC_PROTOCOL
*This
,
50 IN EFI_HANDLE ImageHandle
,
51 IN VOID
*EbcEntryPoint
,
59 IN EFI_EBC_PROTOCOL
*This
,
60 IN OUT UINT64
*Version
66 InitializeEbcCallback (
67 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
73 CommonEbcExceptionHandler (
74 IN EFI_EXCEPTION_TYPE InterruptType
,
75 IN EFI_SYSTEM_CONTEXT SystemContext
81 EbcPeriodicNotifyFunction (
94 // These two functions and the GUID are used to produce an EBC test protocol.
95 // This functionality is definitely not required for execution.
99 InitEbcVmTestProtocol (
100 IN EFI_HANDLE
*Handle
105 EbcVmTestUnsupported (
112 EbcRegisterICacheFlush (
113 IN EFI_EBC_PROTOCOL
*This
,
114 IN EBC_ICACHE_FLUSH Flush
120 EbcDebugGetMaximumProcessorIndex (
121 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
122 OUT UINTN
*MaxProcessorIndex
128 EbcDebugRegisterPeriodicCallback (
129 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
130 IN UINTN ProcessorIndex
,
131 IN EFI_PERIODIC_CALLBACK PeriodicCallback
137 EbcDebugRegisterExceptionCallback (
138 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
139 IN UINTN ProcessorIndex
,
140 IN EFI_EXCEPTION_CALLBACK ExceptionCallback
,
141 IN EFI_EXCEPTION_TYPE ExceptionType
147 EbcDebugInvalidateInstructionCache (
148 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
149 IN UINTN ProcessorIndex
,
155 // We have one linked list of image handles for the whole world. Since
156 // there should only be one interpreter, make them global. They must
157 // also be global since the execution of an EBC image does not provide
160 static EBC_IMAGE_LIST
*mEbcImageList
= NULL
;
163 // Callback function to flush the icache after thunk creation
165 static EBC_ICACHE_FLUSH mEbcICacheFlush
;
168 // These get set via calls by the debug agent
170 static EFI_PERIODIC_CALLBACK mDebugPeriodicCallback
= NULL
;
171 static EFI_EXCEPTION_CALLBACK mDebugExceptionCallback
[MAX_EBC_EXCEPTION
+ 1] = {NULL
};
172 static EFI_GUID mEfiEbcVmTestProtocolGuid
= EFI_EBC_VM_TEST_PROTOCOL_GUID
;
174 static VOID
* mStackBuffer
[MAX_STACK_NUM
];
175 static EFI_HANDLE mStackBufferIndex
[MAX_STACK_NUM
];
176 static UINTN mStackNum
= 0;
179 // Event for Periodic callback
181 static EFI_EVENT mEbcPeriodicEvent
;
182 VM_CONTEXT
*mVmPtr
= NULL
;
186 Initializes the VM EFI interface. Allocates memory for the VM interface
187 and registers the VM protocol.
189 @param ImageHandle EFI image handle.
190 @param SystemTable Pointer to the EFI system table.
192 @return Standard EFI status code.
197 InitializeEbcDriver (
198 IN EFI_HANDLE ImageHandle
,
199 IN EFI_SYSTEM_TABLE
*SystemTable
202 EFI_EBC_PROTOCOL
*EbcProtocol
;
203 EFI_EBC_PROTOCOL
*OldEbcProtocol
;
205 EFI_DEBUG_SUPPORT_PROTOCOL
*EbcDebugProtocol
;
206 EFI_HANDLE
*HandleBuffer
;
212 EbcDebugProtocol
= NULL
;
215 // Allocate memory for our protocol. Then fill in the blanks.
217 EbcProtocol
= AllocatePool (sizeof (EFI_EBC_PROTOCOL
));
219 if (EbcProtocol
== NULL
) {
220 return EFI_OUT_OF_RESOURCES
;
223 EbcProtocol
->CreateThunk
= EbcCreateThunk
;
224 EbcProtocol
->UnloadImage
= EbcUnloadImage
;
225 EbcProtocol
->RegisterICacheFlush
= EbcRegisterICacheFlush
;
226 EbcProtocol
->GetVersion
= EbcGetVersion
;
227 mEbcICacheFlush
= NULL
;
230 // Find any already-installed EBC protocols and uninstall them
234 Status
= gBS
->LocateHandleBuffer (
236 &gEfiEbcProtocolGuid
,
241 if (Status
== EFI_SUCCESS
) {
243 // Loop through the handles
245 for (Index
= 0; Index
< NumHandles
; Index
++) {
246 Status
= gBS
->HandleProtocol (
248 &gEfiEbcProtocolGuid
,
249 (VOID
**) &OldEbcProtocol
251 if (Status
== EFI_SUCCESS
) {
252 if (gBS
->ReinstallProtocolInterface (
254 &gEfiEbcProtocolGuid
,
264 if (HandleBuffer
!= NULL
) {
265 FreePool (HandleBuffer
);
269 // Add the protocol so someone can locate us if we haven't already.
272 Status
= gBS
->InstallProtocolInterface (
274 &gEfiEbcProtocolGuid
,
275 EFI_NATIVE_INTERFACE
,
278 if (EFI_ERROR (Status
)) {
279 FreePool (EbcProtocol
);
284 Status
= InitEBCStack();
285 if (EFI_ERROR(Status
)) {
290 // Allocate memory for our debug protocol. Then fill in the blanks.
292 EbcDebugProtocol
= AllocatePool (sizeof (EFI_DEBUG_SUPPORT_PROTOCOL
));
294 if (EbcDebugProtocol
== NULL
) {
298 EbcDebugProtocol
->Isa
= IsaEbc
;
299 EbcDebugProtocol
->GetMaximumProcessorIndex
= EbcDebugGetMaximumProcessorIndex
;
300 EbcDebugProtocol
->RegisterPeriodicCallback
= EbcDebugRegisterPeriodicCallback
;
301 EbcDebugProtocol
->RegisterExceptionCallback
= EbcDebugRegisterExceptionCallback
;
302 EbcDebugProtocol
->InvalidateInstructionCache
= EbcDebugInvalidateInstructionCache
;
305 // Add the protocol so the debug agent can find us
307 Status
= gBS
->InstallProtocolInterface (
309 &gEfiDebugSupportProtocolGuid
,
310 EFI_NATIVE_INTERFACE
,
314 // This is recoverable, so free the memory and continue.
316 if (EFI_ERROR (Status
)) {
317 FreePool (EbcDebugProtocol
);
321 // Install EbcDebugSupport Protocol Successfully
322 // Now we need to initialize the Ebc default Callback
324 Status
= InitializeEbcCallback (EbcDebugProtocol
);
327 // Produce a VM test interface protocol. Not required for execution.
330 InitEbcVmTestProtocol (&ImageHandle
);
338 Status
= gBS
->LocateHandleBuffer (
340 &gEfiEbcProtocolGuid
,
345 if (Status
== EFI_SUCCESS
) {
347 // Loop through the handles
349 for (Index
= 0; Index
< NumHandles
; Index
++) {
350 Status
= gBS
->HandleProtocol (
352 &gEfiEbcProtocolGuid
,
353 (VOID
**) &OldEbcProtocol
355 if (Status
== EFI_SUCCESS
) {
356 gBS
->UninstallProtocolInterface (
358 &gEfiEbcProtocolGuid
,
365 if (HandleBuffer
!= NULL
) {
366 FreePool (HandleBuffer
);
370 FreePool (EbcProtocol
);
377 This is the top-level routine plugged into the EBC protocol. Since thunks
378 are very processor-specific, from here we dispatch directly to the very
379 processor-specific routine EbcCreateThunks().
381 @param This protocol instance pointer
382 @param ImageHandle handle to the image. The EBC interpreter may use
383 this to keep track of any resource allocations
384 performed in loading and executing the image.
385 @param EbcEntryPoint the entry point for the image (as defined in the
387 @param Thunk pointer to thunk pointer where the address of the
388 created thunk is returned.
397 IN EFI_EBC_PROTOCOL
*This
,
398 IN EFI_HANDLE ImageHandle
,
399 IN VOID
*EbcEntryPoint
,
405 Status
= EbcCreateThunks (
409 FLAG_THUNK_ENTRY_POINT
416 This EBC debugger protocol service is called by the debug agent
418 @param This pointer to the caller's debug support protocol
420 @param MaxProcessorIndex pointer to a caller allocated UINTN in which the
421 maximum processor index is returned.
423 @return Standard EFI_STATUS
429 EbcDebugGetMaximumProcessorIndex (
430 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
431 OUT UINTN
*MaxProcessorIndex
434 *MaxProcessorIndex
= 0;
440 This protocol service is called by the debug agent to register a function
441 for us to call on a periodic basis.
443 @param This pointer to the caller's debug support protocol
445 @param PeriodicCallback pointer to the function to call periodically
447 @return Always EFI_SUCCESS
453 EbcDebugRegisterPeriodicCallback (
454 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
455 IN UINTN ProcessorIndex
,
456 IN EFI_PERIODIC_CALLBACK PeriodicCallback
459 if ((mDebugPeriodicCallback
== NULL
) && (PeriodicCallback
== NULL
)) {
460 return EFI_INVALID_PARAMETER
;
462 if ((mDebugPeriodicCallback
!= NULL
) && (PeriodicCallback
!= NULL
)) {
463 return EFI_ALREADY_STARTED
;
466 mDebugPeriodicCallback
= PeriodicCallback
;
472 This protocol service is called by the debug agent to register a function
473 for us to call when we detect an exception.
475 @param This pointer to the caller's debug support protocol
477 @param ExceptionCallback pointer to the function to the exception
479 @return Always EFI_SUCCESS
485 EbcDebugRegisterExceptionCallback (
486 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
487 IN UINTN ProcessorIndex
,
488 IN EFI_EXCEPTION_CALLBACK ExceptionCallback
,
489 IN EFI_EXCEPTION_TYPE ExceptionType
492 if ((ExceptionType
< 0) || (ExceptionType
> MAX_EBC_EXCEPTION
)) {
493 return EFI_INVALID_PARAMETER
;
495 if ((mDebugExceptionCallback
[ExceptionType
] == NULL
) && (ExceptionCallback
== NULL
)) {
496 return EFI_INVALID_PARAMETER
;
498 if ((mDebugExceptionCallback
[ExceptionType
] != NULL
) && (ExceptionCallback
!= NULL
)) {
499 return EFI_ALREADY_STARTED
;
501 mDebugExceptionCallback
[ExceptionType
] = ExceptionCallback
;
507 This EBC debugger protocol service is called by the debug agent. Required
508 for DebugSupport compliance but is only stubbed out for EBC.
517 EbcDebugInvalidateInstructionCache (
518 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
519 IN UINTN ProcessorIndex
,
529 The VM interpreter calls this function when an exception is detected.
531 @param VmPtr pointer to a VM context for passing info to the
534 @return EFI_SUCCESS if it returns at all
538 EbcDebugSignalException (
539 IN EFI_EXCEPTION_TYPE ExceptionType
,
540 IN EXCEPTION_FLAGS ExceptionFlags
,
544 EFI_SYSTEM_CONTEXT_EBC EbcContext
;
545 EFI_SYSTEM_CONTEXT SystemContext
;
547 ASSERT ((ExceptionType
>= 0) && (ExceptionType
<= MAX_EBC_EXCEPTION
));
549 // Save the exception in the context passed in
551 VmPtr
->ExceptionFlags
|= ExceptionFlags
;
552 VmPtr
->LastException
= ExceptionType
;
554 // If it's a fatal exception, then flag it in the VM context in case an
555 // attached debugger tries to return from it.
557 if (ExceptionFlags
& EXCEPTION_FLAG_FATAL
) {
558 VmPtr
->StopFlags
|= STOPFLAG_APP_DONE
;
562 // If someone's registered for exception callbacks, then call them.
564 // EBC driver will register default exception callback to report the
565 // status code via the status code API
567 if (mDebugExceptionCallback
[ExceptionType
] != NULL
) {
570 // Initialize the context structure
572 EbcContext
.R0
= VmPtr
->R
[0];
573 EbcContext
.R1
= VmPtr
->R
[1];
574 EbcContext
.R2
= VmPtr
->R
[2];
575 EbcContext
.R3
= VmPtr
->R
[3];
576 EbcContext
.R4
= VmPtr
->R
[4];
577 EbcContext
.R5
= VmPtr
->R
[5];
578 EbcContext
.R6
= VmPtr
->R
[6];
579 EbcContext
.R7
= VmPtr
->R
[7];
580 EbcContext
.Ip
= (UINT64
)(UINTN
)VmPtr
->Ip
;
581 EbcContext
.Flags
= VmPtr
->Flags
;
582 EbcContext
.ControlFlags
= 0;
583 SystemContext
.SystemContextEbc
= &EbcContext
;
585 mDebugExceptionCallback
[ExceptionType
] (ExceptionType
, SystemContext
);
587 // Restore the context structure and continue to execute
589 VmPtr
->R
[0] = EbcContext
.R0
;
590 VmPtr
->R
[1] = EbcContext
.R1
;
591 VmPtr
->R
[2] = EbcContext
.R2
;
592 VmPtr
->R
[3] = EbcContext
.R3
;
593 VmPtr
->R
[4] = EbcContext
.R4
;
594 VmPtr
->R
[5] = EbcContext
.R5
;
595 VmPtr
->R
[6] = EbcContext
.R6
;
596 VmPtr
->R
[7] = EbcContext
.R7
;
597 VmPtr
->Ip
= (VMIP
)(UINTN
)EbcContext
.Ip
;
598 VmPtr
->Flags
= EbcContext
.Flags
;
606 To install default Callback function for the VM interpreter.
608 @param This pointer to the instance of DebugSupport protocol
615 InitializeEbcCallback (
616 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
623 // For ExceptionCallback
625 for (Index
= 0; Index
<= MAX_EBC_EXCEPTION
; Index
++) {
626 EbcDebugRegisterExceptionCallback (
629 CommonEbcExceptionHandler
,
635 // For PeriodicCallback
637 Status
= gBS
->CreateEvent (
638 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
640 EbcPeriodicNotifyFunction
,
644 if (EFI_ERROR(Status
)) {
648 Status
= gBS
->SetTimer (
651 EBC_VM_PERIODIC_CALLBACK_RATE
653 if (EFI_ERROR(Status
)) {
662 The default Exception Callback for the VM interpreter.
663 In this function, we report status code, and print debug information
664 about EBC_CONTEXT, then dead loop.
666 @param InterruptType Interrupt type.
667 @param SystemContext EBC system context.
674 CommonEbcExceptionHandler (
675 IN EFI_EXCEPTION_TYPE InterruptType
,
676 IN EFI_SYSTEM_CONTEXT SystemContext
680 // We deadloop here to make it easy to debug this issue.
689 The periodic callback function for EBC VM interpreter, which is used
690 to support the EFI debug support protocol.
692 @param Event The Periodic Callback Event.
693 @param Context It should be the address of VM_CONTEXT pointer.
701 EbcPeriodicNotifyFunction (
708 VmPtr
= *(VM_CONTEXT
**)Context
;
711 EbcDebugPeriodic (VmPtr
);
719 The VM interpreter calls this function on a periodic basis to support
720 the EFI debug support protocol.
722 @param VmPtr pointer to a VM context for passing info to the
725 @return Standard EFI status.
734 EFI_SYSTEM_CONTEXT_EBC EbcContext
;
735 EFI_SYSTEM_CONTEXT SystemContext
;
738 // If someone's registered for periodic callbacks, then call them.
740 if (mDebugPeriodicCallback
!= NULL
) {
743 // Initialize the context structure
745 EbcContext
.R0
= VmPtr
->R
[0];
746 EbcContext
.R1
= VmPtr
->R
[1];
747 EbcContext
.R2
= VmPtr
->R
[2];
748 EbcContext
.R3
= VmPtr
->R
[3];
749 EbcContext
.R4
= VmPtr
->R
[4];
750 EbcContext
.R5
= VmPtr
->R
[5];
751 EbcContext
.R6
= VmPtr
->R
[6];
752 EbcContext
.R7
= VmPtr
->R
[7];
753 EbcContext
.Ip
= (UINT64
)(UINTN
)VmPtr
->Ip
;
754 EbcContext
.Flags
= VmPtr
->Flags
;
755 EbcContext
.ControlFlags
= 0;
756 SystemContext
.SystemContextEbc
= &EbcContext
;
758 mDebugPeriodicCallback (SystemContext
);
761 // Restore the context structure and continue to execute
763 VmPtr
->R
[0] = EbcContext
.R0
;
764 VmPtr
->R
[1] = EbcContext
.R1
;
765 VmPtr
->R
[2] = EbcContext
.R2
;
766 VmPtr
->R
[3] = EbcContext
.R3
;
767 VmPtr
->R
[4] = EbcContext
.R4
;
768 VmPtr
->R
[5] = EbcContext
.R5
;
769 VmPtr
->R
[6] = EbcContext
.R6
;
770 VmPtr
->R
[7] = EbcContext
.R7
;
771 VmPtr
->Ip
= (VMIP
)(UINTN
)EbcContext
.Ip
;
772 VmPtr
->Flags
= EbcContext
.Flags
;
780 This routine is called by the core when an image is being unloaded from
781 memory. Basically we now have the opportunity to do any necessary cleanup.
782 Typically this will include freeing any memory allocated for thunk-creation.
784 @param This protocol instance pointer
785 @param ImageHandle handle to the image being unloaded.
787 @retval EFI_INVALID_PARAMETER the ImageHandle passed in was not found in the
788 internal list of EBC image handles.
789 @retval EFI_STATUS completed successfully
796 IN EFI_EBC_PROTOCOL
*This
,
797 IN EFI_HANDLE ImageHandle
800 EBC_THUNK_LIST
*ThunkList
;
801 EBC_THUNK_LIST
*NextThunkList
;
802 EBC_IMAGE_LIST
*ImageList
;
803 EBC_IMAGE_LIST
*PrevImageList
;
805 // First go through our list of known image handles and see if we've already
806 // created an image list element for this image handle.
808 ReturnEBCStackByHandle(ImageHandle
);
809 PrevImageList
= NULL
;
810 for (ImageList
= mEbcImageList
; ImageList
!= NULL
; ImageList
= ImageList
->Next
) {
811 if (ImageList
->ImageHandle
== ImageHandle
) {
815 // Save the previous so we can connect the lists when we remove this one
817 PrevImageList
= ImageList
;
820 if (ImageList
== NULL
) {
821 return EFI_INVALID_PARAMETER
;
824 // Free up all the thunk buffers and thunks list elements for this image
827 ThunkList
= ImageList
->ThunkList
;
828 while (ThunkList
!= NULL
) {
829 NextThunkList
= ThunkList
->Next
;
830 FreePool (ThunkList
->ThunkBuffer
);
831 FreePool (ThunkList
);
832 ThunkList
= NextThunkList
;
835 // Now remove this image list element from the chain
837 if (PrevImageList
== NULL
) {
841 mEbcImageList
= ImageList
->Next
;
843 PrevImageList
->Next
= ImageList
->Next
;
846 // Now free up the image list element
848 FreePool (ImageList
);
854 Add a thunk to our list of thunks for a given image handle.
855 Also flush the instruction cache since we've written thunk code
856 to memory that will be executed eventually.
858 @param ImageHandle the image handle to which the thunk is tied
859 @param ThunkBuffer the buffer we've created/allocated
860 @param ThunkSize the size of the thunk memory allocated
862 @retval EFI_OUT_OF_RESOURCES memory allocation failed
863 @retval EFI_SUCCESS successful completion
868 IN EFI_HANDLE ImageHandle
,
869 IN VOID
*ThunkBuffer
,
873 EBC_THUNK_LIST
*ThunkList
;
874 EBC_IMAGE_LIST
*ImageList
;
878 // It so far so good, then flush the instruction cache
880 if (mEbcICacheFlush
!= NULL
) {
881 Status
= mEbcICacheFlush ((EFI_PHYSICAL_ADDRESS
) (UINTN
) ThunkBuffer
, ThunkSize
);
882 if (EFI_ERROR (Status
)) {
887 // Go through our list of known image handles and see if we've already
888 // created a image list element for this image handle.
890 for (ImageList
= mEbcImageList
; ImageList
!= NULL
; ImageList
= ImageList
->Next
) {
891 if (ImageList
->ImageHandle
== ImageHandle
) {
896 if (ImageList
== NULL
) {
898 // Allocate a new one
900 ImageList
= AllocatePool (sizeof (EBC_IMAGE_LIST
));
902 if (ImageList
== NULL
) {
903 return EFI_OUT_OF_RESOURCES
;
906 ImageList
->ThunkList
= NULL
;
907 ImageList
->ImageHandle
= ImageHandle
;
908 ImageList
->Next
= mEbcImageList
;
909 mEbcImageList
= ImageList
;
912 // Ok, now create a new thunk element to add to the list
914 ThunkList
= AllocatePool (sizeof (EBC_THUNK_LIST
));
916 if (ThunkList
== NULL
) {
917 return EFI_OUT_OF_RESOURCES
;
920 // Add it to the head of the list
922 ThunkList
->Next
= ImageList
->ThunkList
;
923 ThunkList
->ThunkBuffer
= ThunkBuffer
;
924 ImageList
->ThunkList
= ThunkList
;
931 EbcRegisterICacheFlush (
932 IN EFI_EBC_PROTOCOL
*This
,
933 IN EBC_ICACHE_FLUSH Flush
936 mEbcICacheFlush
= Flush
;
944 IN EFI_EBC_PROTOCOL
*This
,
945 IN OUT UINT64
*Version
948 if (Version
== NULL
) {
949 return EFI_INVALID_PARAMETER
;
952 *Version
= GetVmVersion ();
965 OldTpl
= gBS
->RaiseTPL(TPL_HIGH_LEVEL
);
966 for (Index
= 0; Index
< mStackNum
; Index
++) {
967 if (mStackBufferIndex
[Index
] == NULL
) {
968 mStackBufferIndex
[Index
] = Handle
;
972 gBS
->RestoreTPL(OldTpl
);
973 if (Index
== mStackNum
) {
974 return EFI_OUT_OF_RESOURCES
;
976 *BufferIndex
= Index
;
977 *StackBuffer
= mStackBuffer
[Index
];
986 mStackBufferIndex
[Index
] =NULL
;
991 ReturnEBCStackByHandle(
996 for (Index
= 0; Index
< mStackNum
; Index
++) {
997 if (mStackBufferIndex
[Index
] == Handle
) {
1001 if (Index
== mStackNum
) {
1002 return EFI_NOT_FOUND
;
1004 mStackBufferIndex
[Index
] = NULL
;
1013 for (mStackNum
= 0; mStackNum
< MAX_STACK_NUM
; mStackNum
++) {
1014 mStackBuffer
[mStackNum
] = AllocatePool(STACK_POOL_SIZE
);
1015 mStackBufferIndex
[mStackNum
] = NULL
;
1016 if (mStackBuffer
[mStackNum
] == NULL
) {
1020 if (mStackNum
== 0) {
1021 return EFI_OUT_OF_RESOURCES
;
1032 for (Index
= 0; Index
< mStackNum
; Index
++) {
1033 FreePool(mStackBuffer
[Index
]);
1039 Produce an EBC VM test protocol that can be used for regression tests.
1041 @param IHandle handle on which to install the protocol.
1043 @retval EFI_OUT_OF_RESOURCES memory allocation failed
1044 @retval EFI_SUCCESS successful completion
1049 InitEbcVmTestProtocol (
1050 IN EFI_HANDLE
*IHandle
1055 EFI_EBC_VM_TEST_PROTOCOL
*EbcVmTestProtocol
;
1058 // Allocate memory for the protocol, then fill in the fields
1060 EbcVmTestProtocol
= AllocatePool (sizeof (EFI_EBC_VM_TEST_PROTOCOL
));
1061 if (EbcVmTestProtocol
== NULL
) {
1062 return EFI_OUT_OF_RESOURCES
;
1064 EbcVmTestProtocol
->Execute
= (EBC_VM_TEST_EXECUTE
) EbcExecuteInstructions
;
1066 DEBUG_CODE_BEGIN ();
1067 EbcVmTestProtocol
->Assemble
= (EBC_VM_TEST_ASM
) EbcVmTestUnsupported
;
1068 EbcVmTestProtocol
->Disassemble
= (EBC_VM_TEST_DASM
) EbcVmTestUnsupported
;
1072 // Publish the protocol
1075 Status
= gBS
->InstallProtocolInterface (&Handle
, &mEfiEbcVmTestProtocolGuid
, EFI_NATIVE_INTERFACE
, EbcVmTestProtocol
);
1076 if (EFI_ERROR (Status
)) {
1077 FreePool (EbcVmTestProtocol
);
1083 EbcVmTestUnsupported ()
1085 return EFI_UNSUPPORTED
;