TianoCore EDK2 master
Loading...
Searching...
No Matches
EbcInt.c
Go to the documentation of this file.
1
11#include "EbcInt.h"
12#include "EbcExecute.h"
13#include "EbcDebuggerHook.h"
14
15//
16// We'll keep track of all thunks we create in a linked list. Each
17// thunk is tied to an image handle, so we have a linked list of
18// image handles, with each having a linked list of thunks allocated
19// to that image handle.
20//
21typedef struct _EBC_THUNK_LIST EBC_THUNK_LIST;
23 VOID *ThunkBuffer;
24 EBC_THUNK_LIST *Next;
25};
26
27typedef struct _EBC_IMAGE_LIST EBC_IMAGE_LIST;
29 EBC_IMAGE_LIST *Next;
30 EFI_HANDLE ImageHandle;
31 EBC_THUNK_LIST *ThunkList;
32};
33
49EFIAPI
51 IN EFI_EBC_PROTOCOL *This,
52 IN EFI_HANDLE ImageHandle
53 );
54
75EFIAPI
77 IN EFI_EBC_PROTOCOL *This,
78 IN EFI_HANDLE ImageHandle,
79 IN VOID *EbcEntryPoint,
80 OUT VOID **Thunk
81 );
82
95EFIAPI
97 IN EFI_EBC_PROTOCOL *This,
98 IN OUT UINT64 *Version
99 );
100
112EFIAPI
115 );
116
126VOID
127EFIAPI
129 IN EFI_EXCEPTION_TYPE InterruptType,
130 IN EFI_SYSTEM_CONTEXT SystemContext
131 );
132
141VOID
142EFIAPI
144 IN EFI_EVENT Event,
145 IN VOID *Context
146 );
147
159EFIAPI
161 IN VM_CONTEXT *VmPtr
162 );
163
164//
165// These two functions and the GUID are used to produce an EBC test protocol.
166// This functionality is definitely not required for execution.
167//
168
180 IN EFI_HANDLE *IHandle
181 );
182
190EFIAPI
192 VOID
193 );
194
206EFIAPI
208 IN EFI_EBC_PROTOCOL *This,
209 IN EBC_ICACHE_FLUSH Flush
210 );
211
224EFIAPI
227 OUT UINTN *MaxProcessorIndex
228 );
229
252EFIAPI
255 IN UINTN ProcessorIndex,
256 IN EFI_PERIODIC_CALLBACK PeriodicCallback
257 );
258
285EFIAPI
288 IN UINTN ProcessorIndex,
289 IN EFI_EXCEPTION_CALLBACK ExceptionCallback,
290 IN EFI_EXCEPTION_TYPE ExceptionType
291 );
292
310EFIAPI
313 IN UINTN ProcessorIndex,
314 IN VOID *Start,
315 IN UINT64 Length
316 );
317
318//
319// We have one linked list of image handles for the whole world. Since
320// there should only be one interpreter, make them global. They must
321// also be global since the execution of an EBC image does not provide
322// a This pointer.
323//
324EBC_IMAGE_LIST *mEbcImageList = NULL;
325
326//
327// Callback function to flush the icache after thunk creation
328//
329EBC_ICACHE_FLUSH mEbcICacheFlush;
330
331//
332// These get set via calls by the debug agent
333//
334EFI_PERIODIC_CALLBACK mDebugPeriodicCallback = NULL;
335EFI_EXCEPTION_CALLBACK mDebugExceptionCallback[MAX_EBC_EXCEPTION + 1] = { NULL };
336
337VOID *mStackBuffer[MAX_STACK_NUM];
338EFI_HANDLE mStackBufferIndex[MAX_STACK_NUM];
339UINTN mStackNum = 0;
340
341//
342// Event for Periodic callback
343//
344EFI_EVENT mEbcPeriodicEvent;
345VM_CONTEXT *mVmPtr = NULL;
346
360BOOLEAN
361EFIAPI
364 IN UINT16 ImageType,
365 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL
366 )
367{
368 if ((ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) &&
369 (ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER))
370 {
371 return FALSE;
372 }
373
374 return TRUE;
375}
376
400EFIAPI
403 IN EFI_PHYSICAL_ADDRESS ImageBase,
404 IN UINT64 ImageSize,
405 IN OUT EFI_IMAGE_ENTRY_POINT *EntryPoint
406 )
407{
409 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
410 EFI_STATUS Status;
411
412 ZeroMem (&ImageContext, sizeof (ImageContext));
413
414 ImageContext.Handle = (VOID *)(UINTN)ImageBase;
416
417 Status = PeCoffLoaderGetImageInfo (&ImageContext);
418 if (EFI_ERROR (Status)) {
419 return Status;
420 }
421
422 ASSERT (ImageContext.Machine == EFI_IMAGE_MACHINE_EBC);
423 ASSERT (
424 ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ||
425 ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
426 );
428
430 NULL,
432 );
433
434 return EbcCreateThunk (
435 NULL,
436 (VOID *)(UINTN)ImageBase,
437 (VOID *)(UINTN)*EntryPoint,
438 (VOID **)EntryPoint
439 );
440}
441
454EFIAPI
457 IN EFI_PHYSICAL_ADDRESS ImageBase
458 )
459{
460 return EbcUnloadImage (NULL, (VOID *)(UINTN)ImageBase);
461}
462
463STATIC EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL mPeCoffEmuProtocol = {
467 EDKII_PECOFF_IMAGE_EMULATOR_VERSION,
469};
470
482EFIAPI
484 IN EFI_HANDLE ImageHandle,
485 IN EFI_SYSTEM_TABLE *SystemTable
486 )
487{
488 EFI_EBC_PROTOCOL *EbcProtocol;
489 EFI_EBC_PROTOCOL *OldEbcProtocol;
490 EFI_STATUS Status;
491 EFI_DEBUG_SUPPORT_PROTOCOL *EbcDebugProtocol;
492 EFI_HANDLE *HandleBuffer;
493 UINTN NumHandles;
494 UINTN Index;
495 BOOLEAN Installed;
496
497 EbcProtocol = NULL;
498 EbcDebugProtocol = NULL;
499
500 //
501 // Allocate memory for our protocol. Then fill in the blanks.
502 //
503 EbcProtocol = AllocatePool (sizeof (EFI_EBC_PROTOCOL));
504
505 if (EbcProtocol == NULL) {
506 return EFI_OUT_OF_RESOURCES;
507 }
508
509 EbcProtocol->CreateThunk = EbcCreateThunk;
510 EbcProtocol->UnloadImage = EbcUnloadImage;
511 EbcProtocol->RegisterICacheFlush = EbcRegisterICacheFlush;
512 EbcProtocol->GetVersion = EbcGetVersion;
513 mEbcICacheFlush = NULL;
514
515 //
516 // Find any already-installed EBC protocols and uninstall them
517 //
518 Installed = FALSE;
519 HandleBuffer = NULL;
520 Status = gBS->LocateHandleBuffer (
522 &gEfiEbcProtocolGuid,
523 NULL,
524 &NumHandles,
525 &HandleBuffer
526 );
527 if (Status == EFI_SUCCESS) {
528 //
529 // Loop through the handles
530 //
531 for (Index = 0; Index < NumHandles; Index++) {
532 Status = gBS->HandleProtocol (
533 HandleBuffer[Index],
534 &gEfiEbcProtocolGuid,
535 (VOID **)&OldEbcProtocol
536 );
537 if (Status == EFI_SUCCESS) {
538 if (gBS->ReinstallProtocolInterface (
539 HandleBuffer[Index],
540 &gEfiEbcProtocolGuid,
541 OldEbcProtocol,
542 EbcProtocol
543 ) == EFI_SUCCESS)
544 {
545 Installed = TRUE;
546 }
547 }
548 }
549 }
550
551 if (HandleBuffer != NULL) {
552 FreePool (HandleBuffer);
553 HandleBuffer = NULL;
554 }
555
556 //
557 // Add the protocol so someone can locate us if we haven't already.
558 //
559 if (!Installed) {
560 Status = gBS->InstallMultipleProtocolInterfaces (
561 &ImageHandle,
562 &gEfiEbcProtocolGuid,
563 EbcProtocol,
564 &gEdkiiPeCoffImageEmulatorProtocolGuid,
565 &mPeCoffEmuProtocol,
566 NULL
567 );
568 if (EFI_ERROR (Status)) {
569 FreePool (EbcProtocol);
570 return Status;
571 }
572 }
573
574 Status = InitEBCStack ();
575 if (EFI_ERROR (Status)) {
576 goto ErrorExit;
577 }
578
579 //
580 // Allocate memory for our debug protocol. Then fill in the blanks.
581 //
582 EbcDebugProtocol = AllocatePool (sizeof (EFI_DEBUG_SUPPORT_PROTOCOL));
583
584 if (EbcDebugProtocol == NULL) {
585 goto ErrorExit;
586 }
587
588 EbcDebugProtocol->Isa = IsaEbc;
589 EbcDebugProtocol->GetMaximumProcessorIndex = EbcDebugGetMaximumProcessorIndex;
590 EbcDebugProtocol->RegisterPeriodicCallback = EbcDebugRegisterPeriodicCallback;
591 EbcDebugProtocol->RegisterExceptionCallback = EbcDebugRegisterExceptionCallback;
592 EbcDebugProtocol->InvalidateInstructionCache = EbcDebugInvalidateInstructionCache;
593
594 //
595 // Add the protocol so the debug agent can find us
596 //
597 Status = gBS->InstallProtocolInterface (
598 &ImageHandle,
599 &gEfiDebugSupportProtocolGuid,
601 EbcDebugProtocol
602 );
603 //
604 // This is recoverable, so free the memory and continue.
605 //
606 if (EFI_ERROR (Status)) {
607 FreePool (EbcDebugProtocol);
608 goto ErrorExit;
609 }
610
611 //
612 // Install EbcDebugSupport Protocol Successfully
613 // Now we need to initialize the Ebc default Callback
614 //
615 Status = InitializeEbcCallback (EbcDebugProtocol);
616
617 //
618 // Produce a VM test interface protocol. Not required for execution.
619 //
621 InitEbcVmTestProtocol (&ImageHandle);
623
624 EbcDebuggerHookInit (ImageHandle, EbcDebugProtocol);
625
626 return EFI_SUCCESS;
627
628ErrorExit:
629 FreeEBCStack ();
630 HandleBuffer = NULL;
631 Status = gBS->LocateHandleBuffer (
633 &gEfiEbcProtocolGuid,
634 NULL,
635 &NumHandles,
636 &HandleBuffer
637 );
638 if (Status == EFI_SUCCESS) {
639 //
640 // Loop through the handles
641 //
642 for (Index = 0; Index < NumHandles; Index++) {
643 Status = gBS->HandleProtocol (
644 HandleBuffer[Index],
645 &gEfiEbcProtocolGuid,
646 (VOID **)&OldEbcProtocol
647 );
648 if (Status == EFI_SUCCESS) {
649 gBS->UninstallProtocolInterface (
650 HandleBuffer[Index],
651 &gEfiEbcProtocolGuid,
652 OldEbcProtocol
653 );
654 }
655 }
656 }
657
658 if (HandleBuffer != NULL) {
659 FreePool (HandleBuffer);
660 HandleBuffer = NULL;
661 }
662
663 FreePool (EbcProtocol);
664
665 return Status;
666}
667
688EFIAPI
690 IN EFI_EBC_PROTOCOL *This,
691 IN EFI_HANDLE ImageHandle,
692 IN VOID *EbcEntryPoint,
693 OUT VOID **Thunk
694 )
695{
696 EFI_STATUS Status;
697
698 Status = EbcCreateThunks (
699 ImageHandle,
700 EbcEntryPoint,
701 Thunk,
702 FLAG_THUNK_ENTRY_POINT
703 );
704 return Status;
705}
706
719EFIAPI
722 OUT UINTN *MaxProcessorIndex
723 )
724{
725 *MaxProcessorIndex = 0;
726 return EFI_SUCCESS;
727}
728
751EFIAPI
754 IN UINTN ProcessorIndex,
755 IN EFI_PERIODIC_CALLBACK PeriodicCallback
756 )
757{
758 if ((mDebugPeriodicCallback == NULL) && (PeriodicCallback == NULL)) {
759 return EFI_INVALID_PARAMETER;
760 }
761
762 if ((mDebugPeriodicCallback != NULL) && (PeriodicCallback != NULL)) {
763 return EFI_ALREADY_STARTED;
764 }
765
766 mDebugPeriodicCallback = PeriodicCallback;
767 return EFI_SUCCESS;
768}
769
796EFIAPI
799 IN UINTN ProcessorIndex,
800 IN EFI_EXCEPTION_CALLBACK ExceptionCallback,
801 IN EFI_EXCEPTION_TYPE ExceptionType
802 )
803{
804 if ((ExceptionType < 0) || (ExceptionType > MAX_EBC_EXCEPTION)) {
805 return EFI_INVALID_PARAMETER;
806 }
807
808 if ((mDebugExceptionCallback[ExceptionType] == NULL) && (ExceptionCallback == NULL)) {
809 return EFI_INVALID_PARAMETER;
810 }
811
812 if ((mDebugExceptionCallback[ExceptionType] != NULL) && (ExceptionCallback != NULL)) {
813 return EFI_ALREADY_STARTED;
814 }
815
816 mDebugExceptionCallback[ExceptionType] = ExceptionCallback;
817 return EFI_SUCCESS;
818}
819
837EFIAPI
840 IN UINTN ProcessorIndex,
841 IN VOID *Start,
842 IN UINT64 Length
843 )
844{
845 return EFI_SUCCESS;
846}
847
861 IN EFI_EXCEPTION_TYPE ExceptionType,
862 IN EXCEPTION_FLAGS ExceptionFlags,
863 IN VM_CONTEXT *VmPtr
864 )
865{
866 EFI_SYSTEM_CONTEXT_EBC EbcContext;
867 EFI_SYSTEM_CONTEXT SystemContext;
868
869 ASSERT ((ExceptionType >= 0) && (ExceptionType <= MAX_EBC_EXCEPTION));
870 //
871 // Save the exception in the context passed in
872 //
873 VmPtr->ExceptionFlags |= ExceptionFlags;
874 VmPtr->LastException = (UINTN)ExceptionType;
875 //
876 // If it's a fatal exception, then flag it in the VM context in case an
877 // attached debugger tries to return from it.
878 //
879 if ((ExceptionFlags & EXCEPTION_FLAG_FATAL) != 0) {
880 VmPtr->StopFlags |= STOPFLAG_APP_DONE;
881 }
882
883 //
884 // If someone's registered for exception callbacks, then call them.
885 //
886 // EBC driver will register default exception callback to report the
887 // status code via the status code API
888 //
889 if (mDebugExceptionCallback[ExceptionType] != NULL) {
890 //
891 // Initialize the context structure
892 //
893 EbcContext.R0 = (UINT64)VmPtr->Gpr[0];
894 EbcContext.R1 = (UINT64)VmPtr->Gpr[1];
895 EbcContext.R2 = (UINT64)VmPtr->Gpr[2];
896 EbcContext.R3 = (UINT64)VmPtr->Gpr[3];
897 EbcContext.R4 = (UINT64)VmPtr->Gpr[4];
898 EbcContext.R5 = (UINT64)VmPtr->Gpr[5];
899 EbcContext.R6 = (UINT64)VmPtr->Gpr[6];
900 EbcContext.R7 = (UINT64)VmPtr->Gpr[7];
901 EbcContext.Ip = (UINT64)(UINTN)VmPtr->Ip;
902 EbcContext.Flags = VmPtr->Flags;
903 EbcContext.ControlFlags = 0;
904 SystemContext.SystemContextEbc = &EbcContext;
905
906 mDebugExceptionCallback[ExceptionType](ExceptionType, SystemContext);
907 //
908 // Restore the context structure and continue to execute
909 //
910 VmPtr->Gpr[0] = EbcContext.R0;
911 VmPtr->Gpr[1] = EbcContext.R1;
912 VmPtr->Gpr[2] = EbcContext.R2;
913 VmPtr->Gpr[3] = EbcContext.R3;
914 VmPtr->Gpr[4] = EbcContext.R4;
915 VmPtr->Gpr[5] = EbcContext.R5;
916 VmPtr->Gpr[6] = EbcContext.R6;
917 VmPtr->Gpr[7] = EbcContext.R7;
918 VmPtr->Ip = (VMIP)(UINTN)EbcContext.Ip;
919 VmPtr->Flags = EbcContext.Flags;
920 }
921
922 return EFI_SUCCESS;
923}
924
936EFIAPI
939 )
940{
941 INTN Index;
942 EFI_STATUS Status;
943
944 //
945 // For ExceptionCallback
946 //
947 for (Index = 0; Index <= MAX_EBC_EXCEPTION; Index++) {
949 This,
950 0,
952 Index
953 );
954 }
955
956 //
957 // For PeriodicCallback
958 //
959 Status = gBS->CreateEvent (
960 EVT_TIMER | EVT_NOTIFY_SIGNAL,
961 TPL_NOTIFY,
963 &mVmPtr,
964 &mEbcPeriodicEvent
965 );
966 if (EFI_ERROR (Status)) {
967 return Status;
968 }
969
970 Status = gBS->SetTimer (
971 mEbcPeriodicEvent,
973 EBC_VM_PERIODIC_CALLBACK_RATE
974 );
975 if (EFI_ERROR (Status)) {
976 return Status;
977 }
978
979 return EFI_SUCCESS;
980}
981
991VOID
992EFIAPI
994 IN EFI_EXCEPTION_TYPE InterruptType,
995 IN EFI_SYSTEM_CONTEXT SystemContext
996 )
997{
998 //
999 // We print debug information to let user know what happen.
1000 //
1001 DEBUG ((
1002 DEBUG_ERROR,
1003 "EBC Interrupter Version - 0x%016lx\n",
1004 (UINT64)(((VM_MAJOR_VERSION & 0xFFFF) << 16) | ((VM_MINOR_VERSION & 0xFFFF)))
1005 ));
1006 DEBUG ((
1007 DEBUG_ERROR,
1008 "Exception Type - 0x%016lx\n",
1009 (UINT64)(UINTN)InterruptType
1010 ));
1011 DEBUG ((
1012 DEBUG_ERROR,
1013 " R0 - 0x%016lx, R1 - 0x%016lx\n",
1014 SystemContext.SystemContextEbc->R0,
1015 SystemContext.SystemContextEbc->R1
1016 ));
1017 DEBUG ((
1018 DEBUG_ERROR,
1019 " R2 - 0x%016lx, R3 - 0x%016lx\n",
1020 SystemContext.SystemContextEbc->R2,
1021 SystemContext.SystemContextEbc->R3
1022 ));
1023 DEBUG ((
1024 DEBUG_ERROR,
1025 " R4 - 0x%016lx, R5 - 0x%016lx\n",
1026 SystemContext.SystemContextEbc->R4,
1027 SystemContext.SystemContextEbc->R5
1028 ));
1029 DEBUG ((
1030 DEBUG_ERROR,
1031 " R6 - 0x%016lx, R7 - 0x%016lx\n",
1032 SystemContext.SystemContextEbc->R6,
1033 SystemContext.SystemContextEbc->R7
1034 ));
1035 DEBUG ((
1036 DEBUG_ERROR,
1037 " Flags - 0x%016lx\n",
1038 SystemContext.SystemContextEbc->Flags
1039 ));
1040 DEBUG ((
1041 DEBUG_ERROR,
1042 " ControlFlags - 0x%016lx\n",
1043 SystemContext.SystemContextEbc->ControlFlags
1044 ));
1045 DEBUG ((
1046 DEBUG_ERROR,
1047 " Ip - 0x%016lx\n\n",
1048 SystemContext.SystemContextEbc->Ip
1049 ));
1050
1051 //
1052 // We deadloop here to make it easy to debug this issue.
1053 //
1054 CpuDeadLoop ();
1055
1056 return;
1057}
1058
1067VOID
1068EFIAPI
1070 IN EFI_EVENT Event,
1071 IN VOID *Context
1072 )
1073{
1074 VM_CONTEXT *VmPtr;
1075
1076 VmPtr = *(VM_CONTEXT **)Context;
1077
1078 if (VmPtr != NULL) {
1079 EbcDebugPeriodic (VmPtr);
1080 }
1081
1082 return;
1083}
1084
1096EFIAPI
1098 IN VM_CONTEXT *VmPtr
1099 )
1100{
1101 EFI_SYSTEM_CONTEXT_EBC EbcContext;
1102 EFI_SYSTEM_CONTEXT SystemContext;
1103
1104 //
1105 // If someone's registered for periodic callbacks, then call them.
1106 //
1107 if (mDebugPeriodicCallback != NULL) {
1108 //
1109 // Initialize the context structure
1110 //
1111 EbcContext.R0 = (UINT64)VmPtr->Gpr[0];
1112 EbcContext.R1 = (UINT64)VmPtr->Gpr[1];
1113 EbcContext.R2 = (UINT64)VmPtr->Gpr[2];
1114 EbcContext.R3 = (UINT64)VmPtr->Gpr[3];
1115 EbcContext.R4 = (UINT64)VmPtr->Gpr[4];
1116 EbcContext.R5 = (UINT64)VmPtr->Gpr[5];
1117 EbcContext.R6 = (UINT64)VmPtr->Gpr[6];
1118 EbcContext.R7 = (UINT64)VmPtr->Gpr[7];
1119 EbcContext.Ip = (UINT64)(UINTN)VmPtr->Ip;
1120 EbcContext.Flags = VmPtr->Flags;
1121 EbcContext.ControlFlags = 0;
1122 SystemContext.SystemContextEbc = &EbcContext;
1123
1124 mDebugPeriodicCallback (SystemContext);
1125
1126 //
1127 // Restore the context structure and continue to execute
1128 //
1129 VmPtr->Gpr[0] = EbcContext.R0;
1130 VmPtr->Gpr[1] = EbcContext.R1;
1131 VmPtr->Gpr[2] = EbcContext.R2;
1132 VmPtr->Gpr[3] = EbcContext.R3;
1133 VmPtr->Gpr[4] = EbcContext.R4;
1134 VmPtr->Gpr[5] = EbcContext.R5;
1135 VmPtr->Gpr[6] = EbcContext.R6;
1136 VmPtr->Gpr[7] = EbcContext.R7;
1137 VmPtr->Ip = (VMIP)(UINTN)EbcContext.Ip;
1138 VmPtr->Flags = EbcContext.Flags;
1139 }
1140
1141 return EFI_SUCCESS;
1142}
1143
1159EFIAPI
1161 IN EFI_EBC_PROTOCOL *This,
1162 IN EFI_HANDLE ImageHandle
1163 )
1164{
1165 EBC_THUNK_LIST *ThunkList;
1166 EBC_THUNK_LIST *NextThunkList;
1167 EBC_IMAGE_LIST *ImageList;
1168 EBC_IMAGE_LIST *PrevImageList;
1169
1170 //
1171 // First go through our list of known image handles and see if we've already
1172 // created an image list element for this image handle.
1173 //
1174 ReturnEBCStackByHandle (ImageHandle);
1175 PrevImageList = NULL;
1176 for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {
1177 if (ImageList->ImageHandle == ImageHandle) {
1178 break;
1179 }
1180
1181 //
1182 // Save the previous so we can connect the lists when we remove this one
1183 //
1184 PrevImageList = ImageList;
1185 }
1186
1187 if (ImageList == NULL) {
1188 return EFI_INVALID_PARAMETER;
1189 }
1190
1191 //
1192 // Free up all the thunk buffers and thunks list elements for this image
1193 // handle.
1194 //
1195 ThunkList = ImageList->ThunkList;
1196 while (ThunkList != NULL) {
1197 NextThunkList = ThunkList->Next;
1198 FreePool (ThunkList->ThunkBuffer);
1199 FreePool (ThunkList);
1200 ThunkList = NextThunkList;
1201 }
1202
1203 //
1204 // Now remove this image list element from the chain
1205 //
1206 if (PrevImageList == NULL) {
1207 //
1208 // Remove from head
1209 //
1210 mEbcImageList = ImageList->Next;
1211 } else {
1212 PrevImageList->Next = ImageList->Next;
1213 }
1214
1215 //
1216 // Now free up the image list element
1217 //
1218 FreePool (ImageList);
1219
1220 EbcDebuggerHookEbcUnloadImage (ImageHandle);
1221
1222 return EFI_SUCCESS;
1223}
1224
1240 IN EFI_HANDLE ImageHandle,
1241 IN VOID *ThunkBuffer,
1242 IN UINT32 ThunkSize
1243 )
1244{
1245 EBC_THUNK_LIST *ThunkList;
1246 EBC_IMAGE_LIST *ImageList;
1247 EFI_STATUS Status;
1248
1249 //
1250 // It so far so good, then flush the instruction cache
1251 //
1252 if (mEbcICacheFlush != NULL) {
1253 Status = mEbcICacheFlush ((EFI_PHYSICAL_ADDRESS)(UINTN)ThunkBuffer, ThunkSize);
1254 if (EFI_ERROR (Status)) {
1255 return Status;
1256 }
1257 }
1258
1259 //
1260 // Go through our list of known image handles and see if we've already
1261 // created a image list element for this image handle.
1262 //
1263 for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {
1264 if (ImageList->ImageHandle == ImageHandle) {
1265 break;
1266 }
1267 }
1268
1269 if (ImageList == NULL) {
1270 //
1271 // Allocate a new one
1272 //
1273 ImageList = AllocatePool (sizeof (EBC_IMAGE_LIST));
1274
1275 if (ImageList == NULL) {
1276 return EFI_OUT_OF_RESOURCES;
1277 }
1278
1279 ImageList->ThunkList = NULL;
1280 ImageList->ImageHandle = ImageHandle;
1281 ImageList->Next = mEbcImageList;
1282 mEbcImageList = ImageList;
1283 }
1284
1285 //
1286 // Ok, now create a new thunk element to add to the list
1287 //
1288 ThunkList = AllocatePool (sizeof (EBC_THUNK_LIST));
1289
1290 if (ThunkList == NULL) {
1291 return EFI_OUT_OF_RESOURCES;
1292 }
1293
1294 //
1295 // Add it to the head of the list
1296 //
1297 ThunkList->Next = ImageList->ThunkList;
1298 ThunkList->ThunkBuffer = ThunkBuffer;
1299 ImageList->ThunkList = ThunkList;
1300 return EFI_SUCCESS;
1301}
1302
1314EFIAPI
1316 IN EFI_EBC_PROTOCOL *This,
1317 IN EBC_ICACHE_FLUSH Flush
1318 )
1319{
1320 mEbcICacheFlush = Flush;
1321 return EFI_SUCCESS;
1322}
1323
1336EFIAPI
1338 IN EFI_EBC_PROTOCOL *This,
1339 IN OUT UINT64 *Version
1340 )
1341{
1342 if (Version == NULL) {
1343 return EFI_INVALID_PARAMETER;
1344 }
1345
1346 *Version = GetVmVersion ();
1347 return EFI_SUCCESS;
1348}
1349
1365 IN EFI_HANDLE Handle,
1366 OUT VOID **StackBuffer,
1367 OUT UINTN *BufferIndex
1368 )
1369{
1370 UINTN Index;
1371 EFI_TPL OldTpl;
1372
1373 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
1374 for (Index = 0; Index < mStackNum; Index++) {
1375 if (mStackBufferIndex[Index] == NULL) {
1376 mStackBufferIndex[Index] = Handle;
1377 break;
1378 }
1379 }
1380
1381 gBS->RestoreTPL (OldTpl);
1382 if (Index == mStackNum) {
1383 return EFI_OUT_OF_RESOURCES;
1384 }
1385
1386 *BufferIndex = Index;
1387 *StackBuffer = mStackBuffer[Index];
1388 return EFI_SUCCESS;
1389}
1390
1401 IN UINTN Index
1402 )
1403{
1404 mStackBufferIndex[Index] = NULL;
1405 return EFI_SUCCESS;
1406}
1407
1418 IN EFI_HANDLE Handle
1419 )
1420{
1421 UINTN Index;
1422
1423 for (Index = 0; Index < mStackNum; Index++) {
1424 if (mStackBufferIndex[Index] == Handle) {
1425 break;
1426 }
1427 }
1428
1429 if (Index == mStackNum) {
1430 return EFI_NOT_FOUND;
1431 }
1432
1433 mStackBufferIndex[Index] = NULL;
1434 return EFI_SUCCESS;
1435}
1436
1446 VOID
1447 )
1448{
1449 for (mStackNum = 0; mStackNum < MAX_STACK_NUM; mStackNum++) {
1450 mStackBuffer[mStackNum] = AllocatePool (STACK_POOL_SIZE);
1451 mStackBufferIndex[mStackNum] = NULL;
1452 if (mStackBuffer[mStackNum] == NULL) {
1453 break;
1454 }
1455 }
1456
1457 if (mStackNum == 0) {
1458 return EFI_OUT_OF_RESOURCES;
1459 }
1460
1461 return EFI_SUCCESS;
1462}
1463
1472 VOID
1473 )
1474{
1475 UINTN Index;
1476
1477 for (Index = 0; Index < mStackNum; Index++) {
1478 FreePool (mStackBuffer[Index]);
1479 }
1480
1481 return EFI_SUCCESS;
1482}
1483
1495 IN EFI_HANDLE *IHandle
1496 )
1497{
1498 EFI_HANDLE Handle;
1499 EFI_STATUS Status;
1500 EFI_EBC_VM_TEST_PROTOCOL *EbcVmTestProtocol;
1501
1502 //
1503 // Allocate memory for the protocol, then fill in the fields
1504 //
1505 EbcVmTestProtocol = AllocatePool (sizeof (EFI_EBC_VM_TEST_PROTOCOL));
1506 if (EbcVmTestProtocol == NULL) {
1507 return EFI_OUT_OF_RESOURCES;
1508 }
1509
1510 EbcVmTestProtocol->Execute = (EBC_VM_TEST_EXECUTE)EbcExecuteInstructions;
1511
1513 EbcVmTestProtocol->Assemble = (EBC_VM_TEST_ASM)EbcVmTestUnsupported;
1514 EbcVmTestProtocol->Disassemble = (EBC_VM_TEST_DASM)EbcVmTestUnsupported;
1515 DEBUG_CODE_END ();
1516
1517 //
1518 // Publish the protocol
1519 //
1520 Handle = NULL;
1521 Status = gBS->InstallProtocolInterface (&Handle, &gEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);
1522 if (EFI_ERROR (Status)) {
1523 FreePool (EbcVmTestProtocol);
1524 }
1525
1526 return Status;
1527}
1528
1536EFIAPI
1538 VOID
1539 )
1540{
1541 return EFI_UNSUPPORTED;
1542}
1543
1552VOID *
1553EFIAPI
1555 IN UINTN AllocationSize
1556 )
1557{
1558 VOID *Buffer;
1559 EFI_STATUS Status;
1560
1561 Status = gBS->AllocatePool (EfiBootServicesCode, AllocationSize, &Buffer);
1562 if (EFI_ERROR (Status)) {
1563 return NULL;
1564 }
1565
1566 return Buffer;
1567}
EFI_STATUS EbcCreateThunks(IN EFI_HANDLE ImageHandle, IN VOID *EbcEntryPoint, OUT VOID **Thunk, IN UINT32 Flags)
Definition: EbcSupport.c:362
UINT64 UINTN
INT64 INTN
VOID *EFIAPI InvalidateInstructionCacheRange(IN VOID *Address, IN UINTN Length)
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS(EFIAPI * EBC_ICACHE_FLUSH)(IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 Length)
Definition: Ebc.h:248
UINT64 GetVmVersion(VOID)
Definition: EbcExecute.c:5418
EFI_STATUS EFIAPI EbcExecuteInstructions(IN EFI_EBC_VM_TEST_PROTOCOL *This, IN VM_CONTEXT *VmPtr, IN OUT UINTN *InstructionCount)
Definition: EbcExecute.c:1360
EFI_STATUS EFIAPI EbcVmTestUnsupported(VOID)
Definition: EbcInt.c:1537
EFI_STATUS EFIAPI EbcRegisterICacheFlush(IN EFI_EBC_PROTOCOL *This, IN EBC_ICACHE_FLUSH Flush)
Definition: EbcInt.c:1315
EFI_STATUS EFIAPI EbcCreateThunk(IN EFI_EBC_PROTOCOL *This, IN EFI_HANDLE ImageHandle, IN VOID *EbcEntryPoint, OUT VOID **Thunk)
Definition: EbcInt.c:689
EFI_STATUS InitEbcVmTestProtocol(IN EFI_HANDLE *IHandle)
Definition: EbcInt.c:1494
EFI_STATUS EFIAPI EbcDebugGetMaximumProcessorIndex(IN EFI_DEBUG_SUPPORT_PROTOCOL *This, OUT UINTN *MaxProcessorIndex)
Definition: EbcInt.c:720
EFI_STATUS EbcAddImageThunk(IN EFI_HANDLE ImageHandle, IN VOID *ThunkBuffer, IN UINT32 ThunkSize)
Definition: EbcInt.c:1239
EFI_STATUS EFIAPI EbcUnloadImage(IN EFI_EBC_PROTOCOL *This, IN EFI_HANDLE ImageHandle)
Definition: EbcInt.c:1160
VOID EFIAPI EbcPeriodicNotifyFunction(IN EFI_EVENT Event, IN VOID *Context)
Definition: EbcInt.c:1069
EFI_STATUS EFIAPI EbcDebugRegisterExceptionCallback(IN EFI_DEBUG_SUPPORT_PROTOCOL *This, IN UINTN ProcessorIndex, IN EFI_EXCEPTION_CALLBACK ExceptionCallback, IN EFI_EXCEPTION_TYPE ExceptionType)
Definition: EbcInt.c:797
VOID *EFIAPI EbcAllocatePoolForThunk(IN UINTN AllocationSize)
Definition: EbcInt.c:1554
EFI_STATUS EFIAPI EbcGetVersion(IN EFI_EBC_PROTOCOL *This, IN OUT UINT64 *Version)
Definition: EbcInt.c:1337
EFI_STATUS ReturnEBCStackByHandle(IN EFI_HANDLE Handle)
Definition: EbcInt.c:1417
EFI_STATUS FreeEBCStack(VOID)
Definition: EbcInt.c:1471
EFI_STATUS EFIAPI EbcRegisterImage(IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS ImageBase, IN UINT64 ImageSize, IN OUT EFI_IMAGE_ENTRY_POINT *EntryPoint)
Definition: EbcInt.c:401
EFI_STATUS EbcDebugSignalException(IN EFI_EXCEPTION_TYPE ExceptionType, IN EXCEPTION_FLAGS ExceptionFlags, IN VM_CONTEXT *VmPtr)
Definition: EbcInt.c:860
EFI_STATUS EFIAPI EbcDebugPeriodic(IN VM_CONTEXT *VmPtr)
Definition: EbcInt.c:1097
EFI_STATUS EFIAPI EbcUnregisterImage(IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS ImageBase)
Definition: EbcInt.c:455
EFI_STATUS InitEBCStack(VOID)
Definition: EbcInt.c:1445
EFI_STATUS EFIAPI EbcDebugRegisterPeriodicCallback(IN EFI_DEBUG_SUPPORT_PROTOCOL *This, IN UINTN ProcessorIndex, IN EFI_PERIODIC_CALLBACK PeriodicCallback)
Definition: EbcInt.c:752
EFI_STATUS EFIAPI InitializeEbcDriver(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: EbcInt.c:483
EFI_STATUS ReturnEBCStack(IN UINTN Index)
Definition: EbcInt.c:1400
VOID EFIAPI CommonEbcExceptionHandler(IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_SYSTEM_CONTEXT SystemContext)
Definition: EbcInt.c:993
EFI_STATUS EFIAPI InitializeEbcCallback(IN EFI_DEBUG_SUPPORT_PROTOCOL *This)
Definition: EbcInt.c:937
EFI_STATUS GetEBCStack(IN EFI_HANDLE Handle, OUT VOID **StackBuffer, OUT UINTN *BufferIndex)
Definition: EbcInt.c:1364
BOOLEAN EFIAPI EbcIsImageSupported(IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This, IN UINT16 ImageType, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL)
Definition: EbcInt.c:362
EFI_STATUS EFIAPI EbcDebugInvalidateInstructionCache(IN EFI_DEBUG_SUPPORT_PROTOCOL *This, IN UINTN ProcessorIndex, IN VOID *Start, IN UINT64 Length)
Definition: EbcInt.c:838
EFI_STATUS(EFIAPI * EBC_VM_TEST_EXECUTE)(IN EFI_EBC_VM_TEST_PROTOCOL *This, IN VM_CONTEXT *VmPtr, IN OUT UINTN *InstructionCount)
Definition: EbcVmTest.h:125
UINT8 * VMIP
Definition: EbcVmTest.h:78
EFI_STATUS(EFIAPI * EBC_VM_TEST_ASM)(IN EFI_EBC_VM_TEST_PROTOCOL *This, IN CHAR16 *AsmText, IN OUT INT8 *Buffer, IN OUT UINTN *BufferLen)
Definition: EbcVmTest.h:145
EFI_STATUS(EFIAPI * EBC_VM_TEST_DASM)(IN EFI_EBC_VM_TEST_PROTOCOL *This, IN OUT CHAR16 *AsmText, IN OUT INT8 *Buffer, IN OUT UINTN *Len)
Definition: EbcVmTest.h:166
VOID EbcDebuggerHookInit(IN EFI_HANDLE Handle, IN EFI_DEBUG_SUPPORT_PROTOCOL *EbcDebugProtocol)
Definition: EdbHook.c:329
VOID EbcDebuggerHookEbcUnloadImage(IN EFI_HANDLE Handle)
Definition: EdbHook.c:490
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
INTN EFI_EXCEPTION_TYPE
Definition: DebugSupport.h:35
@ IsaEbc
0x0EBC
Definition: DebugSupport.h:840
VOID(EFIAPI * EFI_EXCEPTION_CALLBACK)(IN EFI_EXCEPTION_TYPE ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext)
Definition: DebugSupport.h:816
#define MAX_EBC_EXCEPTION
Definition: DebugSupport.h:451
VOID(EFIAPI * EFI_PERIODIC_CALLBACK)(IN OUT EFI_SYSTEM_CONTEXT SystemContext)
Definition: DebugSupport.h:829
RETURN_STATUS EFIAPI PeCoffLoaderGetImageInfo(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:577
RETURN_STATUS EFIAPI PeCoffLoaderImageReadFromMemory(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: BasePeCoff.c:1992
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_IMAGE_MACHINE_EBC
Definition: UefiBaseType.h:228
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiBootServicesCode
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ TimerPeriodic
Definition: UefiSpec.h:535
EFI_STATUS(EFIAPI * EFI_IMAGE_ENTRY_POINT)(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: UefiSpec.h:2108
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_INSTRUCTION_SET_ARCHITECTURE Isa
Definition: DebugSupport.h:946
PE_COFF_LOADER_READ_FILE ImageRead
Definition: PeCoffLib.h:100