Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


initial checking of internal decoder
[palacios.git] / palacios / include / palacios / vmm_decoder.h
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #ifndef __VMM_DECODER_H
21 #define __VMM_DECODER_H
22
23 #ifdef __V3VEE__
24
25 #include <palacios/vm_guest.h>
26 #include <palacios/vmm.h>
27
28
29 typedef enum { V3_INVALID_OP,
30                V3_OP_MOVCR2, V3_OP_MOV2CR, V3_OP_SMSW, V3_OP_LMSW, V3_OP_CLTS,
31                V3_OP_INVLPG,
32                V3_OP_ADC, V3_OP_ADD, V3_OP_AND, V3_OP_OR, V3_OP_XOR, V3_OP_SUB,
33                V3_OP_INC, V3_OP_DEC, V3_OP_NEG, V3_OP_MOV, V3_OP_NOT, V3_OP_XCHG, 
34                V3_OP_SETB, V3_OP_SETBE, V3_OP_SETL, V3_OP_SETLE, V3_OP_SETNB, 
35                V3_OP_SETNBE, V3_OP_SETNL, V3_OP_SETNLE, V3_OP_SETNO, V3_OP_SETNP,
36                V3_OP_SETNS, V3_OP_SETNZ, V3_OP_SETO, V3_OP_SETP, V3_OP_SETS, 
37                V3_OP_SETZ, V3_OP_MOVS, V3_OP_STOS, V3_OP_MOVZX, V3_OP_MOVSX} v3_op_type_t;
38
39
40 typedef enum {INVALID_OPERAND, REG_OPERAND, MEM_OPERAND, IMM_OPERAND} v3_operand_type_t;
41
42 struct x86_operand {
43     addr_t operand;
44     uint_t size;
45     v3_operand_type_t type;
46 };
47
48 struct x86_prefixes {
49     uint_t lock   : 1;  // 0xF0
50     uint_t repne  : 1;  // 0xF2
51     uint_t repnz  : 1;  // 0xF2
52     uint_t rep    : 1;  // 0xF3
53     uint_t repe   : 1;  // 0xF3
54     uint_t repz   : 1;  // 0xF3
55     uint_t cs_override : 1;  // 0x2E
56     uint_t ss_override : 1;  // 0x36
57     uint_t ds_override : 1;  // 0x3E
58     uint_t es_override : 1;  // 0x26
59     uint_t fs_override : 1;  // 0x64
60     uint_t gs_override : 1;  // 0x65
61     uint_t br_not_taken : 1;  // 0x2E
62     uint_t br_taken   : 1;  // 0x3E
63     uint_t op_size     : 1;  // 0x66
64     uint_t addr_size   : 1;  // 0x67
65 };
66
67
68 struct x86_instr {
69     struct x86_prefixes prefixes;
70     uint_t instr_length;
71     v3_op_type_t op_type;
72     uint_t num_operands;
73     struct x86_operand dst_operand;
74     struct x86_operand src_operand;
75     struct x86_operand third_operand;
76     addr_t str_op_length;
77     addr_t is_str_op;
78     void * decoder_data;
79 };
80
81
82 /************************/
83 /* EXTERNAL DECODER API */
84 /************************/
85 /* 
86    This is an External API definition that must be implemented by a decoder
87 */
88
89
90 /* 
91  * Initializes a decoder
92  */
93 int v3_init_decoder(struct guest_info * core);
94 int v3_deinit_decoder(struct guest_info * core);
95
96 /* 
97  * Decodes an instruction 
98  * All addresses in arguments are in the host address space
99  * instr_ptr is the host address of the instruction 
100  * IMPORTANT: make sure the instr_ptr is in contiguous host memory
101  *   ie. Copy it to a buffer before the call
102  */
103 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr);
104
105 /* 
106  * Encodes an instruction
107  * All addresses in arguments are in the host address space
108  * The instruction is encoded from the struct, and copied into a 15 byte host buffer
109  * referenced by instr_buf
110  * any unused bytes at the end of instr_buf will be filled with nops
111  * IMPORTANT: instr_buf must be allocated and 15 bytes long
112  */
113 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf);
114
115
116
117 /* Removes a rep prefix in place */
118 void v3_strip_rep_prefix(uchar_t * instr, int length);
119 void v3_get_prefixes(uchar_t * instr, struct x86_prefixes * prefixes);
120
121
122
123
124 #define PREFIX_LOCK         0xF0
125 #define PREFIX_REPNE        0xF2
126 #define PREFIX_REPNZ        0xF2
127 #define PREFIX_REP          0xF3
128 #define PREFIX_REPE         0xF3
129 #define PREFIX_REPZ         0xF3
130 #define PREFIX_CS_OVERRIDE  0x2E
131 #define PREFIX_SS_OVERRIDE  0x36
132 #define PREFIX_DS_OVERRIDE  0x3E
133 #define PREFIX_ES_OVERRIDE  0x26
134 #define PREFIX_FS_OVERRIDE  0x64
135 #define PREFIX_GS_OVERRIDE  0x65
136 #define PREFIX_BR_NOT_TAKEN 0x2E
137 #define PREFIX_BR_TAKEN     0x3E
138 #define PREFIX_OP_SIZE      0x66
139 #define PREFIX_ADDR_SIZE    0x67
140
141
142
143
144 static inline int is_prefix_byte(uchar_t byte) {
145     switch (byte) {
146         case 0xF0:      // lock
147         case 0xF2:      // REPNE/REPNZ
148         case 0xF3:      // REP or REPE/REPZ
149         case 0x2E:      // CS override or Branch hint not taken (with Jcc instrs)
150         case 0x36:      // SS override
151         case 0x3E:      // DS override or Branch hint taken (with Jcc instrs)
152         case 0x26:      // ES override
153         case 0x64:      // FS override
154         case 0x65:      // GS override
155             //case 0x2E:      // branch not taken hint
156             //  case 0x3E:      // branch taken hint
157         case 0x66:      // operand size override
158         case 0x67:      // address size override
159             return 1;
160             break;
161         default:
162             return 0;
163             break;
164     }
165 }
166
167
168 static inline v3_reg_t get_gpr_mask(struct guest_info * info) {
169     switch (info->cpu_mode) {
170         case REAL: 
171         case LONG_16_COMPAT:
172             return 0xffff;
173             break;
174         case PROTECTED:
175         case LONG_32_COMPAT:
176         case PROTECTED_PAE:
177             return 0xffffffff;
178         case LONG:
179             return 0xffffffffffffffffLL;
180         default:
181             PrintError("Unsupported Address Mode\n");
182             return -1;
183     }
184 }
185
186
187
188 static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, struct v3_segment * seg) {
189     switch (info->cpu_mode) {
190         case REAL:
191             // It appears that the segment values are computed and cached in the vmcb structure 
192             // We Need to check this for Intel
193             /*   return addr + (seg->selector << 4);
194                  break;*/
195
196         case PROTECTED:
197         case PROTECTED_PAE:
198         case LONG_32_COMPAT:
199             return addr + seg->base;
200             break;
201
202         case LONG:
203             // In long mode the segment bases are disregarded (forced to 0), unless using 
204             // FS or GS, then the base addresses are added
205             return addr + seg->base;
206
207         case LONG_16_COMPAT:
208         default:
209             PrintError("Unsupported CPU Mode: %d\n", info->cpu_mode);
210             return -1;
211     }
212 }
213
214
215
216 #endif // !__V3VEE__
217
218
219 #endif