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.


*** empty log message ***
[palacios.git] / palacios / src / vmboot / vmxassist / util.c
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>
21
22 #include "util.h"
23 #include "machine.h"
24
25 #define isdigit(c)      ((c) >= '0' && (c) <= '9')
26 #define min(a, b)       ((a) < (b) ? (a) : (b))
27
28 static void putchar(int);
29 static char *printnum(char *, unsigned long, int);
30 static void _doprint(void (*)(int), char const *, va_list);
31
32
33 void
34 dump_regs(struct regs *regs)
35 {
36         printf("eax    %8x ecx    %8x edx    %8x ebx    %8x\n",
37                 regs->eax, regs->ecx, regs->edx, regs->ebx);
38         printf("esp    %8x ebp    %8x esi    %8x edi    %8x\n",
39                 regs->esp, regs->ebp, regs->esi, regs->edi);
40         printf("eip    %8x eflags %8x cs     %8x ds     %8x\n",
41                 regs->eip, regs->eflags, regs->cs, regs->ds);
42         printf("es     %8x fs     %8x uss    %8x uesp   %8x\n",
43                 regs->es, regs->fs, regs->uss, regs->uesp);
44         printf("ves    %8x vds    %8x vfs    %8x vgs    %8x\n",
45                 regs->ves, regs->vds, regs->vfs, regs->vgs);
46         if (regs->trapno != -1 || regs->errno != -1)
47                 printf("trapno %8x errno  %8x\n", regs->trapno, regs->errno);
48
49         printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n",
50                 (long)oldctx.cr0, get_cr2(),
51                 (long)oldctx.cr3, (long)oldctx.cr4);
52 }
53
54 #ifdef DEBUG
55 void
56 hexdump(unsigned char *data, int sz)
57 {
58         unsigned char *d;
59         int i;
60
61         for (d = data; sz > 0; d += 16, sz -= 16) {
62                 int n = sz > 16 ? 16 : sz;
63
64                 printf("%08x: ", (unsigned)d);
65                 for (i = 0; i < n; i++)
66                         printf("%02x%c", d[i], i == 7 ? '-' : ' ');
67                 for (; i < 16; i++)
68                         printf("  %c", i == 7 ? '-' : ' ');
69                 printf("   ");
70                 for (i = 0; i < n; i++)
71                         printf("%c", d[i] >= ' ' && d[i] <= '~' ? d[i] : '.');
72                 printf("\n");
73         }
74 }
75
76 void
77 print_e820_map(struct e820entry *map, int entries)
78 {
79         struct e820entry *m;
80
81         if (entries > 32)
82                 entries = 32;
83
84         for (m = map; m < &map[entries]; m++) {
85                 printf("%08lx%08lx - %08lx%08lx ",
86                         (unsigned long) (m->addr >> 32),
87                         (unsigned long) (m->addr),
88                         (unsigned long) ((m->addr+m->size) >> 32),
89                         (unsigned long) ((m->addr+m->size)));
90
91                 switch (m->type) {
92                 case E820_RAM:
93                         printf("(RAM)\n"); break;
94                 case E820_RESERVED:
95                         printf("(Reserved)\n"); break;
96                 case E820_ACPI:
97                         printf("(ACPI Data)\n"); break;
98                 case E820_NVS:
99                         printf("(ACPI NVS)\n"); break;
100                 default:
101                         printf("(Type %ld)\n", m->type); break;
102                 }
103         }
104 }
105
106 void
107 dump_dtr(unsigned long addr, unsigned long size)
108 {
109         unsigned long long entry;
110         unsigned long base, limit;
111         int i;
112
113         for (i = 0; i < size; i += 8) {
114                 entry = ((unsigned long long *) addr)[i >> 3];
115                 base = (((entry >> (56-24)) & 0xFF000000) |
116                         ((entry >> (32-16)) & 0x00FF0000) |
117                         ((entry >> (   16)) & 0x0000FFFF));
118                 limit = (((entry >> (48-16)) & 0x000F0000) |
119                          ((entry           ) & 0x0000FFFF));
120                 if (entry & (1ULL << (23+32))) /* G */
121                         limit = (limit << 12) | 0xFFF;
122
123                 printf("[0x%x] = 0x%08x%08x, base 0x%lx, limit 0x%lx\n", i,
124                         (unsigned)(entry >> 32), (unsigned)(entry),
125                         base, limit);
126         }
127 }
128
129 void
130 dump_vmx_context(struct vmx_assist_context *c)
131 {
132         printf("eip 0x%lx, esp 0x%lx, eflags 0x%lx\n",
133                 (long) c->eip, (long) c->esp, (long) c->eflags);
134
135         printf("cr0 0x%lx, cr3 0x%lx, cr4 0x%lx\n",
136                 (long)c->cr0, (long)c->cr3, (long)c->cr4);
137
138         printf("idtr: limit 0x%lx, base 0x%lx\n",
139                 (long)c->idtr_limit, (long)c->idtr_base);
140
141         printf("gdtr: limit 0x%lx, base 0x%lx\n",
142                 (long)c->gdtr_limit, (long)c->gdtr_base);
143
144         printf("cs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
145                 (long)c->cs_sel, (long)c->cs_limit, (long)c->cs_base);
146         printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
147                 c->cs_arbytes.fields.seg_type,
148                 c->cs_arbytes.fields.s,
149                 c->cs_arbytes.fields.dpl,
150                 c->cs_arbytes.fields.p,
151                 c->cs_arbytes.fields.avl,
152                 c->cs_arbytes.fields.default_ops_size,
153                 c->cs_arbytes.fields.g,
154                 c->cs_arbytes.fields.null_bit);
155
156         printf("ds: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
157                 (long)c->ds_sel, (long)c->ds_limit, (long)c->ds_base);
158         printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
159                 c->ds_arbytes.fields.seg_type,
160                 c->ds_arbytes.fields.s,
161                 c->ds_arbytes.fields.dpl,
162                 c->ds_arbytes.fields.p,
163                 c->ds_arbytes.fields.avl,
164                 c->ds_arbytes.fields.default_ops_size,
165                 c->ds_arbytes.fields.g,
166                 c->ds_arbytes.fields.null_bit);
167
168         printf("es: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
169                 (long)c->es_sel, (long)c->es_limit, (long)c->es_base);
170         printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
171                 c->es_arbytes.fields.seg_type,
172                 c->es_arbytes.fields.s,
173                 c->es_arbytes.fields.dpl,
174                 c->es_arbytes.fields.p,
175                 c->es_arbytes.fields.avl,
176                 c->es_arbytes.fields.default_ops_size,
177                 c->es_arbytes.fields.g,
178                 c->es_arbytes.fields.null_bit);
179
180         printf("ss: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
181                 (long)c->ss_sel, (long)c->ss_limit, (long)c->ss_base);
182         printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
183                 c->ss_arbytes.fields.seg_type,
184                 c->ss_arbytes.fields.s,
185                 c->ss_arbytes.fields.dpl,
186                 c->ss_arbytes.fields.p,
187                 c->ss_arbytes.fields.avl,
188                 c->ss_arbytes.fields.default_ops_size,
189                 c->ss_arbytes.fields.g,
190                 c->ss_arbytes.fields.null_bit);
191
192         printf("fs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
193                 (long)c->fs_sel, (long)c->fs_limit, (long)c->fs_base);
194         printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
195                 c->fs_arbytes.fields.seg_type,
196                 c->fs_arbytes.fields.s,
197                 c->fs_arbytes.fields.dpl,
198                 c->fs_arbytes.fields.p,
199                 c->fs_arbytes.fields.avl,
200                 c->fs_arbytes.fields.default_ops_size,
201                 c->fs_arbytes.fields.g,
202                 c->fs_arbytes.fields.null_bit);
203
204         printf("gs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
205                 (long)c->gs_sel, (long)c->gs_limit, (long)c->gs_base);
206         printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
207                 c->gs_arbytes.fields.seg_type,
208                 c->gs_arbytes.fields.s,
209                 c->gs_arbytes.fields.dpl,
210                 c->gs_arbytes.fields.p,
211                 c->gs_arbytes.fields.avl,
212                 c->gs_arbytes.fields.default_ops_size,
213                 c->gs_arbytes.fields.g,
214                 c->gs_arbytes.fields.null_bit);
215
216         printf("tr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
217                 (long)c->tr_sel, (long)c->tr_limit, (long)c->tr_base);
218         printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
219                 c->tr_arbytes.fields.seg_type,
220                 c->tr_arbytes.fields.s,
221                 c->tr_arbytes.fields.dpl,
222                 c->tr_arbytes.fields.p,
223                 c->tr_arbytes.fields.avl,
224                 c->tr_arbytes.fields.default_ops_size,
225                 c->tr_arbytes.fields.g,
226                 c->tr_arbytes.fields.null_bit);
227
228         printf("ldtr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
229                 (long)c->ldtr_sel, (long)c->ldtr_limit, (long)c->ldtr_base);
230         printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
231                 c->ldtr_arbytes.fields.seg_type,
232                 c->ldtr_arbytes.fields.s,
233                 c->ldtr_arbytes.fields.dpl,
234                 c->ldtr_arbytes.fields.p,
235                 c->ldtr_arbytes.fields.avl,
236                 c->ldtr_arbytes.fields.default_ops_size,
237                 c->ldtr_arbytes.fields.g,
238                 c->ldtr_arbytes.fields.null_bit);
239
240         printf("GDTR <0x%lx,0x%lx>:\n",
241                 (long)c->gdtr_base, (long)c->gdtr_limit);
242         dump_dtr(c->gdtr_base, c->gdtr_limit);
243 }
244 #endif /* DEBUG */
245
246 /*
247  * Lightweight printf that doesn't drag in everything under the sun.
248  */
249 int
250 printf(const char *fmt, ...)
251 {
252         va_list ap;
253
254         va_start(ap, fmt);
255         _doprint(putchar, fmt, ap);
256         va_end(ap);
257         return 0; /* for gcc compat */
258 }
259
260 int
261 vprintf(const char *fmt, va_list ap)
262 {
263         _doprint(putchar, fmt, ap);
264         return 0; /* for gcc compat */
265 }
266
267 void
268 panic(const char *fmt, ...)
269 {
270         va_list ap;
271
272         va_start(ap, fmt);
273         _doprint(putchar, fmt, ap);
274         putchar('\n');
275         va_end(ap);
276         halt();
277 }
278
279 unsigned
280 strlen(const char *s)
281 {
282         const char *q = s;
283
284         while (*s++)
285                 /* void */;
286         return s - q - 1;
287 }
288
289 static void
290 putchar(int ch)
291 {
292         outb(0xE9, ch);
293 }
294
295 /*
296  * A stripped down version of doprint,
297  * but still powerful enough for most tasks.
298  */
299 static void
300 _doprint(void (*put)(int), char const *fmt, va_list ap)
301 {
302         register char *str, c;
303         int lflag, zflag, nflag;
304         char buffer[17];
305         unsigned value;
306         int i, slen, pad;
307
308         for ( ; *fmt != '\0'; fmt++) {
309                 pad = zflag = nflag = lflag = 0;
310                 if (*fmt == '%') {
311                         c = *++fmt;
312                         if (c == '-' || isdigit(c)) {
313                                 if (c == '-') {
314                                         nflag = 1;
315                                         c = *++fmt;
316                                 }
317                                 zflag = c == '0';
318                                 for (pad = 0; isdigit(c); c = *++fmt)
319                                         pad = (pad * 10) + c - '0';
320                         }
321                         if (c == 'l') { /* long extension */
322                                 lflag = 1;
323                                 c = *++fmt;
324                         }
325                         if (c == 'd' || c == 'u' || c == 'o' || c == 'x') {
326                                 if (lflag)
327                                         value = va_arg(ap, unsigned);
328                                 else
329                                         value = (unsigned) va_arg(ap, unsigned int);
330                                 str = buffer;
331                                 printnum(str, value,
332                                         c == 'o' ? 8 : (c == 'x' ? 16 : 10));
333                                 goto printn;
334                         } else if (c == 'O' || c == 'D' || c == 'X') {
335                                 value = va_arg(ap, unsigned);
336                                 str = buffer;
337                                 printnum(str, value,
338                                         c == 'O' ? 8 : (c == 'X' ? 16 : 10));
339                         printn:
340                                 slen = strlen(str);
341                                 for (i = pad - slen; i > 0; i--)
342                                         put(zflag ? '0' : ' ');
343                                 while (*str) put(*str++);
344                         } else if (c == 's') {
345                                 str = va_arg(ap, char *);
346                                 slen = strlen(str);
347                                 if (nflag == 0)
348                                         for (i = pad - slen; i > 0; i--) put(' ');
349                                 while (*str) put(*str++);
350                                 if (nflag)
351                                         for (i = pad - slen; i > 0; i--) put(' ');
352                         } else if (c == 'c')
353                                 put(va_arg(ap, int));
354                         else
355                                 put(*fmt);
356                 } else
357                         put(*fmt);
358         }
359 }
360
361 static char *
362 printnum(char *p, unsigned long num, int base)
363 {
364         unsigned long n;
365
366         if ((n = num/base) > 0)
367                 p = printnum(p, n, base);
368         *p++ = "0123456789ABCDEF"[(int)(num % base)];
369         *p = '\0';
370         return p;
371 }
372
373 void *
374 memset(void *s, int c, unsigned n)
375 {
376         int t0, t1;
377
378         __asm__ __volatile__ ("cld; rep; stosb"
379                 : "=&c" (t0), "=&D" (t1)
380                 : "a" (c), "1" (s), "0" (n)
381                 : "memory");
382         return s;
383 }
384
385 void *
386 memcpy(void *dest, const void *src, unsigned n)
387 {
388         int t0, t1, t2;
389
390         __asm__ __volatile__(
391                 "cld\n"
392                 "rep; movsl\n"
393                 "testb $2,%b4\n"
394                 "je 1f\n"
395                 "movsw\n"
396                 "1: testb $1,%b4\n"
397                 "je 2f\n"
398                 "movsb\n"
399                 "2:"
400                 : "=&c" (t0), "=&D" (t1), "=&S" (t2)
401                 : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
402                 : "memory"
403         );
404         return dest;
405 }
406