3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Top level module for the EBC virtual machine implementation.
19 Provides auxilliary support routines for the VM. That is, routines
20 that are not particularly related to VM execution of EBC instructions.
25 #include "EbcExecute.h"
28 // We'll keep track of all thunks we create in a linked list. Each
29 // thunk is tied to an image handle, so we have a linked list of
30 // image handles, with each having a linked list of thunks allocated
31 // to that image handle.
33 typedef struct _EBC_THUNK_LIST
{
35 struct _EBC_THUNK_LIST
*Next
;
38 typedef struct _EBC_IMAGE_LIST
{
39 struct _EBC_IMAGE_LIST
*Next
;
40 EFI_HANDLE ImageHandle
;
41 EBC_THUNK_LIST
*ThunkList
;
45 // Function prototypes
50 IN EFI_HANDLE ImageHandle
,
51 IN EFI_SYSTEM_TABLE
*SystemTable
58 IN EFI_EBC_PROTOCOL
*This
,
59 IN EFI_HANDLE ImageHandle
66 IN EFI_EBC_PROTOCOL
*This
,
67 IN EFI_HANDLE ImageHandle
,
68 IN VOID
*EbcEntryPoint
,
76 IN EFI_EBC_PROTOCOL
*This
,
77 IN OUT UINT64
*Version
82 InitializeEbcCallback (
83 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
88 CommonEbcExceptionHandler (
89 IN EFI_EXCEPTION_TYPE InterruptType
,
90 IN EFI_SYSTEM_CONTEXT SystemContext
95 EbcPeriodicNotifyFunction (
107 // These two functions and the GUID are used to produce an EBC test protocol.
108 // This functionality is definitely not required for execution.
112 InitEbcVmTestProtocol (
113 IN EFI_HANDLE
*Handle
118 EbcVmTestUnsupported (
125 EbcRegisterICacheFlush (
126 IN EFI_EBC_PROTOCOL
*This
,
127 IN EBC_ICACHE_FLUSH Flush
133 EbcDebugGetMaximumProcessorIndex (
134 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
135 OUT UINTN
*MaxProcessorIndex
141 EbcDebugRegisterPeriodicCallback (
142 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
143 IN UINTN ProcessorIndex
,
144 IN EFI_PERIODIC_CALLBACK PeriodicCallback
150 EbcDebugRegisterExceptionCallback (
151 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
152 IN UINTN ProcessorIndex
,
153 IN EFI_EXCEPTION_CALLBACK ExceptionCallback
,
154 IN EFI_EXCEPTION_TYPE ExceptionType
160 EbcDebugInvalidateInstructionCache (
161 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
162 IN UINTN ProcessorIndex
,
168 // We have one linked list of image handles for the whole world. Since
169 // there should only be one interpreter, make them global. They must
170 // also be global since the execution of an EBC image does not provide
173 static EBC_IMAGE_LIST
*mEbcImageList
= NULL
;
176 // Callback function to flush the icache after thunk creation
178 static EBC_ICACHE_FLUSH mEbcICacheFlush
;
181 // These get set via calls by the debug agent
183 static EFI_PERIODIC_CALLBACK mDebugPeriodicCallback
= NULL
;
184 static EFI_EXCEPTION_CALLBACK mDebugExceptionCallback
[MAX_EBC_EXCEPTION
+ 1] = {NULL
};
185 static EFI_GUID mEfiEbcVmTestProtocolGuid
= EFI_EBC_VM_TEST_PROTOCOL_GUID
;
188 // Event for Periodic callback
190 static EFI_EVENT mEbcPeriodicEvent
;
191 VM_CONTEXT
*mVmPtr
= NULL
;
195 InitializeEbcDriver (
196 IN EFI_HANDLE ImageHandle
,
197 IN EFI_SYSTEM_TABLE
*SystemTable
203 Initializes the VM EFI interface. Allocates memory for the VM interface
204 and registers the VM protocol.
208 ImageHandle - EFI image handle.
209 SystemTable - Pointer to the EFI system table.
212 Standard EFI status code.
216 EFI_EBC_PROTOCOL
*EbcProtocol
;
217 EFI_EBC_PROTOCOL
*OldEbcProtocol
;
219 EFI_DEBUG_SUPPORT_PROTOCOL
*EbcDebugProtocol
;
220 EFI_HANDLE
*HandleBuffer
;
226 EbcDebugProtocol
= NULL
;
229 // Allocate memory for our protocol. Then fill in the blanks.
231 Status
= gBS
->AllocatePool (
233 sizeof (EFI_EBC_PROTOCOL
),
234 (VOID
**) &EbcProtocol
236 if (Status
!= EFI_SUCCESS
) {
237 return EFI_OUT_OF_RESOURCES
;
240 EbcProtocol
->CreateThunk
= EbcCreateThunk
;
241 EbcProtocol
->UnloadImage
= EbcUnloadImage
;
242 EbcProtocol
->RegisterICacheFlush
= EbcRegisterICacheFlush
;
243 EbcProtocol
->GetVersion
= EbcGetVersion
;
244 mEbcICacheFlush
= NULL
;
247 // Find any already-installed EBC protocols and uninstall them
251 Status
= gBS
->LocateHandleBuffer (
253 &gEfiEbcProtocolGuid
,
258 if (Status
== EFI_SUCCESS
) {
260 // Loop through the handles
262 for (Index
= 0; Index
< NumHandles
; Index
++) {
263 Status
= gBS
->HandleProtocol (
265 &gEfiEbcProtocolGuid
,
266 (VOID
**) &OldEbcProtocol
268 if (Status
== EFI_SUCCESS
) {
269 if (gBS
->ReinstallProtocolInterface (
271 &gEfiEbcProtocolGuid
,
281 if (HandleBuffer
!= NULL
) {
282 gBS
->FreePool (HandleBuffer
);
286 // Add the protocol so someone can locate us if we haven't already.
289 Status
= gBS
->InstallProtocolInterface (
291 &gEfiEbcProtocolGuid
,
292 EFI_NATIVE_INTERFACE
,
295 if (EFI_ERROR (Status
)) {
296 gBS
->FreePool (EbcProtocol
);
301 // Allocate memory for our debug protocol. Then fill in the blanks.
303 Status
= gBS
->AllocatePool (
305 sizeof (EFI_DEBUG_SUPPORT_PROTOCOL
),
306 (VOID
**) &EbcDebugProtocol
308 if (Status
!= EFI_SUCCESS
) {
312 EbcDebugProtocol
->Isa
= IsaEbc
;
313 EbcDebugProtocol
->GetMaximumProcessorIndex
= EbcDebugGetMaximumProcessorIndex
;
314 EbcDebugProtocol
->RegisterPeriodicCallback
= EbcDebugRegisterPeriodicCallback
;
315 EbcDebugProtocol
->RegisterExceptionCallback
= EbcDebugRegisterExceptionCallback
;
316 EbcDebugProtocol
->InvalidateInstructionCache
= EbcDebugInvalidateInstructionCache
;
319 // Add the protocol so the debug agent can find us
321 Status
= gBS
->InstallProtocolInterface (
323 &gEfiDebugSupportProtocolGuid
,
324 EFI_NATIVE_INTERFACE
,
328 // This is recoverable, so free the memory and continue.
330 if (EFI_ERROR (Status
)) {
331 gBS
->FreePool (EbcDebugProtocol
);
335 // Install EbcDebugSupport Protocol Successfully
336 // Now we need to initialize the Ebc default Callback
338 Status
= InitializeEbcCallback (EbcDebugProtocol
);
341 // Produce a VM test interface protocol. Not required for execution.
344 InitEbcVmTestProtocol (&ImageHandle
);
351 Status
= gBS
->LocateHandleBuffer (
353 &gEfiEbcProtocolGuid
,
358 if (Status
== EFI_SUCCESS
) {
360 // Loop through the handles
362 for (Index
= 0; Index
< NumHandles
; Index
++) {
363 Status
= gBS
->HandleProtocol (
365 &gEfiEbcProtocolGuid
,
366 (VOID
**) &OldEbcProtocol
368 if (Status
== EFI_SUCCESS
) {
369 gBS
->UninstallProtocolInterface (
371 &gEfiEbcProtocolGuid
,
378 if (HandleBuffer
!= NULL
) {
379 gBS
->FreePool (HandleBuffer
);
383 gBS
->FreePool (EbcProtocol
);
392 IN EFI_EBC_PROTOCOL
*This
,
393 IN EFI_HANDLE ImageHandle
,
394 IN VOID
*EbcEntryPoint
,
401 This is the top-level routine plugged into the EBC protocol. Since thunks
402 are very processor-specific, from here we dispatch directly to the very
403 processor-specific routine EbcCreateThunks().
407 This - protocol instance pointer
408 ImageHandle - handle to the image. The EBC interpreter may use this to keep
409 track of any resource allocations performed in loading and
411 EbcEntryPoint - the entry point for the image (as defined in the file header)
412 Thunk - pointer to thunk pointer where the address of the created
423 Status
= EbcCreateThunks (
427 FLAG_THUNK_ENTRY_POINT
435 EbcDebugGetMaximumProcessorIndex (
436 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
437 OUT UINTN
*MaxProcessorIndex
443 This EBC debugger protocol service is called by the debug agent
447 This - pointer to the caller's debug support protocol interface
448 MaxProcessorIndex - pointer to a caller allocated UINTN in which the maximum
449 processor index is returned.
457 *MaxProcessorIndex
= 0;
464 EbcDebugRegisterPeriodicCallback (
465 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
466 IN UINTN ProcessorIndex
,
467 IN EFI_PERIODIC_CALLBACK PeriodicCallback
473 This protocol service is called by the debug agent to register a function
474 for us to call on a periodic basis.
479 This - pointer to the caller's debug support protocol interface
480 PeriodicCallback - pointer to the function to call periodically
488 if ((mDebugPeriodicCallback
== NULL
) && (PeriodicCallback
== NULL
)) {
489 return EFI_INVALID_PARAMETER
;
491 if ((mDebugPeriodicCallback
!= NULL
) && (PeriodicCallback
!= NULL
)) {
492 return EFI_ALREADY_STARTED
;
495 mDebugPeriodicCallback
= PeriodicCallback
;
502 EbcDebugRegisterExceptionCallback (
503 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
504 IN UINTN ProcessorIndex
,
505 IN EFI_EXCEPTION_CALLBACK ExceptionCallback
,
506 IN EFI_EXCEPTION_TYPE ExceptionType
512 This protocol service is called by the debug agent to register a function
513 for us to call when we detect an exception.
518 This - pointer to the caller's debug support protocol interface
519 PeriodicCallback - pointer to the function to call periodically
527 if ((ExceptionType
< 0) || (ExceptionType
> MAX_EBC_EXCEPTION
)) {
528 return EFI_INVALID_PARAMETER
;
530 if ((mDebugExceptionCallback
[ExceptionType
] == NULL
) && (ExceptionCallback
== NULL
)) {
531 return EFI_INVALID_PARAMETER
;
533 if ((mDebugExceptionCallback
[ExceptionType
] != NULL
) && (ExceptionCallback
!= NULL
)) {
534 return EFI_ALREADY_STARTED
;
536 mDebugExceptionCallback
[ExceptionType
] = ExceptionCallback
;
543 EbcDebugInvalidateInstructionCache (
544 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
,
545 IN UINTN ProcessorIndex
,
553 This EBC debugger protocol service is called by the debug agent. Required
554 for DebugSupport compliance but is only stubbed out for EBC.
568 EbcDebugSignalException (
569 IN EFI_EXCEPTION_TYPE ExceptionType
,
570 IN EXCEPTION_FLAGS ExceptionFlags
,
577 The VM interpreter calls this function when an exception is detected.
581 VmPtr - pointer to a VM context for passing info to the EFI debugger.
585 EFI_SUCCESS if it returns at all
589 EFI_SYSTEM_CONTEXT_EBC EbcContext
;
590 EFI_SYSTEM_CONTEXT SystemContext
;
592 ASSERT ((ExceptionType
>= 0) && (ExceptionType
<= MAX_EBC_EXCEPTION
));
594 // Save the exception in the context passed in
596 VmPtr
->ExceptionFlags
|= ExceptionFlags
;
597 VmPtr
->LastException
= ExceptionType
;
599 // If it's a fatal exception, then flag it in the VM context in case an
600 // attached debugger tries to return from it.
602 if (ExceptionFlags
& EXCEPTION_FLAG_FATAL
) {
603 VmPtr
->StopFlags
|= STOPFLAG_APP_DONE
;
607 // If someone's registered for exception callbacks, then call them.
609 // EBC driver will register default exception callback to report the
610 // status code via the status code API
612 if (mDebugExceptionCallback
[ExceptionType
] != NULL
) {
615 // Initialize the context structure
617 EbcContext
.R0
= VmPtr
->R
[0];
618 EbcContext
.R1
= VmPtr
->R
[1];
619 EbcContext
.R2
= VmPtr
->R
[2];
620 EbcContext
.R3
= VmPtr
->R
[3];
621 EbcContext
.R4
= VmPtr
->R
[4];
622 EbcContext
.R5
= VmPtr
->R
[5];
623 EbcContext
.R6
= VmPtr
->R
[6];
624 EbcContext
.R7
= VmPtr
->R
[7];
625 EbcContext
.Ip
= (UINT64
)(UINTN
)VmPtr
->Ip
;
626 EbcContext
.Flags
= VmPtr
->Flags
;
627 EbcContext
.ControlFlags
= 0;
628 SystemContext
.SystemContextEbc
= &EbcContext
;
630 mDebugExceptionCallback
[ExceptionType
] (ExceptionType
, SystemContext
);
632 // Restore the context structure and continue to execute
634 VmPtr
->R
[0] = EbcContext
.R0
;
635 VmPtr
->R
[1] = EbcContext
.R1
;
636 VmPtr
->R
[2] = EbcContext
.R2
;
637 VmPtr
->R
[3] = EbcContext
.R3
;
638 VmPtr
->R
[4] = EbcContext
.R4
;
639 VmPtr
->R
[5] = EbcContext
.R5
;
640 VmPtr
->R
[6] = EbcContext
.R6
;
641 VmPtr
->R
[7] = EbcContext
.R7
;
642 VmPtr
->Ip
= (VMIP
)(UINTN
)EbcContext
.Ip
;
643 VmPtr
->Flags
= EbcContext
.Flags
;
650 InitializeEbcCallback (
651 IN EFI_DEBUG_SUPPORT_PROTOCOL
*This
657 To install default Callback function for the VM interpreter.
661 This - pointer to the instance of DebugSupport protocol
673 // For ExceptionCallback
675 for (Index
= 0; Index
<= MAX_EBC_EXCEPTION
; Index
++) {
676 EbcDebugRegisterExceptionCallback (
679 CommonEbcExceptionHandler
,
685 // For PeriodicCallback
687 Status
= gBS
->CreateEvent (
688 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
690 EbcPeriodicNotifyFunction
,
694 if (EFI_ERROR(Status
)) {
698 Status
= gBS
->SetTimer (
701 EBC_VM_PERIODIC_CALLBACK_RATE
703 if (EFI_ERROR(Status
)) {
711 CommonEbcExceptionHandler (
712 IN EFI_EXCEPTION_TYPE InterruptType
,
713 IN EFI_SYSTEM_CONTEXT SystemContext
719 The default Exception Callback for the VM interpreter.
720 In this function, we report status code, and print debug information
721 about EBC_CONTEXT, then dead loop.
725 InterruptType - Interrupt type.
726 SystemContext - EBC system context.
735 // We deadloop here to make it easy to debug this issue.
744 EbcPeriodicNotifyFunction (
752 The periodic callback function for EBC VM interpreter, which is used
753 to support the EFI debug support protocol.
757 Event - The Periodic Callback Event.
758 Context - It should be the address of VM_CONTEXT pointer.
768 VmPtr
= *(VM_CONTEXT
**)Context
;
771 EbcDebugPeriodic (VmPtr
);
786 The VM interpreter calls this function on a periodic basis to support
787 the EFI debug support protocol.
791 VmPtr - pointer to a VM context for passing info to the debugger.
799 EFI_SYSTEM_CONTEXT_EBC EbcContext
;
800 EFI_SYSTEM_CONTEXT SystemContext
;
803 // If someone's registered for periodic callbacks, then call them.
805 if (mDebugPeriodicCallback
!= NULL
) {
808 // Initialize the context structure
810 EbcContext
.R0
= VmPtr
->R
[0];
811 EbcContext
.R1
= VmPtr
->R
[1];
812 EbcContext
.R2
= VmPtr
->R
[2];
813 EbcContext
.R3
= VmPtr
->R
[3];
814 EbcContext
.R4
= VmPtr
->R
[4];
815 EbcContext
.R5
= VmPtr
->R
[5];
816 EbcContext
.R6
= VmPtr
->R
[6];
817 EbcContext
.R7
= VmPtr
->R
[7];
818 EbcContext
.Ip
= (UINT64
)(UINTN
)VmPtr
->Ip
;
819 EbcContext
.Flags
= VmPtr
->Flags
;
820 EbcContext
.ControlFlags
= 0;
821 SystemContext
.SystemContextEbc
= &EbcContext
;
823 mDebugPeriodicCallback (SystemContext
);
826 // Restore the context structure and continue to execute
828 VmPtr
->R
[0] = EbcContext
.R0
;
829 VmPtr
->R
[1] = EbcContext
.R1
;
830 VmPtr
->R
[2] = EbcContext
.R2
;
831 VmPtr
->R
[3] = EbcContext
.R3
;
832 VmPtr
->R
[4] = EbcContext
.R4
;
833 VmPtr
->R
[5] = EbcContext
.R5
;
834 VmPtr
->R
[6] = EbcContext
.R6
;
835 VmPtr
->R
[7] = EbcContext
.R7
;
836 VmPtr
->Ip
= (VMIP
)(UINTN
)EbcContext
.Ip
;
837 VmPtr
->Flags
= EbcContext
.Flags
;
847 IN EFI_EBC_PROTOCOL
*This
,
848 IN EFI_HANDLE ImageHandle
854 This routine is called by the core when an image is being unloaded from
855 memory. Basically we now have the opportunity to do any necessary cleanup.
856 Typically this will include freeing any memory allocated for thunk-creation.
860 This - protocol instance pointer
861 ImageHandle - handle to the image being unloaded.
865 EFI_INVALID_PARAMETER - the ImageHandle passed in was not found in
866 the internal list of EBC image handles.
867 EFI_STATUS - completed successfully
871 EBC_THUNK_LIST
*ThunkList
;
872 EBC_THUNK_LIST
*NextThunkList
;
873 EBC_IMAGE_LIST
*ImageList
;
874 EBC_IMAGE_LIST
*PrevImageList
;
876 // First go through our list of known image handles and see if we've already
877 // created an image list element for this image handle.
879 PrevImageList
= NULL
;
880 for (ImageList
= mEbcImageList
; ImageList
!= NULL
; ImageList
= ImageList
->Next
) {
881 if (ImageList
->ImageHandle
== ImageHandle
) {
885 // Save the previous so we can connect the lists when we remove this one
887 PrevImageList
= ImageList
;
890 if (ImageList
== NULL
) {
891 return EFI_INVALID_PARAMETER
;
894 // Free up all the thunk buffers and thunks list elements for this image
897 ThunkList
= ImageList
->ThunkList
;
898 while (ThunkList
!= NULL
) {
899 NextThunkList
= ThunkList
->Next
;
900 gBS
->FreePool (ThunkList
->ThunkBuffer
);
901 gBS
->FreePool (ThunkList
);
902 ThunkList
= NextThunkList
;
905 // Now remove this image list element from the chain
907 if (PrevImageList
== NULL
) {
911 mEbcImageList
= ImageList
->Next
;
913 PrevImageList
->Next
= ImageList
->Next
;
916 // Now free up the image list element
918 gBS
->FreePool (ImageList
);
924 IN EFI_HANDLE ImageHandle
,
925 IN VOID
*ThunkBuffer
,
932 Add a thunk to our list of thunks for a given image handle.
933 Also flush the instruction cache since we've written thunk code
934 to memory that will be executed eventually.
938 ImageHandle - the image handle to which the thunk is tied
939 ThunkBuffer - the buffer we've created/allocated
940 ThunkSize - the size of the thunk memory allocated
944 EFI_OUT_OF_RESOURCES - memory allocation failed
945 EFI_SUCCESS - successful completion
949 EBC_THUNK_LIST
*ThunkList
;
950 EBC_IMAGE_LIST
*ImageList
;
954 // It so far so good, then flush the instruction cache
956 if (mEbcICacheFlush
!= NULL
) {
957 Status
= mEbcICacheFlush ((EFI_PHYSICAL_ADDRESS
) (UINTN
) ThunkBuffer
, ThunkSize
);
958 if (EFI_ERROR (Status
)) {
963 // Go through our list of known image handles and see if we've already
964 // created a image list element for this image handle.
966 for (ImageList
= mEbcImageList
; ImageList
!= NULL
; ImageList
= ImageList
->Next
) {
967 if (ImageList
->ImageHandle
== ImageHandle
) {
972 if (ImageList
== NULL
) {
974 // Allocate a new one
976 Status
= gBS
->AllocatePool (
978 sizeof (EBC_IMAGE_LIST
),
981 if (Status
!= EFI_SUCCESS
) {
982 return EFI_OUT_OF_RESOURCES
;
985 ImageList
->ThunkList
= NULL
;
986 ImageList
->ImageHandle
= ImageHandle
;
987 ImageList
->Next
= mEbcImageList
;
988 mEbcImageList
= ImageList
;
991 // Ok, now create a new thunk element to add to the list
993 Status
= gBS
->AllocatePool (
995 sizeof (EBC_THUNK_LIST
),
998 if (Status
!= EFI_SUCCESS
) {
999 return EFI_OUT_OF_RESOURCES
;
1002 // Add it to the head of the list
1004 ThunkList
->Next
= ImageList
->ThunkList
;
1005 ThunkList
->ThunkBuffer
= ThunkBuffer
;
1006 ImageList
->ThunkList
= ThunkList
;
1013 EbcRegisterICacheFlush (
1014 IN EFI_EBC_PROTOCOL
*This
,
1015 IN EBC_ICACHE_FLUSH Flush
1018 mEbcICacheFlush
= Flush
;
1026 IN EFI_EBC_PROTOCOL
*This
,
1027 IN OUT UINT64
*Version
1030 if (Version
== NULL
) {
1031 return EFI_INVALID_PARAMETER
;
1034 *Version
= GetVmVersion ();
1040 InitEbcVmTestProtocol (
1041 IN EFI_HANDLE
*IHandle
1045 Routine Description:
1047 Produce an EBC VM test protocol that can be used for regression tests.
1051 IHandle - handle on which to install the protocol.
1055 EFI_OUT_OF_RESOURCES - memory allocation failed
1056 EFI_SUCCESS - successful completion
1062 EFI_EBC_VM_TEST_PROTOCOL
*EbcVmTestProtocol
;
1065 // Allocate memory for the protocol, then fill in the fields
1067 Status
= gBS
->AllocatePool (EfiBootServicesData
, sizeof (EFI_EBC_VM_TEST_PROTOCOL
), (VOID
**) &EbcVmTestProtocol
);
1068 if (Status
!= EFI_SUCCESS
) {
1069 return EFI_OUT_OF_RESOURCES
;
1071 EbcVmTestProtocol
->Execute
= (EBC_VM_TEST_EXECUTE
) EbcExecuteInstructions
;
1073 DEBUG_CODE_BEGIN ();
1074 EbcVmTestProtocol
->Assemble
= (EBC_VM_TEST_ASM
) EbcVmTestUnsupported
;
1075 EbcVmTestProtocol
->Disassemble
= (EBC_VM_TEST_DASM
) EbcVmTestUnsupported
;
1079 // Publish the protocol
1082 Status
= gBS
->InstallProtocolInterface (&Handle
, &mEfiEbcVmTestProtocolGuid
, EFI_NATIVE_INTERFACE
, EbcVmTestProtocol
);
1083 if (EFI_ERROR (Status
)) {
1084 gBS
->FreePool (EbcVmTestProtocol
);
1090 EbcVmTestUnsupported ()
1092 return EFI_UNSUPPORTED
;