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