ia64/xen-unstable

view tools/tests/test_x86_emulator.c @ 8097:7363637e2721

merge

Keir did a similar change earlier, but my version removed some special case
code as well, now that __gpfn_to_mfn() can protect itself.
author Michael.Fetterman@cl.cam.ac.uk
date Mon Nov 28 15:22:47 2005 +0100 (2005-11-28)
parents 34d251183985
children c259492dfb43
line source
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdint.h>
6 typedef uint8_t u8;
7 typedef uint16_t u16;
8 typedef uint32_t u32;
9 typedef uint64_t u64;
10 typedef int8_t s8;
11 typedef int16_t s16;
12 typedef int32_t s32;
13 typedef int64_t s64;
14 #include <public/xen.h>
15 #include <asm-x86/x86_emulate.h>
17 static int read_any(
18 unsigned long addr,
19 unsigned long *val,
20 unsigned int bytes)
21 {
22 switch ( bytes )
23 {
24 case 1: *val = *(u8 *)addr; break;
25 case 2: *val = *(u16 *)addr; break;
26 case 4: *val = *(u32 *)addr; break;
27 case 8: *val = *(unsigned long *)addr; break;
28 }
29 return X86EMUL_CONTINUE;
30 }
32 static int write_any(
33 unsigned long addr,
34 unsigned long val,
35 unsigned int bytes)
36 {
37 switch ( bytes )
38 {
39 case 1: *(u8 *)addr = (u8)val; break;
40 case 2: *(u16 *)addr = (u16)val; break;
41 case 4: *(u32 *)addr = (u32)val; break;
42 case 8: *(unsigned long *)addr = val; break;
43 }
44 return X86EMUL_CONTINUE;
45 }
47 static int cmpxchg_any(
48 unsigned long addr,
49 unsigned long old,
50 unsigned long new,
51 unsigned int bytes)
52 {
53 switch ( bytes )
54 {
55 case 1: *(u8 *)addr = (u8)new; break;
56 case 2: *(u16 *)addr = (u16)new; break;
57 case 4: *(u32 *)addr = (u32)new; break;
58 case 8: *(unsigned long *)addr = new; break;
59 }
60 return X86EMUL_CONTINUE;
61 }
63 static int cmpxchg8b_any(
64 unsigned long addr,
65 unsigned long old_lo,
66 unsigned long old_hi,
67 unsigned long new_lo,
68 unsigned long new_hi)
69 {
70 ((unsigned long *)addr)[0] = new_lo;
71 ((unsigned long *)addr)[1] = new_hi;
72 return X86EMUL_CONTINUE;
73 }
75 static struct x86_mem_emulator emulops = {
76 read_any, write_any, read_any, write_any, cmpxchg_any, cmpxchg8b_any
77 };
79 int main(int argc, char **argv)
80 {
81 struct cpu_user_regs regs;
82 char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */
83 unsigned int res = 0x7FFFFFFF;
84 u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 };
85 unsigned long cr2;
86 int rc;
88 printf("%-40s", "Testing addl %%ecx,(%%eax)...");
89 instr[0] = 0x01; instr[1] = 0x08;
90 regs.eflags = 0x200;
91 regs.eip = (unsigned long)&instr[0];
92 regs.ecx = 0x12345678;
93 cr2 = (unsigned long)&res;
94 res = 0x7FFFFFFF;
95 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
96 if ( (rc != 0) ||
97 (res != 0x92345677) ||
98 (regs.eflags != 0xa94) ||
99 (regs.eip != (unsigned long)&instr[2]) )
100 goto fail;
101 printf("okay\n");
103 printf("%-40s", "Testing xorl (%%eax),%%ecx...");
104 instr[0] = 0x33; instr[1] = 0x08;
105 regs.eflags = 0x200;
106 regs.eip = (unsigned long)&instr[0];
107 #ifdef __x86_64__
108 regs.ecx = 0xFFFFFFFF12345678UL;
109 #else
110 regs.ecx = 0x12345678UL;
111 #endif
112 cr2 = (unsigned long)&res;
113 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
114 if ( (rc != 0) ||
115 (res != 0x92345677) ||
116 (regs.ecx != 0x8000000FUL) ||
117 (regs.eip != (unsigned long)&instr[2]) )
118 goto fail;
119 printf("okay\n");
121 printf("%-40s", "Testing lock cmpxchgb %%cl,(%%eax)...");
122 instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x08;
123 regs.eflags = 0x200;
124 regs.eip = (unsigned long)&instr[0];
125 regs.eax = 0x92345677UL;
126 regs.ecx = 0xAA;
127 cr2 = (unsigned long)&res;
128 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
129 if ( (rc != 0) ||
130 (res != 0x923456AA) ||
131 (regs.eflags != 0x244) ||
132 (regs.eax != 0x92345677UL) ||
133 (regs.eip != (unsigned long)&instr[4]) )
134 goto fail;
135 printf("okay\n");
137 printf("%-40s", "Testing lock cmpxchgb %%cl,(%%eax)...");
138 instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x08;
139 regs.eflags = 0x200;
140 regs.eip = (unsigned long)&instr[0];
141 regs.eax = 0xAABBCC77UL;
142 regs.ecx = 0xFF;
143 cr2 = (unsigned long)&res;
144 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
145 if ( (rc != 0) ||
146 (res != 0x923456AA) ||
147 ((regs.eflags&0x240) != 0x200) ||
148 (regs.eax != 0xAABBCCAA) ||
149 (regs.ecx != 0xFF) ||
150 (regs.eip != (unsigned long)&instr[4]) )
151 goto fail;
152 printf("okay\n");
154 printf("%-40s", "Testing xchgl %%ecx,(%%eax)...");
155 instr[0] = 0x87; instr[1] = 0x08;
156 regs.eflags = 0x200;
157 regs.eip = (unsigned long)&instr[0];
158 regs.ecx = 0x12345678;
159 cr2 = (unsigned long)&res;
160 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
161 if ( (rc != 0) ||
162 (res != 0x12345678) ||
163 (regs.eflags != 0x200) ||
164 (regs.ecx != 0x923456AA) ||
165 (regs.eip != (unsigned long)&instr[2]) )
166 goto fail;
167 printf("okay\n");
169 printf("%-40s", "Testing lock cmpxchgl %%ecx,(%%eax)...");
170 instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb1; instr[3] = 0x08;
171 regs.eflags = 0x200;
172 res = 0x923456AA;
173 regs.eip = (unsigned long)&instr[0];
174 regs.eax = 0x923456AAUL;
175 regs.ecx = 0xDDEEFF00L;
176 cr2 = (unsigned long)&res;
177 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
178 if ( (rc != 0) ||
179 (res != 0xDDEEFF00) ||
180 (regs.eflags != 0x244) ||
181 (regs.eax != 0x923456AAUL) ||
182 (regs.eip != (unsigned long)&instr[4]) )
183 goto fail;
184 printf("okay\n");
186 printf("%-40s", "Testing rep movsw...");
187 instr[0] = 0xf3; instr[1] = 0x66; instr[2] = 0xa5;
188 res = 0x22334455;
189 regs.eflags = 0x200;
190 regs.ecx = 23;
191 regs.eip = (unsigned long)&instr[0];
192 regs.esi = (unsigned long)&res + 0;
193 regs.edi = (unsigned long)&res + 2;
194 regs.error_code = 0; /* read fault */
195 cr2 = regs.esi;
196 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
197 if ( (rc != 0) ||
198 (res != 0x44554455) ||
199 (regs.eflags != 0x200) ||
200 (regs.ecx != 22) ||
201 (regs.esi != ((unsigned long)&res + 2)) ||
202 (regs.edi != ((unsigned long)&res + 4)) ||
203 (regs.eip != (unsigned long)&instr[0]) )
204 goto fail;
205 printf("okay\n");
207 printf("%-40s", "Testing btrl $0x1,(%edi)...");
208 instr[0] = 0x0f; instr[1] = 0xba; instr[2] = 0x37; instr[3] = 0x01;
209 res = 0x2233445F;
210 regs.eflags = 0x200;
211 regs.eip = (unsigned long)&instr[0];
212 regs.edi = (unsigned long)&res;
213 cr2 = regs.edi;
214 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
215 if ( (rc != 0) ||
216 (res != 0x2233445D) ||
217 ((regs.eflags&0x201) != 0x201) ||
218 (regs.eip != (unsigned long)&instr[4]) )
219 goto fail;
220 printf("okay\n");
222 printf("%-40s", "Testing cmpxchg8b (%edi) [succeeding]...");
223 instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
224 regs.eflags = 0x200;
225 regs.eax = cmpxchg8b_res[0];
226 regs.edx = cmpxchg8b_res[1];
227 regs.ebx = 0x9999AAAA;
228 regs.ecx = 0xCCCCFFFF;
229 regs.eip = (unsigned long)&instr[0];
230 regs.edi = (unsigned long)cmpxchg8b_res;
231 cr2 = regs.edi;
232 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
233 if ( (rc != 0) ||
234 (cmpxchg8b_res[0] != 0x9999AAAA) ||
235 (cmpxchg8b_res[1] != 0xCCCCFFFF) ||
236 ((regs.eflags&0x240) != 0x240) ||
237 (regs.eip != (unsigned long)&instr[3]) )
238 goto fail;
239 printf("okay\n");
241 printf("%-40s", "Testing cmpxchg8b (%edi) [failing]...");
242 instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
243 regs.eip = (unsigned long)&instr[0];
244 regs.edi = (unsigned long)cmpxchg8b_res;
245 cr2 = regs.edi;
246 rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
247 if ( (rc != 0) ||
248 (cmpxchg8b_res[0] != 0x9999AAAA) ||
249 (cmpxchg8b_res[1] != 0xCCCCFFFF) ||
250 (regs.eax != 0x9999AAAA) ||
251 (regs.edx != 0xCCCCFFFF) ||
252 ((regs.eflags&0x240) != 0x200) ||
253 (regs.eip != (unsigned long)&instr[3]) )
254 goto fail;
255 printf("okay\n");
257 return 0;
259 fail:
260 printf("failed!\n");
261 return 1;
262 }