• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
EdbDisasmBREAK(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmJMP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmJMP8(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmCALL(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmRET(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmCMP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmUnsignedDataManip(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmSignedDataManip(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmMOVxx(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmMOVsnw(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmMOVsnd(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmLOADSP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmSTORESP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmPUSH(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmPOP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmCMPI(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmPUSHn(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmPOPn(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmMOVI(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmMOVIn(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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
EdbDisasmMOVREL(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)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