Changeset 99404 in vbox for trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Universal/EbcDxe/EbcExecute.c
- Timestamp:
- Apr 14, 2023 3:17:44 PM (23 months ago)
- svn:sync-xref-src-repo-rev:
- 156854
- Location:
- trunk/src/VBox/Devices/EFI/FirmwareNew
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/FirmwareNew
-
Property svn:mergeinfo
changed from (toggle deleted branches)
to (toggle deleted branches)/vendor/edk2/current 103735-103757,103769-103776,129194-145445 /vendor/edk2/current 103735-103757,103769-103776,129194-156846
-
Property svn:mergeinfo
changed from (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Universal/EbcDxe/EbcExecute.c
r80721 r99404 10 10 #include "EbcExecute.h" 11 11 #include "EbcDebuggerHook.h" 12 13 12 14 13 // … … 16 15 // size of operands or data. 17 16 // 18 #define DATA_SIZE_INVALID 019 #define DATA_SIZE_8 120 #define DATA_SIZE_16 221 #define DATA_SIZE_32 422 #define DATA_SIZE_64 823 #define DATA_SIZE_N 48// 4 or 817 #define DATA_SIZE_INVALID 0 18 #define DATA_SIZE_8 1 19 #define DATA_SIZE_16 2 20 #define DATA_SIZE_32 4 21 #define DATA_SIZE_64 8 22 #define DATA_SIZE_N 48 // 4 or 8 24 23 // 25 24 // Structure we'll use to dispatch opcodes to execute functions. 26 25 // 27 26 typedef struct { 28 EFI_STATUS (*ExecuteFunction) (IN VM_CONTEXT * VmPtr); 29 } 30 VM_TABLE_ENTRY; 27 EFI_STATUS (*ExecuteFunction)( 28 IN VM_CONTEXT *VmPtr 29 ); 30 } VM_TABLE_ENTRY; 31 31 32 32 typedef 33 33 UINT64 34 34 (*DATA_MANIP_EXEC_FUNCTION) ( 35 IN VM_CONTEXT *VmPtr,36 IN UINT64 Op1,37 IN UINT64 Op235 IN VM_CONTEXT *VmPtr, 36 IN UINT64 Op1, 37 IN UINT64 Op2 38 38 ); 39 39 … … 62 62 INT16 63 63 VmReadIndex16 ( 64 IN VM_CONTEXT 65 IN UINT32 64 IN VM_CONTEXT *VmPtr, 65 IN UINT32 CodeOffset 66 66 ); 67 67 … … 78 78 INT32 79 79 VmReadIndex32 ( 80 IN VM_CONTEXT 81 IN UINT32 80 IN VM_CONTEXT *VmPtr, 81 IN UINT32 CodeOffset 82 82 ); 83 83 … … 94 94 INT64 95 95 VmReadIndex64 ( 96 IN VM_CONTEXT 97 IN UINT32 96 IN VM_CONTEXT *VmPtr, 97 IN UINT32 CodeOffset 98 98 ); 99 99 … … 109 109 UINT8 110 110 VmReadMem8 ( 111 IN VM_CONTEXT 112 IN UINTN 111 IN VM_CONTEXT *VmPtr, 112 IN UINTN Addr 113 113 ); 114 114 … … 124 124 UINT16 125 125 VmReadMem16 ( 126 IN VM_CONTEXT *VmPtr,127 IN UINTN Addr126 IN VM_CONTEXT *VmPtr, 127 IN UINTN Addr 128 128 ); 129 129 … … 139 139 UINT32 140 140 VmReadMem32 ( 141 IN VM_CONTEXT *VmPtr,142 IN UINTN Addr141 IN VM_CONTEXT *VmPtr, 142 IN UINTN Addr 143 143 ); 144 144 … … 154 154 UINT64 155 155 VmReadMem64 ( 156 IN VM_CONTEXT 157 IN UINTN 156 IN VM_CONTEXT *VmPtr, 157 IN UINTN Addr 158 158 ); 159 159 … … 169 169 UINTN 170 170 VmReadMemN ( 171 IN VM_CONTEXT 172 IN UINTN 171 IN VM_CONTEXT *VmPtr, 172 IN UINTN Addr 173 173 ); 174 174 … … 198 198 EFI_STATUS 199 199 VmWriteMem8 ( 200 IN VM_CONTEXT 201 IN UINTN 202 IN UINT8 200 IN VM_CONTEXT *VmPtr, 201 IN UINTN Addr, 202 IN UINT8 Data 203 203 ); 204 204 … … 228 228 EFI_STATUS 229 229 VmWriteMem16 ( 230 IN VM_CONTEXT 231 IN UINTN 232 IN UINT16 230 IN VM_CONTEXT *VmPtr, 231 IN UINTN Addr, 232 IN UINT16 Data 233 233 ); 234 234 … … 258 258 EFI_STATUS 259 259 VmWriteMem32 ( 260 IN VM_CONTEXT 261 IN UINTN 262 IN UINT32 260 IN VM_CONTEXT *VmPtr, 261 IN UINTN Addr, 262 IN UINT32 Data 263 263 ); 264 264 … … 277 277 UINT16 278 278 VmReadCode16 ( 279 IN VM_CONTEXT *VmPtr,280 IN UINT32 Offset279 IN VM_CONTEXT *VmPtr, 280 IN UINT32 Offset 281 281 ); 282 282 … … 295 295 UINT32 296 296 VmReadCode32 ( 297 IN VM_CONTEXT *VmPtr,298 IN UINT32 Offset297 IN VM_CONTEXT *VmPtr, 298 IN UINT32 Offset 299 299 ); 300 300 … … 313 313 UINT64 314 314 VmReadCode64 ( 315 IN VM_CONTEXT *VmPtr,316 IN UINT32 Offset315 IN VM_CONTEXT *VmPtr, 316 IN UINT32 Offset 317 317 ); 318 318 … … 333 333 INT8 334 334 VmReadImmed8 ( 335 IN VM_CONTEXT *VmPtr,336 IN UINT32 Offset335 IN VM_CONTEXT *VmPtr, 336 IN UINT32 Offset 337 337 ); 338 338 … … 353 353 INT16 354 354 VmReadImmed16 ( 355 IN VM_CONTEXT *VmPtr,356 IN UINT32 Offset355 IN VM_CONTEXT *VmPtr, 356 IN UINT32 Offset 357 357 ); 358 358 … … 373 373 INT32 374 374 VmReadImmed32 ( 375 IN VM_CONTEXT *VmPtr,376 IN UINT32 Offset375 IN VM_CONTEXT *VmPtr, 376 IN UINT32 Offset 377 377 ); 378 378 … … 393 393 INT64 394 394 VmReadImmed64 ( 395 IN VM_CONTEXT *VmPtr,396 IN UINT32 Offset395 IN VM_CONTEXT *VmPtr, 396 IN UINT32 Offset 397 397 ); 398 398 … … 418 418 UINTN 419 419 ConvertStackAddr ( 420 IN VM_CONTEXT 421 IN UINTN 420 IN VM_CONTEXT *VmPtr, 421 IN UINTN Addr 422 422 ); 423 423 … … 442 442 EFI_STATUS 443 443 ExecuteDataManip ( 444 IN VM_CONTEXT 445 IN BOOLEAN 444 IN VM_CONTEXT *VmPtr, 445 IN BOOLEAN IsSignedOp 446 446 ); 447 447 … … 449 449 // Functions that execute VM opcodes 450 450 // 451 451 452 /** 452 453 Execute the EBC BREAK instruction. … … 459 460 EFI_STATUS 460 461 ExecuteBREAK ( 461 IN VM_CONTEXT *VmPtr462 IN VM_CONTEXT *VmPtr 462 463 ); 463 464 … … 489 490 EFI_STATUS 490 491 ExecuteJMP ( 491 IN VM_CONTEXT *VmPtr492 IN VM_CONTEXT *VmPtr 492 493 ); 493 494 … … 505 506 EFI_STATUS 506 507 ExecuteJMP8 ( 507 IN VM_CONTEXT *VmPtr508 IN VM_CONTEXT *VmPtr 508 509 ); 509 510 … … 526 527 EFI_STATUS 527 528 ExecuteCALL ( 528 IN VM_CONTEXT *VmPtr529 IN VM_CONTEXT *VmPtr 529 530 ); 530 531 … … 542 543 EFI_STATUS 543 544 ExecuteRET ( 544 IN VM_CONTEXT *VmPtr545 IN VM_CONTEXT *VmPtr 545 546 ); 546 547 … … 559 560 EFI_STATUS 560 561 ExecuteCMP ( 561 IN VM_CONTEXT *VmPtr562 IN VM_CONTEXT *VmPtr 562 563 ); 563 564 … … 576 577 EFI_STATUS 577 578 ExecuteCMPI ( 578 IN VM_CONTEXT *VmPtr579 IN VM_CONTEXT *VmPtr 579 580 ); 580 581 … … 602 603 EFI_STATUS 603 604 ExecuteMOVxx ( 604 IN VM_CONTEXT *VmPtr605 IN VM_CONTEXT *VmPtr 605 606 ); 606 607 … … 628 629 EFI_STATUS 629 630 ExecuteMOVI ( 630 IN VM_CONTEXT *VmPtr631 IN VM_CONTEXT *VmPtr 631 632 ); 632 633 … … 647 648 EFI_STATUS 648 649 ExecuteMOVIn ( 649 IN VM_CONTEXT *VmPtr650 IN VM_CONTEXT *VmPtr 650 651 ); 651 652 … … 666 667 EFI_STATUS 667 668 ExecuteMOVREL ( 668 IN VM_CONTEXT *VmPtr669 IN VM_CONTEXT *VmPtr 669 670 ); 670 671 … … 682 683 EFI_STATUS 683 684 ExecutePUSHn ( 684 IN VM_CONTEXT *VmPtr685 IN VM_CONTEXT *VmPtr 685 686 ); 686 687 … … 698 699 EFI_STATUS 699 700 ExecutePUSH ( 700 IN VM_CONTEXT *VmPtr701 IN VM_CONTEXT *VmPtr 701 702 ); 702 703 … … 714 715 EFI_STATUS 715 716 ExecutePOPn ( 716 IN VM_CONTEXT *VmPtr717 IN VM_CONTEXT *VmPtr 717 718 ); 718 719 … … 730 731 EFI_STATUS 731 732 ExecutePOP ( 732 IN VM_CONTEXT *VmPtr733 IN VM_CONTEXT *VmPtr 733 734 ); 734 735 … … 752 753 EFI_STATUS 753 754 ExecuteSignedDataManip ( 754 IN VM_CONTEXT 755 IN VM_CONTEXT *VmPtr 755 756 ); 756 757 … … 774 775 EFI_STATUS 775 776 ExecuteUnsignedDataManip ( 776 IN VM_CONTEXT 777 IN VM_CONTEXT *VmPtr 777 778 ); 778 779 … … 791 792 EFI_STATUS 792 793 ExecuteLOADSP ( 793 IN VM_CONTEXT *VmPtr794 IN VM_CONTEXT *VmPtr 794 795 ); 795 796 … … 808 809 EFI_STATUS 809 810 ExecuteSTORESP ( 810 IN VM_CONTEXT *VmPtr811 IN VM_CONTEXT *VmPtr 811 812 ); 812 813 … … 832 833 EFI_STATUS 833 834 ExecuteMOVsnd ( 834 IN VM_CONTEXT *VmPtr835 IN VM_CONTEXT *VmPtr 835 836 ); 836 837 … … 856 857 EFI_STATUS 857 858 ExecuteMOVsnw ( 858 IN VM_CONTEXT *VmPtr859 IN VM_CONTEXT *VmPtr 859 860 ); 860 861 … … 862 863 // Data manipulation subfunctions 863 864 // 865 864 866 /** 865 867 Execute the EBC NOT instruction.s … … 877 879 UINT64 878 880 ExecuteNOT ( 879 IN VM_CONTEXT 880 IN UINT64 881 IN UINT64 881 IN VM_CONTEXT *VmPtr, 882 IN UINT64 Op1, 883 IN UINT64 Op2 882 884 ); 883 885 … … 897 899 UINT64 898 900 ExecuteNEG ( 899 IN VM_CONTEXT 900 IN UINT64 901 IN UINT64 901 IN VM_CONTEXT *VmPtr, 902 IN UINT64 Op1, 903 IN UINT64 Op2 902 904 ); 903 905 … … 917 919 UINT64 918 920 ExecuteADD ( 919 IN VM_CONTEXT 920 IN UINT64 921 IN UINT64 921 IN VM_CONTEXT *VmPtr, 922 IN UINT64 Op1, 923 IN UINT64 Op2 922 924 ); 923 925 … … 937 939 UINT64 938 940 ExecuteSUB ( 939 IN VM_CONTEXT 940 IN UINT64 941 IN UINT64 941 IN VM_CONTEXT *VmPtr, 942 IN UINT64 Op1, 943 IN UINT64 Op2 942 944 ); 943 945 … … 957 959 UINT64 958 960 ExecuteMUL ( 959 IN VM_CONTEXT 960 IN UINT64 961 IN UINT64 961 IN VM_CONTEXT *VmPtr, 962 IN UINT64 Op1, 963 IN UINT64 Op2 962 964 ); 963 965 … … 977 979 UINT64 978 980 ExecuteMULU ( 979 IN VM_CONTEXT 980 IN UINT64 981 IN UINT64 981 IN VM_CONTEXT *VmPtr, 982 IN UINT64 Op1, 983 IN UINT64 Op2 982 984 ); 983 985 … … 997 999 UINT64 998 1000 ExecuteDIV ( 999 IN VM_CONTEXT 1000 IN UINT64 1001 IN UINT64 1001 IN VM_CONTEXT *VmPtr, 1002 IN UINT64 Op1, 1003 IN UINT64 Op2 1002 1004 ); 1003 1005 … … 1017 1019 UINT64 1018 1020 ExecuteDIVU ( 1019 IN VM_CONTEXT 1020 IN UINT64 1021 IN UINT64 1021 IN VM_CONTEXT *VmPtr, 1022 IN UINT64 Op1, 1023 IN UINT64 Op2 1022 1024 ); 1023 1025 … … 1037 1039 UINT64 1038 1040 ExecuteMOD ( 1039 IN VM_CONTEXT 1040 IN UINT64 1041 IN UINT64 1041 IN VM_CONTEXT *VmPtr, 1042 IN UINT64 Op1, 1043 IN UINT64 Op2 1042 1044 ); 1043 1045 … … 1057 1059 UINT64 1058 1060 ExecuteMODU ( 1059 IN VM_CONTEXT 1060 IN UINT64 1061 IN UINT64 1061 IN VM_CONTEXT *VmPtr, 1062 IN UINT64 Op1, 1063 IN UINT64 Op2 1062 1064 ); 1063 1065 … … 1077 1079 UINT64 1078 1080 ExecuteAND ( 1079 IN VM_CONTEXT 1080 IN UINT64 1081 IN UINT64 1081 IN VM_CONTEXT *VmPtr, 1082 IN UINT64 Op1, 1083 IN UINT64 Op2 1082 1084 ); 1083 1085 … … 1097 1099 UINT64 1098 1100 ExecuteOR ( 1099 IN VM_CONTEXT 1100 IN UINT64 1101 IN UINT64 1101 IN VM_CONTEXT *VmPtr, 1102 IN UINT64 Op1, 1103 IN UINT64 Op2 1102 1104 ); 1103 1105 … … 1117 1119 UINT64 1118 1120 ExecuteXOR ( 1119 IN VM_CONTEXT 1120 IN UINT64 1121 IN UINT64 1121 IN VM_CONTEXT *VmPtr, 1122 IN UINT64 Op1, 1123 IN UINT64 Op2 1122 1124 ); 1123 1125 … … 1137 1139 UINT64 1138 1140 ExecuteSHL ( 1139 IN VM_CONTEXT 1140 IN UINT64 1141 IN UINT64 1141 IN VM_CONTEXT *VmPtr, 1142 IN UINT64 Op1, 1143 IN UINT64 Op2 1142 1144 ); 1143 1145 … … 1157 1159 UINT64 1158 1160 ExecuteSHR ( 1159 IN VM_CONTEXT 1160 IN UINT64 1161 IN UINT64 1161 IN VM_CONTEXT *VmPtr, 1162 IN UINT64 Op1, 1163 IN UINT64 Op2 1162 1164 ); 1163 1165 … … 1177 1179 UINT64 1178 1180 ExecuteASHR ( 1179 IN VM_CONTEXT 1180 IN UINT64 1181 IN UINT64 1181 IN VM_CONTEXT *VmPtr, 1182 IN UINT64 Op1, 1183 IN UINT64 Op2 1182 1184 ); 1183 1185 … … 1197 1199 UINT64 1198 1200 ExecuteEXTNDB ( 1199 IN VM_CONTEXT 1200 IN UINT64 1201 IN UINT64 1201 IN VM_CONTEXT *VmPtr, 1202 IN UINT64 Op1, 1203 IN UINT64 Op2 1202 1204 ); 1203 1205 … … 1217 1219 UINT64 1218 1220 ExecuteEXTNDW ( 1219 IN VM_CONTEXT 1220 IN UINT64 1221 IN UINT64 1221 IN VM_CONTEXT *VmPtr, 1222 IN UINT64 Op1, 1223 IN UINT64 Op2 1222 1224 ); 1223 1225 … … 1237 1239 UINT64 1238 1240 ExecuteEXTNDD ( 1239 IN VM_CONTEXT 1240 IN UINT64 1241 IN UINT64 1241 IN VM_CONTEXT *VmPtr, 1242 IN UINT64 Op1, 1243 IN UINT64 Op2 1242 1244 ); 1243 1245 … … 1246 1248 // call these functions to perform the operation. 1247 1249 // 1248 CONST DATA_MANIP_EXEC_FUNCTION mDataManipDispatchTable[] = {1250 CONST DATA_MANIP_EXEC_FUNCTION mDataManipDispatchTable[] = { 1249 1251 ExecuteNOT, 1250 1252 ExecuteNEG, … … 1268 1270 }; 1269 1271 1270 CONST VM_TABLE_ENTRY 1271 { ExecuteBREAK },// opcode 0x001272 { ExecuteJMP },// opcode 0x011273 { ExecuteJMP8 },// opcode 0x021274 { ExecuteCALL },// opcode 0x031275 { ExecuteRET },// opcode 0x041276 { ExecuteCMP },// opcode 0x05 CMPeq1277 { ExecuteCMP },// opcode 0x06 CMPlte1278 { ExecuteCMP },// opcode 0x07 CMPgte1279 { ExecuteCMP },// opcode 0x08 CMPulte1280 { ExecuteCMP },// opcode 0x09 CMPugte1272 CONST VM_TABLE_ENTRY mVmOpcodeTable[] = { 1273 { ExecuteBREAK }, // opcode 0x00 1274 { ExecuteJMP }, // opcode 0x01 1275 { ExecuteJMP8 }, // opcode 0x02 1276 { ExecuteCALL }, // opcode 0x03 1277 { ExecuteRET }, // opcode 0x04 1278 { ExecuteCMP }, // opcode 0x05 CMPeq 1279 { ExecuteCMP }, // opcode 0x06 CMPlte 1280 { ExecuteCMP }, // opcode 0x07 CMPgte 1281 { ExecuteCMP }, // opcode 0x08 CMPulte 1282 { ExecuteCMP }, // opcode 0x09 CMPugte 1281 1283 { ExecuteUnsignedDataManip }, // opcode 0x0A NOT 1282 { ExecuteSignedDataManip },// opcode 0x0B NEG1283 { ExecuteSignedDataManip },// opcode 0x0C ADD1284 { ExecuteSignedDataManip },// opcode 0x0D SUB1285 { ExecuteSignedDataManip },// opcode 0x0E MUL1284 { ExecuteSignedDataManip }, // opcode 0x0B NEG 1285 { ExecuteSignedDataManip }, // opcode 0x0C ADD 1286 { ExecuteSignedDataManip }, // opcode 0x0D SUB 1287 { ExecuteSignedDataManip }, // opcode 0x0E MUL 1286 1288 { ExecuteUnsignedDataManip }, // opcode 0x0F MULU 1287 { ExecuteSignedDataManip },// opcode 0x10 DIV1289 { ExecuteSignedDataManip }, // opcode 0x10 DIV 1288 1290 { ExecuteUnsignedDataManip }, // opcode 0x11 DIVU 1289 { ExecuteSignedDataManip },// opcode 0x12 MOD1291 { ExecuteSignedDataManip }, // opcode 0x12 MOD 1290 1292 { ExecuteUnsignedDataManip }, // opcode 0x13 MODU 1291 1293 { ExecuteUnsignedDataManip }, // opcode 0x14 AND … … 1294 1296 { ExecuteUnsignedDataManip }, // opcode 0x17 SHL 1295 1297 { ExecuteUnsignedDataManip }, // opcode 0x18 SHR 1296 { ExecuteSignedDataManip },// opcode 0x19 ASHR1298 { ExecuteSignedDataManip }, // opcode 0x19 ASHR 1297 1299 { ExecuteUnsignedDataManip }, // opcode 0x1A EXTNDB 1298 1300 { ExecuteUnsignedDataManip }, // opcode 0x1B EXTNDW 1299 1301 { ExecuteUnsignedDataManip }, // opcode 0x1C EXTNDD 1300 { ExecuteMOVxx },// opcode 0x1D MOVBW1301 { ExecuteMOVxx },// opcode 0x1E MOVWW1302 { ExecuteMOVxx },// opcode 0x1F MOVDW1303 { ExecuteMOVxx },// opcode 0x20 MOVQW1304 { ExecuteMOVxx },// opcode 0x21 MOVBD1305 { ExecuteMOVxx },// opcode 0x22 MOVWD1306 { ExecuteMOVxx },// opcode 0x23 MOVDD1307 { ExecuteMOVxx },// opcode 0x24 MOVQD1308 { ExecuteMOVsnw },// opcode 0x25 MOVsnw1309 { ExecuteMOVsnd },// opcode 0x26 MOVsnd1310 { NULL },// opcode 0x271311 { ExecuteMOVxx },// opcode 0x28 MOVqq1312 { ExecuteLOADSP },// opcode 0x29 LOADSP SP1, R21313 { ExecuteSTORESP },// opcode 0x2A STORESP R1, SP21314 { ExecutePUSH },// opcode 0x2B PUSH {@}R1 [imm16]1315 { ExecutePOP },// opcode 0x2C POP {@}R1 [imm16]1316 { ExecuteCMPI },// opcode 0x2D CMPIEQ1317 { ExecuteCMPI },// opcode 0x2E CMPILTE1318 { ExecuteCMPI },// opcode 0x2F CMPIGTE1319 { ExecuteCMPI },// opcode 0x30 CMPIULTE1320 { ExecuteCMPI },// opcode 0x31 CMPIUGTE1321 { ExecuteMOVxx },// opcode 0x32 MOVN1322 { ExecuteMOVxx },// opcode 0x33 MOVND1323 { NULL },// opcode 0x341324 { ExecutePUSHn },// opcode 0x351325 { ExecutePOPn },// opcode 0x361326 { ExecuteMOVI },// opcode 0x37 - mov immediate data1327 { ExecuteMOVIn },// opcode 0x38 - mov immediate natural1328 { ExecuteMOVREL },// opcode 0x39 - move data relative to PC1329 { NULL },// opcode 0x3a1330 { NULL },// opcode 0x3b1331 { NULL },// opcode 0x3c1332 { NULL },// opcode 0x3d1333 { NULL },// opcode 0x3e1334 { NULL }// opcode 0x3f1302 { ExecuteMOVxx }, // opcode 0x1D MOVBW 1303 { ExecuteMOVxx }, // opcode 0x1E MOVWW 1304 { ExecuteMOVxx }, // opcode 0x1F MOVDW 1305 { ExecuteMOVxx }, // opcode 0x20 MOVQW 1306 { ExecuteMOVxx }, // opcode 0x21 MOVBD 1307 { ExecuteMOVxx }, // opcode 0x22 MOVWD 1308 { ExecuteMOVxx }, // opcode 0x23 MOVDD 1309 { ExecuteMOVxx }, // opcode 0x24 MOVQD 1310 { ExecuteMOVsnw }, // opcode 0x25 MOVsnw 1311 { ExecuteMOVsnd }, // opcode 0x26 MOVsnd 1312 { NULL }, // opcode 0x27 1313 { ExecuteMOVxx }, // opcode 0x28 MOVqq 1314 { ExecuteLOADSP }, // opcode 0x29 LOADSP SP1, R2 1315 { ExecuteSTORESP }, // opcode 0x2A STORESP R1, SP2 1316 { ExecutePUSH }, // opcode 0x2B PUSH {@}R1 [imm16] 1317 { ExecutePOP }, // opcode 0x2C POP {@}R1 [imm16] 1318 { ExecuteCMPI }, // opcode 0x2D CMPIEQ 1319 { ExecuteCMPI }, // opcode 0x2E CMPILTE 1320 { ExecuteCMPI }, // opcode 0x2F CMPIGTE 1321 { ExecuteCMPI }, // opcode 0x30 CMPIULTE 1322 { ExecuteCMPI }, // opcode 0x31 CMPIUGTE 1323 { ExecuteMOVxx }, // opcode 0x32 MOVN 1324 { ExecuteMOVxx }, // opcode 0x33 MOVND 1325 { NULL }, // opcode 0x34 1326 { ExecutePUSHn }, // opcode 0x35 1327 { ExecutePOPn }, // opcode 0x36 1328 { ExecuteMOVI }, // opcode 0x37 - mov immediate data 1329 { ExecuteMOVIn }, // opcode 0x38 - mov immediate natural 1330 { ExecuteMOVREL }, // opcode 0x39 - move data relative to PC 1331 { NULL }, // opcode 0x3a 1332 { NULL }, // opcode 0x3b 1333 { NULL }, // opcode 0x3c 1334 { NULL }, // opcode 0x3d 1335 { NULL }, // opcode 0x3e 1336 { NULL } // opcode 0x3f 1335 1337 }; 1336 1338 … … 1338 1340 // Length of JMP instructions, depending on upper two bits of opcode. 1339 1341 // 1340 CONST UINT8 1342 CONST UINT8 mJMPLen[] = { 2, 2, 6, 10 }; 1341 1343 1342 1344 /** … … 1357 1359 EFIAPI 1358 1360 EbcExecuteInstructions ( 1359 IN EFI_EBC_VM_TEST_PROTOCOL *This,1360 IN VM_CONTEXT *VmPtr,1361 IN OUT UINTN *InstructionCount1361 IN EFI_EBC_VM_TEST_PROTOCOL *This, 1362 IN VM_CONTEXT *VmPtr, 1363 IN OUT UINTN *InstructionCount 1362 1364 ) 1363 1365 { … … 1384 1386 // 1385 1387 while (InstructionsLeft != 0) { 1386 ExecFunc = (UINTN) 1387 if (ExecFunc == (UINTN) 1388 ExecFunc = (UINTN)mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction; 1389 if (ExecFunc == (UINTN)NULL) { 1388 1390 EbcDebugSignalException (EXCEPT_EBC_INVALID_OPCODE, EXCEPTION_FLAG_FATAL, VmPtr); 1389 1391 return EFI_UNSUPPORTED; … … 1404 1406 } 1405 1407 1406 1407 1408 /** 1408 1409 Execute an EBC image from an entry point or from a published protocol. … … 1416 1417 EFI_STATUS 1417 1418 EbcExecute ( 1418 IN VM_CONTEXT *VmPtr1419 IN VM_CONTEXT *VmPtr 1419 1420 ) 1420 1421 { … … 1432 1433 // Make sure the magic value has been put on the stack before we got here. 1433 1434 // 1434 if (*VmPtr->StackMagicPtr != (UINTN) 1435 if (*VmPtr->StackMagicPtr != (UINTN)VM_STACK_KEY_VALUE) { 1435 1436 StackCorrupted = 1; 1436 1437 } 1437 1438 1438 VmPtr->FramePtr = (VOID *) ((UINT8 *) (UINTN)VmPtr->Gpr[0] + 8);1439 VmPtr->FramePtr = (VOID *)((UINT8 *)(UINTN)VmPtr->Gpr[0] + 8); 1439 1440 1440 1441 // … … 1442 1443 // 1443 1444 DEBUG_CODE_BEGIN (); 1444 Status = gBS->LocateProtocol ( 1445 &gEfiEbcSimpleDebuggerProtocolGuid, 1446 NULL, 1447 (VOID **) &EbcSimpleDebugger 1448 ); 1449 if (EFI_ERROR (Status)) { 1450 EbcSimpleDebugger = NULL; 1451 } 1445 Status = gBS->LocateProtocol ( 1446 &gEfiEbcSimpleDebuggerProtocolGuid, 1447 NULL, 1448 (VOID **)&EbcSimpleDebugger 1449 ); 1450 if (EFI_ERROR (Status)) { 1451 EbcSimpleDebugger = NULL; 1452 } 1453 1452 1454 DEBUG_CODE_END (); 1453 1455 … … 1457 1459 // which could then be used in a disassembly listing to find the problem. 1458 1460 // 1459 VmPtr->EntryPoint = (VOID *) 1461 VmPtr->EntryPoint = (VOID *)VmPtr->Ip; 1460 1462 1461 1463 // … … 1469 1471 // 1470 1472 DEBUG_CODE_BEGIN (); 1471 if (EbcSimpleDebugger != NULL) { 1472 EbcSimpleDebugger->Debugger (EbcSimpleDebugger, VmPtr); 1473 } 1473 if (EbcSimpleDebugger != NULL) { 1474 EbcSimpleDebugger->Debugger (EbcSimpleDebugger, VmPtr); 1475 } 1476 1474 1477 DEBUG_CODE_END (); 1475 1478 … … 1478 1481 // function pointer is null then generate an exception. 1479 1482 // 1480 ExecFunc = (UINTN) 1481 if (ExecFunc == (UINTN) 1483 ExecFunc = (UINTN)mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction; 1484 if (ExecFunc == (UINTN)NULL) { 1482 1485 EbcDebugSignalException (EXCEPT_EBC_INVALID_OPCODE, EXCEPTION_FLAG_FATAL, VmPtr); 1483 1486 Status = EFI_UNSUPPORTED; … … 1506 1509 EbcDebugSignalException (EXCEPT_EBC_STEP, EXCEPTION_FLAG_NONE, VmPtr); 1507 1510 } 1511 1508 1512 // 1509 1513 // Make sure stack has not been corrupted. Only report it once though. 1510 1514 // 1511 if ((StackCorrupted == 0) && (*VmPtr->StackMagicPtr != (UINTN) 1515 if ((StackCorrupted == 0) && (*VmPtr->StackMagicPtr != (UINTN)VM_STACK_KEY_VALUE)) { 1512 1516 EbcDebugSignalException (EXCEPT_EBC_STACK_FAULT, EXCEPTION_FLAG_FATAL, VmPtr); 1513 1517 StackCorrupted = 1; 1514 1518 } 1515 if ((StackCorrupted == 0) && ((UINT64)VmPtr->Gpr[0] <= (UINT64)(UINTN) VmPtr->StackTop)) { 1519 1520 if ((StackCorrupted == 0) && ((UINT64)VmPtr->Gpr[0] <= (UINT64)(UINTN)VmPtr->StackTop)) { 1516 1521 EbcDebugSignalException (EXCEPT_EBC_STACK_FAULT, EXCEPTION_FLAG_FATAL, VmPtr); 1517 1522 StackCorrupted = 1; … … 1520 1525 1521 1526 Done: 1522 mVmPtr 1527 mVmPtr = NULL; 1523 1528 1524 1529 return Status; 1525 1530 } 1526 1527 1531 1528 1532 /** … … 1549 1553 EFI_STATUS 1550 1554 ExecuteMOVxx ( 1551 IN VM_CONTEXT *VmPtr1555 IN VM_CONTEXT *VmPtr 1552 1556 ) 1553 1557 { … … 1566 1570 1567 1571 Opcode = GETOPCODE (VmPtr); 1568 OpcMasked = (UINT8) 1572 OpcMasked = (UINT8)(Opcode & OPCODE_M_OPCODE); 1569 1573 1570 1574 // … … 1576 1580 // Assume no indexes 1577 1581 // 1578 Index64Op1 1579 Index64Op2 1580 Data64 1582 Index64Op1 = 0; 1583 Index64Op2 = 0; 1584 Data64 = 0; 1581 1585 1582 1586 // … … 1595 1599 // 1596 1600 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) { 1597 Index16 1598 Index64Op1 = (INT64)Index16;1599 Size += sizeof (UINT16);1601 Index16 = VmReadIndex16 (VmPtr, 2); 1602 Index64Op1 = (INT64)Index16; 1603 Size += sizeof (UINT16); 1600 1604 } 1601 1605 1602 1606 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) { 1603 Index16 1604 Index64Op2 = (INT64)Index16;1605 Size += sizeof (UINT16);1607 Index16 = VmReadIndex16 (VmPtr, Size); 1608 Index64Op2 = (INT64)Index16; 1609 Size += sizeof (UINT16); 1606 1610 } 1607 1611 } else if ((OpcMasked <= OPCODE_MOVQD) || (OpcMasked == OPCODE_MOVND)) { … … 1610 1614 // 1611 1615 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) { 1612 Index32 1613 Index64Op1 = (INT64)Index32;1614 Size += sizeof (UINT32);1616 Index32 = VmReadIndex32 (VmPtr, 2); 1617 Index64Op1 = (INT64)Index32; 1618 Size += sizeof (UINT32); 1615 1619 } 1616 1620 1617 1621 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) { 1618 Index32 1619 Index64Op2 = (INT64)Index32;1620 Size += sizeof (UINT32);1622 Index32 = VmReadIndex32 (VmPtr, Size); 1623 Index64Op2 = (INT64)Index32; 1624 Size += sizeof (UINT32); 1621 1625 } 1622 1626 } else if (OpcMasked == OPCODE_MOVQQ) { … … 1626 1630 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) { 1627 1631 Index64Op1 = VmReadIndex64 (VmPtr, 2); 1628 Size += sizeof (UINT64);1632 Size += sizeof (UINT64); 1629 1633 } 1630 1634 1631 1635 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) { 1632 1636 Index64Op2 = VmReadIndex64 (VmPtr, Size); 1633 Size += sizeof (UINT64);1637 Size += sizeof (UINT64); 1634 1638 } 1635 1639 } else { … … 1645 1649 } 1646 1650 } 1651 1647 1652 // 1648 1653 // Determine the size of the move, and create a mask for it so we can … … 1650 1655 // 1651 1656 if ((OpcMasked == OPCODE_MOVBW) || (OpcMasked == OPCODE_MOVBD)) { 1652 MoveSize 1653 DataMask 1657 MoveSize = DATA_SIZE_8; 1658 DataMask = 0xFF; 1654 1659 } else if ((OpcMasked == OPCODE_MOVWW) || (OpcMasked == OPCODE_MOVWD)) { 1655 MoveSize 1656 DataMask 1660 MoveSize = DATA_SIZE_16; 1661 DataMask = 0xFFFF; 1657 1662 } else if ((OpcMasked == OPCODE_MOVDW) || (OpcMasked == OPCODE_MOVDD)) { 1658 MoveSize 1659 DataMask 1663 MoveSize = DATA_SIZE_32; 1664 DataMask = 0xFFFFFFFF; 1660 1665 } else if ((OpcMasked == OPCODE_MOVQW) || (OpcMasked == OPCODE_MOVQD) || (OpcMasked == OPCODE_MOVQQ)) { 1661 MoveSize 1662 DataMask = (UINT64)~0;1666 MoveSize = DATA_SIZE_64; 1667 DataMask = (UINT64) ~0; 1663 1668 } else if ((OpcMasked == OPCODE_MOVNW) || (OpcMasked == OPCODE_MOVND)) { 1664 MoveSize 1665 DataMask = (UINT64)~0 >> (64 - 8 * sizeof (UINTN));1669 MoveSize = DATA_SIZE_N; 1670 DataMask = (UINT64) ~0 >> (64 - 8 * sizeof (UINTN)); 1666 1671 } else { 1667 1672 // … … 1671 1676 return EFI_UNSUPPORTED; 1672 1677 } 1678 1673 1679 // 1674 1680 // Now get the source address … … 1678 1684 // Indirect form @R2. Compute address of operand2 1679 1685 // 1680 Source = (UINTN) 1686 Source = (UINTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index64Op2); 1681 1687 // 1682 1688 // Now get the data from the source. Always 0-extend and let the compiler … … 1684 1690 // 1685 1691 switch (MoveSize) { 1686 case DATA_SIZE_8:1687 Data64 = (UINT64) (UINT8)VmReadMem8 (VmPtr, Source);1688 break;1689 1690 case DATA_SIZE_16:1691 Data64 = (UINT64) (UINT16)VmReadMem16 (VmPtr, Source);1692 break;1693 1694 case DATA_SIZE_32:1695 Data64 = (UINT64) (UINT32)VmReadMem32 (VmPtr, Source);1696 break;1697 1698 case DATA_SIZE_64:1699 Data64 = (UINT64)VmReadMem64 (VmPtr, Source);1700 break;1701 1702 case DATA_SIZE_N:1703 Data64 = (UINT64) (UINTN)VmReadMemN (VmPtr, Source);1704 break;1705 1706 default:1707 //1708 // not reached1709 //1710 break;1692 case DATA_SIZE_8: 1693 Data64 = (UINT64)(UINT8)VmReadMem8 (VmPtr, Source); 1694 break; 1695 1696 case DATA_SIZE_16: 1697 Data64 = (UINT64)(UINT16)VmReadMem16 (VmPtr, Source); 1698 break; 1699 1700 case DATA_SIZE_32: 1701 Data64 = (UINT64)(UINT32)VmReadMem32 (VmPtr, Source); 1702 break; 1703 1704 case DATA_SIZE_64: 1705 Data64 = (UINT64)VmReadMem64 (VmPtr, Source); 1706 break; 1707 1708 case DATA_SIZE_N: 1709 Data64 = (UINT64)(UINTN)VmReadMemN (VmPtr, Source); 1710 break; 1711 1712 default: 1713 // 1714 // not reached 1715 // 1716 break; 1711 1717 } 1712 1718 } else { … … 1714 1720 // Not indirect source: MOVxx {@}Rx, Ry [Index] 1715 1721 // 1716 Data64 = (UINT64) 1722 Data64 = (UINT64)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index64Op2); 1717 1723 // 1718 1724 // Did Operand2 have an index? If so, treat as two signed values since … … 1738 1744 (OPERAND1_REGNUM (Operands) == 0) && 1739 1745 (OPERAND1_INDIRECT (Operands)) 1740 ) { 1741 Data64 = (UINT64) ConvertStackAddr (VmPtr, (UINTN) (INT64) Data64); 1746 ) 1747 { 1748 Data64 = (UINT64)ConvertStackAddr (VmPtr, (UINTN)(INT64)Data64); 1742 1749 } 1743 1750 } 1744 1751 } 1752 1745 1753 // 1746 1754 // Now write it back … … 1750 1758 // Reuse the Source variable to now be dest. 1751 1759 // 1752 Source = (UINTN) 1760 Source = (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index64Op1); 1753 1761 // 1754 1762 // Do the write based on the size 1755 1763 // 1756 1764 switch (MoveSize) { 1757 case DATA_SIZE_8:1758 VmWriteMem8 (VmPtr, Source, (UINT8)Data64);1759 break;1760 1761 case DATA_SIZE_16:1762 VmWriteMem16 (VmPtr, Source, (UINT16)Data64);1763 break;1764 1765 case DATA_SIZE_32:1766 VmWriteMem32 (VmPtr, Source, (UINT32)Data64);1767 break;1768 1769 case DATA_SIZE_64:1770 VmWriteMem64 (VmPtr, Source, Data64);1771 break;1772 1773 case DATA_SIZE_N:1774 VmWriteMemN (VmPtr, Source, (UINTN)Data64);1775 break;1776 1777 default:1778 //1779 // not reached1780 //1781 break;1765 case DATA_SIZE_8: 1766 VmWriteMem8 (VmPtr, Source, (UINT8)Data64); 1767 break; 1768 1769 case DATA_SIZE_16: 1770 VmWriteMem16 (VmPtr, Source, (UINT16)Data64); 1771 break; 1772 1773 case DATA_SIZE_32: 1774 VmWriteMem32 (VmPtr, Source, (UINT32)Data64); 1775 break; 1776 1777 case DATA_SIZE_64: 1778 VmWriteMem64 (VmPtr, Source, Data64); 1779 break; 1780 1781 case DATA_SIZE_N: 1782 VmWriteMemN (VmPtr, Source, (UINTN)Data64); 1783 break; 1784 1785 default: 1786 // 1787 // not reached 1788 // 1789 break; 1782 1790 } 1783 1791 } else { … … 1794 1802 return EFI_UNSUPPORTED; 1795 1803 } 1804 1796 1805 // 1797 1806 // Direct storage in register. Clear unused bits and store back to … … 1800 1809 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Data64 & DataMask; 1801 1810 } 1811 1802 1812 // 1803 1813 // Advance the instruction pointer … … 1807 1817 } 1808 1818 1809 1810 1819 /** 1811 1820 Execute the EBC BREAK instruction. … … 1818 1827 EFI_STATUS 1819 1828 ExecuteBREAK ( 1820 IN VM_CONTEXT *VmPtr1829 IN VM_CONTEXT *VmPtr 1821 1830 ) 1822 1831 { … … 1828 1837 INT32 Offset; 1829 1838 1830 Thunk = NULL;1839 Thunk = NULL; 1831 1840 Operands = GETOPERANDS (VmPtr); 1832 1841 switch (Operands) { 1833 // 1834 // Runaway program break. Generate an exception and terminate 1835 // 1836 case 0: 1837 EbcDebugSignalException (EXCEPT_EBC_BAD_BREAK, EXCEPTION_FLAG_FATAL, VmPtr); 1838 break; 1839 1840 // 1841 // Get VM version -- return VM revision number in R7 1842 // 1843 case 1: 1844 // 1845 // Bits: 1846 // 63-17 = 0 1847 // 16-8 = Major version 1848 // 7-0 = Minor version 1849 // 1850 VmPtr->Gpr[7] = GetVmVersion (); 1851 break; 1852 1853 // 1854 // Debugger breakpoint 1855 // 1856 case 3: 1857 VmPtr->StopFlags |= STOPFLAG_BREAKPOINT; 1858 // 1859 // See if someone has registered a handler 1860 // 1861 EbcDebugSignalException ( 1862 EXCEPT_EBC_BREAKPOINT, 1863 EXCEPTION_FLAG_NONE, 1864 VmPtr 1865 ); 1866 break; 1867 1868 // 1869 // System call, which there are none, so NOP it. 1870 // 1871 case 4: 1872 break; 1873 1874 // 1875 // Create a thunk for EBC code. R7 points to a 32-bit (in a 64-bit slot) 1876 // "offset from self" pointer to the EBC entry point. 1877 // After we're done, *(UINT64 *)R7 will be the address of the new thunk. 1878 // 1879 case 5: 1880 Offset = (INT32) VmReadMem32 (VmPtr, (UINTN) VmPtr->Gpr[7]); 1881 U64EbcEntryPoint = (UINT64) (VmPtr->Gpr[7] + Offset + 4); 1882 EbcEntryPoint = (VOID *) (UINTN) U64EbcEntryPoint; 1883 1884 // 1885 // Now create a new thunk 1886 // 1887 Status = EbcCreateThunks (VmPtr->ImageHandle, EbcEntryPoint, &Thunk, 0); 1888 if (EFI_ERROR (Status)) { 1889 return Status; 1890 } 1891 1892 // 1893 // Finally replace the EBC entry point memory with the thunk address 1894 // 1895 VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[7], (UINT64) (UINTN) Thunk); 1896 break; 1897 1898 // 1899 // Compiler setting version per value in R7 1900 // 1901 case 6: 1902 VmPtr->CompilerVersion = (UINT32) VmPtr->Gpr[7]; 1903 // 1904 // Check compiler version against VM version? 1905 // 1906 break; 1907 1908 // 1909 // Unhandled break code. Signal exception. 1910 // 1911 default: 1912 EbcDebugSignalException (EXCEPT_EBC_BAD_BREAK, EXCEPTION_FLAG_FATAL, VmPtr); 1913 break; 1914 } 1842 // 1843 // Runaway program break. Generate an exception and terminate 1844 // 1845 case 0: 1846 EbcDebugSignalException (EXCEPT_EBC_BAD_BREAK, EXCEPTION_FLAG_FATAL, VmPtr); 1847 break; 1848 1849 // 1850 // Get VM version -- return VM revision number in R7 1851 // 1852 case 1: 1853 // 1854 // Bits: 1855 // 63-17 = 0 1856 // 16-8 = Major version 1857 // 7-0 = Minor version 1858 // 1859 VmPtr->Gpr[7] = GetVmVersion (); 1860 break; 1861 1862 // 1863 // Debugger breakpoint 1864 // 1865 case 3: 1866 VmPtr->StopFlags |= STOPFLAG_BREAKPOINT; 1867 // 1868 // See if someone has registered a handler 1869 // 1870 EbcDebugSignalException ( 1871 EXCEPT_EBC_BREAKPOINT, 1872 EXCEPTION_FLAG_NONE, 1873 VmPtr 1874 ); 1875 break; 1876 1877 // 1878 // System call, which there are none, so NOP it. 1879 // 1880 case 4: 1881 break; 1882 1883 // 1884 // Create a thunk for EBC code. R7 points to a 32-bit (in a 64-bit slot) 1885 // "offset from self" pointer to the EBC entry point. 1886 // After we're done, *(UINT64 *)R7 will be the address of the new thunk. 1887 // 1888 case 5: 1889 Offset = (INT32)VmReadMem32 (VmPtr, (UINTN)VmPtr->Gpr[7]); 1890 U64EbcEntryPoint = (UINT64)(VmPtr->Gpr[7] + Offset + 4); 1891 EbcEntryPoint = (VOID *)(UINTN)U64EbcEntryPoint; 1892 1893 // 1894 // Now create a new thunk 1895 // 1896 Status = EbcCreateThunks (VmPtr->ImageHandle, EbcEntryPoint, &Thunk, 0); 1897 if (EFI_ERROR (Status)) { 1898 return Status; 1899 } 1900 1901 // 1902 // Finally replace the EBC entry point memory with the thunk address 1903 // 1904 VmWriteMem64 (VmPtr, (UINTN)VmPtr->Gpr[7], (UINT64)(UINTN)Thunk); 1905 break; 1906 1907 // 1908 // Compiler setting version per value in R7 1909 // 1910 case 6: 1911 VmPtr->CompilerVersion = (UINT32)VmPtr->Gpr[7]; 1912 // 1913 // Check compiler version against VM version? 1914 // 1915 break; 1916 1917 // 1918 // Unhandled break code. Signal exception. 1919 // 1920 default: 1921 EbcDebugSignalException (EXCEPT_EBC_BAD_BREAK, EXCEPTION_FLAG_FATAL, VmPtr); 1922 break; 1923 } 1924 1915 1925 // 1916 1926 // Advance IP … … 1919 1929 return EFI_SUCCESS; 1920 1930 } 1921 1922 1931 1923 1932 /** … … 1948 1957 EFI_STATUS 1949 1958 ExecuteJMP ( 1950 IN VM_CONTEXT *VmPtr1959 IN VM_CONTEXT *VmPtr 1951 1960 ) 1952 1961 { … … 1973 1982 // If we haven't met the condition, then simply advance the IP and return. 1974 1983 // 1975 CompareSet = (UINT8) 1976 ConditionFlag = (UINT8) 1984 CompareSet = (UINT8)(((Operand & JMP_M_CS) != 0) ? 1 : 0); 1985 ConditionFlag = (UINT8)VMFLAG_ISSET (VmPtr, VMFLAGS_CC); 1977 1986 if ((Operand & CONDITION_M_CONDITIONAL) != 0) { 1978 1987 if (CompareSet != ConditionFlag) { … … 1983 1992 } 1984 1993 } 1994 1985 1995 // 1986 1996 // Check for 64-bit form and do it right away since it's the most … … 2000 2010 return EFI_UNSUPPORTED; 2001 2011 } 2012 2002 2013 // 2003 2014 // 64-bit immediate data is full address. Read the immediate data, 2004 2015 // check for alignment, and jump absolute. 2005 2016 // 2006 Data64 = (UINT64) 2007 if (!IS_ALIGNED ((UINTN) 2017 Data64 = (UINT64)VmReadImmed64 (VmPtr, 2); 2018 if (!IS_ALIGNED ((UINTN)Data64, sizeof (UINT16))) { 2008 2019 EbcDebugSignalException ( 2009 2020 EXCEPT_EBC_ALIGNMENT_CHECK, … … 2020 2031 EbcDebuggerHookJMPStart (VmPtr); 2021 2032 if ((Operand & JMP_M_RELATIVE) != 0) { 2022 VmPtr->Ip += (UINTN) 2033 VmPtr->Ip += (UINTN)Data64 + Size; 2023 2034 } else { 2024 VmPtr->Ip = (VMIP) (UINTN) Data64; 2025 } 2035 VmPtr->Ip = (VMIP)(UINTN)Data64; 2036 } 2037 2026 2038 EbcDebuggerHookJMPEnd (VmPtr); 2027 2039 2028 2040 return EFI_SUCCESS; 2029 2041 } 2042 2030 2043 // 2031 2044 // 32-bit forms: … … 2044 2057 Index32 = 0; 2045 2058 } 2059 2046 2060 // 2047 2061 // Get the register data. If R == 0, then special case where it's ignored. … … 2050 2064 Data64 = 0; 2051 2065 } else { 2052 Data64 = (UINT64) OPERAND1_REGDATA (VmPtr, Operand); 2053 } 2066 Data64 = (UINT64)OPERAND1_REGDATA (VmPtr, Operand); 2067 } 2068 2054 2069 // 2055 2070 // Decode the forms … … 2059 2074 // Form: JMP32 @Rx {Index32} 2060 2075 // 2061 Addr = VmReadMemN (VmPtr, (UINTN) 2062 if (!IS_ALIGNED ((UINTN) 2076 Addr = VmReadMemN (VmPtr, (UINTN)Data64 + Index32); 2077 if (!IS_ALIGNED ((UINTN)Addr, sizeof (UINT16))) { 2063 2078 EbcDebugSignalException ( 2064 2079 EXCEPT_EBC_ALIGNMENT_CHECK, … … 2072 2087 EbcDebuggerHookJMPStart (VmPtr); 2073 2088 if ((Operand & JMP_M_RELATIVE) != 0) { 2074 VmPtr->Ip += (UINTN) 2089 VmPtr->Ip += (UINTN)Addr + Size; 2075 2090 } else { 2076 VmPtr->Ip = (VMIP) Addr; 2077 } 2091 VmPtr->Ip = (VMIP)Addr; 2092 } 2093 2078 2094 EbcDebuggerHookJMPEnd (VmPtr); 2079 2080 2095 } else { 2081 2096 // 2082 2097 // Form: JMP32 Rx {Immed32} 2083 2098 // 2084 Addr = (UINTN) 2085 if (!IS_ALIGNED ((UINTN) 2099 Addr = (UINTN)(Data64 + Index32); 2100 if (!IS_ALIGNED ((UINTN)Addr, sizeof (UINT16))) { 2086 2101 EbcDebugSignalException ( 2087 2102 EXCEPT_EBC_ALIGNMENT_CHECK, … … 2095 2110 EbcDebuggerHookJMPStart (VmPtr); 2096 2111 if ((Operand & JMP_M_RELATIVE) != 0) { 2097 VmPtr->Ip += (UINTN) 2112 VmPtr->Ip += (UINTN)Addr + Size; 2098 2113 } else { 2099 VmPtr->Ip = (VMIP) Addr; 2100 } 2114 VmPtr->Ip = (VMIP)Addr; 2115 } 2116 2101 2117 EbcDebuggerHookJMPEnd (VmPtr); 2102 2103 2118 } 2104 2119 2105 2120 return EFI_SUCCESS; 2106 2121 } 2107 2108 2122 2109 2123 /** … … 2120 2134 EFI_STATUS 2121 2135 ExecuteJMP8 ( 2122 IN VM_CONTEXT *VmPtr2123 ) 2124 { 2125 UINT8 Opcode;2126 UINT8 ConditionFlag;2127 UINT8 CompareSet;2128 INT8 Offset;2136 IN VM_CONTEXT *VmPtr 2137 ) 2138 { 2139 UINT8 Opcode; 2140 UINT8 ConditionFlag; 2141 UINT8 CompareSet; 2142 INT8 Offset; 2129 2143 2130 2144 // … … 2132 2146 // 2133 2147 Opcode = GETOPCODE (VmPtr); 2134 CompareSet = (UINT8) 2135 ConditionFlag = (UINT8) 2148 CompareSet = (UINT8)(((Opcode & JMP_M_CS) != 0) ? 1 : 0); 2149 ConditionFlag = (UINT8)VMFLAG_ISSET (VmPtr, VMFLAGS_CC); 2136 2150 2137 2151 // … … 2146 2160 } 2147 2161 } 2162 2148 2163 // 2149 2164 // Get the offset from the instruction stream. It's relative to the … … 2160 2175 } 2161 2176 2162 2163 2177 /** 2164 2178 Execute the EBC MOVI. … … 2184 2198 EFI_STATUS 2185 2199 ExecuteMOVI ( 2186 IN VM_CONTEXT *VmPtr2200 IN VM_CONTEXT *VmPtr 2187 2201 ) 2188 2202 { … … 2198 2212 // Get the opcode and operands byte so we can get R1 and R2 2199 2213 // 2200 Opcode 2201 Operands 2214 Opcode = GETOPCODE (VmPtr); 2215 Operands = GETOPERANDS (VmPtr); 2202 2216 2203 2217 // … … 2211 2225 Size = 2; 2212 2226 } 2227 2213 2228 // 2214 2229 // Extract the immediate data. Sign-extend always. 2215 2230 // 2216 2231 if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) { 2217 ImmData64 = (INT64) (INT16)VmReadImmed16 (VmPtr, Size);2218 Size += 2;2232 ImmData64 = (INT64)(INT16)VmReadImmed16 (VmPtr, Size); 2233 Size += 2; 2219 2234 } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) { 2220 ImmData64 = (INT64) (INT32)VmReadImmed32 (VmPtr, Size);2221 Size += 4;2235 ImmData64 = (INT64)(INT32)VmReadImmed32 (VmPtr, Size); 2236 Size += 4; 2222 2237 } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) { 2223 ImmData64 = (INT64) 2224 Size += 8;2238 ImmData64 = (INT64)VmReadImmed64 (VmPtr, Size); 2239 Size += 8; 2225 2240 } else { 2226 2241 // … … 2234 2249 return EFI_UNSUPPORTED; 2235 2250 } 2251 2236 2252 // 2237 2253 // Now write back the result … … 2249 2265 return EFI_UNSUPPORTED; 2250 2266 } 2267 2251 2268 // 2252 2269 // Writing directly to a register. Clear unused bits. … … 2259 2276 Mask64 = 0x00000000FFFFFFFF; 2260 2277 } else { 2261 Mask64 = (UINT64) ~0;2278 Mask64 = (UINT64) ~0; 2262 2279 } 2263 2280 … … 2267 2284 // Get the address then write back based on size of the move 2268 2285 // 2269 Op1 = (UINT64) 2286 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2270 2287 if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH8) { 2271 VmWriteMem8 (VmPtr, (UINTN) Op1, (UINT8)ImmData64);2288 VmWriteMem8 (VmPtr, (UINTN)Op1, (UINT8)ImmData64); 2272 2289 } else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH16) { 2273 VmWriteMem16 (VmPtr, (UINTN) Op1, (UINT16)ImmData64);2290 VmWriteMem16 (VmPtr, (UINTN)Op1, (UINT16)ImmData64); 2274 2291 } else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH32) { 2275 VmWriteMem32 (VmPtr, (UINTN) Op1, (UINT32)ImmData64);2292 VmWriteMem32 (VmPtr, (UINTN)Op1, (UINT32)ImmData64); 2276 2293 } else { 2277 VmWriteMem64 (VmPtr, (UINTN) Op1, (UINT64) ImmData64); 2278 } 2279 } 2294 VmWriteMem64 (VmPtr, (UINTN)Op1, (UINT64)ImmData64); 2295 } 2296 } 2297 2280 2298 // 2281 2299 // Advance the instruction pointer … … 2285 2303 } 2286 2304 2287 2288 2305 /** 2289 2306 Execute the EBC MOV immediate natural. This instruction moves an immediate … … 2302 2319 EFI_STATUS 2303 2320 ExecuteMOVIn ( 2304 IN VM_CONTEXT *VmPtr2321 IN VM_CONTEXT *VmPtr 2305 2322 ) 2306 2323 { … … 2317 2334 // Get the opcode and operands byte so we can get R1 and R2 2318 2335 // 2319 Opcode 2320 Operands 2336 Opcode = GETOPCODE (VmPtr); 2337 Operands = GETOPERANDS (VmPtr); 2321 2338 2322 2339 // … … 2330 2347 Size = 2; 2331 2348 } 2349 2332 2350 // 2333 2351 // Extract the immediate data and convert to a 64-bit index. 2334 2352 // 2335 2353 if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) { 2336 ImmedIndex16 2337 ImmedIndex64 = (INT64)ImmedIndex16;2338 Size += 2;2354 ImmedIndex16 = VmReadIndex16 (VmPtr, Size); 2355 ImmedIndex64 = (INT64)ImmedIndex16; 2356 Size += 2; 2339 2357 } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) { 2340 ImmedIndex32 2341 ImmedIndex64 = (INT64)ImmedIndex32;2342 Size += 4;2358 ImmedIndex32 = VmReadIndex32 (VmPtr, Size); 2359 ImmedIndex64 = (INT64)ImmedIndex32; 2360 Size += 4; 2343 2361 } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) { 2344 2362 ImmedIndex64 = VmReadIndex64 (VmPtr, Size); 2345 Size += 8;2363 Size += 8; 2346 2364 } else { 2347 2365 // … … 2355 2373 return EFI_UNSUPPORTED; 2356 2374 } 2375 2357 2376 // 2358 2377 // Now write back the result … … 2377 2396 // Get the address 2378 2397 // 2379 Op1 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2380 VmWriteMemN (VmPtr, (UINTN) Op1, (UINTN)(INTN) ImmedIndex64); 2381 } 2398 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2399 VmWriteMemN (VmPtr, (UINTN)Op1, (UINTN)(INTN)ImmedIndex64); 2400 } 2401 2382 2402 // 2383 2403 // Advance the instruction pointer … … 2387 2407 } 2388 2408 2389 2390 2409 /** 2391 2410 Execute the EBC MOVREL instruction. … … 2404 2423 EFI_STATUS 2405 2424 ExecuteMOVREL ( 2406 IN VM_CONTEXT *VmPtr2425 IN VM_CONTEXT *VmPtr 2407 2426 ) 2408 2427 { … … 2418 2437 // Get the opcode and operands byte so we can get R1 and R2 2419 2438 // 2420 Opcode 2421 Operands 2439 Opcode = GETOPCODE (VmPtr); 2440 Operands = GETOPERANDS (VmPtr); 2422 2441 2423 2442 // … … 2431 2450 Size = 2; 2432 2451 } 2452 2433 2453 // 2434 2454 // Get the immediate data. 2435 2455 // 2436 2456 if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) { 2437 ImmData64 = (INT64) 2438 Size += 2;2457 ImmData64 = (INT64)VmReadImmed16 (VmPtr, Size); 2458 Size += 2; 2439 2459 } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) { 2440 ImmData64 = (INT64) 2441 Size += 4;2460 ImmData64 = (INT64)VmReadImmed32 (VmPtr, Size); 2461 Size += 4; 2442 2462 } else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) { 2443 2463 ImmData64 = VmReadImmed64 (VmPtr, Size); 2444 Size += 8;2464 Size += 8; 2445 2465 } else { 2446 2466 // … … 2454 2474 return EFI_UNSUPPORTED; 2455 2475 } 2476 2456 2477 // 2457 2478 // Compute the value and write back the result 2458 2479 // 2459 Op2 = (UINT64) ((INT64) ((UINT64) (UINTN) VmPtr->Ip) + (INT64)ImmData64 + Size);2480 Op2 = (UINT64)((INT64)((UINT64)(UINTN)VmPtr->Ip) + (INT64)ImmData64 + Size); 2460 2481 if (!OPERAND1_INDIRECT (Operands)) { 2461 2482 // … … 2471 2492 } 2472 2493 2473 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (VM_REGISTER) 2494 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (VM_REGISTER)Op2; 2474 2495 } else { 2475 2496 // … … 2478 2499 // we're talking addresses here. 2479 2500 // 2480 Op1 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2481 VmWriteMemN (VmPtr, (UINTN) Op1, (UINTN) Op2); 2482 } 2501 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2502 VmWriteMemN (VmPtr, (UINTN)Op1, (UINTN)Op2); 2503 } 2504 2483 2505 // 2484 2506 // Advance the instruction pointer … … 2487 2509 return EFI_SUCCESS; 2488 2510 } 2489 2490 2511 2491 2512 /** … … 2510 2531 EFI_STATUS 2511 2532 ExecuteMOVsnw ( 2512 IN VM_CONTEXT *VmPtr2533 IN VM_CONTEXT *VmPtr 2513 2534 ) 2514 2535 { … … 2523 2544 // Get the opcode and operand bytes 2524 2545 // 2525 Opcode 2526 Operands 2527 2528 Op1Index 2546 Opcode = GETOPCODE (VmPtr); 2547 Operands = GETOPERANDS (VmPtr); 2548 2549 Op1Index = Op2Index = 0; 2529 2550 2530 2551 // … … 2532 2553 // 2533 2554 Size = 2; 2534 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) {2555 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) { 2535 2556 if (OPERAND1_INDIRECT (Operands)) { 2536 2557 Op1Index = VmReadIndex16 (VmPtr, 2); … … 2559 2580 Size += sizeof (UINT16); 2560 2581 } 2582 2561 2583 // 2562 2584 // Get the data from the source. … … 2564 2586 Op2 = (UINT64)(INT64)(INTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Op2Index); 2565 2587 if (OPERAND2_INDIRECT (Operands)) { 2566 Op2 = (UINT64)(INT64)(INTN)VmReadMemN (VmPtr, (UINTN) Op2); 2567 } 2588 Op2 = (UINT64)(INT64)(INTN)VmReadMemN (VmPtr, (UINTN)Op2); 2589 } 2590 2568 2591 // 2569 2592 // Now write back the result. … … 2572 2595 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Op2; 2573 2596 } else { 2574 VmWriteMemN (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN) Op2); 2575 } 2597 VmWriteMemN (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN)Op2); 2598 } 2599 2576 2600 // 2577 2601 // Advance the instruction pointer … … 2580 2604 return EFI_SUCCESS; 2581 2605 } 2582 2583 2606 2584 2607 /** … … 2603 2626 EFI_STATUS 2604 2627 ExecuteMOVsnd ( 2605 IN VM_CONTEXT *VmPtr2628 IN VM_CONTEXT *VmPtr 2606 2629 ) 2607 2630 { … … 2616 2639 // Get the opcode and operand bytes 2617 2640 // 2618 Opcode 2619 Operands 2620 2621 Op1Index 2641 Opcode = GETOPCODE (VmPtr); 2642 Operands = GETOPERANDS (VmPtr); 2643 2644 Op1Index = Op2Index = 0; 2622 2645 2623 2646 // … … 2652 2675 Size += sizeof (UINT32); 2653 2676 } 2677 2654 2678 // 2655 2679 // Get the data from the source. … … 2657 2681 Op2 = (UINT64)(INT64)(INTN)(INT64)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Op2Index); 2658 2682 if (OPERAND2_INDIRECT (Operands)) { 2659 Op2 = (UINT64)(INT64)(INTN)(INT64)VmReadMemN (VmPtr, (UINTN) Op2); 2660 } 2683 Op2 = (UINT64)(INT64)(INTN)(INT64)VmReadMemN (VmPtr, (UINTN)Op2); 2684 } 2685 2661 2686 // 2662 2687 // Now write back the result. … … 2665 2690 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Op2; 2666 2691 } else { 2667 VmWriteMemN (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN) Op2); 2668 } 2692 VmWriteMemN (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN)Op2); 2693 } 2694 2669 2695 // 2670 2696 // Advance the instruction pointer … … 2674 2700 } 2675 2701 2676 2677 2702 /** 2678 2703 Execute the EBC PUSHn instruction … … 2688 2713 EFI_STATUS 2689 2714 ExecutePUSHn ( 2690 IN VM_CONTEXT *VmPtr2691 ) 2692 { 2693 UINT8 Opcode;2694 UINT8 Operands;2695 INT16 Index16;2696 UINTN DataN;2715 IN VM_CONTEXT *VmPtr 2716 ) 2717 { 2718 UINT8 Opcode; 2719 UINT8 Operands; 2720 INT16 Index16; 2721 UINTN DataN; 2697 2722 2698 2723 // 2699 2724 // Get opcode and operands 2700 2725 // 2701 Opcode 2702 Operands 2726 Opcode = GETOPCODE (VmPtr); 2727 Operands = GETOPERANDS (VmPtr); 2703 2728 2704 2729 // … … 2714 2739 VmPtr->Ip += 4; 2715 2740 } else { 2716 Index16 = 0;2741 Index16 = 0; 2717 2742 VmPtr->Ip += 2; 2718 2743 } 2744 2719 2745 // 2720 2746 // Get the data to push 2721 2747 // 2722 2748 if (OPERAND1_INDIRECT (Operands)) { 2723 DataN = VmReadMemN (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16)); 2724 } else { 2725 DataN = (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16); 2726 } 2749 DataN = VmReadMemN (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16)); 2750 } else { 2751 DataN = (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16); 2752 } 2753 2727 2754 // 2728 2755 // Adjust the stack down. 2729 2756 // 2730 2757 VmPtr->Gpr[0] -= sizeof (UINTN); 2731 VmWriteMemN (VmPtr, (UINTN) 2758 VmWriteMemN (VmPtr, (UINTN)VmPtr->Gpr[0], DataN); 2732 2759 return EFI_SUCCESS; 2733 2760 } 2734 2735 2761 2736 2762 /** … … 2747 2773 EFI_STATUS 2748 2774 ExecutePUSH ( 2749 IN VM_CONTEXT *VmPtr2775 IN VM_CONTEXT *VmPtr 2750 2776 ) 2751 2777 { … … 2759 2785 // Get opcode and operands 2760 2786 // 2761 Opcode 2762 Operands 2787 Opcode = GETOPCODE (VmPtr); 2788 Operands = GETOPERANDS (VmPtr); 2763 2789 // 2764 2790 // Get immediate index if present, then advance the IP. … … 2773 2799 VmPtr->Ip += 4; 2774 2800 } else { 2775 Index16 = 0;2801 Index16 = 0; 2776 2802 VmPtr->Ip += 2; 2777 2803 } 2804 2778 2805 // 2779 2806 // Get the data to push … … 2781 2808 if ((Opcode & PUSHPOP_M_64) != 0) { 2782 2809 if (OPERAND1_INDIRECT (Operands)) { 2783 Data64 = VmReadMem64 (VmPtr, (UINTN) 2810 Data64 = VmReadMem64 (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16)); 2784 2811 } else { 2785 Data64 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2786 } 2812 Data64 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2813 } 2814 2787 2815 // 2788 2816 // Adjust the stack down, then write back the data 2789 2817 // 2790 2818 VmPtr->Gpr[0] -= sizeof (UINT64); 2791 VmWriteMem64 (VmPtr, (UINTN) 2819 VmWriteMem64 (VmPtr, (UINTN)VmPtr->Gpr[0], Data64); 2792 2820 } else { 2793 2821 // … … 2795 2823 // 2796 2824 if (OPERAND1_INDIRECT (Operands)) { 2797 Data32 = VmReadMem32 (VmPtr, (UINTN) 2825 Data32 = VmReadMem32 (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16)); 2798 2826 } else { 2799 Data32 = (UINT32) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2800 } 2827 Data32 = (UINT32)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16; 2828 } 2829 2801 2830 // 2802 2831 // Adjust the stack down and write the data 2803 2832 // 2804 2833 VmPtr->Gpr[0] -= sizeof (UINT32); 2805 VmWriteMem32 (VmPtr, (UINTN) 2834 VmWriteMem32 (VmPtr, (UINTN)VmPtr->Gpr[0], Data32); 2806 2835 } 2807 2836 2808 2837 return EFI_SUCCESS; 2809 2838 } 2810 2811 2839 2812 2840 /** … … 2823 2851 EFI_STATUS 2824 2852 ExecutePOPn ( 2825 IN VM_CONTEXT *VmPtr2826 ) 2827 { 2828 UINT8 Opcode;2829 UINT8 Operands;2830 INT16 Index16;2831 UINTN DataN;2853 IN VM_CONTEXT *VmPtr 2854 ) 2855 { 2856 UINT8 Opcode; 2857 UINT8 Operands; 2858 INT16 Index16; 2859 UINTN DataN; 2832 2860 2833 2861 // 2834 2862 // Get opcode and operands 2835 2863 // 2836 Opcode 2837 Operands 2864 Opcode = GETOPCODE (VmPtr); 2865 Operands = GETOPERANDS (VmPtr); 2838 2866 // 2839 2867 // Get immediate data if present, and advance the IP … … 2848 2876 VmPtr->Ip += 4; 2849 2877 } else { 2850 Index16 = 0;2878 Index16 = 0; 2851 2879 VmPtr->Ip += 2; 2852 2880 } 2881 2853 2882 // 2854 2883 // Read the data off the stack, then adjust the stack pointer 2855 2884 // 2856 DataN = VmReadMemN (VmPtr, (UINTN)VmPtr->Gpr[0]);2885 DataN = VmReadMemN (VmPtr, (UINTN)VmPtr->Gpr[0]); 2857 2886 VmPtr->Gpr[0] += sizeof (UINTN); 2858 2887 // … … 2860 2889 // 2861 2890 if (OPERAND1_INDIRECT (Operands)) { 2862 VmWriteMemN (VmPtr, (UINTN) 2863 } else { 2864 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (INT64) (UINT64) (UINTN)(DataN + Index16);2891 VmWriteMemN (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), DataN); 2892 } else { 2893 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (INT64)(UINT64)(UINTN)(DataN + Index16); 2865 2894 } 2866 2895 2867 2896 return EFI_SUCCESS; 2868 2897 } 2869 2870 2898 2871 2899 /** … … 2882 2910 EFI_STATUS 2883 2911 ExecutePOP ( 2884 IN VM_CONTEXT *VmPtr2912 IN VM_CONTEXT *VmPtr 2885 2913 ) 2886 2914 { … … 2894 2922 // Get opcode and operands 2895 2923 // 2896 Opcode 2897 Operands 2924 Opcode = GETOPCODE (VmPtr); 2925 Operands = GETOPERANDS (VmPtr); 2898 2926 // 2899 2927 // Get immediate data if present, and advance the IP. … … 2908 2936 VmPtr->Ip += 4; 2909 2937 } else { 2910 Index16 = 0;2938 Index16 = 0; 2911 2939 VmPtr->Ip += 2; 2912 2940 } 2941 2913 2942 // 2914 2943 // Get the data off the stack, then write it to the appropriate location … … 2918 2947 // Read the data off the stack, then adjust the stack pointer 2919 2948 // 2920 Data64 = VmReadMem64 (VmPtr, (UINTN)VmPtr->Gpr[0]);2949 Data64 = VmReadMem64 (VmPtr, (UINTN)VmPtr->Gpr[0]); 2921 2950 VmPtr->Gpr[0] += sizeof (UINT64); 2922 2951 // … … 2924 2953 // 2925 2954 if (OPERAND1_INDIRECT (Operands)) { 2926 VmWriteMem64 (VmPtr, (UINTN) 2955 VmWriteMem64 (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), Data64); 2927 2956 } else { 2928 2957 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Data64 + Index16; … … 2932 2961 // 32-bit pop. Read it off the stack and adjust the stack pointer 2933 2962 // 2934 Data32 = (INT32) VmReadMem32 (VmPtr, (UINTN)VmPtr->Gpr[0]);2963 Data32 = (INT32)VmReadMem32 (VmPtr, (UINTN)VmPtr->Gpr[0]); 2935 2964 VmPtr->Gpr[0] += sizeof (UINT32); 2936 2965 // … … 2938 2967 // 2939 2968 if (OPERAND1_INDIRECT (Operands)) { 2940 VmWriteMem32 (VmPtr, (UINTN) 2969 VmWriteMem32 (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), Data32); 2941 2970 } else { 2942 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (INT64) 2971 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (INT64)Data32 + Index16; 2943 2972 } 2944 2973 } … … 2946 2975 return EFI_SUCCESS; 2947 2976 } 2948 2949 2977 2950 2978 /** … … 2966 2994 EFI_STATUS 2967 2995 ExecuteCALL ( 2968 IN VM_CONTEXT *VmPtr2969 ) 2970 { 2971 UINT8 Opcode;2972 UINT8 Operands;2973 INT32 Immed32;2974 UINT8 Size;2975 INT64 Immed64;2976 VOID *FramePtr;2996 IN VM_CONTEXT *VmPtr 2997 ) 2998 { 2999 UINT8 Opcode; 3000 UINT8 Operands; 3001 INT32 Immed32; 3002 UINT8 Size; 3003 INT64 Immed64; 3004 VOID *FramePtr; 2977 3005 2978 3006 // 2979 3007 // Get opcode and operands 2980 3008 // 2981 Opcode 2982 Operands 3009 Opcode = GETOPCODE (VmPtr); 3010 Operands = GETOPERANDS (VmPtr); 2983 3011 2984 3012 if ((Operands & OPERAND_M_NATIVE_CALL) != 0) { … … 2991 3019 // Assign these as well to avoid compiler warnings 2992 3020 // 2993 Immed64 2994 Immed32 2995 2996 FramePtr 3021 Immed64 = 0; 3022 Immed32 = 0; 3023 3024 FramePtr = VmPtr->FramePtr; 2997 3025 // 2998 3026 // Determine the instruction size, and get immediate data if present … … 3017 3045 Size = 2; 3018 3046 } 3047 3019 3048 // 3020 3049 // If it's a call to EBC, adjust the stack pointer down 16 bytes and … … 3023 3052 if ((Operands & OPERAND_M_NATIVE_CALL) == 0) { 3024 3053 VmPtr->Gpr[0] -= 8; 3025 VmWriteMemN (VmPtr, (UINTN) VmPtr->Gpr[0], (UINTN) FramePtr); 3026 VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->Gpr[0]; 3027 VmPtr->Gpr[0] -= 8; 3028 VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[0], (UINT64) (UINTN) (VmPtr->Ip + Size)); 3029 } 3054 VmWriteMemN (VmPtr, (UINTN)VmPtr->Gpr[0], (UINTN)FramePtr); 3055 VmPtr->FramePtr = (VOID *)(UINTN)VmPtr->Gpr[0]; 3056 VmPtr->Gpr[0] -= 8; 3057 VmWriteMem64 (VmPtr, (UINTN)VmPtr->Gpr[0], (UINT64)(UINTN)(VmPtr->Ip + Size)); 3058 } 3059 3030 3060 // 3031 3061 // If 64-bit data, then absolute jump only … … 3036 3066 // 3037 3067 if ((Operands & OPERAND_M_NATIVE_CALL) == 0) { 3038 VmPtr->Ip = (VMIP) (UINTN)Immed64;3068 VmPtr->Ip = (VMIP)(UINTN)Immed64; 3039 3069 } else { 3040 3070 // 3041 3071 // Call external function, get the return value, and advance the IP 3042 3072 // 3043 EbcLLCALLEX (VmPtr, (UINTN) Immed64, (UINTN)VmPtr->Gpr[0], FramePtr, Size);3073 EbcLLCALLEX (VmPtr, (UINTN)Immed64, (UINTN)VmPtr->Gpr[0], FramePtr, Size); 3044 3074 } 3045 3075 } else { … … 3050 3080 // 3051 3081 if (OPERAND1_REGNUM (Operands) != 0) { 3052 Immed64 = (UINT64) (UINTN) VmPtr->Gpr[OPERAND1_REGNUM (Operands)]; 3053 } 3082 Immed64 = (UINT64)(UINTN)VmPtr->Gpr[OPERAND1_REGNUM (Operands)]; 3083 } 3084 3054 3085 // 3055 3086 // Get final address 3056 3087 // 3057 3088 if (OPERAND1_INDIRECT (Operands)) { 3058 Immed64 = (INT64) (UINT64) (UINTN) VmReadMemN (VmPtr, (UINTN)(Immed64 + Immed32));3089 Immed64 = (INT64)(UINT64)(UINTN)VmReadMemN (VmPtr, (UINTN)(Immed64 + Immed32)); 3059 3090 } else { 3060 3091 Immed64 += Immed32; 3061 3092 } 3093 3062 3094 // 3063 3095 // Now determine if external call, and then if relative or absolute … … 3071 3103 VmPtr->Ip += Immed64 + Size; 3072 3104 } else { 3073 VmPtr->Ip = (VMIP) (UINTN)Immed64;3105 VmPtr->Ip = (VMIP)(UINTN)Immed64; 3074 3106 } 3075 3107 } else { … … 3078 3110 // 3079 3111 if ((Operands & OPERAND_M_RELATIVE_ADDR) != 0) { 3080 EbcLLCALLEX (VmPtr, (UINTN) (Immed64 + VmPtr->Ip + Size), (UINTN)VmPtr->Gpr[0], FramePtr, Size);3112 EbcLLCALLEX (VmPtr, (UINTN)(Immed64 + VmPtr->Ip + Size), (UINTN)VmPtr->Gpr[0], FramePtr, Size); 3081 3113 } else { 3082 3114 if ((VmPtr->StopFlags & STOPFLAG_BREAK_ON_CALLEX) != 0) { … … 3084 3116 } 3085 3117 3086 EbcLLCALLEX (VmPtr, (UINTN) Immed64, (UINTN)VmPtr->Gpr[0], FramePtr, Size);3118 EbcLLCALLEX (VmPtr, (UINTN)Immed64, (UINTN)VmPtr->Gpr[0], FramePtr, Size); 3087 3119 } 3088 3120 } … … 3098 3130 } 3099 3131 3100 3101 3132 /** 3102 3133 Execute the EBC RET instruction. … … 3112 3143 EFI_STATUS 3113 3144 ExecuteRET ( 3114 IN VM_CONTEXT *VmPtr 3115 ) 3116 { 3117 3145 IN VM_CONTEXT *VmPtr 3146 ) 3147 { 3118 3148 EbcDebuggerHookRETStart (VmPtr); 3119 3149 … … 3122 3152 // flag and return 3123 3153 // 3124 if (VmPtr->StackRetAddr == (UINT64) 3154 if (VmPtr->StackRetAddr == (UINT64)VmPtr->Gpr[0]) { 3125 3155 VmPtr->StopFlags |= STOPFLAG_APP_DONE; 3126 3156 } else { … … 3129 3159 // to it 3130 3160 // 3131 if (!IS_ALIGNED ((UINTN) 3161 if (!IS_ALIGNED ((UINTN)VmPtr->Gpr[0], sizeof (UINT16))) { 3132 3162 EbcDebugSignalException ( 3133 3163 EXCEPT_EBC_ALIGNMENT_CHECK, … … 3136 3166 ); 3137 3167 } 3168 3138 3169 // 3139 3170 // Restore the IP and frame pointer from the stack 3140 3171 // 3141 VmPtr->Ip = (VMIP) (UINTN) VmReadMem64 (VmPtr, (UINTN) VmPtr->Gpr[0]); 3142 VmPtr->Gpr[0] += 8; 3143 VmPtr->FramePtr = (VOID *) VmReadMemN (VmPtr, (UINTN) VmPtr->Gpr[0]); 3144 VmPtr->Gpr[0] += 8; 3145 } 3146 3172 VmPtr->Ip = (VMIP)(UINTN)VmReadMem64 (VmPtr, (UINTN)VmPtr->Gpr[0]); 3173 VmPtr->Gpr[0] += 8; 3174 VmPtr->FramePtr = (VOID *)VmReadMemN (VmPtr, (UINTN)VmPtr->Gpr[0]); 3175 VmPtr->Gpr[0] += 8; 3176 } 3147 3177 3148 3178 EbcDebuggerHookRETEnd (VmPtr); … … 3150 3180 return EFI_SUCCESS; 3151 3181 } 3152 3153 3182 3154 3183 /** … … 3166 3195 EFI_STATUS 3167 3196 ExecuteCMP ( 3168 IN VM_CONTEXT *VmPtr3197 IN VM_CONTEXT *VmPtr 3169 3198 ) 3170 3199 { … … 3180 3209 // Get opcode and operands 3181 3210 // 3182 Opcode 3183 Operands 3211 Opcode = GETOPCODE (VmPtr); 3212 Operands = GETOPERANDS (VmPtr); 3184 3213 // 3185 3214 // Get the register data we're going to compare to … … 3201 3230 Size = 2; 3202 3231 } 3232 3203 3233 // 3204 3234 // Now get Op2 … … 3206 3236 if (OPERAND2_INDIRECT (Operands)) { 3207 3237 if ((Opcode & OPCODE_M_64BIT) != 0) { 3208 Op2 = (INT64) VmReadMem64 (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16));3238 Op2 = (INT64)VmReadMem64 (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16)); 3209 3239 } else { 3210 3240 // 3211 3241 // 32-bit operations. 0-extend the values for all cases. 3212 3242 // 3213 Op2 = (INT64) (UINT64) ((UINT32) VmReadMem32 (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16)));3243 Op2 = (INT64)(UINT64)((UINT32)VmReadMem32 (VmPtr, (UINTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16))); 3214 3244 } 3215 3245 } else { 3216 3246 Op2 = VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16; 3217 3247 } 3248 3218 3249 // 3219 3250 // Now do the compare … … 3225 3256 // 3226 3257 switch (Opcode & OPCODE_M_OPCODE) { 3227 case OPCODE_CMPEQ: 3228 if (Op1 == Op2) { 3229 Flag = 1; 3230 } 3231 break; 3232 3233 case OPCODE_CMPLTE: 3234 if (Op1 <= Op2) { 3235 Flag = 1; 3236 } 3237 break; 3238 3239 case OPCODE_CMPGTE: 3240 if (Op1 >= Op2) { 3241 Flag = 1; 3242 } 3243 break; 3244 3245 case OPCODE_CMPULTE: 3246 if ((UINT64) Op1 <= (UINT64) Op2) { 3247 Flag = 1; 3248 } 3249 break; 3250 3251 case OPCODE_CMPUGTE: 3252 if ((UINT64) Op1 >= (UINT64) Op2) { 3253 Flag = 1; 3254 } 3255 break; 3256 3257 default: 3258 ASSERT (0); 3258 case OPCODE_CMPEQ: 3259 if (Op1 == Op2) { 3260 Flag = 1; 3261 } 3262 3263 break; 3264 3265 case OPCODE_CMPLTE: 3266 if (Op1 <= Op2) { 3267 Flag = 1; 3268 } 3269 3270 break; 3271 3272 case OPCODE_CMPGTE: 3273 if (Op1 >= Op2) { 3274 Flag = 1; 3275 } 3276 3277 break; 3278 3279 case OPCODE_CMPULTE: 3280 if ((UINT64)Op1 <= (UINT64)Op2) { 3281 Flag = 1; 3282 } 3283 3284 break; 3285 3286 case OPCODE_CMPUGTE: 3287 if ((UINT64)Op1 >= (UINT64)Op2) { 3288 Flag = 1; 3289 } 3290 3291 break; 3292 3293 default: 3294 ASSERT (0); 3259 3295 } 3260 3296 } else { … … 3263 3299 // 3264 3300 switch (Opcode & OPCODE_M_OPCODE) { 3265 case OPCODE_CMPEQ: 3266 if ((INT32) Op1 == (INT32) Op2) { 3267 Flag = 1; 3268 } 3269 break; 3270 3271 case OPCODE_CMPLTE: 3272 if ((INT32) Op1 <= (INT32) Op2) { 3273 Flag = 1; 3274 } 3275 break; 3276 3277 case OPCODE_CMPGTE: 3278 if ((INT32) Op1 >= (INT32) Op2) { 3279 Flag = 1; 3280 } 3281 break; 3282 3283 case OPCODE_CMPULTE: 3284 if ((UINT32) Op1 <= (UINT32) Op2) { 3285 Flag = 1; 3286 } 3287 break; 3288 3289 case OPCODE_CMPUGTE: 3290 if ((UINT32) Op1 >= (UINT32) Op2) { 3291 Flag = 1; 3292 } 3293 break; 3294 3295 default: 3296 ASSERT (0); 3297 } 3298 } 3301 case OPCODE_CMPEQ: 3302 if ((INT32)Op1 == (INT32)Op2) { 3303 Flag = 1; 3304 } 3305 3306 break; 3307 3308 case OPCODE_CMPLTE: 3309 if ((INT32)Op1 <= (INT32)Op2) { 3310 Flag = 1; 3311 } 3312 3313 break; 3314 3315 case OPCODE_CMPGTE: 3316 if ((INT32)Op1 >= (INT32)Op2) { 3317 Flag = 1; 3318 } 3319 3320 break; 3321 3322 case OPCODE_CMPULTE: 3323 if ((UINT32)Op1 <= (UINT32)Op2) { 3324 Flag = 1; 3325 } 3326 3327 break; 3328 3329 case OPCODE_CMPUGTE: 3330 if ((UINT32)Op1 >= (UINT32)Op2) { 3331 Flag = 1; 3332 } 3333 3334 break; 3335 3336 default: 3337 ASSERT (0); 3338 } 3339 } 3340 3299 3341 // 3300 3342 // Now set the flag accordingly for the comparison … … 3305 3347 VMFLAG_CLEAR (VmPtr, (UINT64)VMFLAGS_CC); 3306 3348 } 3349 3307 3350 // 3308 3351 // Advance the IP … … 3312 3355 } 3313 3356 3314 3315 3357 /** 3316 3358 Execute the EBC CMPI instruction … … 3327 3369 EFI_STATUS 3328 3370 ExecuteCMPI ( 3329 IN VM_CONTEXT *VmPtr3371 IN VM_CONTEXT *VmPtr 3330 3372 ) 3331 3373 { … … 3341 3383 // Get opcode and operands 3342 3384 // 3343 Opcode 3344 Operands 3385 Opcode = GETOPCODE (VmPtr); 3386 Operands = GETOPERANDS (VmPtr); 3345 3387 3346 3388 // … … 3350 3392 if ((Operands & OPERAND_M_CMPI_INDEX) != 0) { 3351 3393 Index16 = VmReadIndex16 (VmPtr, 2); 3352 Size += 2;3394 Size += 2; 3353 3395 } else { 3354 3396 Index16 = 0; 3355 3397 } 3398 3356 3399 // 3357 3400 // Get operand1 data we're going to compare to 3358 3401 // 3359 Op1 = (INT64) 3402 Op1 = (INT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)]; 3360 3403 if (OPERAND1_INDIRECT (Operands)) { 3361 3404 // … … 3363 3406 // 3364 3407 if ((Opcode & OPCODE_M_CMPI64) != 0) { 3365 Op1 = (INT64) VmReadMem64 (VmPtr, (UINTN)Op1 + Index16);3408 Op1 = (INT64)VmReadMem64 (VmPtr, (UINTN)Op1 + Index16); 3366 3409 } else { 3367 Op1 = (INT64) VmReadMem32 (VmPtr, (UINTN)Op1 + Index16);3410 Op1 = (INT64)VmReadMem32 (VmPtr, (UINTN)Op1 + Index16); 3368 3411 } 3369 3412 } else { … … 3382 3425 } 3383 3426 } 3427 3384 3428 // 3385 3429 // Get immediate data -- 16- or 32-bit sign extended 3386 3430 // 3387 3431 if ((Opcode & OPCODE_M_CMPI32_DATA) != 0) { 3388 Op2 = (INT64)VmReadImmed32 (VmPtr, Size);3432 Op2 = (INT64)VmReadImmed32 (VmPtr, Size); 3389 3433 Size += 4; 3390 3434 } else { … … 3392 3436 // 16-bit immediate data. Sign extend always. 3393 3437 // 3394 Op2 = (INT64) ((INT16)VmReadImmed16 (VmPtr, Size));3438 Op2 = (INT64)((INT16)VmReadImmed16 (VmPtr, Size)); 3395 3439 Size += 2; 3396 3440 } 3441 3397 3442 // 3398 3443 // Now do the compare … … 3404 3449 // 3405 3450 switch (Opcode & OPCODE_M_OPCODE) { 3406 case OPCODE_CMPIEQ: 3407 if (Op1 == (INT64) Op2) { 3408 Flag = 1; 3409 } 3410 break; 3411 3412 case OPCODE_CMPILTE: 3413 if (Op1 <= (INT64) Op2) { 3414 Flag = 1; 3415 } 3416 break; 3417 3418 case OPCODE_CMPIGTE: 3419 if (Op1 >= (INT64) Op2) { 3420 Flag = 1; 3421 } 3422 break; 3423 3424 case OPCODE_CMPIULTE: 3425 if ((UINT64) Op1 <= (UINT64) ((UINT32) Op2)) { 3426 Flag = 1; 3427 } 3428 break; 3429 3430 case OPCODE_CMPIUGTE: 3431 if ((UINT64) Op1 >= (UINT64) ((UINT32) Op2)) { 3432 Flag = 1; 3433 } 3434 break; 3435 3436 default: 3437 ASSERT (0); 3451 case OPCODE_CMPIEQ: 3452 if (Op1 == (INT64)Op2) { 3453 Flag = 1; 3454 } 3455 3456 break; 3457 3458 case OPCODE_CMPILTE: 3459 if (Op1 <= (INT64)Op2) { 3460 Flag = 1; 3461 } 3462 3463 break; 3464 3465 case OPCODE_CMPIGTE: 3466 if (Op1 >= (INT64)Op2) { 3467 Flag = 1; 3468 } 3469 3470 break; 3471 3472 case OPCODE_CMPIULTE: 3473 if ((UINT64)Op1 <= (UINT64)((UINT32)Op2)) { 3474 Flag = 1; 3475 } 3476 3477 break; 3478 3479 case OPCODE_CMPIUGTE: 3480 if ((UINT64)Op1 >= (UINT64)((UINT32)Op2)) { 3481 Flag = 1; 3482 } 3483 3484 break; 3485 3486 default: 3487 ASSERT (0); 3438 3488 } 3439 3489 } else { … … 3442 3492 // 3443 3493 switch (Opcode & OPCODE_M_OPCODE) { 3444 case OPCODE_CMPIEQ: 3445 if ((INT32) Op1 == Op2) { 3446 Flag = 1; 3447 } 3448 break; 3449 3450 case OPCODE_CMPILTE: 3451 if ((INT32) Op1 <= Op2) { 3452 Flag = 1; 3453 } 3454 break; 3455 3456 case OPCODE_CMPIGTE: 3457 if ((INT32) Op1 >= Op2) { 3458 Flag = 1; 3459 } 3460 break; 3461 3462 case OPCODE_CMPIULTE: 3463 if ((UINT32) Op1 <= (UINT32) Op2) { 3464 Flag = 1; 3465 } 3466 break; 3467 3468 case OPCODE_CMPIUGTE: 3469 if ((UINT32) Op1 >= (UINT32) Op2) { 3470 Flag = 1; 3471 } 3472 break; 3473 3474 default: 3475 ASSERT (0); 3476 } 3477 } 3494 case OPCODE_CMPIEQ: 3495 if ((INT32)Op1 == Op2) { 3496 Flag = 1; 3497 } 3498 3499 break; 3500 3501 case OPCODE_CMPILTE: 3502 if ((INT32)Op1 <= Op2) { 3503 Flag = 1; 3504 } 3505 3506 break; 3507 3508 case OPCODE_CMPIGTE: 3509 if ((INT32)Op1 >= Op2) { 3510 Flag = 1; 3511 } 3512 3513 break; 3514 3515 case OPCODE_CMPIULTE: 3516 if ((UINT32)Op1 <= (UINT32)Op2) { 3517 Flag = 1; 3518 } 3519 3520 break; 3521 3522 case OPCODE_CMPIUGTE: 3523 if ((UINT32)Op1 >= (UINT32)Op2) { 3524 Flag = 1; 3525 } 3526 3527 break; 3528 3529 default: 3530 ASSERT (0); 3531 } 3532 } 3533 3478 3534 // 3479 3535 // Now set the flag accordingly for the comparison … … 3484 3540 VMFLAG_CLEAR (VmPtr, (UINT64)VMFLAGS_CC); 3485 3541 } 3542 3486 3543 // 3487 3544 // Advance the IP … … 3491 3548 } 3492 3549 3493 3494 3550 /** 3495 3551 Execute the EBC NOT instruction.s … … 3507 3563 UINT64 3508 3564 ExecuteNOT ( 3509 IN VM_CONTEXT 3510 IN UINT64 3511 IN UINT64 3565 IN VM_CONTEXT *VmPtr, 3566 IN UINT64 Op1, 3567 IN UINT64 Op2 3512 3568 ) 3513 3569 { 3514 3570 return ~Op2; 3515 3571 } 3516 3517 3572 3518 3573 /** … … 3531 3586 UINT64 3532 3587 ExecuteNEG ( 3533 IN VM_CONTEXT 3534 IN UINT64 3535 IN UINT64 3588 IN VM_CONTEXT *VmPtr, 3589 IN UINT64 Op1, 3590 IN UINT64 Op2 3536 3591 ) 3537 3592 { 3538 3593 return ~Op2 + 1; 3539 3594 } 3540 3541 3595 3542 3596 /** … … 3555 3609 UINT64 3556 3610 ExecuteADD ( 3557 IN VM_CONTEXT 3558 IN UINT64 3559 IN UINT64 3611 IN VM_CONTEXT *VmPtr, 3612 IN UINT64 Op1, 3613 IN UINT64 Op2 3560 3614 ) 3561 3615 { 3562 3616 return Op1 + Op2; 3563 3617 } 3564 3565 3618 3566 3619 /** … … 3579 3632 UINT64 3580 3633 ExecuteSUB ( 3581 IN VM_CONTEXT 3582 IN UINT64 3583 IN UINT64 3634 IN VM_CONTEXT *VmPtr, 3635 IN UINT64 Op1, 3636 IN UINT64 Op2 3584 3637 ) 3585 3638 { 3586 3639 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) { 3587 return (UINT64) ((INT64) ((INT64) Op1 - (INT64) Op2)); 3588 } else { 3589 return (UINT64) ((INT64) ((INT32) ((INT32) Op1 - (INT32) Op2))); 3590 } 3591 } 3592 3640 return (UINT64)((INT64)((INT64)Op1 - (INT64)Op2)); 3641 } else { 3642 return (UINT64)((INT64)((INT32)((INT32)Op1 - (INT32)Op2))); 3643 } 3644 } 3593 3645 3594 3646 /** … … 3607 3659 UINT64 3608 3660 ExecuteMUL ( 3609 IN VM_CONTEXT 3610 IN UINT64 3611 IN UINT64 3661 IN VM_CONTEXT *VmPtr, 3662 IN UINT64 Op1, 3663 IN UINT64 Op2 3612 3664 ) 3613 3665 { … … 3615 3667 return MultS64x64 ((INT64)Op1, (INT64)Op2); 3616 3668 } else { 3617 return (UINT64) ((INT64) ((INT32) ((INT32) Op1 * (INT32) Op2))); 3618 } 3619 } 3620 3669 return (UINT64)((INT64)((INT32)((INT32)Op1 * (INT32)Op2))); 3670 } 3671 } 3621 3672 3622 3673 /** … … 3635 3686 UINT64 3636 3687 ExecuteMULU ( 3637 IN VM_CONTEXT 3638 IN UINT64 3639 IN UINT64 3688 IN VM_CONTEXT *VmPtr, 3689 IN UINT64 Op1, 3690 IN UINT64 Op2 3640 3691 ) 3641 3692 { … … 3643 3694 return MultU64x64 (Op1, Op2); 3644 3695 } else { 3645 return (UINT64) ((UINT32) ((UINT32) Op1 * (UINT32) Op2)); 3646 } 3647 } 3648 3696 return (UINT64)((UINT32)((UINT32)Op1 * (UINT32)Op2)); 3697 } 3698 } 3649 3699 3650 3700 /** … … 3663 3713 UINT64 3664 3714 ExecuteDIV ( 3665 IN VM_CONTEXT 3666 IN UINT64 3667 IN UINT64 3668 ) 3669 { 3670 INT64 3715 IN VM_CONTEXT *VmPtr, 3716 IN UINT64 Op1, 3717 IN UINT64 Op2 3718 ) 3719 { 3720 INT64 Remainder; 3671 3721 3672 3722 // … … 3683 3733 } else { 3684 3734 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) { 3685 return (UINT64) 3735 return (UINT64)(DivS64x64Remainder (Op1, Op2, &Remainder)); 3686 3736 } else { 3687 return (UINT64) ((INT64) ((INT32) Op1 / (INT32) Op2)); 3688 } 3689 } 3690 } 3691 3737 return (UINT64)((INT64)((INT32)Op1 / (INT32)Op2)); 3738 } 3739 } 3740 } 3692 3741 3693 3742 /** … … 3706 3755 UINT64 3707 3756 ExecuteDIVU ( 3708 IN VM_CONTEXT 3709 IN UINT64 3710 IN UINT64 3757 IN VM_CONTEXT *VmPtr, 3758 IN UINT64 Op1, 3759 IN UINT64 Op2 3711 3760 ) 3712 3761 { … … 3728 3777 // 3729 3778 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) { 3730 return (UINT64) 3779 return (UINT64)(DivU64x64Remainder (Op1, Op2, &Remainder)); 3731 3780 } else { 3732 return (UINT64) ((UINT32) Op1 / (UINT32) Op2); 3733 } 3734 } 3735 } 3736 3781 return (UINT64)((UINT32)Op1 / (UINT32)Op2); 3782 } 3783 } 3784 } 3737 3785 3738 3786 /** … … 3751 3799 UINT64 3752 3800 ExecuteMOD ( 3753 IN VM_CONTEXT 3754 IN UINT64 3755 IN UINT64 3756 ) 3757 { 3758 INT64 3801 IN VM_CONTEXT *VmPtr, 3802 IN UINT64 Op1, 3803 IN UINT64 Op2 3804 ) 3805 { 3806 INT64 Remainder; 3759 3807 3760 3808 // … … 3774 3822 } 3775 3823 3776 3777 3824 /** 3778 3825 Execute the EBC MODU instruction. … … 3790 3837 UINT64 3791 3838 ExecuteMODU ( 3792 IN VM_CONTEXT 3793 IN UINT64 3794 IN UINT64 3839 IN VM_CONTEXT *VmPtr, 3840 IN UINT64 Op1, 3841 IN UINT64 Op2 3795 3842 ) 3796 3843 { … … 3813 3860 } 3814 3861 3815 3816 3862 /** 3817 3863 Execute the EBC AND instruction. … … 3829 3875 UINT64 3830 3876 ExecuteAND ( 3831 IN VM_CONTEXT 3832 IN UINT64 3833 IN UINT64 3877 IN VM_CONTEXT *VmPtr, 3878 IN UINT64 Op1, 3879 IN UINT64 Op2 3834 3880 ) 3835 3881 { 3836 3882 return Op1 & Op2; 3837 3883 } 3838 3839 3884 3840 3885 /** … … 3853 3898 UINT64 3854 3899 ExecuteOR ( 3855 IN VM_CONTEXT 3856 IN UINT64 3857 IN UINT64 3900 IN VM_CONTEXT *VmPtr, 3901 IN UINT64 Op1, 3902 IN UINT64 Op2 3858 3903 ) 3859 3904 { 3860 3905 return Op1 | Op2; 3861 3906 } 3862 3863 3907 3864 3908 /** … … 3877 3921 UINT64 3878 3922 ExecuteXOR ( 3879 IN VM_CONTEXT 3880 IN UINT64 3881 IN UINT64 3923 IN VM_CONTEXT *VmPtr, 3924 IN UINT64 Op1, 3925 IN UINT64 Op2 3882 3926 ) 3883 3927 { 3884 3928 return Op1 ^ Op2; 3885 3929 } 3886 3887 3930 3888 3931 /** … … 3901 3944 UINT64 3902 3945 ExecuteSHL ( 3903 IN VM_CONTEXT 3904 IN UINT64 3905 IN UINT64 3946 IN VM_CONTEXT *VmPtr, 3947 IN UINT64 Op1, 3948 IN UINT64 Op2 3906 3949 ) 3907 3950 { … … 3909 3952 return LShiftU64 (Op1, (UINTN)Op2); 3910 3953 } else { 3911 return (UINT64) ((UINT32) ((UINT32) Op1 << (UINT32) Op2)); 3912 } 3913 } 3914 3954 return (UINT64)((UINT32)((UINT32)Op1 << (UINT32)Op2)); 3955 } 3956 } 3915 3957 3916 3958 /** … … 3929 3971 UINT64 3930 3972 ExecuteSHR ( 3931 IN VM_CONTEXT 3932 IN UINT64 3933 IN UINT64 3973 IN VM_CONTEXT *VmPtr, 3974 IN UINT64 Op1, 3975 IN UINT64 Op2 3934 3976 ) 3935 3977 { … … 3937 3979 return RShiftU64 (Op1, (UINTN)Op2); 3938 3980 } else { 3939 return (UINT64) ((UINT32) Op1 >> (UINT32) Op2); 3940 } 3941 } 3942 3981 return (UINT64)((UINT32)Op1 >> (UINT32)Op2); 3982 } 3983 } 3943 3984 3944 3985 /** … … 3957 3998 UINT64 3958 3999 ExecuteASHR ( 3959 IN VM_CONTEXT 3960 IN UINT64 3961 IN UINT64 4000 IN VM_CONTEXT *VmPtr, 4001 IN UINT64 Op1, 4002 IN UINT64 Op2 3962 4003 ) 3963 4004 { … … 3965 4006 return ARShiftU64 (Op1, (UINTN)Op2); 3966 4007 } else { 3967 return (UINT64) ((INT64) ((INT32) Op1 >> (UINT32) Op2)); 3968 } 3969 } 3970 4008 return (UINT64)((INT64)((INT32)Op1 >> (UINT32)Op2)); 4009 } 4010 } 3971 4011 3972 4012 /** … … 3985 4025 UINT64 3986 4026 ExecuteEXTNDB ( 3987 IN VM_CONTEXT *VmPtr, 3988 IN UINT64 Op1, 3989 IN UINT64 Op2 3990 ) 3991 { 3992 INT8 Data8; 3993 INT64 Data64; 4027 IN VM_CONTEXT *VmPtr, 4028 IN UINT64 Op1, 4029 IN UINT64 Op2 4030 ) 4031 { 4032 INT8 Data8; 4033 INT64 Data64; 4034 3994 4035 // 3995 4036 // Convert to byte, then return as 64-bit signed value to let compiler 3996 4037 // sign-extend the value 3997 4038 // 3998 Data8 = (INT8) Op2; 3999 Data64 = (INT64) Data8; 4000 4001 return (UINT64) Data64; 4002 } 4003 4039 Data8 = (INT8)Op2; 4040 Data64 = (INT64)Data8; 4041 4042 return (UINT64)Data64; 4043 } 4004 4044 4005 4045 /** … … 4018 4058 UINT64 4019 4059 ExecuteEXTNDW ( 4020 IN VM_CONTEXT *VmPtr, 4021 IN UINT64 Op1, 4022 IN UINT64 Op2 4023 ) 4024 { 4025 INT16 Data16; 4026 INT64 Data64; 4060 IN VM_CONTEXT *VmPtr, 4061 IN UINT64 Op1, 4062 IN UINT64 Op2 4063 ) 4064 { 4065 INT16 Data16; 4066 INT64 Data64; 4067 4027 4068 // 4028 4069 // Convert to word, then return as 64-bit signed value to let compiler 4029 4070 // sign-extend the value 4030 4071 // 4031 Data16 = (INT16) Op2; 4032 Data64 = (INT64) Data16; 4033 4034 return (UINT64) Data64; 4035 } 4072 Data16 = (INT16)Op2; 4073 Data64 = (INT64)Data16; 4074 4075 return (UINT64)Data64; 4076 } 4077 4036 4078 // 4037 4079 // Execute the EBC EXTNDD instruction. … … 4058 4100 UINT64 4059 4101 ExecuteEXTNDD ( 4060 IN VM_CONTEXT *VmPtr, 4061 IN UINT64 Op1, 4062 IN UINT64 Op2 4063 ) 4064 { 4065 INT32 Data32; 4066 INT64 Data64; 4102 IN VM_CONTEXT *VmPtr, 4103 IN UINT64 Op1, 4104 IN UINT64 Op2 4105 ) 4106 { 4107 INT32 Data32; 4108 INT64 Data64; 4109 4067 4110 // 4068 4111 // Convert to 32-bit value, then return as 64-bit signed value to let compiler 4069 4112 // sign-extend the value 4070 4113 // 4071 Data32 = (INT32) Op2; 4072 Data64 = (INT64) Data32; 4073 4074 return (UINT64) Data64; 4075 } 4076 4114 Data32 = (INT32)Op2; 4115 Data64 = (INT64)Data32; 4116 4117 return (UINT64)Data64; 4118 } 4077 4119 4078 4120 /** … … 4095 4137 EFI_STATUS 4096 4138 ExecuteSignedDataManip ( 4097 IN VM_CONTEXT 4139 IN VM_CONTEXT *VmPtr 4098 4140 ) 4099 4141 { … … 4104 4146 return ExecuteDataManip (VmPtr, TRUE); 4105 4147 } 4106 4107 4148 4108 4149 /** … … 4125 4166 EFI_STATUS 4126 4167 ExecuteUnsignedDataManip ( 4127 IN VM_CONTEXT 4168 IN VM_CONTEXT *VmPtr 4128 4169 ) 4129 4170 { … … 4134 4175 return ExecuteDataManip (VmPtr, FALSE); 4135 4176 } 4136 4137 4177 4138 4178 /** … … 4156 4196 EFI_STATUS 4157 4197 ExecuteDataManip ( 4158 IN VM_CONTEXT 4159 IN BOOLEAN 4198 IN VM_CONTEXT *VmPtr, 4199 IN BOOLEAN IsSignedOp 4160 4200 ) 4161 4201 { … … 4171 4211 // Get opcode and operands 4172 4212 // 4173 Opcode 4174 Operands 4213 Opcode = GETOPCODE (VmPtr); 4214 Operands = GETOPERANDS (VmPtr); 4175 4215 4176 4216 // … … 4192 4232 Size = 2; 4193 4233 } 4234 4194 4235 // 4195 4236 // Now get operand2 (source). It's of format {@}R2 {Index16|Immed16} 4196 4237 // 4197 Op2 = (UINT64) 4238 Op2 = (UINT64)VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16; 4198 4239 if (OPERAND2_INDIRECT (Operands)) { 4199 4240 // … … 4201 4242 // 4202 4243 if ((Opcode & DATAMANIP_M_64) != 0) { 4203 Op2 = VmReadMem64 (VmPtr, (UINTN) 4244 Op2 = VmReadMem64 (VmPtr, (UINTN)Op2); 4204 4245 } else { 4205 4246 // … … 4207 4248 // 4208 4249 if (IsSignedOp) { 4209 Op2 = (UINT64) (INT64) ((INT32) VmReadMem32 (VmPtr, (UINTN)Op2));4250 Op2 = (UINT64)(INT64)((INT32)VmReadMem32 (VmPtr, (UINTN)Op2)); 4210 4251 } else { 4211 Op2 = (UINT64) VmReadMem32 (VmPtr, (UINTN)Op2);4252 Op2 = (UINT64)VmReadMem32 (VmPtr, (UINTN)Op2); 4212 4253 } 4213 4254 } … … 4215 4256 if ((Opcode & DATAMANIP_M_64) == 0) { 4216 4257 if (IsSignedOp) { 4217 Op2 = (UINT64) (INT64) ((INT32)Op2);4258 Op2 = (UINT64)(INT64)((INT32)Op2); 4218 4259 } else { 4219 Op2 = (UINT64) ((UINT32)Op2);4260 Op2 = (UINT64)((UINT32)Op2); 4220 4261 } 4221 4262 } 4222 4263 } 4264 4223 4265 // 4224 4266 // Get operand1 (destination and sometimes also an actual operand) 4225 4267 // of form {@}R1 4226 4268 // 4227 Op1 = (UINT64) 4269 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)]; 4228 4270 if (OPERAND1_INDIRECT (Operands)) { 4229 4271 if ((Opcode & DATAMANIP_M_64) != 0) { 4230 Op1 = VmReadMem64 (VmPtr, (UINTN) 4272 Op1 = VmReadMem64 (VmPtr, (UINTN)Op1); 4231 4273 } else { 4232 4274 if (IsSignedOp) { 4233 Op1 = (UINT64) (INT64) ((INT32) VmReadMem32 (VmPtr, (UINTN)Op1));4275 Op1 = (UINT64)(INT64)((INT32)VmReadMem32 (VmPtr, (UINTN)Op1)); 4234 4276 } else { 4235 Op1 = (UINT64) VmReadMem32 (VmPtr, (UINTN)Op1);4277 Op1 = (UINT64)VmReadMem32 (VmPtr, (UINTN)Op1); 4236 4278 } 4237 4279 } … … 4239 4281 if ((Opcode & DATAMANIP_M_64) == 0) { 4240 4282 if (IsSignedOp) { 4241 Op1 = (UINT64) (INT64) ((INT32)Op1);4283 Op1 = (UINT64)(INT64)((INT32)Op1); 4242 4284 } else { 4243 Op1 = (UINT64) ((UINT32)Op1);4285 Op1 = (UINT64)((UINT32)Op1); 4244 4286 } 4245 4287 } 4246 4288 } 4289 4247 4290 // 4248 4291 // Dispatch to the computation function … … 4250 4293 DataManipDispatchTableIndex = (Opcode & OPCODE_M_OPCODE) - OPCODE_NOT; 4251 4294 if ((DataManipDispatchTableIndex < 0) || 4252 (DataManipDispatchTableIndex >= ARRAY_SIZE (mDataManipDispatchTable))) { 4295 (DataManipDispatchTableIndex >= ARRAY_SIZE (mDataManipDispatchTable))) 4296 { 4253 4297 EbcDebugSignalException ( 4254 4298 EXCEPT_EBC_INVALID_OPCODE, … … 4264 4308 Op2 = mDataManipDispatchTable[DataManipDispatchTableIndex](VmPtr, Op1, Op2); 4265 4309 } 4310 4266 4311 // 4267 4312 // Write back the result. 4268 4313 // 4269 4314 if (OPERAND1_INDIRECT (Operands)) { 4270 Op1 = (UINT64) 4315 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)]; 4271 4316 if ((Opcode & DATAMANIP_M_64) != 0) { 4272 VmWriteMem64 (VmPtr, (UINTN) 4317 VmWriteMem64 (VmPtr, (UINTN)Op1, Op2); 4273 4318 } else { 4274 VmWriteMem32 (VmPtr, (UINTN) Op1, (UINT32)Op2);4319 VmWriteMem32 (VmPtr, (UINTN)Op1, (UINT32)Op2); 4275 4320 } 4276 4321 } else { … … 4284 4329 } 4285 4330 } 4331 4286 4332 // 4287 4333 // Advance the instruction pointer … … 4291 4337 } 4292 4338 4293 4294 4339 /** 4295 4340 Execute the EBC LOADSP instruction. … … 4306 4351 EFI_STATUS 4307 4352 ExecuteLOADSP ( 4308 IN VM_CONTEXT *VmPtr4309 ) 4310 { 4311 UINT8 Operands;4353 IN VM_CONTEXT *VmPtr 4354 ) 4355 { 4356 UINT8 Operands; 4312 4357 4313 4358 // … … 4320 4365 // 4321 4366 switch (OPERAND1_REGNUM (Operands)) { 4322 //4323 // Set flags4324 //4325 case 0:4326 //4327 // Spec states that this instruction will not modify reserved bits in4328 // the flags register.4329 //4330 VmPtr->Flags = (VmPtr->Flags &~VMFLAGS_ALL_VALID) | (VmPtr->Gpr[OPERAND2_REGNUM (Operands)] & VMFLAGS_ALL_VALID);4331 break;4332 4333 default:4334 EbcDebugSignalException (4335 EXCEPT_EBC_INSTRUCTION_ENCODING,4336 EXCEPTION_FLAG_WARNING,4337 VmPtr4338 );4339 VmPtr->Ip += 2;4340 return EFI_UNSUPPORTED;4367 // 4368 // Set flags 4369 // 4370 case 0: 4371 // 4372 // Spec states that this instruction will not modify reserved bits in 4373 // the flags register. 4374 // 4375 VmPtr->Flags = (VmPtr->Flags &~VMFLAGS_ALL_VALID) | (VmPtr->Gpr[OPERAND2_REGNUM (Operands)] & VMFLAGS_ALL_VALID); 4376 break; 4377 4378 default: 4379 EbcDebugSignalException ( 4380 EXCEPT_EBC_INSTRUCTION_ENCODING, 4381 EXCEPTION_FLAG_WARNING, 4382 VmPtr 4383 ); 4384 VmPtr->Ip += 2; 4385 return EFI_UNSUPPORTED; 4341 4386 } 4342 4387 … … 4345 4390 } 4346 4391 4347 4348 4392 /** 4349 4393 Execute the EBC STORESP instruction. … … 4360 4404 EFI_STATUS 4361 4405 ExecuteSTORESP ( 4362 IN VM_CONTEXT *VmPtr4363 ) 4364 { 4365 UINT8 Operands;4406 IN VM_CONTEXT *VmPtr 4407 ) 4408 { 4409 UINT8 Operands; 4366 4410 4367 4411 // … … 4374 4418 // 4375 4419 switch (OPERAND2_REGNUM (Operands)) { 4376 //4377 // Get flags4378 //4379 case 0:4380 //4381 // Retrieve the value in the flags register, then clear reserved bits4382 //4383 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (UINT64)(VmPtr->Flags & VMFLAGS_ALL_VALID);4384 break;4385 4386 //4387 // Get IP -- address of following instruction4388 //4389 case 1:4390 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (UINT64) (UINTN)VmPtr->Ip + 2;4391 break;4392 4393 default:4394 EbcDebugSignalException (4395 EXCEPT_EBC_INSTRUCTION_ENCODING,4396 EXCEPTION_FLAG_WARNING,4397 VmPtr4398 );4399 VmPtr->Ip += 2;4400 return EFI_UNSUPPORTED;4401 break;4420 // 4421 // Get flags 4422 // 4423 case 0: 4424 // 4425 // Retrieve the value in the flags register, then clear reserved bits 4426 // 4427 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (UINT64)(VmPtr->Flags & VMFLAGS_ALL_VALID); 4428 break; 4429 4430 // 4431 // Get IP -- address of following instruction 4432 // 4433 case 1: 4434 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (UINT64)(UINTN)VmPtr->Ip + 2; 4435 break; 4436 4437 default: 4438 EbcDebugSignalException ( 4439 EXCEPT_EBC_INSTRUCTION_ENCODING, 4440 EXCEPTION_FLAG_WARNING, 4441 VmPtr 4442 ); 4443 VmPtr->Ip += 2; 4444 return EFI_UNSUPPORTED; 4445 break; 4402 4446 } 4403 4447 … … 4405 4449 return EFI_SUCCESS; 4406 4450 } 4407 4408 4451 4409 4452 /** … … 4431 4474 INT16 4432 4475 VmReadIndex16 ( 4433 IN VM_CONTEXT 4434 IN UINT32 4476 IN VM_CONTEXT *VmPtr, 4477 IN UINT32 CodeOffset 4435 4478 ) 4436 4479 { … … 4450 4493 // Get the mask for NaturalUnits. First get the number of bits from the index. 4451 4494 // 4452 NBits = (INT16) 4495 NBits = (INT16)((Index & 0x7000) >> 12); 4453 4496 4454 4497 // … … 4460 4503 // Now using the number of bits, create a mask. 4461 4504 // 4462 Mask = (INT16) ((INT16)~0 << NBits);4505 Mask = (INT16)((INT16) ~0 << NBits); 4463 4506 4464 4507 // 4465 4508 // Now using the mask, extract NaturalUnits from the lower bits of the index. 4466 4509 // 4467 NaturalUnits = (INT16) 4510 NaturalUnits = (INT16)(Index &~Mask); 4468 4511 4469 4512 // 4470 4513 // Now compute ConstUnits 4471 4514 // 4472 ConstUnits = (INT16)(((Index &~0xF000) & Mask) >> NBits);4473 4474 Offset = (INT16)(NaturalUnits * sizeof (UINTN) + ConstUnits);4515 ConstUnits = (INT16)(((Index &~0xF000) & Mask) >> NBits); 4516 4517 Offset = (INT16)(NaturalUnits * sizeof (UINTN) + ConstUnits); 4475 4518 4476 4519 // … … 4483 4526 // Offset = -1 * Offset; 4484 4527 // 4485 Offset = (INT16) ((INT32)Offset * -1);4528 Offset = (INT16)((INT32)Offset * -1); 4486 4529 } 4487 4530 4488 4531 return Offset; 4489 4532 } 4490 4491 4533 4492 4534 /** … … 4502 4544 INT32 4503 4545 VmReadIndex32 ( 4504 IN VM_CONTEXT 4505 IN UINT32 4546 IN VM_CONTEXT *VmPtr, 4547 IN UINT32 CodeOffset 4506 4548 ) 4507 4549 { … … 4528 4570 // Now using the number of bits, create a mask. 4529 4571 // 4530 Mask = (INT32) ~0 << NBits;4572 Mask = (INT32) ~0 << NBits; 4531 4573 4532 4574 // … … 4538 4580 // Now compute ConstUnits 4539 4581 // 4540 ConstUnits 4541 4542 Offset 4582 ConstUnits = ((Index &~0xF0000000) & Mask) >> NBits; 4583 4584 Offset = NaturalUnits * sizeof (UINTN) + ConstUnits; 4543 4585 4544 4586 // … … 4551 4593 return Offset; 4552 4594 } 4553 4554 4595 4555 4596 /** … … 4565 4606 INT64 4566 4607 VmReadIndex64 ( 4567 IN VM_CONTEXT 4568 IN UINT32 4608 IN VM_CONTEXT *VmPtr, 4609 IN UINT32 CodeOffset 4569 4610 ) 4570 4611 { … … 4591 4632 // Now using the number of bits, create a mask. 4592 4633 // 4593 Mask = (LShiftU64 ((UINT64) ~0, (UINTN)NBits));4634 Mask = (LShiftU64 ((UINT64) ~0, (UINTN)NBits)); 4594 4635 4595 4636 // … … 4603 4644 ConstUnits = ARShiftU64 (((Index &~0xF000000000000000ULL) & Mask), (UINTN)NBits); 4604 4645 4605 Offset = MultU64x64 ((UINT64)NaturalUnits, sizeof (UINTN)) + ConstUnits;4646 Offset = MultU64x64 ((UINT64)NaturalUnits, sizeof (UINTN)) + ConstUnits; 4606 4647 4607 4648 // … … 4614 4655 return Offset; 4615 4656 } 4616 4617 4657 4618 4658 /** … … 4641 4681 EFI_STATUS 4642 4682 VmWriteMem8 ( 4643 IN VM_CONTEXT 4644 IN UINTN 4645 IN UINT8 4683 IN VM_CONTEXT *VmPtr, 4684 IN UINTN Addr, 4685 IN UINT8 Data 4646 4686 ) 4647 4687 { … … 4649 4689 // Convert the address if it's in the stack gap 4650 4690 // 4651 Addr 4652 *(UINT8 *) 4691 Addr = ConvertStackAddr (VmPtr, Addr); 4692 *(UINT8 *)Addr = Data; 4653 4693 return EFI_SUCCESS; 4654 4694 } … … 4679 4719 EFI_STATUS 4680 4720 VmWriteMem16 ( 4681 IN VM_CONTEXT 4682 IN UINTN 4683 IN UINT16 4721 IN VM_CONTEXT *VmPtr, 4722 IN UINTN Addr, 4723 IN UINT16 Data 4684 4724 ) 4685 4725 { … … 4695 4735 // 4696 4736 if (IS_ALIGNED (Addr, sizeof (UINT16))) { 4697 *(UINT16 *) 4737 *(UINT16 *)Addr = Data; 4698 4738 } else { 4699 4739 // … … 4701 4741 // 4702 4742 MemoryFence (); 4703 if ((Status = VmWriteMem8 (VmPtr, Addr, (UINT8) 4743 if ((Status = VmWriteMem8 (VmPtr, Addr, (UINT8)Data)) != EFI_SUCCESS) { 4704 4744 return Status; 4705 4745 } 4706 4746 4707 4747 MemoryFence (); 4708 if ((Status = VmWriteMem8 (VmPtr, Addr + 1, (UINT8) 4748 if ((Status = VmWriteMem8 (VmPtr, Addr + 1, (UINT8)(Data >> 8))) != EFI_SUCCESS) { 4709 4749 return Status; 4710 4750 } … … 4715 4755 return EFI_SUCCESS; 4716 4756 } 4717 4718 4757 4719 4758 /** … … 4742 4781 EFI_STATUS 4743 4782 VmWriteMem32 ( 4744 IN VM_CONTEXT 4745 IN UINTN 4746 IN UINT32 4783 IN VM_CONTEXT *VmPtr, 4784 IN UINTN Addr, 4785 IN UINT32 Data 4747 4786 ) 4748 4787 { … … 4758 4797 // 4759 4798 if (IS_ALIGNED (Addr, sizeof (UINT32))) { 4760 *(UINT32 *) 4799 *(UINT32 *)Addr = Data; 4761 4800 } else { 4762 4801 // … … 4764 4803 // 4765 4804 MemoryFence (); 4766 if ((Status = VmWriteMem16 (VmPtr, Addr, (UINT16) 4805 if ((Status = VmWriteMem16 (VmPtr, Addr, (UINT16)Data)) != EFI_SUCCESS) { 4767 4806 return Status; 4768 4807 } 4769 4808 4770 4809 MemoryFence (); 4771 if ((Status = VmWriteMem16 (VmPtr, Addr + sizeof (UINT16), (UINT16) 4810 if ((Status = VmWriteMem16 (VmPtr, Addr + sizeof (UINT16), (UINT16)(Data >> 16))) != EFI_SUCCESS) { 4772 4811 return Status; 4773 4812 } … … 4778 4817 return EFI_SUCCESS; 4779 4818 } 4780 4781 4819 4782 4820 /** … … 4805 4843 EFI_STATUS 4806 4844 VmWriteMem64 ( 4807 IN VM_CONTEXT 4808 IN UINTN 4809 IN UINT64 4845 IN VM_CONTEXT *VmPtr, 4846 IN UINTN Addr, 4847 IN UINT64 Data 4810 4848 ) 4811 4849 { … … 4821 4859 // 4822 4860 if (IS_ALIGNED (Addr, sizeof (UINT64))) { 4823 *(UINT64 *) 4861 *(UINT64 *)Addr = Data; 4824 4862 } else { 4825 4863 // … … 4827 4865 // 4828 4866 MemoryFence (); 4829 if ((Status = VmWriteMem32 (VmPtr, Addr, (UINT32) 4867 if ((Status = VmWriteMem32 (VmPtr, Addr, (UINT32)Data)) != EFI_SUCCESS) { 4830 4868 return Status; 4831 4869 } 4832 4870 4833 4871 MemoryFence (); 4834 if ((Status = VmWriteMem32 (VmPtr, Addr + sizeof (UINT32), (UINT32) RShiftU64(Data, 32))) != EFI_SUCCESS) {4872 if ((Status = VmWriteMem32 (VmPtr, Addr + sizeof (UINT32), (UINT32)RShiftU64 (Data, 32))) != EFI_SUCCESS) { 4835 4873 return Status; 4836 4874 } … … 4841 4879 return EFI_SUCCESS; 4842 4880 } 4843 4844 4881 4845 4882 /** … … 4868 4905 EFI_STATUS 4869 4906 VmWriteMemN ( 4870 IN VM_CONTEXT 4871 IN UINTN 4872 IN UINTN 4907 IN VM_CONTEXT *VmPtr, 4908 IN UINTN Addr, 4909 IN UINTN Data 4873 4910 ) 4874 4911 { … … 4887 4924 // 4888 4925 if (IS_ALIGNED (Addr, sizeof (UINTN))) { 4889 *(UINTN *) 4926 *(UINTN *)Addr = Data; 4890 4927 } else { 4891 4928 for (Index = 0; Index < sizeof (UINTN) / sizeof (UINT32); Index++) { 4892 4929 MemoryFence (); 4893 Status = VmWriteMem32 (VmPtr, Addr + Index * sizeof (UINT32), (UINT32) 4930 Status = VmWriteMem32 (VmPtr, Addr + Index * sizeof (UINT32), (UINT32)Data); 4894 4931 MemoryFence (); 4895 Data = (UINTN) 4932 Data = (UINTN)RShiftU64 ((UINT64)Data, 32); 4896 4933 } 4897 4934 } … … 4899 4936 return Status; 4900 4937 } 4901 4902 4938 4903 4939 /** … … 4917 4953 INT8 4918 4954 VmReadImmed8 ( 4919 IN VM_CONTEXT *VmPtr,4920 IN UINT32 Offset4955 IN VM_CONTEXT *VmPtr, 4956 IN UINT32 Offset 4921 4957 ) 4922 4958 { … … 4924 4960 // Simply return the data in flat memory space 4925 4961 // 4926 return * (INT8 *)(VmPtr->Ip + Offset);4962 return *(INT8 *)(VmPtr->Ip + Offset); 4927 4963 } 4928 4964 … … 4943 4979 INT16 4944 4980 VmReadImmed16 ( 4945 IN VM_CONTEXT *VmPtr,4946 IN UINT32 Offset4981 IN VM_CONTEXT *VmPtr, 4982 IN UINT32 Offset 4947 4983 ) 4948 4984 { … … 4950 4986 // Read direct if aligned 4951 4987 // 4952 if (IS_ALIGNED ((UINTN) 4953 return * (INT16 *)(VmPtr->Ip + Offset);4988 if (IS_ALIGNED ((UINTN)VmPtr->Ip + Offset, sizeof (INT16))) { 4989 return *(INT16 *)(VmPtr->Ip + Offset); 4954 4990 } else { 4955 4991 // … … 4962 4998 ); 4963 4999 } 5000 4964 5001 // 4965 5002 // Return unaligned data 4966 5003 // 4967 return (INT16) (*(UINT8 *) (VmPtr->Ip + Offset) + (*(UINT8 *) (VmPtr->Ip + Offset + 1) << 8)); 4968 } 4969 5004 return (INT16)(*(UINT8 *)(VmPtr->Ip + Offset) + (*(UINT8 *)(VmPtr->Ip + Offset + 1) << 8)); 5005 } 4970 5006 4971 5007 /** … … 4985 5021 INT32 4986 5022 VmReadImmed32 ( 4987 IN VM_CONTEXT *VmPtr,4988 IN UINT32 Offset5023 IN VM_CONTEXT *VmPtr, 5024 IN UINT32 Offset 4989 5025 ) 4990 5026 { … … 4994 5030 // Read direct if aligned 4995 5031 // 4996 if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT32))) { 4997 return * (INT32 *) (VmPtr->Ip + Offset); 4998 } 5032 if (IS_ALIGNED ((UINTN)VmPtr->Ip + Offset, sizeof (UINT32))) { 5033 return *(INT32 *)(VmPtr->Ip + Offset); 5034 } 5035 4999 5036 // 5000 5037 // Return unaligned data 5001 5038 // 5002 Data = (UINT32) 5039 Data = (UINT32)VmReadCode16 (VmPtr, Offset); 5003 5040 Data |= (UINT32)(VmReadCode16 (VmPtr, Offset + 2) << 16); 5004 5041 return Data; 5005 5042 } 5006 5007 5043 5008 5044 /** … … 5022 5058 INT64 5023 5059 VmReadImmed64 ( 5024 IN VM_CONTEXT *VmPtr,5025 IN UINT32 Offset5060 IN VM_CONTEXT *VmPtr, 5061 IN UINT32 Offset 5026 5062 ) 5027 5063 { … … 5033 5069 // Read direct if aligned 5034 5070 // 5035 if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT64))) { 5036 return * (UINT64 *) (VmPtr->Ip + Offset); 5037 } 5071 if (IS_ALIGNED ((UINTN)VmPtr->Ip + Offset, sizeof (UINT64))) { 5072 return *(UINT64 *)(VmPtr->Ip + Offset); 5073 } 5074 5038 5075 // 5039 5076 // Return unaligned data. 5040 5077 // 5041 Ptr = (UINT8 *)&Data64;5042 Data32 5043 *(UINT32 *) 5044 Ptr 5045 Data32 5046 *(UINT32 *) 5078 Ptr = (UINT8 *)&Data64; 5079 Data32 = VmReadCode32 (VmPtr, Offset); 5080 *(UINT32 *)Ptr = Data32; 5081 Ptr += sizeof (Data32); 5082 Data32 = VmReadCode32 (VmPtr, Offset + sizeof (UINT32)); 5083 *(UINT32 *)Ptr = Data32; 5047 5084 return Data64; 5048 5085 } 5049 5050 5086 5051 5087 /** … … 5063 5099 UINT16 5064 5100 VmReadCode16 ( 5065 IN VM_CONTEXT *VmPtr,5066 IN UINT32 Offset5101 IN VM_CONTEXT *VmPtr, 5102 IN UINT32 Offset 5067 5103 ) 5068 5104 { … … 5070 5106 // Read direct if aligned 5071 5107 // 5072 if (IS_ALIGNED ((UINTN) 5073 return * (UINT16 *)(VmPtr->Ip + Offset);5108 if (IS_ALIGNED ((UINTN)VmPtr->Ip + Offset, sizeof (UINT16))) { 5109 return *(UINT16 *)(VmPtr->Ip + Offset); 5074 5110 } else { 5075 5111 // … … 5082 5118 ); 5083 5119 } 5120 5084 5121 // 5085 5122 // Return unaligned data 5086 5123 // 5087 return (UINT16) (*(UINT8 *) (VmPtr->Ip + Offset) + (*(UINT8 *) (VmPtr->Ip + Offset + 1) << 8)); 5088 } 5089 5124 return (UINT16)(*(UINT8 *)(VmPtr->Ip + Offset) + (*(UINT8 *)(VmPtr->Ip + Offset + 1) << 8)); 5125 } 5090 5126 5091 5127 /** … … 5103 5139 UINT32 5104 5140 VmReadCode32 ( 5105 IN VM_CONTEXT *VmPtr,5106 IN UINT32 Offset5141 IN VM_CONTEXT *VmPtr, 5142 IN UINT32 Offset 5107 5143 ) 5108 5144 { 5109 5145 UINT32 Data; 5146 5110 5147 // 5111 5148 // Read direct if aligned 5112 5149 // 5113 if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT32))) { 5114 return * (UINT32 *) (VmPtr->Ip + Offset); 5115 } 5150 if (IS_ALIGNED ((UINTN)VmPtr->Ip + Offset, sizeof (UINT32))) { 5151 return *(UINT32 *)(VmPtr->Ip + Offset); 5152 } 5153 5116 5154 // 5117 5155 // Return unaligned data 5118 5156 // 5119 Data = (UINT32)VmReadCode16 (VmPtr, Offset);5157 Data = (UINT32)VmReadCode16 (VmPtr, Offset); 5120 5158 Data |= (VmReadCode16 (VmPtr, Offset + 2) << 16); 5121 5159 return Data; 5122 5160 } 5123 5161 5124 5125 5162 /** 5126 5163 Reads 64-bit unsigned data from the code stream. … … 5137 5174 UINT64 5138 5175 VmReadCode64 ( 5139 IN VM_CONTEXT *VmPtr,5140 IN UINT32 Offset5176 IN VM_CONTEXT *VmPtr, 5177 IN UINT32 Offset 5141 5178 ) 5142 5179 { … … 5148 5185 // Read direct if aligned 5149 5186 // 5150 if (IS_ALIGNED ((UINTN) VmPtr->Ip + Offset, sizeof (UINT64))) { 5151 return * (UINT64 *) (VmPtr->Ip + Offset); 5152 } 5187 if (IS_ALIGNED ((UINTN)VmPtr->Ip + Offset, sizeof (UINT64))) { 5188 return *(UINT64 *)(VmPtr->Ip + Offset); 5189 } 5190 5153 5191 // 5154 5192 // Return unaligned data. 5155 5193 // 5156 Ptr = (UINT8 *)&Data64;5157 Data32 5158 *(UINT32 *) 5159 Ptr 5160 Data32 5161 *(UINT32 *) 5194 Ptr = (UINT8 *)&Data64; 5195 Data32 = VmReadCode32 (VmPtr, Offset); 5196 *(UINT32 *)Ptr = Data32; 5197 Ptr += sizeof (Data32); 5198 Data32 = VmReadCode32 (VmPtr, Offset + sizeof (UINT32)); 5199 *(UINT32 *)Ptr = Data32; 5162 5200 return Data64; 5163 5201 } 5164 5165 5202 5166 5203 /** … … 5175 5212 UINT8 5176 5213 VmReadMem8 ( 5177 IN VM_CONTEXT 5178 IN UINTN 5214 IN VM_CONTEXT *VmPtr, 5215 IN UINTN Addr 5179 5216 ) 5180 5217 { … … 5186 5223 // Simply return the data in flat memory space 5187 5224 // 5188 return * (UINT8 *)Addr;5225 return *(UINT8 *)Addr; 5189 5226 } 5190 5227 … … 5200 5237 UINT16 5201 5238 VmReadMem16 ( 5202 IN VM_CONTEXT *VmPtr,5203 IN UINTN Addr5239 IN VM_CONTEXT *VmPtr, 5240 IN UINTN Addr 5204 5241 ) 5205 5242 { … … 5212 5249 // 5213 5250 if (IS_ALIGNED (Addr, sizeof (UINT16))) { 5214 return * (UINT16 *) Addr; 5215 } 5251 return *(UINT16 *)Addr; 5252 } 5253 5216 5254 // 5217 5255 // Return unaligned data 5218 5256 // 5219 return (UINT16) (*(UINT8 *) Addr + (*(UINT8 *)(Addr + 1) << 8));5257 return (UINT16)(*(UINT8 *)Addr + (*(UINT8 *)(Addr + 1) << 8)); 5220 5258 } 5221 5259 … … 5231 5269 UINT32 5232 5270 VmReadMem32 ( 5233 IN VM_CONTEXT *VmPtr,5234 IN UINTN Addr5271 IN VM_CONTEXT *VmPtr, 5272 IN UINTN Addr 5235 5273 ) 5236 5274 { … … 5245 5283 // 5246 5284 if (IS_ALIGNED (Addr, sizeof (UINT32))) { 5247 return * (UINT32 *) Addr; 5248 } 5285 return *(UINT32 *)Addr; 5286 } 5287 5249 5288 // 5250 5289 // Return unaligned data 5251 5290 // 5252 Data = (UINT32)VmReadMem16 (VmPtr, Addr);5291 Data = (UINT32)VmReadMem16 (VmPtr, Addr); 5253 5292 Data |= (VmReadMem16 (VmPtr, Addr + 2) << 16); 5254 5293 return Data; … … 5266 5305 UINT64 5267 5306 VmReadMem64 ( 5268 IN VM_CONTEXT 5269 IN UINTN 5307 IN VM_CONTEXT *VmPtr, 5308 IN UINTN Addr 5270 5309 ) 5271 5310 { … … 5282 5321 // 5283 5322 if (IS_ALIGNED (Addr, sizeof (UINT64))) { 5284 return * (UINT64 *) Addr; 5285 } 5323 return *(UINT64 *)Addr; 5324 } 5325 5286 5326 // 5287 5327 // Return unaligned data. Assume little endian. 5288 5328 // 5289 5329 Data32 = VmReadMem32 (VmPtr, Addr); 5290 Data = (UINT64)VmReadMem32 (VmPtr, Addr + sizeof (UINT32));5291 Data = LShiftU64 (Data, 32) | Data32;5330 Data = (UINT64)VmReadMem32 (VmPtr, Addr + sizeof (UINT32)); 5331 Data = LShiftU64 (Data, 32) | Data32; 5292 5332 return Data; 5293 5333 } 5294 5295 5334 5296 5335 /** … … 5315 5354 UINTN 5316 5355 ConvertStackAddr ( 5317 IN VM_CONTEXT 5318 IN UINTN 5319 ) 5320 { 5321 ASSERT (((Addr < VmPtr->LowStackTop) || (Addr > VmPtr->HighStackBottom)));5356 IN VM_CONTEXT *VmPtr, 5357 IN UINTN Addr 5358 ) 5359 { 5360 ASSERT (((Addr < VmPtr->LowStackTop) || (Addr > VmPtr->HighStackBottom))); 5322 5361 return Addr; 5323 5362 } 5324 5325 5363 5326 5364 /** … … 5335 5373 UINTN 5336 5374 VmReadMemN ( 5337 IN VM_CONTEXT 5338 IN UINTN 5339 ) 5340 { 5341 UINTN Data;5375 IN VM_CONTEXT *VmPtr, 5376 IN UINTN Addr 5377 ) 5378 { 5379 UINTN Data; 5342 5380 volatile UINT32 Size; 5343 UINT8 *FromPtr; 5344 UINT8 *ToPtr; 5381 UINT8 *FromPtr; 5382 UINT8 *ToPtr; 5383 5345 5384 // 5346 5385 // Convert the address if it's in the stack gap … … 5351 5390 // 5352 5391 if (IS_ALIGNED (Addr, sizeof (UINTN))) { 5353 return * (UINTN *) Addr; 5354 } 5392 return *(UINTN *)Addr; 5393 } 5394 5355 5395 // 5356 5396 // Return unaligned data 5357 5397 // 5358 5398 Data = 0; 5359 FromPtr = (UINT8 *) 5360 ToPtr = (UINT8 *) 5399 FromPtr = (UINT8 *)Addr; 5400 ToPtr = (UINT8 *)&Data; 5361 5401 5362 5402 for (Size = 0; Size < sizeof (Data); Size++) { … … 5380 5420 ) 5381 5421 { 5382 return (UINT64) 5383 } 5422 return (UINT64)(((VM_MAJOR_VERSION & 0xFFFF) << 16) | ((VM_MINOR_VERSION & 0xFFFF))); 5423 }
Note:
See TracChangeset
for help on using the changeset viewer.