Home | History | Annotate | Download | only in EbcDebugger
      1 /** @file
      2 
      3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 
     13 **/
     14 
     15 #include "Edb.h"
     16 
     17 //
     18 // Debugger Disasm definition
     19 //
     20 #define EDB_DISASM_DEFINE(func) \
     21 UINTN \
     22 func ( \
     23   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress, \
     24   IN     EFI_SYSTEM_CONTEXT        SystemContext, \
     25   OUT    CHAR16                    **DisasmString \
     26   )
     27 
     28 EDB_DISASM_DEFINE (EdbDisasmBREAK);
     29 EDB_DISASM_DEFINE (EdbDisasmJMP);
     30 EDB_DISASM_DEFINE (EdbDisasmJMP8);
     31 EDB_DISASM_DEFINE (EdbDisasmCALL);
     32 EDB_DISASM_DEFINE (EdbDisasmRET);
     33 EDB_DISASM_DEFINE (EdbDisasmCMP);
     34 EDB_DISASM_DEFINE (EdbDisasmUnsignedDataManip);
     35 EDB_DISASM_DEFINE (EdbDisasmSignedDataManip);
     36 EDB_DISASM_DEFINE (EdbDisasmMOVxx);
     37 EDB_DISASM_DEFINE (EdbDisasmMOVsnw);
     38 EDB_DISASM_DEFINE (EdbDisasmMOVsnd);
     39 EDB_DISASM_DEFINE (EdbDisasmLOADSP);
     40 EDB_DISASM_DEFINE (EdbDisasmSTORESP);
     41 EDB_DISASM_DEFINE (EdbDisasmPUSH);
     42 EDB_DISASM_DEFINE (EdbDisasmPOP);
     43 EDB_DISASM_DEFINE (EdbDisasmCMPI);
     44 EDB_DISASM_DEFINE (EdbDisasmPUSHn);
     45 EDB_DISASM_DEFINE (EdbDisasmPOPn);
     46 EDB_DISASM_DEFINE (EdbDisasmMOVI);
     47 EDB_DISASM_DEFINE (EdbDisasmMOVIn);
     48 EDB_DISASM_DEFINE (EdbDisasmMOVREL);
     49 
     50 //
     51 // Debugger Disasm Table
     52 //
     53 EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[] = {
     54   EdbDisasmBREAK,             // opcode 0x00 BREAK
     55   EdbDisasmJMP,               // opcode 0x01 JMP
     56   EdbDisasmJMP8,              // opcode 0x02 JMP8
     57   EdbDisasmCALL,              // opcode 0x03 CALL
     58   EdbDisasmRET,               // opcode 0x04 RET
     59   EdbDisasmCMP,               // opcode 0x05 CMPEQ
     60   EdbDisasmCMP,               // opcode 0x06 CMPLTE
     61   EdbDisasmCMP,               // opcode 0x07 CMPGTE
     62   EdbDisasmCMP,               // opcode 0x08 CMPULTE
     63   EdbDisasmCMP,               // opcode 0x09 CMPUGTE
     64   EdbDisasmUnsignedDataManip, // opcode 0x0A NOT
     65   EdbDisasmSignedDataManip,   // opcode 0x0B NEG
     66   EdbDisasmSignedDataManip,   // opcode 0x0C ADD
     67   EdbDisasmSignedDataManip,   // opcode 0x0D SUB
     68   EdbDisasmSignedDataManip,   // opcode 0x0E MUL
     69   EdbDisasmUnsignedDataManip, // opcode 0x0F MULU
     70   EdbDisasmSignedDataManip,   // opcode 0x10 DIV
     71   EdbDisasmUnsignedDataManip, // opcode 0x11 DIVU
     72   EdbDisasmSignedDataManip,   // opcode 0x12 MOD
     73   EdbDisasmUnsignedDataManip, // opcode 0x13 MODU
     74   EdbDisasmUnsignedDataManip, // opcode 0x14 AND
     75   EdbDisasmUnsignedDataManip, // opcode 0x15 OR
     76   EdbDisasmUnsignedDataManip, // opcode 0x16 XOR
     77   EdbDisasmUnsignedDataManip, // opcode 0x17 SHL
     78   EdbDisasmUnsignedDataManip, // opcode 0x18 SHR
     79   EdbDisasmSignedDataManip,   // opcode 0x19 ASHR
     80   EdbDisasmUnsignedDataManip, // opcode 0x1A EXTNDB
     81   EdbDisasmUnsignedDataManip, // opcode 0x1B EXTNDW
     82   EdbDisasmUnsignedDataManip, // opcode 0x1C EXTNDD
     83   EdbDisasmMOVxx,             // opcode 0x1D MOVBW
     84   EdbDisasmMOVxx,             // opcode 0x1E MOVWW
     85   EdbDisasmMOVxx,             // opcode 0x1F MOVDW
     86   EdbDisasmMOVxx,             // opcode 0x20 MOVQW
     87   EdbDisasmMOVxx,             // opcode 0x21 MOVBD
     88   EdbDisasmMOVxx,             // opcode 0x22 MOVWD
     89   EdbDisasmMOVxx,             // opcode 0x23 MOVDD
     90   EdbDisasmMOVxx,             // opcode 0x24 MOVQD
     91   EdbDisasmMOVsnw,            // opcode 0x25 MOVSNW
     92   EdbDisasmMOVsnd,            // opcode 0x26 MOVSND
     93   NULL,                       // opcode 0x27
     94   EdbDisasmMOVxx,             // opcode 0x28 MOVQQ
     95   EdbDisasmLOADSP,            // opcode 0x29 LOADSP
     96   EdbDisasmSTORESP,           // opcode 0x2A STORESP
     97   EdbDisasmPUSH,              // opcode 0x2B PUSH
     98   EdbDisasmPOP,               // opcode 0x2C POP
     99   EdbDisasmCMPI,              // opcode 0x2D CMPIEQ
    100   EdbDisasmCMPI,              // opcode 0x2E CMPILTE
    101   EdbDisasmCMPI,              // opcode 0x2F CMPIGTE
    102   EdbDisasmCMPI,              // opcode 0x30 CMPIULTE
    103   EdbDisasmCMPI,              // opcode 0x31 CMPIUGTE
    104   EdbDisasmMOVxx,             // opcode 0x32 MOVNW
    105   EdbDisasmMOVxx,             // opcode 0x33 MOVND
    106   NULL,                       // opcode 0x34
    107   EdbDisasmPUSHn,             // opcode 0x35 PUSHN
    108   EdbDisasmPOPn,              // opcode 0x36 POPN
    109   EdbDisasmMOVI,              // opcode 0x37 MOVI
    110   EdbDisasmMOVIn,             // opcode 0x38 MOVIN
    111   EdbDisasmMOVREL,            // opcode 0x39 MOVREL
    112 };
    113 
    114 /**
    115 
    116   Disasm instruction - BREAK.
    117 
    118   @param  InstructionAddress - The instruction address
    119   @param  SystemContext      - EBC system context.
    120   @param  DisasmString       - The instruction string
    121 
    122   @return Instruction length
    123 
    124 **/
    125 UINTN
    126 EdbDisasmBREAK (
    127   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    128   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    129   OUT    CHAR16                    **DisasmString
    130   )
    131 {
    132   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_BREAK);
    133 
    134   if (*(UINT8 *)(UINTN)(InstructionAddress + 1) > 6) {
    135     return 0;
    136   }
    137 
    138   //
    139   // Construct Disasm String
    140   //
    141   if (DisasmString != NULL) {
    142     *DisasmString = EdbPreInstructionString ();
    143 
    144     EdbPrintInstructionName (L"BREAK");
    145     EdbPrintDatan (*(UINT8 *)(UINTN)(InstructionAddress + 1));
    146 
    147     EdbPostInstructionString ();
    148   }
    149 
    150   return 2;
    151 }
    152 
    153 extern CONST UINT8                    mJMPLen[];
    154 
    155 /**
    156 
    157   Disasm instruction - JMP.
    158 
    159   @param  InstructionAddress - The instruction address
    160   @param  SystemContext      - EBC system context.
    161   @param  DisasmString       - The instruction string
    162 
    163   @return Instruction length
    164 
    165 **/
    166 UINTN
    167 EdbDisasmJMP (
    168   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    169   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    170   OUT    CHAR16                    **DisasmString
    171   )
    172 {
    173   UINT8   Modifiers;
    174   UINT8   Operands;
    175   UINTN   Size;
    176   UINT32  Data32;
    177   UINT64  Data64;
    178 
    179   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_JMP);
    180 
    181   Modifiers  = GET_MODIFIERS (InstructionAddress);
    182   Operands   = GET_OPERANDS (InstructionAddress);
    183   Size = (UINTN)mJMPLen[(Modifiers >> 6) & 0x03];
    184 
    185   //
    186   // Construct Disasm String
    187   //
    188   if (DisasmString != NULL) {
    189     *DisasmString = EdbPreInstructionString ();
    190 
    191     EdbPrintInstructionName (L"JMP");
    192 //    if (Modifiers & OPCODE_M_IMMDATA64) {
    193 //      EdbPrintInstructionName (L"64");
    194 //    } else {
    195 //      EdbPrintInstructionName (L"32");
    196 //    }
    197     if ((Modifiers & CONDITION_M_CONDITIONAL) != 0) {
    198       if ((Modifiers & JMP_M_CS) != 0) {
    199         EdbPrintInstructionName (L"cs");
    200       } else {
    201         EdbPrintInstructionName (L"cc");
    202       }
    203     }
    204 
    205     InstructionAddress += 2;
    206     if ((Modifiers & OPCODE_M_IMMDATA64) != 0) {
    207       CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
    208       if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
    209         EdbPrintData64 (Data64);
    210       } else {
    211         return 0;
    212       }
    213     } else {
    214       CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
    215       EdbPrintRegister1 (Operands);
    216 
    217       if ((Operands & OPERAND_M_INDIRECT1) == 0) {
    218         if ((Modifiers & OPCODE_M_IMMDATA) == 0) {
    219           Data32 = 0;
    220         }
    221         EdbPrintImmDatan (Data32);
    222       } else {
    223         EdbPrintRawIndexData32 (Data32);
    224       }
    225     }
    226 
    227     EdbPostInstructionString ();
    228   }
    229 
    230   return Size;
    231 }
    232 
    233 /**
    234 
    235   Disasm instruction - JMP8.
    236 
    237   @param  InstructionAddress - The instruction address
    238   @param  SystemContext      - EBC system context.
    239   @param  DisasmString       - The instruction string
    240 
    241   @return Instruction length
    242 
    243 **/
    244 UINTN
    245 EdbDisasmJMP8 (
    246   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    247   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    248   OUT    CHAR16                    **DisasmString
    249   )
    250 {
    251   UINT8   Modifiers;
    252 
    253   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_JMP8);
    254   Modifiers  = GET_MODIFIERS (InstructionAddress);
    255 
    256   //
    257   // Construct Disasm String
    258   //
    259   if (DisasmString != NULL) {
    260     *DisasmString = EdbPreInstructionString ();
    261 
    262     EdbPrintInstructionName (L"JMP8");
    263     if ((Modifiers & CONDITION_M_CONDITIONAL) != 0) {
    264       if ((Modifiers & JMP_M_CS) != 0) {
    265         EdbPrintInstructionName (L"cs");
    266       } else {
    267         EdbPrintInstructionName (L"cc");
    268       }
    269     }
    270 
    271     EdbPrintData8 (*(UINT8 *)(UINTN)(InstructionAddress + 1));
    272 
    273     EdbPostInstructionString ();
    274   }
    275 
    276   return 2;
    277 }
    278 
    279 /**
    280 
    281   Disasm instruction - CALL.
    282 
    283   @param  InstructionAddress - The instruction address
    284   @param  SystemContext      - EBC system context.
    285   @param  DisasmString       - The instruction string
    286 
    287   @return Instruction length
    288 
    289 **/
    290 UINTN
    291 EdbDisasmCALL (
    292   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    293   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    294   OUT    CHAR16                    **DisasmString
    295   )
    296 {
    297   UINT8   Modifiers;
    298   UINT8   Operands;
    299   UINTN   Size;
    300   UINT32  Data32;
    301   UINT64  Data64;
    302   UINT64  Ip;
    303   UINTN   Result;
    304   EFI_PHYSICAL_ADDRESS      SavedInstructionAddress;
    305 
    306   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_CALL);
    307   SavedInstructionAddress = InstructionAddress;
    308 
    309   Modifiers  = GET_MODIFIERS (InstructionAddress);
    310   Operands   = GET_OPERANDS (InstructionAddress);
    311   Size = (UINTN)mJMPLen[(Modifiers >> 6) & 0x03];
    312 
    313   //
    314   // Construct Disasm String
    315   //
    316   if (DisasmString != NULL) {
    317     *DisasmString = EdbPreInstructionString ();
    318 
    319     EdbPrintInstructionName (L"CALL");
    320 //    if (Modifiers & OPCODE_M_IMMDATA64) {
    321 //      EdbPrintInstructionName (L"64");
    322 //    } else {
    323 //      EdbPrintInstructionName (L"32");
    324 //    }
    325     if ((Operands & OPERAND_M_NATIVE_CALL) != 0) {
    326       EdbPrintInstructionName (L"EX");
    327     }
    328 //    if ((Operands & OPERAND_M_RELATIVE_ADDR) == 0) {
    329 //      EdbPrintInstructionName (L"a");
    330 //    }
    331 
    332     InstructionAddress += 2;
    333     if ((Modifiers & OPCODE_M_IMMDATA64) != 0) {
    334       CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
    335       Ip = Data64;
    336       if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
    337         Result = EdbFindAndPrintSymbol ((UINTN)Ip);
    338         if (Result == 0) {
    339           EdbPrintData64 (Data64);
    340         }
    341       } else {
    342         return 0;
    343       }
    344     } else {
    345       if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
    346         CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
    347       } else {
    348         Data32 = 0;
    349       }
    350 
    351       if ((Operands & OPERAND_M_OP1) == 0) {
    352         Ip = (UINT64)Data32;
    353       } else {
    354         Ip = GetRegisterValue (SystemContext, (Operands & OPERAND_M_OP1));
    355       }
    356 
    357       if ((Operands & OPERAND_M_INDIRECT1) == 0) {
    358         if ((Operands & OPERAND_M_RELATIVE_ADDR) != 0) {
    359           Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Ip + Size));
    360         } else {
    361           Result = EdbFindAndPrintSymbol ((UINTN)Ip);
    362         }
    363         if (Result == 0) {
    364           EdbPrintRegister1 (Operands);
    365           if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
    366             EdbPrintImmData32 (Data32);
    367           }
    368         }
    369       } else {
    370         EdbPrintRegister1 (Operands);
    371         if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
    372           EdbPrintRawIndexData32 (Data32);
    373         }
    374       }
    375     }
    376 
    377     EdbPostInstructionString ();
    378   }
    379 
    380   return Size;
    381 }
    382 
    383 /**
    384 
    385   Disasm instruction - RET.
    386 
    387   @param  InstructionAddress - The instruction address
    388   @param  SystemContext      - EBC system context.
    389   @param  DisasmString       - The instruction string
    390 
    391   @return Instruction length
    392 
    393 **/
    394 UINTN
    395 EdbDisasmRET (
    396   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    397   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    398   OUT    CHAR16                    **DisasmString
    399   )
    400 {
    401   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_RET);
    402 
    403   if (*(UINT8 *)(UINTN)(InstructionAddress + 1) != 0) {
    404     return 0;
    405   }
    406 
    407   //
    408   // Construct Disasm String
    409   //
    410   if (DisasmString != NULL) {
    411     *DisasmString = EdbPreInstructionString ();
    412 
    413     EdbPrintInstructionName (L"RET");
    414 
    415     EdbPostInstructionString ();
    416   }
    417 
    418   return 2;
    419 }
    420 
    421 /**
    422 
    423   Disasm instruction - CMP.
    424 
    425   @param  InstructionAddress - The instruction address
    426   @param  SystemContext      - EBC system context.
    427   @param  DisasmString       - The instruction string
    428 
    429   @return Instruction length
    430 
    431 **/
    432 UINTN
    433 EdbDisasmCMP (
    434   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    435   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    436   OUT    CHAR16                    **DisasmString
    437   )
    438 {
    439   UINT8  Opcode;
    440   UINT8  Modifiers;
    441   UINT8  Operands;
    442   UINT16 Data16;
    443   UINTN  Size;
    444 
    445   ASSERT (
    446     (GET_OPCODE(InstructionAddress) == OPCODE_CMPEQ)   ||
    447     (GET_OPCODE(InstructionAddress) == OPCODE_CMPLTE)  ||
    448     (GET_OPCODE(InstructionAddress) == OPCODE_CMPGTE)  ||
    449     (GET_OPCODE(InstructionAddress) == OPCODE_CMPULTE) ||
    450     (GET_OPCODE(InstructionAddress) == OPCODE_CMPUGTE)
    451     );
    452 
    453   Opcode     = GET_OPCODE (InstructionAddress);
    454   Modifiers  = GET_MODIFIERS (InstructionAddress);
    455   Operands   = GET_OPERANDS (InstructionAddress);
    456   if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
    457     Size = 4;
    458   } else {
    459     Size = 2;
    460   }
    461 
    462   //
    463   // Construct Disasm String
    464   //
    465   if (DisasmString != NULL) {
    466     *DisasmString = EdbPreInstructionString ();
    467 
    468     EdbPrintInstructionName (L"CMP");
    469 //    if (Modifiers & OPCODE_M_64BIT) {
    470 //      EdbPrintInstructionName (L"64");
    471 //    } else {
    472 //      EdbPrintInstructionName (L"32");
    473 //    }
    474     switch (Opcode) {
    475     case OPCODE_CMPEQ:
    476       EdbPrintInstructionName (L"eq");
    477       break;
    478     case OPCODE_CMPLTE:
    479       EdbPrintInstructionName (L"lte");
    480       break;
    481     case OPCODE_CMPGTE:
    482       EdbPrintInstructionName (L"gte");
    483       break;
    484     case OPCODE_CMPULTE:
    485       EdbPrintInstructionName (L"ulte");
    486       break;
    487     case OPCODE_CMPUGTE:
    488       EdbPrintInstructionName (L"ugte");
    489       break;
    490     }
    491 
    492     EdbPrintRegister1 (Operands);
    493     InstructionAddress += 2;
    494 
    495     EdbPrintComma ();
    496     EdbPrintRegister2 (Operands);
    497 
    498     if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
    499       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
    500       if ((Operands & OPERAND_M_INDIRECT2) != 0) {
    501         EdbPrintRawIndexData16 (Data16);
    502       } else {
    503         EdbPrintImmDatan (Data16);
    504       }
    505     }
    506 
    507     EdbPostInstructionString ();
    508   }
    509 
    510   return Size;
    511 }
    512 
    513 /**
    514 
    515   Disasm instruction - Unsigned Data Manipulate.
    516 
    517   @param  InstructionAddress - The instruction address
    518   @param  SystemContext      - EBC system context.
    519   @param  DisasmString       - The instruction string
    520 
    521   @return Instruction length
    522 
    523 **/
    524 UINTN
    525 EdbDisasmUnsignedDataManip (
    526   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    527   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    528   OUT    CHAR16                    **DisasmString
    529   )
    530 {
    531   UINT8  Modifiers;
    532   UINT8  Opcode;
    533   UINT8  Operands;
    534   UINTN  Size;
    535   UINT16 Data16;
    536 
    537   ASSERT (
    538     (GET_OPCODE(InstructionAddress) == OPCODE_NOT)    ||
    539     (GET_OPCODE(InstructionAddress) == OPCODE_MULU)   ||
    540     (GET_OPCODE(InstructionAddress) == OPCODE_DIVU)   ||
    541     (GET_OPCODE(InstructionAddress) == OPCODE_MODU)   ||
    542     (GET_OPCODE(InstructionAddress) == OPCODE_AND)    ||
    543     (GET_OPCODE(InstructionAddress) == OPCODE_OR)     ||
    544     (GET_OPCODE(InstructionAddress) == OPCODE_XOR)    ||
    545     (GET_OPCODE(InstructionAddress) == OPCODE_SHL)    ||
    546     (GET_OPCODE(InstructionAddress) == OPCODE_SHR)    ||
    547     (GET_OPCODE(InstructionAddress) == OPCODE_EXTNDB) ||
    548     (GET_OPCODE(InstructionAddress) == OPCODE_EXTNDW) ||
    549     (GET_OPCODE(InstructionAddress) == OPCODE_EXTNDD)
    550     );
    551 
    552   Opcode     = GET_OPCODE (InstructionAddress);
    553   Operands   = GET_OPERANDS (InstructionAddress);
    554   Modifiers  = GET_MODIFIERS (InstructionAddress);
    555   if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) {
    556     Size = 4;
    557   } else {
    558     Size = 2;
    559   }
    560 
    561   //
    562   // Construct Disasm String
    563   //
    564   if (DisasmString != NULL) {
    565     *DisasmString = EdbPreInstructionString ();
    566 
    567     switch (Opcode) {
    568     case OPCODE_NOT:
    569       EdbPrintInstructionName (L"NOT");
    570       break;
    571     case OPCODE_MULU:
    572       EdbPrintInstructionName (L"MULU");
    573       break;
    574     case OPCODE_DIVU:
    575       EdbPrintInstructionName (L"DIVU");
    576       break;
    577     case OPCODE_MODU:
    578       EdbPrintInstructionName (L"MODU");
    579       break;
    580     case OPCODE_AND:
    581       EdbPrintInstructionName (L"AND");
    582       break;
    583     case OPCODE_OR:
    584       EdbPrintInstructionName (L"OR");
    585       break;
    586     case OPCODE_XOR:
    587       EdbPrintInstructionName (L"XOR");
    588       break;
    589     case OPCODE_SHL:
    590       EdbPrintInstructionName (L"SHL");
    591       break;
    592     case OPCODE_SHR:
    593       EdbPrintInstructionName (L"SHR");
    594       break;
    595     case OPCODE_EXTNDB:
    596       EdbPrintInstructionName (L"EXTNDB");
    597       break;
    598     case OPCODE_EXTNDW:
    599       EdbPrintInstructionName (L"EXTNDW");
    600       break;
    601     case OPCODE_EXTNDD:
    602       EdbPrintInstructionName (L"EXTNDD");
    603       break;
    604     }
    605 //    if (Modifiers & DATAMANIP_M_64) {
    606 //      EdbPrintInstructionName (L"64");
    607 //    } else {
    608 //      EdbPrintInstructionName (L"32");
    609 //    }
    610 
    611     EdbPrintRegister1 (Operands);
    612     EdbPrintComma ();
    613     EdbPrintRegister2 (Operands);
    614 
    615     InstructionAddress += 2;
    616     if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) {
    617       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
    618       if ((Operands & OPERAND_M_INDIRECT2) != 0) {
    619         EdbPrintRawIndexData16 (Data16);
    620       } else {
    621         EdbPrintImmDatan (Data16);
    622       }
    623     }
    624 
    625     EdbPostInstructionString ();
    626   }
    627 
    628   return Size;
    629 }
    630 
    631 /**
    632 
    633   Disasm instruction - Signed Data Manipulate,
    634 
    635   @param  InstructionAddress - The instruction address
    636   @param  SystemContext      - EBC system context.
    637   @param  DisasmString       - The instruction string
    638 
    639   @return Instruction length
    640 
    641 **/
    642 UINTN
    643 EdbDisasmSignedDataManip (
    644   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    645   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    646   OUT    CHAR16                    **DisasmString
    647   )
    648 {
    649   UINT8  Modifiers;
    650   UINT8  Opcode;
    651   UINT8  Operands;
    652   UINTN  Size;
    653   UINT16 Data16;
    654 
    655   ASSERT (
    656     (GET_OPCODE(InstructionAddress) == OPCODE_NEG)   ||
    657     (GET_OPCODE(InstructionAddress) == OPCODE_ADD)   ||
    658     (GET_OPCODE(InstructionAddress) == OPCODE_SUB)   ||
    659     (GET_OPCODE(InstructionAddress) == OPCODE_MUL)   ||
    660     (GET_OPCODE(InstructionAddress) == OPCODE_DIV)   ||
    661     (GET_OPCODE(InstructionAddress) == OPCODE_MOD)   ||
    662     (GET_OPCODE(InstructionAddress) == OPCODE_ASHR)
    663     );
    664 
    665   Opcode     = GET_OPCODE (InstructionAddress);
    666   Operands   = GET_OPERANDS (InstructionAddress);
    667   Modifiers  = GET_MODIFIERS (InstructionAddress);
    668   if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) {
    669     Size = 4;
    670   } else {
    671     Size = 2;
    672   }
    673 
    674   //
    675   // Construct Disasm String
    676   //
    677   if (DisasmString != NULL) {
    678     *DisasmString = EdbPreInstructionString ();
    679 
    680     switch (Opcode) {
    681     case OPCODE_NEG:
    682       EdbPrintInstructionName (L"NEG");
    683       break;
    684     case OPCODE_ADD:
    685       EdbPrintInstructionName (L"ADD");
    686       break;
    687     case OPCODE_SUB:
    688       EdbPrintInstructionName (L"SUB");
    689       break;
    690     case OPCODE_MUL:
    691       EdbPrintInstructionName (L"MUL");
    692       break;
    693     case OPCODE_DIV:
    694       EdbPrintInstructionName (L"DIV");
    695       break;
    696     case OPCODE_MOD:
    697       EdbPrintInstructionName (L"MOD");
    698       break;
    699     case OPCODE_ASHR:
    700       EdbPrintInstructionName (L"ASHR");
    701       break;
    702     }
    703 //    if (Modifiers & DATAMANIP_M_64) {
    704 //      EdbPrintInstructionName (L"64");
    705 //    } else {
    706 //      EdbPrintInstructionName (L"32");
    707 //    }
    708 
    709     EdbPrintRegister1 (Operands);
    710     EdbPrintComma ();
    711     EdbPrintRegister2 (Operands);
    712 
    713     InstructionAddress += 2;
    714     if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) {
    715       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
    716       if ((Operands & OPERAND_M_INDIRECT2) != 0) {
    717         EdbPrintRawIndexData16 (Data16);
    718       } else {
    719         EdbPrintImmDatan (Data16);
    720       }
    721     }
    722 
    723     EdbPostInstructionString ();
    724   }
    725 
    726   return Size;
    727 }
    728 
    729 /**
    730 
    731   Disasm instruction - MOVxx.
    732 
    733   @param  InstructionAddress - The instruction address
    734   @param  SystemContext      - EBC system context.
    735   @param  DisasmString       - The instruction string
    736 
    737   @return Instruction length
    738 
    739 **/
    740 UINTN
    741 EdbDisasmMOVxx (
    742   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    743   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    744   OUT    CHAR16                    **DisasmString
    745   )
    746 {
    747   UINT8   Modifiers;
    748   UINT8   Opcode;
    749   UINT8   Operands;
    750   UINTN   Size;
    751   UINT16  Data16;
    752   UINT32  Data32;
    753   UINT64  Data64;
    754 
    755   ASSERT (
    756     (GET_OPCODE(InstructionAddress) == OPCODE_MOVBW)   ||
    757     (GET_OPCODE(InstructionAddress) == OPCODE_MOVWW)   ||
    758     (GET_OPCODE(InstructionAddress) == OPCODE_MOVDW)   ||
    759     (GET_OPCODE(InstructionAddress) == OPCODE_MOVQW)   ||
    760     (GET_OPCODE(InstructionAddress) == OPCODE_MOVBD)   ||
    761     (GET_OPCODE(InstructionAddress) == OPCODE_MOVWD)   ||
    762     (GET_OPCODE(InstructionAddress) == OPCODE_MOVDD)   ||
    763     (GET_OPCODE(InstructionAddress) == OPCODE_MOVQD)   ||
    764     (GET_OPCODE(InstructionAddress) == OPCODE_MOVQQ)   ||
    765     (GET_OPCODE(InstructionAddress) == OPCODE_MOVNW)   ||
    766     (GET_OPCODE(InstructionAddress) == OPCODE_MOVND)
    767     );
    768 
    769   Opcode     = GET_OPCODE (InstructionAddress);
    770   Modifiers  = GET_MODIFIERS (InstructionAddress);
    771   Operands   = GET_OPERANDS (InstructionAddress);
    772   Size = 2;
    773   if ((Modifiers & (OPCODE_M_IMMED_OP1 | OPCODE_M_IMMED_OP2)) != 0) {
    774     if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
    775       if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
    776         Size += 2;
    777       }
    778       if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
    779         Size += 2;
    780       }
    781     } else if (((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) != 0) {
    782       if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
    783         Size += 4;
    784       }
    785       if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
    786         Size += 4;
    787       }
    788     } else if (Opcode == OPCODE_MOVQQ) {
    789       if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
    790         Size += 8;
    791       }
    792       if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
    793         Size += 8;
    794       }
    795     }
    796   }
    797 
    798   //
    799   // Construct Disasm String
    800   //
    801   if (DisasmString != NULL) {
    802     *DisasmString = EdbPreInstructionString ();
    803 
    804     EdbPrintInstructionName (L"MOV");
    805     switch (Opcode) {
    806     case OPCODE_MOVBW:
    807       EdbPrintInstructionName (L"bw");
    808       break;
    809     case OPCODE_MOVWW:
    810       EdbPrintInstructionName (L"ww");
    811       break;
    812     case OPCODE_MOVDW:
    813       EdbPrintInstructionName (L"dw");
    814       break;
    815     case OPCODE_MOVQW:
    816       EdbPrintInstructionName (L"qw");
    817       break;
    818     case OPCODE_MOVBD:
    819       EdbPrintInstructionName (L"bd");
    820       break;
    821     case OPCODE_MOVWD:
    822       EdbPrintInstructionName (L"wd");
    823       break;
    824     case OPCODE_MOVDD:
    825       EdbPrintInstructionName (L"dd");
    826       break;
    827     case OPCODE_MOVQD:
    828       EdbPrintInstructionName (L"qd");
    829       break;
    830     case OPCODE_MOVQQ:
    831       EdbPrintInstructionName (L"qq");
    832       break;
    833     case OPCODE_MOVNW:
    834       EdbPrintInstructionName (L"nw");
    835       break;
    836     case OPCODE_MOVND:
    837       EdbPrintInstructionName (L"nd");
    838       break;
    839     }
    840 
    841     EdbPrintRegister1 (Operands);
    842 
    843     InstructionAddress += 2;
    844     if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
    845       if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
    846         CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
    847         InstructionAddress += 2;
    848         EdbPrintRawIndexData16 (Data16);
    849       } else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) {
    850         CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
    851         InstructionAddress += 4;
    852         EdbPrintRawIndexData32 (Data32);
    853       } else if (Opcode == OPCODE_MOVQQ) {
    854         CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
    855         InstructionAddress += 8;
    856         EdbPrintRawIndexData64 (Data64);
    857       }
    858     }
    859 
    860     EdbPrintComma ();
    861     EdbPrintRegister2 (Operands);
    862 
    863     if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
    864       if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
    865         CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
    866         EdbPrintRawIndexData16 (Data16);
    867       } else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) {
    868         CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
    869         EdbPrintRawIndexData32 (Data32);
    870       } else if (Opcode == OPCODE_MOVQQ) {
    871         CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
    872         EdbPrintRawIndexData64 (Data64);
    873       }
    874     }
    875 
    876     EdbPostInstructionString ();
    877   }
    878 
    879   return Size;
    880 }
    881 
    882 /**
    883 
    884   Disasm instruction - MOVsnw.
    885 
    886   @param  InstructionAddress - The instruction address
    887   @param  SystemContext      - EBC system context.
    888   @param  DisasmString       - The instruction string
    889 
    890   @return Instruction length
    891 
    892 **/
    893 UINTN
    894 EdbDisasmMOVsnw (
    895   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    896   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    897   OUT    CHAR16                    **DisasmString
    898   )
    899 {
    900   UINT8  Modifiers;
    901   UINT8  Operands;
    902   UINTN  Size;
    903   UINT16 Data16;
    904 
    905   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVSNW);
    906 
    907   Modifiers  = GET_MODIFIERS (InstructionAddress);
    908   Operands   = GET_OPERANDS (InstructionAddress);
    909   Size = 2;
    910   if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
    911     Size += 2;
    912   }
    913   if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
    914     Size += 2;
    915   }
    916 
    917   //
    918   // Construct Disasm String
    919   //
    920   if (DisasmString != NULL) {
    921     *DisasmString = EdbPreInstructionString ();
    922 
    923     EdbPrintInstructionName (L"MOVsnw");
    924 
    925     EdbPrintRegister1 (Operands);
    926 
    927     InstructionAddress += 2;
    928     if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
    929       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
    930       InstructionAddress += 2;
    931       EdbPrintRawIndexData16 (Data16);
    932     }
    933 
    934     EdbPrintComma ();
    935     EdbPrintRegister2 (Operands);
    936 
    937     if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
    938       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
    939       if ((Operands & OPERAND_M_INDIRECT2) != 0) {
    940         EdbPrintRawIndexData16 (Data16);
    941       } else {
    942         EdbPrintImmDatan (Data16);
    943       }
    944     }
    945 
    946     EdbPostInstructionString ();
    947   }
    948 
    949   return Size;
    950 }
    951 
    952 /**
    953 
    954   Disasm instruction - MOVsnd.
    955 
    956   @param  InstructionAddress - The instruction address
    957   @param  SystemContext      - EBC system context.
    958   @param  DisasmString       - The instruction string
    959 
    960   @return Instruction length
    961 
    962 **/
    963 UINTN
    964 EdbDisasmMOVsnd (
    965   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
    966   IN     EFI_SYSTEM_CONTEXT        SystemContext,
    967   OUT    CHAR16                    **DisasmString
    968   )
    969 {
    970   UINT8  Modifiers;
    971   UINT8  Operands;
    972   UINTN  Size;
    973   UINT32 Data32;
    974 
    975   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVSND);
    976 
    977   Modifiers  = GET_MODIFIERS (InstructionAddress);
    978   Operands   = GET_OPERANDS (InstructionAddress);
    979   Size = 2;
    980   if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
    981     Size += 4;
    982   }
    983   if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
    984     Size += 4;
    985   }
    986 
    987   //
    988   // Construct Disasm String
    989   //
    990   if (DisasmString != NULL) {
    991     *DisasmString = EdbPreInstructionString ();
    992 
    993     EdbPrintInstructionName (L"MOVsnd");
    994 
    995     EdbPrintRegister1 (Operands);
    996 
    997     InstructionAddress += 2;
    998     if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
    999       CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
   1000       InstructionAddress += 4;
   1001       EdbPrintRawIndexData32 (Data32);
   1002     }
   1003 
   1004     EdbPrintComma ();
   1005     EdbPrintRegister2 (Operands);
   1006 
   1007     if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
   1008       CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
   1009       if ((Operands & OPERAND_M_INDIRECT2) != 0) {
   1010         EdbPrintRawIndexData32 (Data32);
   1011       } else {
   1012         EdbPrintImmDatan (Data32);
   1013       }
   1014     }
   1015 
   1016     EdbPostInstructionString ();
   1017   }
   1018 
   1019   return Size;
   1020 }
   1021 
   1022 /**
   1023 
   1024   Disasm instruction - LOADSP.
   1025 
   1026   @param  InstructionAddress - The instruction address
   1027   @param  SystemContext      - EBC system context.
   1028   @param  DisasmString       - The instruction string
   1029 
   1030   @return Instruction length
   1031 
   1032 **/
   1033 UINTN
   1034 EdbDisasmLOADSP (
   1035   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1036   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1037   OUT    CHAR16                    **DisasmString
   1038   )
   1039 {
   1040   UINT8  Operands;
   1041 
   1042   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_LOADSP);
   1043 
   1044   Operands   = GET_OPERANDS (InstructionAddress);
   1045 
   1046   //
   1047   // Construct Disasm String
   1048   //
   1049   if (DisasmString != NULL) {
   1050     *DisasmString = EdbPreInstructionString ();
   1051 
   1052     EdbPrintInstructionName (L"LOADSP");
   1053 
   1054     EdbPrintDedicatedRegister1 (Operands);
   1055 
   1056     EdbPrintRegister2 (Operands);
   1057 
   1058     EdbPostInstructionString ();
   1059   }
   1060 
   1061   return 2;
   1062 }
   1063 
   1064 /**
   1065 
   1066   Disasm instruction - STORESP.
   1067 
   1068   @param  InstructionAddress - The instruction address
   1069   @param  SystemContext      - EBC system context.
   1070   @param  DisasmString       - The instruction string
   1071 
   1072   @return Instruction length
   1073 
   1074 **/
   1075 UINTN
   1076 EdbDisasmSTORESP (
   1077   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1078   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1079   OUT    CHAR16                    **DisasmString
   1080   )
   1081 {
   1082   UINT8  Operands;
   1083 
   1084   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_STORESP);
   1085 
   1086   Operands   = GET_OPERANDS (InstructionAddress);
   1087 
   1088   //
   1089   // Construct Disasm String
   1090   //
   1091   if (DisasmString != NULL) {
   1092     *DisasmString = EdbPreInstructionString ();
   1093 
   1094     EdbPrintInstructionName (L"STORESP");
   1095 
   1096     EdbPrintRegister1 (Operands);
   1097 
   1098     EdbPrintDedicatedRegister2 (Operands);
   1099 
   1100     EdbPostInstructionString ();
   1101   }
   1102 
   1103   return 2;
   1104 }
   1105 
   1106 
   1107 /**
   1108 
   1109   Disasm instruction - PUSH.
   1110 
   1111   @param  InstructionAddress - The instruction address
   1112   @param  SystemContext      - EBC system context.
   1113   @param  DisasmString       - The instruction string
   1114 
   1115   @return Instruction length
   1116 
   1117 **/
   1118 UINTN
   1119 EdbDisasmPUSH (
   1120   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1121   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1122   OUT    CHAR16                    **DisasmString
   1123   )
   1124 {
   1125   UINT8  Modifiers;
   1126   UINT8  Operands;
   1127   UINTN  Size;
   1128   UINT16 Data16;
   1129 
   1130   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_PUSH);
   1131 
   1132   Operands   = GET_OPERANDS (InstructionAddress);
   1133   Modifiers  = GET_MODIFIERS (InstructionAddress);
   1134   if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
   1135     Size = 4;
   1136   } else {
   1137     Size = 2;
   1138   }
   1139 
   1140   //
   1141   // Construct Disasm String
   1142   //
   1143   if (DisasmString != NULL) {
   1144     *DisasmString = EdbPreInstructionString ();
   1145 
   1146     EdbPrintInstructionName (L"PUSH");
   1147 //    if (Modifiers & PUSHPOP_M_64) {
   1148 //      EdbPrintInstructionName (L"64");
   1149 //    } else {
   1150 //      EdbPrintInstructionName (L"32");
   1151 //    }
   1152 
   1153     EdbPrintRegister1 (Operands);
   1154 
   1155     InstructionAddress += 2;
   1156     if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
   1157       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1158       if ((Operands & OPERAND_M_INDIRECT1) != 0) {
   1159         EdbPrintRawIndexData16 (Data16);
   1160       } else {
   1161         EdbPrintImmDatan (Data16);
   1162       }
   1163     }
   1164 
   1165     EdbPostInstructionString ();
   1166   }
   1167 
   1168   return Size;
   1169 }
   1170 
   1171 /**
   1172 
   1173   Disasm instruction - POP.
   1174 
   1175   @param  InstructionAddress - The instruction address
   1176   @param  SystemContext      - EBC system context.
   1177   @param  DisasmString       - The instruction string
   1178 
   1179   @return Instruction length
   1180 
   1181 **/
   1182 UINTN
   1183 EdbDisasmPOP (
   1184   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1185   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1186   OUT    CHAR16                    **DisasmString
   1187   )
   1188 {
   1189   UINT8  Modifiers;
   1190   UINT8  Operands;
   1191   UINTN  Size;
   1192   UINT16 Data16;
   1193 
   1194   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_POP);
   1195 
   1196   Operands   = GET_OPERANDS (InstructionAddress);
   1197   Modifiers  = GET_MODIFIERS (InstructionAddress);
   1198   if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
   1199     Size = 4;
   1200   } else {
   1201     Size = 2;
   1202   }
   1203 
   1204   //
   1205   // Construct Disasm String
   1206   //
   1207   if (DisasmString != NULL) {
   1208     *DisasmString = EdbPreInstructionString ();
   1209 
   1210     EdbPrintInstructionName (L"POP");
   1211 //    if (Modifiers & PUSHPOP_M_64) {
   1212 //      EdbPrintInstructionName (L"64");
   1213 //    } else {
   1214 //      EdbPrintInstructionName (L"32");
   1215 //    }
   1216 
   1217     EdbPrintRegister1 (Operands);
   1218 
   1219     InstructionAddress += 2;
   1220     if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
   1221       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1222       if ((Operands & OPERAND_M_INDIRECT1) != 0) {
   1223         EdbPrintRawIndexData16 (Data16);
   1224       } else {
   1225         EdbPrintImmDatan (Data16);
   1226       }
   1227     }
   1228 
   1229     EdbPostInstructionString ();
   1230   }
   1231 
   1232   return Size;
   1233 }
   1234 
   1235 /**
   1236 
   1237   Disasm instruction - CMPI.
   1238 
   1239   @param  InstructionAddress - The instruction address
   1240   @param  SystemContext      - EBC system context.
   1241   @param  DisasmString       - The instruction string
   1242 
   1243   @return Instruction length
   1244 
   1245 **/
   1246 UINTN
   1247 EdbDisasmCMPI (
   1248   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1249   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1250   OUT    CHAR16                    **DisasmString
   1251   )
   1252 {
   1253   UINT8  Modifiers;
   1254   UINT8  Opcode;
   1255   UINT8  Operands;
   1256   UINT16 Data16;
   1257   UINT32 Data32;
   1258   UINTN  Size;
   1259 
   1260   ASSERT (
   1261     (GET_OPCODE(InstructionAddress) == OPCODE_CMPIEQ)   ||
   1262     (GET_OPCODE(InstructionAddress) == OPCODE_CMPILTE)  ||
   1263     (GET_OPCODE(InstructionAddress) == OPCODE_CMPIGTE)  ||
   1264     (GET_OPCODE(InstructionAddress) == OPCODE_CMPIULTE) ||
   1265     (GET_OPCODE(InstructionAddress) == OPCODE_CMPIUGTE)
   1266     );
   1267 
   1268   Modifiers  = GET_MODIFIERS (InstructionAddress);
   1269   Opcode     = GET_OPCODE (InstructionAddress);
   1270   Operands   = GET_OPERANDS (InstructionAddress);
   1271 
   1272   if ((Operands & 0xE0) != 0) {
   1273     return 0;
   1274   }
   1275 
   1276   Size = 2;
   1277   if ((Operands & OPERAND_M_CMPI_INDEX) != 0) {
   1278     Size += 2;
   1279   }
   1280   if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) {
   1281     Size += 4;
   1282   } else {
   1283     Size += 2;
   1284   }
   1285 
   1286   //
   1287   // Construct Disasm String
   1288   //
   1289   if (DisasmString != NULL) {
   1290     *DisasmString = EdbPreInstructionString ();
   1291 
   1292     EdbPrintInstructionName (L"CMPI");
   1293 //    if (Modifiers & OPCODE_M_CMPI64) {
   1294 //      EdbPrintInstructionName (L"64");
   1295 //    } else {
   1296 //      EdbPrintInstructionName (L"32");
   1297 //    }
   1298     if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) {
   1299       EdbPrintInstructionName (L"d");
   1300     } else {
   1301       EdbPrintInstructionName (L"w");
   1302     }
   1303     switch (Opcode) {
   1304     case OPCODE_CMPIEQ:
   1305       EdbPrintInstructionName (L"eq");
   1306       break;
   1307     case OPCODE_CMPILTE:
   1308       EdbPrintInstructionName (L"lte");
   1309       break;
   1310     case OPCODE_CMPIGTE:
   1311       EdbPrintInstructionName (L"gte");
   1312       break;
   1313     case OPCODE_CMPIULTE:
   1314       EdbPrintInstructionName (L"ulte");
   1315       break;
   1316     case OPCODE_CMPIUGTE:
   1317       EdbPrintInstructionName (L"ugte");
   1318       break;
   1319     }
   1320 
   1321     EdbPrintRegister1 (Operands);
   1322 
   1323     InstructionAddress += 2;
   1324     if ((Operands & OPERAND_M_CMPI_INDEX) != 0) {
   1325       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1326       InstructionAddress += 2;
   1327       EdbPrintRawIndexData16 (Data16);
   1328     }
   1329 
   1330     EdbPrintComma ();
   1331 
   1332     if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) {
   1333       CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
   1334       EdbPrintDatan (Data32);
   1335     } else {
   1336       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1337       EdbPrintDatan (Data16);
   1338     }
   1339 
   1340     EdbPostInstructionString ();
   1341   }
   1342 
   1343   return Size;
   1344 }
   1345 
   1346 /**
   1347 
   1348   Disasm instruction - PUSHn.
   1349 
   1350   @param  InstructionAddress - The instruction address
   1351   @param  SystemContext      - EBC system context.
   1352   @param  DisasmString       - The instruction string
   1353 
   1354   @return Instruction length
   1355 
   1356 **/
   1357 UINTN
   1358 EdbDisasmPUSHn (
   1359   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1360   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1361   OUT    CHAR16                    **DisasmString
   1362   )
   1363 {
   1364   UINT8  Modifiers;
   1365   UINT8  Operands;
   1366   UINTN  Size;
   1367   UINT16 Data16;
   1368 
   1369   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_PUSHN);
   1370 
   1371   Operands   = GET_OPERANDS (InstructionAddress);
   1372   Modifiers  = GET_MODIFIERS (InstructionAddress);
   1373   if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
   1374     Size = 4;
   1375   } else {
   1376     Size = 2;
   1377   }
   1378 
   1379   //
   1380   // Construct Disasm String
   1381   //
   1382   if (DisasmString != NULL) {
   1383     *DisasmString = EdbPreInstructionString ();
   1384 
   1385     EdbPrintInstructionName (L"PUSHn");
   1386 
   1387     EdbPrintRegister1 (Operands);
   1388 
   1389     InstructionAddress += 2;
   1390     if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
   1391       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1392       if ((Operands & OPERAND_M_INDIRECT1) != 0) {
   1393         EdbPrintRawIndexData16 (Data16);
   1394       } else {
   1395         EdbPrintImmDatan (Data16);
   1396       }
   1397     }
   1398 
   1399     EdbPostInstructionString ();
   1400   }
   1401 
   1402   return Size;
   1403 }
   1404 
   1405 /**
   1406 
   1407   Disasm instruction - POPn.
   1408 
   1409   @param  InstructionAddress - The instruction address
   1410   @param  SystemContext      - EBC system context.
   1411   @param  DisasmString       - The instruction string
   1412 
   1413   @return Instruction length
   1414 
   1415 **/
   1416 UINTN
   1417 EdbDisasmPOPn (
   1418   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1419   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1420   OUT    CHAR16                    **DisasmString
   1421   )
   1422 {
   1423   UINT8  Modifiers;
   1424   UINT8  Operands;
   1425   UINTN  Size;
   1426   UINT16 Data16;
   1427 
   1428   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_POPN);
   1429 
   1430   Operands   = GET_OPERANDS (InstructionAddress);
   1431   Modifiers  = GET_MODIFIERS (InstructionAddress);
   1432   if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
   1433     Size = 4;
   1434   } else {
   1435     Size = 2;
   1436   }
   1437 
   1438   //
   1439   // Construct Disasm String
   1440   //
   1441   if (DisasmString != NULL) {
   1442     *DisasmString = EdbPreInstructionString ();
   1443 
   1444     EdbPrintInstructionName (L"POPn");
   1445 
   1446     EdbPrintRegister1 (Operands);
   1447 
   1448     InstructionAddress += 2;
   1449     if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
   1450       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1451       if ((Operands & OPERAND_M_INDIRECT1) != 0) {
   1452         EdbPrintRawIndexData16 (Data16);
   1453       } else {
   1454         EdbPrintImmDatan (Data16);
   1455       }
   1456     }
   1457 
   1458     EdbPostInstructionString ();
   1459   }
   1460 
   1461   return Size;
   1462 }
   1463 
   1464 /**
   1465 
   1466   Disasm instruction - MOVI.
   1467 
   1468   @param  InstructionAddress - The instruction address
   1469   @param  SystemContext      - EBC system context.
   1470   @param  DisasmString       - The instruction string
   1471 
   1472   @return Instruction length
   1473 
   1474 **/
   1475 UINTN
   1476 EdbDisasmMOVI (
   1477   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1478   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1479   OUT    CHAR16                    **DisasmString
   1480   )
   1481 {
   1482   UINT8  Modifiers;
   1483   UINT8  Operands;
   1484   UINTN  Size;
   1485   UINT16 Data16;
   1486   UINT32 Data32;
   1487   UINT64 Data64;
   1488 
   1489   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVI);
   1490 
   1491   Modifiers  = GET_MODIFIERS (InstructionAddress);
   1492   Operands   = GET_OPERANDS (InstructionAddress);
   1493 
   1494   if ((Operands & MOVI_M_IMMDATA) != 0) {
   1495     Size    = 4;
   1496   } else {
   1497     Size    = 2;
   1498   }
   1499   if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
   1500     Size += 2;
   1501   } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
   1502     Size += 4;
   1503   } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
   1504     Size += 8;
   1505   }
   1506 
   1507   //
   1508   // Construct Disasm String
   1509   //
   1510   if (DisasmString != NULL) {
   1511     *DisasmString = EdbPreInstructionString ();
   1512 
   1513     EdbPrintInstructionName (L"MOVI");
   1514     switch (Operands & MOVI_M_MOVEWIDTH) {
   1515     case MOVI_MOVEWIDTH8:
   1516       EdbPrintInstructionName (L"b");
   1517       break;
   1518     case MOVI_MOVEWIDTH16:
   1519       EdbPrintInstructionName (L"w");
   1520       break;
   1521     case MOVI_MOVEWIDTH32:
   1522       EdbPrintInstructionName (L"d");
   1523       break;
   1524     case MOVI_MOVEWIDTH64:
   1525       EdbPrintInstructionName (L"q");
   1526       break;
   1527     }
   1528     switch (Modifiers & MOVI_M_DATAWIDTH) {
   1529     case MOVI_DATAWIDTH16:
   1530       EdbPrintInstructionName (L"w");
   1531       break;
   1532     case MOVI_DATAWIDTH32:
   1533       EdbPrintInstructionName (L"d");
   1534       break;
   1535     case MOVI_DATAWIDTH64:
   1536       EdbPrintInstructionName (L"q");
   1537       break;
   1538     }
   1539 
   1540     EdbPrintRegister1 (Operands);
   1541 
   1542     InstructionAddress += 2;
   1543     if ((Operands & MOVI_M_IMMDATA) != 0) {
   1544       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1545       InstructionAddress += 2;
   1546       EdbPrintRawIndexData16 (Data16);
   1547     }
   1548 
   1549     EdbPrintComma ();
   1550 
   1551     switch (Modifiers & MOVI_M_DATAWIDTH) {
   1552     case MOVI_DATAWIDTH16:
   1553       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1554       EdbPrintDatan (Data16);
   1555       break;
   1556     case MOVI_DATAWIDTH32:
   1557       CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
   1558       EdbPrintDatan (Data32);
   1559       break;
   1560     case MOVI_DATAWIDTH64:
   1561       CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
   1562       EdbPrintData64n (Data64);
   1563       break;
   1564     }
   1565 
   1566     EdbPostInstructionString ();
   1567   }
   1568 
   1569   return Size;
   1570 }
   1571 
   1572 /**
   1573 
   1574   Disasm instruction - MOVIn.
   1575 
   1576   @param  InstructionAddress - The instruction address
   1577   @param  SystemContext      - EBC system context.
   1578   @param  DisasmString       - The instruction string
   1579 
   1580   @return Instruction length
   1581 
   1582 **/
   1583 UINTN
   1584 EdbDisasmMOVIn (
   1585   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1586   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1587   OUT    CHAR16                    **DisasmString
   1588   )
   1589 {
   1590   UINT8  Modifiers;
   1591   UINT8  Operands;
   1592   UINTN  Size;
   1593   UINT16 Data16;
   1594   UINT32 Data32;
   1595   UINT64 Data64;
   1596 
   1597   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVIN);
   1598 
   1599   Modifiers  = GET_MODIFIERS (InstructionAddress);
   1600   Operands   = GET_OPERANDS (InstructionAddress);
   1601 
   1602   if ((Operands & MOVI_M_IMMDATA) != 0) {
   1603     Size    = 4;
   1604   } else {
   1605     Size    = 2;
   1606   }
   1607   if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
   1608     Size += 2;
   1609   } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
   1610     Size += 4;
   1611   } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
   1612     Size += 8;
   1613   }
   1614 
   1615   //
   1616   // Construct Disasm String
   1617   //
   1618   if (DisasmString != NULL) {
   1619     *DisasmString = EdbPreInstructionString ();
   1620 
   1621     EdbPrintInstructionName (L"MOVIn");
   1622     switch (Modifiers & MOVI_M_DATAWIDTH) {
   1623     case MOVI_DATAWIDTH16:
   1624       EdbPrintInstructionName (L"w");
   1625       break;
   1626     case MOVI_DATAWIDTH32:
   1627       EdbPrintInstructionName (L"d");
   1628       break;
   1629     case MOVI_DATAWIDTH64:
   1630       EdbPrintInstructionName (L"q");
   1631       break;
   1632     }
   1633 
   1634     EdbPrintRegister1 (Operands);
   1635 
   1636     InstructionAddress += 2;
   1637     if ((Operands & MOVI_M_IMMDATA) != 0) {
   1638       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1639       InstructionAddress += 2;
   1640       EdbPrintRawIndexData16 (Data16);
   1641     }
   1642 
   1643     EdbPrintComma ();
   1644 
   1645     switch (Modifiers & MOVI_M_DATAWIDTH) {
   1646     case MOVI_DATAWIDTH16:
   1647       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1648       EdbPrintRawIndexData16 (Data16);
   1649       break;
   1650     case MOVI_DATAWIDTH32:
   1651       CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
   1652       EdbPrintRawIndexData32 (Data32);
   1653       break;
   1654     case MOVI_DATAWIDTH64:
   1655       CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
   1656       EdbPrintRawIndexData64 (Data64);
   1657       break;
   1658     }
   1659 
   1660     EdbPostInstructionString ();
   1661   }
   1662 
   1663   return Size;
   1664 }
   1665 
   1666 /**
   1667 
   1668   Disasm instruction - MOVREL.
   1669 
   1670   @param  InstructionAddress - The instruction address
   1671   @param  SystemContext      - EBC system context.
   1672   @param  DisasmString       - The instruction string
   1673 
   1674   @return Instruction length
   1675 
   1676 **/
   1677 UINTN
   1678 EdbDisasmMOVREL (
   1679   IN     EFI_PHYSICAL_ADDRESS      InstructionAddress,
   1680   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1681   OUT    CHAR16                    **DisasmString
   1682   )
   1683 {
   1684   UINT8   Modifiers;
   1685   UINT8   Operands;
   1686   UINTN   Size;
   1687   UINT16  Data16;
   1688   UINT32  Data32;
   1689   UINT64  Data64;
   1690   UINTN   Result;
   1691   EFI_PHYSICAL_ADDRESS      SavedInstructionAddress;
   1692 
   1693   ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVREL);
   1694   SavedInstructionAddress = InstructionAddress;
   1695 
   1696   Modifiers  = GET_MODIFIERS (InstructionAddress);
   1697   Operands   = GET_OPERANDS (InstructionAddress);
   1698 
   1699   if ((Operands & MOVI_M_IMMDATA) != 0) {
   1700     Size    = 4;
   1701   } else {
   1702     Size    = 2;
   1703   }
   1704   if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
   1705     Size += 2;
   1706   } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
   1707     Size += 4;
   1708   } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
   1709     Size += 8;
   1710   } else {
   1711     return 0;
   1712   }
   1713 
   1714   //
   1715   // Construct Disasm String
   1716   //
   1717   if (DisasmString != NULL) {
   1718     *DisasmString = EdbPreInstructionString ();
   1719 
   1720     EdbPrintInstructionName (L"MOVrel");
   1721     switch (Modifiers & MOVI_M_DATAWIDTH) {
   1722     case MOVI_DATAWIDTH16:
   1723       EdbPrintInstructionName (L"w");
   1724       break;
   1725     case MOVI_DATAWIDTH32:
   1726       EdbPrintInstructionName (L"d");
   1727       break;
   1728     case MOVI_DATAWIDTH64:
   1729       EdbPrintInstructionName (L"q");
   1730       break;
   1731     }
   1732 
   1733     EdbPrintRegister1 (Operands);
   1734 
   1735     InstructionAddress += 2;
   1736     if ((Operands & MOVI_M_IMMDATA) != 0) {
   1737       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1738       InstructionAddress += 2;
   1739       EdbPrintRawIndexData16 (Data16);
   1740     }
   1741 
   1742     EdbPrintComma ();
   1743 
   1744     switch (Modifiers & MOVI_M_DATAWIDTH) {
   1745     case MOVI_DATAWIDTH16:
   1746       CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
   1747       Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT16)Data16));
   1748       if (Result == 0) {
   1749         EdbPrintData16 (Data16);
   1750       }
   1751       break;
   1752     case MOVI_DATAWIDTH32:
   1753       CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
   1754       Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT32)Data32));
   1755       if (Result == 0) {
   1756         EdbPrintData32 (Data32);
   1757       }
   1758       break;
   1759     case MOVI_DATAWIDTH64:
   1760       CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
   1761       if (sizeof(UINTN) == sizeof(UINT64)) {
   1762         Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT64)Data64));
   1763       } else {
   1764         Result = 0;
   1765       }
   1766       if (Result == 0) {
   1767         EdbPrintData64 (Data64);
   1768       }
   1769       break;
   1770     }
   1771 
   1772     EdbPostInstructionString ();
   1773   }
   1774 
   1775   return Size;
   1776 }
   1777