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 extern EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[];
     18 
     19 typedef struct {
     20   CHAR16    Name[EDB_INSTRUCTION_NAME_MAX_LENGTH];
     21   CHAR16    Content[EDB_INSTRUCTION_CONTENT_MAX_LENGTH];
     22   CHAR16    Tail;
     23 } EDB_INSTRUCTION_STRING;
     24 
     25 EDB_INSTRUCTION_STRING mInstructionString;
     26 UINTN                  mInstructionNameOffset;
     27 UINTN                  mInstructionContentOffset;
     28 
     29 /**
     30 
     31   Set offset for Instruction name and content.
     32 
     33   @param  InstructionNameOffset     - Instruction name offset
     34   @param  InstructionContentOffset  - Instruction content offset
     35 
     36 **/
     37 VOID
     38 EdbSetOffset (
     39   IN UINTN InstructionNameOffset,
     40   IN UINTN InstructionContentOffset
     41   )
     42 {
     43   mInstructionNameOffset = InstructionNameOffset;
     44   mInstructionContentOffset = InstructionContentOffset;
     45 
     46   return ;
     47 }
     48 
     49 /**
     50 
     51   Pre instruction string construction.
     52 
     53   @return Instruction string
     54 
     55 **/
     56 CHAR16 *
     57 EdbPreInstructionString (
     58   VOID
     59   )
     60 {
     61   ZeroMem (&mInstructionString, sizeof(mInstructionString));
     62   mInstructionNameOffset    = 0;
     63   mInstructionContentOffset = 0;
     64 
     65   return (CHAR16 *)&mInstructionString;
     66 }
     67 
     68 /**
     69 
     70   Post instruction string construction.
     71 
     72   @return Instruction string
     73 
     74 **/
     75 CHAR16 *
     76 EdbPostInstructionString (
     77   VOID
     78   )
     79 {
     80   CHAR16 *Char;
     81 
     82   for (Char = (CHAR16 *)&mInstructionString; Char < &mInstructionString.Tail; Char++) {
     83     if (*Char == 0) {
     84       *Char = L' ';
     85     }
     86   }
     87   mInstructionString.Tail = 0;
     88 
     89   mInstructionNameOffset    = 0;
     90   mInstructionContentOffset = 0;
     91 
     92   return (CHAR16 *)&mInstructionString;
     93 }
     94 
     95 /**
     96 
     97   Get Sign, NaturalUnits, and ConstantUnits of the WORD data.
     98 
     99   @param  Data16        - WORD data
    100   @param  NaturalUnits  - Natural Units of the WORD
    101   @param  ConstantUnits - Constant Units of the WORD
    102 
    103   @return Sign value of WORD
    104 
    105 **/
    106 BOOLEAN
    107 EdbGetNaturalIndex16 (
    108   IN  UINT16  Data16,
    109   OUT UINTN   *NaturalUnits,
    110   OUT UINTN   *ConstantUnits
    111   )
    112 {
    113   BOOLEAN Sign;
    114   UINTN   NaturalUnitBit;
    115 
    116   Sign = (BOOLEAN)(Data16 >> 15);
    117   NaturalUnitBit = (UINTN)((Data16 >> 12) & 0x7);
    118   NaturalUnitBit *= 2;
    119   Data16 = Data16 & 0xFFF;
    120   *NaturalUnits = (UINTN)(Data16 & ((1 << NaturalUnitBit) - 1));
    121   *ConstantUnits = (UINTN)((Data16 >> NaturalUnitBit) & ((1 << (12 - NaturalUnitBit)) - 1));
    122 
    123   return Sign;
    124 }
    125 
    126 /**
    127 
    128   Get Sign, NaturalUnits, and ConstantUnits of the DWORD data.
    129 
    130   @param  Data32        - DWORD data
    131   @param  NaturalUnits  - Natural Units of the DWORD
    132   @param  ConstantUnits - Constant Units of the DWORD
    133 
    134   @return Sign value of DWORD
    135 
    136 **/
    137 BOOLEAN
    138 EdbGetNaturalIndex32 (
    139   IN  UINT32  Data32,
    140   OUT UINTN   *NaturalUnits,
    141   OUT UINTN   *ConstantUnits
    142   )
    143 {
    144   BOOLEAN Sign;
    145   UINTN   NaturalUnitBit;
    146 
    147   Sign = (BOOLEAN)(Data32 >> 31);
    148   NaturalUnitBit = (UINTN)((Data32 >> 28) & 0x7);
    149   NaturalUnitBit *= 4;
    150   Data32 = Data32 & 0xFFFFFFF;
    151   *NaturalUnits = (UINTN)(Data32 & ((1 << NaturalUnitBit) - 1));
    152   *ConstantUnits = (UINTN)((Data32 >> NaturalUnitBit) & ((1 << (28 - NaturalUnitBit)) - 1));
    153 
    154   return Sign;
    155 }
    156 
    157 /**
    158 
    159   Get Sign, NaturalUnits, and ConstantUnits of the QWORD data.
    160 
    161   @param  Data64        - QWORD data
    162   @param  NaturalUnits  - Natural Units of the QWORD
    163   @param  ConstantUnits - Constant Units of the QWORD
    164 
    165   @return Sign value of QWORD
    166 
    167 **/
    168 BOOLEAN
    169 EdbGetNaturalIndex64 (
    170   IN  UINT64  Data64,
    171   OUT UINT64  *NaturalUnits,
    172   OUT UINT64  *ConstantUnits
    173   )
    174 {
    175   BOOLEAN Sign;
    176   UINTN   NaturalUnitBit;
    177 
    178   Sign = (BOOLEAN)RShiftU64 (Data64, 63);
    179   NaturalUnitBit = (UINTN)(RShiftU64 (Data64, 60) & 0x7);
    180   NaturalUnitBit *= 8;
    181   Data64 = RShiftU64 (LShiftU64 (Data64, 4), 4);
    182   *NaturalUnits = (UINT64)(Data64 & (LShiftU64 (1, NaturalUnitBit) - 1));
    183   *ConstantUnits = (UINT64)(RShiftU64 (Data64, NaturalUnitBit) & (LShiftU64 (1, (60 - NaturalUnitBit)) - 1));
    184 
    185   return Sign;
    186 }
    187 
    188 /**
    189 
    190   Get Bit Width of the value.
    191 
    192   @param  Value - data
    193 
    194   @return Bit width
    195 
    196 **/
    197 UINT8
    198 EdbGetBitWidth (
    199   IN UINT64  Value
    200   )
    201 {
    202   if (Value >= 10000000000000) {
    203     return 14;
    204   } else if (Value >= 1000000000000) {
    205     return 13;
    206   } else if (Value >= 100000000000) {
    207     return 12;
    208   } else if (Value >= 10000000000) {
    209     return 11;
    210   } else if (Value >= 1000000000) {
    211     return 10;
    212   } else if (Value >= 100000000) {
    213     return 9;
    214   } else if (Value >= 10000000) {
    215     return 8;
    216   } else if (Value >= 1000000) {
    217     return 7;
    218   } else if (Value >= 100000) {
    219     return 6;
    220   } else if (Value >= 10000) {
    221     return 5;
    222   } else if (Value >= 1000) {
    223     return 4;
    224   } else if (Value >= 100) {
    225     return 3;
    226   } else if (Value >= 10) {
    227     return 2;
    228   } else {
    229     return 1;
    230   }
    231 }
    232 
    233 /**
    234 
    235   Print the instruction name.
    236 
    237   @param  Name - instruction name
    238 
    239   @return Instruction name offset
    240 
    241 **/
    242 UINTN
    243 EdbPrintInstructionName (
    244   IN CHAR16                 *Name
    245   )
    246 {
    247   EDBSPrintWithOffset (
    248     mInstructionString.Name,
    249     EDB_INSTRUCTION_NAME_MAX_SIZE,
    250     mInstructionNameOffset,
    251     L"%s",
    252     Name
    253     );
    254   mInstructionNameOffset += StrLen (Name);
    255 
    256   return mInstructionNameOffset;
    257 }
    258 
    259 /**
    260 
    261   Print register 1 in operands.
    262 
    263   @param  Operands - instruction operands
    264 
    265   @return Instruction content offset
    266 
    267 **/
    268 UINTN
    269 EdbPrintRegister1 (
    270   IN UINT8                  Operands
    271   )
    272 {
    273   if ((Operands & OPERAND_M_INDIRECT1) != 0) {
    274     EDBSPrintWithOffset (
    275       mInstructionString.Content,
    276       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    277       mInstructionContentOffset,
    278       L"@"
    279       );
    280     mInstructionContentOffset += 1;
    281   }
    282   EDBSPrintWithOffset (
    283     mInstructionString.Content,
    284     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    285     mInstructionContentOffset,
    286     L"R%d",
    287     (UINTN)(Operands & OPERAND_M_OP1)
    288     );
    289   mInstructionContentOffset += 2;
    290 
    291   return mInstructionContentOffset;
    292 }
    293 
    294 /**
    295 
    296   Print register 2 in operands.
    297 
    298   @param  Operands - instruction operands
    299 
    300   @return Instruction content offset
    301 
    302 **/
    303 UINTN
    304 EdbPrintRegister2 (
    305   IN UINT8                  Operands
    306   )
    307 {
    308   if ((Operands & OPERAND_M_INDIRECT2) != 0) {
    309     EDBSPrintWithOffset (
    310       mInstructionString.Content,
    311       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    312       mInstructionContentOffset,
    313       L"@"
    314       );
    315     mInstructionContentOffset += 1;
    316   }
    317   EDBSPrintWithOffset (
    318     mInstructionString.Content,
    319     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    320     mInstructionContentOffset,
    321     L"R%d",
    322     (UINTN)((Operands & OPERAND_M_OP2) >> 4)
    323     );
    324   mInstructionContentOffset += 2;
    325 
    326   return mInstructionContentOffset;
    327 }
    328 
    329 /**
    330 
    331   Print dedicated register 1 in operands.
    332 
    333   @param Operands - instruction operands
    334 
    335   @return Instruction content offset
    336 
    337 **/
    338 UINTN
    339 EdbPrintDedicatedRegister1 (
    340   IN UINT8                  Operands
    341   )
    342 {
    343   switch (Operands & OPERAND_M_OP1) {
    344   case 0:
    345     EDBSPrintWithOffset (
    346       mInstructionString.Content,
    347       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    348       mInstructionContentOffset,
    349       L"[FLAGS]"
    350       );
    351     mInstructionContentOffset += 7;
    352     break;
    353   case 1:
    354     EDBSPrintWithOffset (
    355       mInstructionString.Content,
    356       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    357       mInstructionContentOffset,
    358       L"[IP]"
    359       );
    360     mInstructionContentOffset += 4;
    361     break;
    362   }
    363 
    364   return mInstructionContentOffset;
    365 }
    366 
    367 /**
    368 
    369   Print dedicated register 2 in operands.
    370 
    371   @param  Operands - instruction operands
    372 
    373   @return Instruction content offset
    374 
    375 **/
    376 UINTN
    377 EdbPrintDedicatedRegister2 (
    378   IN UINT8                  Operands
    379   )
    380 {
    381   switch ((Operands & OPERAND_M_OP2) >> 4) {
    382   case 0:
    383     EDBSPrintWithOffset (
    384       mInstructionString.Content,
    385       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    386       mInstructionContentOffset,
    387       L"[FLAGS]"
    388       );
    389     mInstructionContentOffset += 7;
    390     break;
    391   case 1:
    392     EDBSPrintWithOffset (
    393       mInstructionString.Content,
    394       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    395       mInstructionContentOffset,
    396       L"[IP]"
    397       );
    398     mInstructionContentOffset += 4;
    399     break;
    400   }
    401 
    402   return mInstructionContentOffset;
    403 }
    404 
    405 /**
    406 
    407   Print the hexical UINTN index data to instruction content.
    408 
    409   @param  Sign          - Signed bit of UINTN data
    410   @param  NaturalUnits  - natural units of UINTN data
    411   @param  ConstantUnits - natural units of UINTN data
    412 
    413   @return Instruction content offset
    414 
    415 **/
    416 UINTN
    417 EdbPrintIndexData (
    418   IN BOOLEAN                Sign,
    419   IN UINTN                  NaturalUnits,
    420   IN UINTN                  ConstantUnits
    421   )
    422 {
    423   EDBSPrintWithOffset (
    424     mInstructionString.Content,
    425     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    426     mInstructionContentOffset,
    427     L"(%s%d,%s%d)",
    428     Sign ? L"-" : L"+",
    429     NaturalUnits,
    430     Sign ? L"-" : L"+",
    431     ConstantUnits
    432     );
    433   mInstructionContentOffset  = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits);
    434 
    435   return mInstructionContentOffset;
    436 }
    437 
    438 /**
    439 
    440   Print the hexical QWORD index data to instruction content.
    441 
    442   @param  Sign          - Signed bit of QWORD data
    443   @param  NaturalUnits  - natural units of QWORD data
    444   @param  ConstantUnits - natural units of QWORD data
    445 
    446   @return Instruction content offset
    447 
    448 **/
    449 UINTN
    450 EdbPrintIndexData64 (
    451   IN BOOLEAN                Sign,
    452   IN UINT64                 NaturalUnits,
    453   IN UINT64                 ConstantUnits
    454   )
    455 {
    456   EDBSPrintWithOffset (
    457     mInstructionString.Content,
    458     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    459     mInstructionContentOffset,
    460     L"(%s%ld,%s%ld)",
    461     Sign ? L"-" : L"+",
    462     NaturalUnits,
    463     Sign ? L"-" : L"+",
    464     ConstantUnits
    465     );
    466   mInstructionContentOffset  = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits);
    467 
    468   return mInstructionContentOffset;
    469 }
    470 
    471 /**
    472 
    473   Print the hexical WORD raw index data to instruction content.
    474 
    475   @param  Data16 - WORD data
    476 
    477   @return Instruction content offset
    478 
    479 **/
    480 UINTN
    481 EdbPrintRawIndexData16 (
    482   IN UINT16                 Data16
    483   )
    484 {
    485   BOOLEAN Sign;
    486   UINTN   NaturalUnits;
    487   UINTN   ConstantUnits;
    488   UINTN   Offset;
    489 
    490   Sign = EdbGetNaturalIndex16 (Data16, &NaturalUnits, &ConstantUnits);
    491   Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits);
    492 
    493   return Offset;
    494 }
    495 
    496 /**
    497 
    498   Print the hexical DWORD raw index data to instruction content.
    499 
    500   @param  Data32 - DWORD data
    501 
    502   @return Instruction content offset
    503 
    504 **/
    505 UINTN
    506 EdbPrintRawIndexData32 (
    507   IN UINT32                 Data32
    508   )
    509 {
    510   BOOLEAN Sign;
    511   UINTN   NaturalUnits;
    512   UINTN   ConstantUnits;
    513   UINTN   Offset;
    514 
    515   Sign = EdbGetNaturalIndex32 (Data32, &NaturalUnits, &ConstantUnits);
    516   Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits);
    517 
    518   return Offset;
    519 }
    520 
    521 /**
    522 
    523   Print the hexical QWORD raw index data to instruction content.
    524 
    525   @param  Data64 - QWORD data
    526 
    527   @return Instruction content offset
    528 
    529 **/
    530 UINTN
    531 EdbPrintRawIndexData64 (
    532   IN UINT64                 Data64
    533   )
    534 {
    535   BOOLEAN Sign;
    536   UINT64  NaturalUnits;
    537   UINT64  ConstantUnits;
    538   UINTN   Offset;
    539 
    540   Sign = EdbGetNaturalIndex64 (Data64, &NaturalUnits, &ConstantUnits);
    541   Offset = EdbPrintIndexData64 (Sign, NaturalUnits, ConstantUnits);
    542 
    543   return Offset;
    544 }
    545 
    546 /**
    547 
    548   Print the hexical BYTE immediate data to instruction content.
    549 
    550   @param  Data - BYTE data
    551 
    552   @return Instruction content offset
    553 
    554 **/
    555 UINTN
    556 EdbPrintImmData8 (
    557   IN UINT8                  Data
    558   )
    559 {
    560   EDBSPrintWithOffset (
    561     mInstructionString.Content,
    562     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    563     mInstructionContentOffset,
    564     L"(0x%02x)",
    565     (UINTN)Data
    566     );
    567   mInstructionContentOffset  += 6;
    568 
    569   return mInstructionContentOffset;
    570 }
    571 
    572 /**
    573 
    574   Print the hexical WORD immediate data to instruction content.
    575 
    576   @param  Data - WORD data
    577 
    578   @return Instruction content offset
    579 
    580 **/
    581 UINTN
    582 EdbPrintImmData16 (
    583   IN UINT16                 Data
    584   )
    585 {
    586   EDBSPrintWithOffset (
    587     mInstructionString.Content,
    588     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    589     mInstructionContentOffset,
    590     L"(0x%04x)",
    591     (UINTN)Data
    592     );
    593   mInstructionContentOffset  += 8;
    594 
    595   return mInstructionContentOffset;
    596 }
    597 
    598 /**
    599 
    600   Print the hexical DWORD immediate data to instruction content.
    601 
    602   @param  Data - DWORD data
    603 
    604   @return Instruction content offset
    605 
    606 **/
    607 UINTN
    608 EdbPrintImmData32 (
    609   IN UINT32                 Data
    610   )
    611 {
    612   EDBSPrintWithOffset (
    613     mInstructionString.Content,
    614     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    615     mInstructionContentOffset,
    616     L"(0x%08x)",
    617     (UINTN)Data
    618     );
    619   mInstructionContentOffset  += 12;
    620 
    621   return mInstructionContentOffset;
    622 }
    623 
    624 /**
    625 
    626   Print the hexical QWORD immediate data to instruction content.
    627 
    628   @param  Data - QWORD data
    629 
    630   @return Instruction content offset
    631 
    632 **/
    633 UINTN
    634 EdbPrintImmData64 (
    635   IN UINT64                 Data
    636   )
    637 {
    638   EDBSPrintWithOffset (
    639     mInstructionString.Content,
    640     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    641     mInstructionContentOffset,
    642     L"(0x%016lx)",
    643     Data
    644     );
    645   mInstructionContentOffset  += 20;
    646 
    647   return mInstructionContentOffset;
    648 }
    649 
    650 /**
    651 
    652   Print the decimal UINTN immediate data to instruction content.
    653 
    654   @param  Data - UINTN data
    655 
    656   @return Instruction content offset
    657 
    658 **/
    659 UINTN
    660 EdbPrintImmDatan (
    661   IN UINTN                  Data
    662   )
    663 {
    664   EDBSPrintWithOffset (
    665     mInstructionString.Content,
    666     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    667     mInstructionContentOffset,
    668     L"(%d)",
    669     (UINTN)Data
    670     );
    671   mInstructionContentOffset  = mInstructionContentOffset + 2 + EdbGetBitWidth (Data);
    672 
    673   return mInstructionContentOffset;
    674 }
    675 
    676 /**
    677 
    678   Print the decimal QWORD immediate data to instruction content.
    679 
    680   @param  Data64 - QWORD data
    681 
    682   @return Instruction content offset
    683 
    684 **/
    685 UINTN
    686 EdbPrintImmData64n (
    687   IN UINT64                 Data64
    688   )
    689 {
    690   EDBSPrintWithOffset (
    691     mInstructionString.Content,
    692     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    693     mInstructionContentOffset,
    694     L"(%ld)",
    695     Data64
    696     );
    697   mInstructionContentOffset  = mInstructionContentOffset + 2 + EdbGetBitWidth (Data64);
    698 
    699   return mInstructionContentOffset;
    700 }
    701 
    702 /**
    703 
    704   Print the hexical BYTE to instruction content.
    705 
    706   @param  Data8 - BYTE data
    707 
    708   @return Instruction content offset
    709 
    710 **/
    711 UINTN
    712 EdbPrintData8 (
    713   IN UINT8                  Data8
    714   )
    715 {
    716   EDBSPrintWithOffset (
    717     mInstructionString.Content,
    718     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    719     mInstructionContentOffset,
    720     L"0x%02x",
    721     (UINTN)Data8
    722     );
    723   mInstructionContentOffset += 4;
    724 
    725   return mInstructionContentOffset;
    726 }
    727 
    728 /**
    729 
    730   Print the hexical WORD to instruction content.
    731 
    732   @param  Data16 - WORD data
    733 
    734   @return Instruction content offset
    735 
    736 **/
    737 UINTN
    738 EdbPrintData16 (
    739   IN UINT16                 Data16
    740   )
    741 {
    742   EDBSPrintWithOffset (
    743     mInstructionString.Content,
    744     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    745     mInstructionContentOffset,
    746     L"0x%04x",
    747     (UINTN)Data16
    748     );
    749   mInstructionContentOffset += 6;
    750 
    751   return mInstructionContentOffset;
    752 }
    753 
    754 /**
    755 
    756   Print the hexical DWORD to instruction content.
    757 
    758   @param  Data32 - DWORD data
    759 
    760   @return Instruction content offset
    761 
    762 **/
    763 UINTN
    764 EdbPrintData32 (
    765   IN UINT32                 Data32
    766   )
    767 {
    768   EDBSPrintWithOffset (
    769     mInstructionString.Content,
    770     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    771     mInstructionContentOffset,
    772     L"0x%08x",
    773     (UINTN)Data32
    774     );
    775   mInstructionContentOffset += 10;
    776 
    777   return mInstructionContentOffset;
    778 }
    779 
    780 /**
    781 
    782   Print the hexical QWORD to instruction content.
    783 
    784   @param  Data64 - QWORD data
    785 
    786   @return Instruction content offset
    787 
    788 **/
    789 UINTN
    790 EdbPrintData64 (
    791   IN UINT64                 Data64
    792   )
    793 {
    794   EDBSPrintWithOffset (
    795     mInstructionString.Content,
    796     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    797     mInstructionContentOffset,
    798     L"0x%016lx",
    799     (UINT64)Data64
    800     );
    801   mInstructionContentOffset += 18;
    802 
    803   return mInstructionContentOffset;
    804 }
    805 
    806 /**
    807 
    808   Print the decimal unsigned UINTN to instruction content.
    809 
    810   @param  Data - unsigned UINTN data
    811 
    812   @return Instruction content offset
    813 
    814 **/
    815 UINTN
    816 EdbPrintDatan (
    817   IN UINTN                  Data
    818   )
    819 {
    820   EDBSPrintWithOffset (
    821     mInstructionString.Content,
    822     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    823     mInstructionContentOffset,
    824     L"%d",
    825     (UINTN)Data
    826     );
    827   mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data);
    828 
    829   return mInstructionContentOffset;
    830 }
    831 
    832 /**
    833 
    834   Print the decimal unsigned QWORD to instruction content.
    835 
    836   @param  Data64 - unsigned QWORD data
    837 
    838   @return Instruction content offset
    839 
    840 **/
    841 UINTN
    842 EdbPrintData64n (
    843   IN UINT64                 Data64
    844   )
    845 {
    846   EDBSPrintWithOffset (
    847     mInstructionString.Content,
    848     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    849     mInstructionContentOffset,
    850     L"%ld",
    851     Data64
    852     );
    853   mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data64);
    854 
    855   return mInstructionContentOffset;
    856 }
    857 
    858 /**
    859 
    860   Print the decimal signed BYTE to instruction content.
    861 
    862   @param  Data8 - signed BYTE data
    863 
    864   @return Instruction content offset
    865 
    866 **/
    867 UINTN
    868 EdbPrintData8s (
    869   IN UINT8                  Data8
    870   )
    871 {
    872   BOOLEAN Sign;
    873 
    874   Sign = (BOOLEAN)(Data8 >> 7);
    875 
    876   EDBSPrintWithOffset (
    877     mInstructionString.Content,
    878     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    879     mInstructionContentOffset,
    880     L"%s%d",
    881     Sign ? L"-" : L"+",
    882     (UINTN)(Data8 & 0x7F)
    883     );
    884   mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data8 & 0x7F);
    885 
    886   return mInstructionContentOffset;
    887 }
    888 
    889 /**
    890 
    891   Print the decimal signed WORD to instruction content.
    892 
    893   @param  Data16 - signed WORD data
    894 
    895   @return Instruction content offset
    896 
    897 **/
    898 UINTN
    899 EdbPrintData16s (
    900   IN UINT16                 Data16
    901   )
    902 {
    903   BOOLEAN Sign;
    904 
    905   Sign = (BOOLEAN)(Data16 >> 15);
    906 
    907   EDBSPrintWithOffset (
    908     mInstructionString.Content,
    909     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    910     mInstructionContentOffset,
    911     L"%s%d",
    912     Sign ? L"-" : L"+",
    913     (UINTN)(Data16 & 0x7FFF)
    914     );
    915   mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data16 & 0x7FFF);
    916 
    917   return mInstructionContentOffset;
    918 }
    919 
    920 /**
    921 
    922   Print the decimal signed DWORD to instruction content.
    923 
    924   @param  Data32 - signed DWORD data
    925 
    926   @return Instruction content offset
    927 
    928 **/
    929 UINTN
    930 EdbPrintData32s (
    931   IN UINT32                 Data32
    932   )
    933 {
    934   BOOLEAN Sign;
    935 
    936   Sign = (BOOLEAN)(Data32 >> 31);
    937 
    938   EDBSPrintWithOffset (
    939     mInstructionString.Content,
    940     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    941     mInstructionContentOffset,
    942     L"%s%d",
    943     Sign ? L"-" : L"+",
    944     (UINTN)(Data32 & 0x7FFFFFFF)
    945     );
    946   mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data32 & 0x7FFFFFFF);
    947 
    948   return mInstructionContentOffset;
    949 }
    950 
    951 /**
    952 
    953   Print the decimal signed QWORD to instruction content.
    954 
    955   @param  Data64 - signed QWORD data
    956 
    957   @return Instruction content offset
    958 
    959 **/
    960 UINTN
    961 EdbPrintData64s (
    962   IN UINT64                 Data64
    963   )
    964 {
    965   BOOLEAN Sign;
    966   INT64   Data64s;
    967 
    968   Sign = (BOOLEAN)RShiftU64 (Data64, 63);
    969   Data64s = (INT64)RShiftU64 (LShiftU64 (Data64, 1), 1);
    970 
    971   EDBSPrintWithOffset (
    972     mInstructionString.Content,
    973     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    974     mInstructionContentOffset,
    975     L"%s%ld",
    976     Sign ? L"-" : L"+",
    977     (UINT64)Data64s
    978     );
    979   mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data64s);
    980 
    981   return mInstructionContentOffset;
    982 }
    983 
    984 /**
    985 
    986   Print the comma to instruction content.
    987 
    988   @return Instruction content offset
    989 
    990 **/
    991 UINTN
    992 EdbPrintComma (
    993   VOID
    994   )
    995 {
    996   EDBSPrintWithOffset (
    997     mInstructionString.Content,
    998     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
    999     mInstructionContentOffset,
   1000     L", "
   1001     );
   1002   mInstructionContentOffset += 2;
   1003 
   1004   return mInstructionContentOffset;
   1005 }
   1006 
   1007 /**
   1008 
   1009   Find the symbol string according to address, then print it.
   1010 
   1011   @param  Address - instruction address
   1012 
   1013   @retval 1 - symbol string is found and printed
   1014   @retval 0 - symbol string not found
   1015 
   1016 **/
   1017 UINTN
   1018 EdbFindAndPrintSymbol (
   1019   IN UINTN                  Address
   1020   )
   1021 {
   1022   CHAR8 *SymbolStr;
   1023 
   1024   SymbolStr = FindSymbolStr (Address);
   1025   if (SymbolStr != NULL) {
   1026     EDBSPrintWithOffset (
   1027       mInstructionString.Content,
   1028       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
   1029       mInstructionContentOffset,
   1030       L"[%a]",
   1031       SymbolStr
   1032       );
   1033     return 1;
   1034   }
   1035 
   1036   return 0;
   1037 }
   1038 
   1039 /**
   1040 
   1041   Print the EBC byte code.
   1042 
   1043   @param  InstructionAddress - instruction address
   1044   @param  InstructionNumber  - instruction number
   1045 
   1046 **/
   1047 VOID
   1048 EdbPrintRaw (
   1049   IN EFI_PHYSICAL_ADDRESS   InstructionAddress,
   1050   IN UINTN                  InstructionNumber
   1051   )
   1052 {
   1053   UINTN  LineNumber;
   1054   UINTN  ByteNumber;
   1055   UINTN  LineIndex;
   1056   UINTN  ByteIndex;
   1057   CHAR8  *SymbolStr;
   1058 
   1059   if (InstructionNumber == 0) {
   1060     return ;
   1061   }
   1062 
   1063   LineNumber = InstructionNumber / EDB_BYTECODE_NUMBER_IN_LINE;
   1064   ByteNumber = InstructionNumber % EDB_BYTECODE_NUMBER_IN_LINE;
   1065   if (ByteNumber == 0) {
   1066     LineNumber -= 1;
   1067     ByteNumber  = EDB_BYTECODE_NUMBER_IN_LINE;
   1068   }
   1069 
   1070   //
   1071   // Print Symbol
   1072   //
   1073   SymbolStr = FindSymbolStr ((UINTN)InstructionAddress);
   1074   if (SymbolStr != NULL) {
   1075     EDBPrint (L"[%a]:\n", SymbolStr);
   1076   }
   1077 
   1078   for (LineIndex = 0; LineIndex < LineNumber; LineIndex++) {
   1079     EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress);
   1080     for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE; ByteIndex++) {
   1081       EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress);
   1082       InstructionAddress += 1;
   1083     }
   1084     EDBPrint (L"\n");
   1085   }
   1086 
   1087   EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress);
   1088   for (ByteIndex = 0; ByteIndex < ByteNumber; ByteIndex++) {
   1089     EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress);
   1090     InstructionAddress += 1;
   1091   }
   1092   for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE - ByteNumber; ByteIndex++) {
   1093     EDBPrint (L"   ");
   1094   }
   1095 
   1096   return ;
   1097 }
   1098 
   1099 /**
   1100 
   1101   Print the EBC asm code.
   1102 
   1103   @param  DebuggerPrivate - EBC Debugger private data structure
   1104   @param  SystemContext   - EBC system context.
   1105 
   1106   @retval EFI_SUCCESS - show disasm successfully
   1107 
   1108 **/
   1109 EFI_STATUS
   1110 EdbShowDisasm (
   1111   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
   1112   IN     EFI_SYSTEM_CONTEXT        SystemContext
   1113   )
   1114 {
   1115   EFI_PHYSICAL_ADDRESS    InstructionAddress;
   1116   UINTN                   InstructionNumber;
   1117   UINTN                   InstructionLength;
   1118   UINT8                   Opcode;
   1119   CHAR16                  *InstructionString;
   1120 //  UINTN                   Result;
   1121 
   1122   InstructionAddress = DebuggerPrivate->InstructionScope;
   1123   for (InstructionNumber = 0; InstructionNumber < DebuggerPrivate->InstructionNumber; InstructionNumber++) {
   1124 
   1125     //
   1126     // Break each 0x10 instruction
   1127     //
   1128     if (((InstructionNumber % EFI_DEBUGGER_LINE_NUMBER_IN_PAGE) == 0) &&
   1129         (InstructionNumber != 0)) {
   1130       if (SetPageBreak ()) {
   1131         break;
   1132       }
   1133     }
   1134 
   1135     Opcode = GET_OPCODE(InstructionAddress);
   1136     if ((Opcode < OPCODE_MAX) && (mEdbDisasmInstructionTable[Opcode] != NULL)) {
   1137       InstructionLength = mEdbDisasmInstructionTable [Opcode] (InstructionAddress, SystemContext, &InstructionString);
   1138       if (InstructionLength != 0) {
   1139 
   1140         //
   1141         // Print Source
   1142         //
   1143 //        Result = EdbPrintSource ((UINTN)InstructionAddress, FALSE);
   1144 
   1145         if (!DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly) {
   1146 
   1147           EdbPrintRaw (InstructionAddress, InstructionLength);
   1148           if (InstructionString != NULL) {
   1149             EDBPrint (L"%s\n", InstructionString);
   1150           } else {
   1151             EDBPrint (L"%s\n", L"<Unknown Instruction>");
   1152           }
   1153         }
   1154 
   1155         EdbPrintSource ((UINTN)InstructionAddress, TRUE);
   1156 
   1157         InstructionAddress += InstructionLength;
   1158       } else {
   1159         //
   1160         // Something wrong with OPCODE
   1161         //
   1162         EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE);
   1163         EDBPrint (L"%s\n", L"<Bad Instruction>");
   1164         break;
   1165       }
   1166     } else {
   1167       //
   1168       // Something wrong with OPCODE
   1169       //
   1170       EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE);
   1171       EDBPrint (L"%s\n", L"<Bad Instruction>");
   1172       break;
   1173     }
   1174   }
   1175 
   1176   return EFI_SUCCESS;
   1177 }
   1178 
   1179 /**
   1180 
   1181   Get register value accroding to the system context, and register index.
   1182 
   1183   @param  SystemContext   - EBC system context.
   1184   @param  Index           - EBC register index
   1185 
   1186   @return register value
   1187 
   1188 **/
   1189 UINT64
   1190 GetRegisterValue (
   1191   IN     EFI_SYSTEM_CONTEXT        SystemContext,
   1192   IN     UINT8                     Index
   1193   )
   1194 {
   1195   switch (Index) {
   1196   case 0:
   1197     return SystemContext.SystemContextEbc->R0;
   1198   case 1:
   1199     return SystemContext.SystemContextEbc->R1;
   1200   case 2:
   1201     return SystemContext.SystemContextEbc->R2;
   1202   case 3:
   1203     return SystemContext.SystemContextEbc->R3;
   1204   case 4:
   1205     return SystemContext.SystemContextEbc->R4;
   1206   case 5:
   1207     return SystemContext.SystemContextEbc->R5;
   1208   case 6:
   1209     return SystemContext.SystemContextEbc->R6;
   1210   case 7:
   1211     return SystemContext.SystemContextEbc->R7;
   1212   default:
   1213     ASSERT (FALSE);
   1214     break;
   1215   }
   1216   return 0;
   1217 }
   1218