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.


Ported palacios to Kbuild
[palacios.git] / bios / vmxassist / util.c
diff --git a/bios/vmxassist/util.c b/bios/vmxassist/util.c
new file mode 100644 (file)
index 0000000..0181fe7
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * util.c: Commonly used utility functions.
+ *
+ * Leendert van Doorn, leendert@watson.ibm.com
+ * Copyright (c) 2005, International Business Machines Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include <stdarg.h>
+
+#include "util.h"
+#include "machine.h"
+
+#define        isdigit(c)      ((c) >= '0' && (c) <= '9')
+#define        min(a, b)       ((a) < (b) ? (a) : (b))
+
+static void putchar(int);
+static char *printnum(char *, unsigned long, int);
+static void _doprint(void (*)(int), char const *, va_list);
+
+
+void
+dump_regs(struct regs *regs)
+{
+       printf("eax    %8x ecx    %8x edx    %8x ebx    %8x\n",
+               regs->eax, regs->ecx, regs->edx, regs->ebx);
+       printf("esp    %8x ebp    %8x esi    %8x edi    %8x\n",
+               regs->esp, regs->ebp, regs->esi, regs->edi);
+       printf("eip    %8x eflags %8x cs     %8x ds     %8x\n",
+               regs->eip, regs->eflags, regs->cs, regs->ds);
+       printf("es     %8x fs     %8x uss    %8x uesp   %8x\n",
+               regs->es, regs->fs, regs->uss, regs->uesp);
+       printf("ves    %8x vds    %8x vfs    %8x vgs    %8x\n",
+               regs->ves, regs->vds, regs->vfs, regs->vgs);
+       if (regs->trapno != -1 || regs->errno != -1)
+               printf("trapno %8x errno  %8x\n", regs->trapno, regs->errno);
+
+       printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n",
+               (long)oldctx.cr0, get_cr2(),
+               (long)oldctx.cr3, (long)oldctx.cr4);
+}
+
+#ifdef DEBUG
+void
+hexdump(unsigned char *data, int sz)
+{
+       unsigned char *d;
+       int i;
+
+       for (d = data; sz > 0; d += 16, sz -= 16) {
+               int n = sz > 16 ? 16 : sz;
+
+               printf("%08x: ", (unsigned)d);
+               for (i = 0; i < n; i++)
+                       printf("%02x%c", d[i], i == 7 ? '-' : ' ');
+               for (; i < 16; i++)
+                       printf("  %c", i == 7 ? '-' : ' ');
+               printf("   ");
+               for (i = 0; i < n; i++)
+                       printf("%c", d[i] >= ' ' && d[i] <= '~' ? d[i] : '.');
+               printf("\n");
+       }
+}
+
+void
+print_e820_map(struct e820entry *map, int entries)
+{
+       struct e820entry *m;
+
+       if (entries > 32)
+               entries = 32;
+
+       for (m = map; m < &map[entries]; m++) {
+               printf("%08lx%08lx - %08lx%08lx ",
+                       (unsigned long) (m->addr >> 32),
+                       (unsigned long) (m->addr),
+                       (unsigned long) ((m->addr+m->size) >> 32),
+                       (unsigned long) ((m->addr+m->size)));
+
+               switch (m->type) {
+               case E820_RAM:
+                       printf("(RAM)\n"); break;
+               case E820_RESERVED:
+                       printf("(Reserved)\n"); break;
+               case E820_ACPI:
+                       printf("(ACPI Data)\n"); break;
+               case E820_NVS:
+                       printf("(ACPI NVS)\n"); break;
+               default:
+                       printf("(Type %ld)\n", m->type); break;
+               }
+       }
+}
+
+void
+dump_dtr(unsigned long addr, unsigned long size)
+{
+       unsigned long long entry;
+       unsigned long base, limit;
+       int i;
+
+       for (i = 0; i < size; i += 8) {
+               entry = ((unsigned long long *) addr)[i >> 3];
+               base = (((entry >> (56-24)) & 0xFF000000) |
+                       ((entry >> (32-16)) & 0x00FF0000) |
+                       ((entry >> (   16)) & 0x0000FFFF));
+               limit = (((entry >> (48-16)) & 0x000F0000) |
+                        ((entry           ) & 0x0000FFFF));
+               if (entry & (1ULL << (23+32))) /* G */
+                       limit = (limit << 12) | 0xFFF;
+
+               printf("[0x%x] = 0x%08x%08x, base 0x%lx, limit 0x%lx\n", i,
+                       (unsigned)(entry >> 32), (unsigned)(entry),
+                       base, limit);
+       }
+}
+
+void
+dump_vmx_context(struct vmx_assist_context *c)
+{
+       printf("eip 0x%lx, esp 0x%lx, eflags 0x%lx\n",
+               (long) c->eip, (long) c->esp, (long) c->eflags);
+
+       printf("cr0 0x%lx, cr3 0x%lx, cr4 0x%lx\n",
+               (long)c->cr0, (long)c->cr3, (long)c->cr4);
+
+       printf("idtr: limit 0x%lx, base 0x%lx\n",
+               (long)c->idtr_limit, (long)c->idtr_base);
+
+       printf("gdtr: limit 0x%lx, base 0x%lx\n",
+               (long)c->gdtr_limit, (long)c->gdtr_base);
+
+       printf("cs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
+               (long)c->cs_sel, (long)c->cs_limit, (long)c->cs_base);
+       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
+               c->cs_arbytes.fields.seg_type,
+               c->cs_arbytes.fields.s,
+               c->cs_arbytes.fields.dpl,
+               c->cs_arbytes.fields.p,
+               c->cs_arbytes.fields.avl,
+               c->cs_arbytes.fields.default_ops_size,
+               c->cs_arbytes.fields.g,
+               c->cs_arbytes.fields.null_bit);
+
+       printf("ds: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
+               (long)c->ds_sel, (long)c->ds_limit, (long)c->ds_base);
+       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
+               c->ds_arbytes.fields.seg_type,
+               c->ds_arbytes.fields.s,
+               c->ds_arbytes.fields.dpl,
+               c->ds_arbytes.fields.p,
+               c->ds_arbytes.fields.avl,
+               c->ds_arbytes.fields.default_ops_size,
+               c->ds_arbytes.fields.g,
+               c->ds_arbytes.fields.null_bit);
+
+       printf("es: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
+               (long)c->es_sel, (long)c->es_limit, (long)c->es_base);
+       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
+               c->es_arbytes.fields.seg_type,
+               c->es_arbytes.fields.s,
+               c->es_arbytes.fields.dpl,
+               c->es_arbytes.fields.p,
+               c->es_arbytes.fields.avl,
+               c->es_arbytes.fields.default_ops_size,
+               c->es_arbytes.fields.g,
+               c->es_arbytes.fields.null_bit);
+
+       printf("ss: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
+               (long)c->ss_sel, (long)c->ss_limit, (long)c->ss_base);
+       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
+               c->ss_arbytes.fields.seg_type,
+               c->ss_arbytes.fields.s,
+               c->ss_arbytes.fields.dpl,
+               c->ss_arbytes.fields.p,
+               c->ss_arbytes.fields.avl,
+               c->ss_arbytes.fields.default_ops_size,
+               c->ss_arbytes.fields.g,
+               c->ss_arbytes.fields.null_bit);
+
+       printf("fs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
+               (long)c->fs_sel, (long)c->fs_limit, (long)c->fs_base);
+       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
+               c->fs_arbytes.fields.seg_type,
+               c->fs_arbytes.fields.s,
+               c->fs_arbytes.fields.dpl,
+               c->fs_arbytes.fields.p,
+               c->fs_arbytes.fields.avl,
+               c->fs_arbytes.fields.default_ops_size,
+               c->fs_arbytes.fields.g,
+               c->fs_arbytes.fields.null_bit);
+
+       printf("gs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
+               (long)c->gs_sel, (long)c->gs_limit, (long)c->gs_base);
+       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
+               c->gs_arbytes.fields.seg_type,
+               c->gs_arbytes.fields.s,
+               c->gs_arbytes.fields.dpl,
+               c->gs_arbytes.fields.p,
+               c->gs_arbytes.fields.avl,
+               c->gs_arbytes.fields.default_ops_size,
+               c->gs_arbytes.fields.g,
+               c->gs_arbytes.fields.null_bit);
+
+       printf("tr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
+               (long)c->tr_sel, (long)c->tr_limit, (long)c->tr_base);
+       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
+               c->tr_arbytes.fields.seg_type,
+               c->tr_arbytes.fields.s,
+               c->tr_arbytes.fields.dpl,
+               c->tr_arbytes.fields.p,
+               c->tr_arbytes.fields.avl,
+               c->tr_arbytes.fields.default_ops_size,
+               c->tr_arbytes.fields.g,
+               c->tr_arbytes.fields.null_bit);
+
+       printf("ldtr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
+               (long)c->ldtr_sel, (long)c->ldtr_limit, (long)c->ldtr_base);
+       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
+               c->ldtr_arbytes.fields.seg_type,
+               c->ldtr_arbytes.fields.s,
+               c->ldtr_arbytes.fields.dpl,
+               c->ldtr_arbytes.fields.p,
+               c->ldtr_arbytes.fields.avl,
+               c->ldtr_arbytes.fields.default_ops_size,
+               c->ldtr_arbytes.fields.g,
+               c->ldtr_arbytes.fields.null_bit);
+
+       printf("GDTR <0x%lx,0x%lx>:\n",
+               (long)c->gdtr_base, (long)c->gdtr_limit);
+       dump_dtr(c->gdtr_base, c->gdtr_limit);
+}
+#endif /* DEBUG */
+
+/*
+ * Lightweight printf that doesn't drag in everything under the sun.
+ */
+int
+printf(const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       _doprint(putchar, fmt, ap);
+       va_end(ap);
+       return 0; /* for gcc compat */
+}
+
+int
+vprintf(const char *fmt, va_list ap)
+{
+       _doprint(putchar, fmt, ap);
+       return 0; /* for gcc compat */
+}
+
+void
+panic(const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       _doprint(putchar, fmt, ap);
+       putchar('\n');
+       va_end(ap);
+       halt();
+}
+
+unsigned
+strlen(const char *s)
+{
+       const char *q = s;
+
+       while (*s++)
+               /* void */;
+       return s - q - 1;
+}
+
+static void
+putchar(int ch)
+{
+       outb(0xE9, ch);
+}
+
+/*
+ * A stripped down version of doprint,
+ * but still powerful enough for most tasks.
+ */
+static void
+_doprint(void (*put)(int), char const *fmt, va_list ap)
+{
+       register char *str, c;
+       int lflag, zflag, nflag;
+       char buffer[17];
+       unsigned value;
+       int i, slen, pad;
+
+       for ( ; *fmt != '\0'; fmt++) {
+               pad = zflag = nflag = lflag = 0;
+               if (*fmt == '%') {
+                       c = *++fmt;
+                       if (c == '-' || isdigit(c)) {
+                               if (c == '-') {
+                                       nflag = 1;
+                                       c = *++fmt;
+                               }
+                               zflag = c == '0';
+                               for (pad = 0; isdigit(c); c = *++fmt)
+                                       pad = (pad * 10) + c - '0';
+                       }
+                       if (c == 'l') { /* long extension */
+                               lflag = 1;
+                               c = *++fmt;
+                       }
+                       if (c == 'd' || c == 'u' || c == 'o' || c == 'x') {
+                               if (lflag)
+                                       value = va_arg(ap, unsigned);
+                               else
+                                       value = (unsigned) va_arg(ap, unsigned int);
+                               str = buffer;
+                               printnum(str, value,
+                                       c == 'o' ? 8 : (c == 'x' ? 16 : 10));
+                               goto printn;
+                       } else if (c == 'O' || c == 'D' || c == 'X') {
+                               value = va_arg(ap, unsigned);
+                               str = buffer;
+                               printnum(str, value,
+                                       c == 'O' ? 8 : (c == 'X' ? 16 : 10));
+                       printn:
+                               slen = strlen(str);
+                               for (i = pad - slen; i > 0; i--)
+                                       put(zflag ? '0' : ' ');
+                               while (*str) put(*str++);
+                       } else if (c == 's') {
+                               str = va_arg(ap, char *);
+                               slen = strlen(str);
+                               if (nflag == 0)
+                                       for (i = pad - slen; i > 0; i--) put(' ');
+                               while (*str) put(*str++);
+                               if (nflag)
+                                       for (i = pad - slen; i > 0; i--) put(' ');
+                       } else if (c == 'c')
+                               put(va_arg(ap, int));
+                       else
+                               put(*fmt);
+               } else
+                       put(*fmt);
+       }
+}
+
+static char *
+printnum(char *p, unsigned long num, int base)
+{
+       unsigned long n;
+
+       if ((n = num/base) > 0)
+               p = printnum(p, n, base);
+       *p++ = "0123456789ABCDEF"[(int)(num % base)];
+       *p = '\0';
+       return p;
+}
+
+void *
+memset(void *s, int c, unsigned n)
+{
+        int t0, t1;
+
+        __asm__ __volatile__ ("cld; rep; stosb"
+                : "=&c" (t0), "=&D" (t1)
+                : "a" (c), "1" (s), "0" (n)
+                : "memory");
+        return s;
+}
+
+void *
+memcpy(void *dest, const void *src, unsigned n)
+{
+       int t0, t1, t2;
+
+       __asm__ __volatile__(
+               "cld\n"
+               "rep; movsl\n"
+               "testb $2,%b4\n"
+               "je 1f\n"
+               "movsw\n"
+               "1: testb $1,%b4\n"
+               "je 2f\n"
+               "movsb\n"
+               "2:"
+               : "=&c" (t0), "=&D" (t1), "=&S" (t2)
+               : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
+               : "memory"
+       );
+       return dest;
+}
+