ia64/xen-unstable

view tools/firmware/vmxassist/util.c @ 12773:275a8f9a0710

Remove useless segments push/pop in VMXAssist.
According to Intel Spec, segments registors are cleared when exiting
virtual-8086 mode through trap or interrupts gate, so it's no need to
save their values in stack.
Signed-off-by: Xin Li <xin.b.li@intel.com>
author kfraser@localhost.localdomain
date Mon Dec 04 09:20:12 2006 +0000 (2006-12-04)
parents f3ee62b7fb52
children feeca16435bf
line source
1 /*
2 * util.c: Commonly used utility functions.
3 *
4 * Leendert van Doorn, leendert@watson.ibm.com
5 * Copyright (c) 2005, International Business Machines Corporation.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 */
20 #include <stdarg.h>
22 #include "util.h"
23 #include "machine.h"
25 #define isdigit(c) ((c) >= '0' && (c) <= '9')
26 #define min(a, b) ((a) < (b) ? (a) : (b))
28 static void putchar(int);
29 static char *printnum(char *, unsigned long, int);
30 static void _doprint(void (*)(int), char const *, va_list);
32 void
33 cpuid_addr_value(uint64_t addr, uint64_t *value)
34 {
35 uint32_t addr_low = (uint32_t)addr;
36 uint32_t addr_high = (uint32_t)(addr >> 32);
37 uint32_t value_low, value_high;
38 static unsigned int addr_leaf;
40 if (!addr_leaf) {
41 unsigned int eax, ebx, ecx, edx;
42 __asm__ __volatile__(
43 "cpuid"
44 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
45 : "0" (0x40000000));
46 addr_leaf = eax + 1;
47 }
49 __asm__ __volatile__(
50 "cpuid"
51 : "=c" (value_low), "=d" (value_high)
52 : "a" (addr_leaf), "0" (addr_low), "1" (addr_high)
53 : "ebx");
55 *value = (uint64_t)value_high << 32 | value_low;
56 }
58 void
59 dump_regs(struct regs *regs)
60 {
61 printf("eax %8x ecx %8x edx %8x ebx %8x\n",
62 regs->eax, regs->ecx, regs->edx, regs->ebx);
63 printf("esp %8x ebp %8x esi %8x edi %8x\n",
64 regs->esp, regs->ebp, regs->esi, regs->edi);
65 printf("trapno %8x errno %8x\n", regs->trapno, regs->errno);
66 printf("eip %8x cs %8x eflags %8x\n",
67 regs->eip, regs->cs, regs->eflags);
68 printf("uesp %8x uss %8x\n",
69 regs->uesp, regs->uss);
70 printf("ves %8x vds %8x vfs %8x vgs %8x\n",
71 regs->ves, regs->vds, regs->vfs, regs->vgs);
73 printf("cr0 %8lx cr2 %8x cr3 %8lx cr4 %8lx\n\n",
74 (long)oldctx.cr0, get_cr2(),
75 (long)oldctx.cr3, (long)oldctx.cr4);
76 }
78 #ifdef DEBUG
79 void
80 hexdump(unsigned char *data, int sz)
81 {
82 unsigned char *d;
83 int i;
85 for (d = data; sz > 0; d += 16, sz -= 16) {
86 int n = sz > 16 ? 16 : sz;
88 printf("%08x: ", (unsigned)d);
89 for (i = 0; i < n; i++)
90 printf("%02x%c", d[i], i == 7 ? '-' : ' ');
91 for (; i < 16; i++)
92 printf(" %c", i == 7 ? '-' : ' ');
93 printf(" ");
94 for (i = 0; i < n; i++)
95 printf("%c", d[i] >= ' ' && d[i] <= '~' ? d[i] : '.');
96 printf("\n");
97 }
98 }
100 void
101 print_e820_map(struct e820entry *map, int entries)
102 {
103 struct e820entry *m;
105 if (entries > 32)
106 entries = 32;
108 for (m = map; m < &map[entries]; m++) {
109 printf("%08lx%08lx - %08lx%08lx ",
110 (unsigned long) (m->addr >> 32),
111 (unsigned long) (m->addr),
112 (unsigned long) ((m->addr+m->size) >> 32),
113 (unsigned long) ((m->addr+m->size)));
115 switch (m->type) {
116 case E820_RAM:
117 printf("(RAM)\n"); break;
118 case E820_RESERVED:
119 printf("(Reserved)\n"); break;
120 case E820_ACPI:
121 printf("(ACPI Data)\n"); break;
122 case E820_NVS:
123 printf("(ACPI NVS)\n"); break;
124 default:
125 printf("(Type %ld)\n", m->type); break;
126 }
127 }
128 }
130 void
131 dump_dtr(unsigned long addr, unsigned long size)
132 {
133 unsigned long long entry;
134 unsigned long base, limit;
135 int i;
137 for (i = 0; i < size; i += 8) {
138 entry = ((unsigned long long *) addr)[i >> 3];
139 base = (((entry >> (56-24)) & 0xFF000000) |
140 ((entry >> (32-16)) & 0x00FF0000) |
141 ((entry >> ( 16)) & 0x0000FFFF));
142 limit = (((entry >> (48-16)) & 0x000F0000) |
143 ((entry ) & 0x0000FFFF));
144 if (entry & (1ULL << (23+32))) /* G */
145 limit = (limit << 12) | 0xFFF;
147 printf("[0x%x] = 0x%08x%08x, base 0x%lx, limit 0x%lx\n", i,
148 (unsigned)(entry >> 32), (unsigned)(entry),
149 base, limit);
150 }
151 }
153 void
154 dump_vmx_context(struct vmx_assist_context *c)
155 {
156 printf("eip 0x%lx, esp 0x%lx, eflags 0x%lx\n",
157 (long) c->eip, (long) c->esp, (long) c->eflags);
159 printf("cr0 0x%lx, cr3 0x%lx, cr4 0x%lx\n",
160 (long)c->cr0, (long)c->cr3, (long)c->cr4);
162 printf("idtr: limit 0x%lx, base 0x%lx\n",
163 (long)c->idtr_limit, (long)c->idtr_base);
165 printf("gdtr: limit 0x%lx, base 0x%lx\n",
166 (long)c->gdtr_limit, (long)c->gdtr_base);
168 printf("cs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
169 (long)c->cs_sel, (long)c->cs_limit, (long)c->cs_base);
170 printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
171 c->cs_arbytes.fields.seg_type,
172 c->cs_arbytes.fields.s,
173 c->cs_arbytes.fields.dpl,
174 c->cs_arbytes.fields.p,
175 c->cs_arbytes.fields.avl,
176 c->cs_arbytes.fields.default_ops_size,
177 c->cs_arbytes.fields.g,
178 c->cs_arbytes.fields.null_bit);
180 printf("ds: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
181 (long)c->ds_sel, (long)c->ds_limit, (long)c->ds_base);
182 printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
183 c->ds_arbytes.fields.seg_type,
184 c->ds_arbytes.fields.s,
185 c->ds_arbytes.fields.dpl,
186 c->ds_arbytes.fields.p,
187 c->ds_arbytes.fields.avl,
188 c->ds_arbytes.fields.default_ops_size,
189 c->ds_arbytes.fields.g,
190 c->ds_arbytes.fields.null_bit);
192 printf("es: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
193 (long)c->es_sel, (long)c->es_limit, (long)c->es_base);
194 printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
195 c->es_arbytes.fields.seg_type,
196 c->es_arbytes.fields.s,
197 c->es_arbytes.fields.dpl,
198 c->es_arbytes.fields.p,
199 c->es_arbytes.fields.avl,
200 c->es_arbytes.fields.default_ops_size,
201 c->es_arbytes.fields.g,
202 c->es_arbytes.fields.null_bit);
204 printf("ss: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
205 (long)c->ss_sel, (long)c->ss_limit, (long)c->ss_base);
206 printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
207 c->ss_arbytes.fields.seg_type,
208 c->ss_arbytes.fields.s,
209 c->ss_arbytes.fields.dpl,
210 c->ss_arbytes.fields.p,
211 c->ss_arbytes.fields.avl,
212 c->ss_arbytes.fields.default_ops_size,
213 c->ss_arbytes.fields.g,
214 c->ss_arbytes.fields.null_bit);
216 printf("fs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
217 (long)c->fs_sel, (long)c->fs_limit, (long)c->fs_base);
218 printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
219 c->fs_arbytes.fields.seg_type,
220 c->fs_arbytes.fields.s,
221 c->fs_arbytes.fields.dpl,
222 c->fs_arbytes.fields.p,
223 c->fs_arbytes.fields.avl,
224 c->fs_arbytes.fields.default_ops_size,
225 c->fs_arbytes.fields.g,
226 c->fs_arbytes.fields.null_bit);
228 printf("gs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
229 (long)c->gs_sel, (long)c->gs_limit, (long)c->gs_base);
230 printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
231 c->gs_arbytes.fields.seg_type,
232 c->gs_arbytes.fields.s,
233 c->gs_arbytes.fields.dpl,
234 c->gs_arbytes.fields.p,
235 c->gs_arbytes.fields.avl,
236 c->gs_arbytes.fields.default_ops_size,
237 c->gs_arbytes.fields.g,
238 c->gs_arbytes.fields.null_bit);
240 printf("tr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
241 (long)c->tr_sel, (long)c->tr_limit, (long)c->tr_base);
242 printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
243 c->tr_arbytes.fields.seg_type,
244 c->tr_arbytes.fields.s,
245 c->tr_arbytes.fields.dpl,
246 c->tr_arbytes.fields.p,
247 c->tr_arbytes.fields.avl,
248 c->tr_arbytes.fields.default_ops_size,
249 c->tr_arbytes.fields.g,
250 c->tr_arbytes.fields.null_bit);
252 printf("ldtr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
253 (long)c->ldtr_sel, (long)c->ldtr_limit, (long)c->ldtr_base);
254 printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
255 c->ldtr_arbytes.fields.seg_type,
256 c->ldtr_arbytes.fields.s,
257 c->ldtr_arbytes.fields.dpl,
258 c->ldtr_arbytes.fields.p,
259 c->ldtr_arbytes.fields.avl,
260 c->ldtr_arbytes.fields.default_ops_size,
261 c->ldtr_arbytes.fields.g,
262 c->ldtr_arbytes.fields.null_bit);
264 printf("GDTR <0x%lx,0x%lx>:\n",
265 (long)c->gdtr_base, (long)c->gdtr_limit);
266 dump_dtr(c->gdtr_base, c->gdtr_limit);
267 }
268 #endif /* DEBUG */
270 /*
271 * Lightweight printf that doesn't drag in everything under the sun.
272 */
273 int
274 printf(const char *fmt, ...)
275 {
276 va_list ap;
278 va_start(ap, fmt);
279 _doprint(putchar, fmt, ap);
280 va_end(ap);
281 return 0; /* for gcc compat */
282 }
284 int
285 vprintf(const char *fmt, va_list ap)
286 {
287 _doprint(putchar, fmt, ap);
288 return 0; /* for gcc compat */
289 }
291 void
292 panic(const char *fmt, ...)
293 {
294 va_list ap;
296 va_start(ap, fmt);
297 _doprint(putchar, fmt, ap);
298 putchar('\n');
299 va_end(ap);
300 halt();
301 }
303 unsigned
304 strlen(const char *s)
305 {
306 const char *q = s;
308 while (*s++)
309 /* void */;
310 return s - q - 1;
311 }
313 static void
314 putchar(int ch)
315 {
316 outb(0xE9, ch);
317 }
319 /*
320 * A stripped down version of doprint,
321 * but still powerful enough for most tasks.
322 */
323 static void
324 _doprint(void (*put)(int), char const *fmt, va_list ap)
325 {
326 register char *str, c;
327 int lflag, zflag, nflag;
328 char buffer[17];
329 unsigned value;
330 int i, slen, pad;
332 for ( ; *fmt != '\0'; fmt++) {
333 pad = zflag = nflag = lflag = 0;
334 if (*fmt == '%') {
335 c = *++fmt;
336 if (c == '-' || isdigit(c)) {
337 if (c == '-') {
338 nflag = 1;
339 c = *++fmt;
340 }
341 zflag = c == '0';
342 for (pad = 0; isdigit(c); c = *++fmt)
343 pad = (pad * 10) + c - '0';
344 }
345 if (c == 'l') { /* long extension */
346 lflag = 1;
347 c = *++fmt;
348 }
349 if (c == 'd' || c == 'u' || c == 'o' || c == 'x') {
350 if (lflag)
351 value = va_arg(ap, unsigned);
352 else
353 value = (unsigned) va_arg(ap, unsigned int);
354 str = buffer;
355 printnum(str, value,
356 c == 'o' ? 8 : (c == 'x' ? 16 : 10));
357 goto printn;
358 } else if (c == 'O' || c == 'D' || c == 'X') {
359 value = va_arg(ap, unsigned);
360 str = buffer;
361 printnum(str, value,
362 c == 'O' ? 8 : (c == 'X' ? 16 : 10));
363 printn:
364 slen = strlen(str);
365 for (i = pad - slen; i > 0; i--)
366 put(zflag ? '0' : ' ');
367 while (*str) put(*str++);
368 } else if (c == 's') {
369 str = va_arg(ap, char *);
370 slen = strlen(str);
371 if (nflag == 0)
372 for (i = pad - slen; i > 0; i--) put(' ');
373 while (*str) put(*str++);
374 if (nflag)
375 for (i = pad - slen; i > 0; i--) put(' ');
376 } else if (c == 'c')
377 put(va_arg(ap, int));
378 else
379 put(*fmt);
380 } else
381 put(*fmt);
382 }
383 }
385 static char *
386 printnum(char *p, unsigned long num, int base)
387 {
388 unsigned long n;
390 if ((n = num/base) > 0)
391 p = printnum(p, n, base);
392 *p++ = "0123456789ABCDEF"[(int)(num % base)];
393 *p = '\0';
394 return p;
395 }
397 void *
398 memset(void *s, int c, unsigned n)
399 {
400 int t0, t1;
402 __asm__ __volatile__ ("cld; rep; stosb"
403 : "=&c" (t0), "=&D" (t1)
404 : "a" (c), "1" (s), "0" (n)
405 : "memory");
406 return s;
407 }
409 void *
410 memcpy(void *dest, const void *src, unsigned n)
411 {
412 int t0, t1, t2;
414 __asm__ __volatile__(
415 "cld\n"
416 "rep; movsl\n"
417 "testb $2,%b4\n"
418 "je 1f\n"
419 "movsw\n"
420 "1: testb $1,%b4\n"
421 "je 2f\n"
422 "movsb\n"
423 "2:"
424 : "=&c" (t0), "=&D" (t1), "=&S" (t2)
425 : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
426 : "memory"
427 );
428 return dest;
429 }