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.


Release 1.0
[palacios.git] / palacios / include / palacios / vmm_util.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_UTIL_H
21 #define __VMM_UTIL_H
22
23 #ifdef __V3VEE__
24
25 #include <palacios/vmm_types.h>
26
27
28 typedef union reg_ex {
29   ullong_t r_reg;
30   struct {
31     uint_t low;
32     uint_t high;
33   } e_reg;
34
35 } reg_ex_t;
36
37
38
39 // These are the GPRs layed out according to 'pusha'
40 struct VMM_GPRs {
41   uint_t edi;
42   uint_t esi;
43   uint_t ebp;
44   uint_t esp;
45   uint_t ebx;
46   uint_t edx;
47   uint_t ecx;
48   uint_t eax;
49 };
50
51
52 #define GET_LOW_32(x) (*((uint_t*)(&(x))))
53 #define GET_HIGH_32(x) (*((uint_t*)(((uchar_t*)(&(x)))+4)))
54
55
56 void PrintTraceHex(uchar_t x);
57 void PrintTraceLL(ullong_t num);
58 void PrintTraceMemDump(uchar_t * start, int n);
59
60
61
62
63 #define rdtsc(low,high)                                         \
64      __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
65
66 #define rdtscl(low)                                             \
67      __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
68
69 #if defined(__i386__)
70
71 #define rdtscll(val)                            \
72      __asm__ __volatile__("rdtsc" : "=A" (val))
73
74 #elif defined(__x86_64__)
75
76 #define rdtscll(val) do {                                   \
77     unsigned int a,d;                                       \
78     asm volatile("rdtsc" : "=a" (a), "=d" (d));             \
79     (val) = ((unsigned long)a) | (((unsigned long)d)<<32);  \
80   } while(0)
81
82 #endif
83
84
85
86
87
88
89
90
91
92 #ifdef __V3_64BIT__
93 #define do_divll do_div
94
95
96 #define do_div(n,base) ({                                       \
97         uint32_t __base = (base);                               \
98         uint32_t __rem;                                         \
99         __rem = ((uint64_t)(n)) % __base;                       \
100         (n) = ((uint64_t)(n)) / __base;                         \
101         __rem;                                                  \
102  })
103
104 #else
105
106 /*
107  * do_div() is NOT a C function. It wants to return
108  * two values (the quotient and the remainder), but
109  * since that doesn't work very well in C, what it
110  * does is:
111  *
112  * - modifies the 64-bit dividend _in_place_
113  * - returns the 32-bit remainder
114  *
115  * This ends up being the most efficient "calling
116  * convention" on x86.
117  */
118 #define do_div(n,base) ({                                    \
119       unsigned long __upper, __low, __high, __mod, __base;   \
120       __base = (base);                                       \
121       asm("":"=a" (__low), "=d" (__high):"A" (n));           \
122       __upper = __high;                                      \
123       if (__high) {                                          \
124         __upper = __high % (__base);                         \
125         __high = __high / (__base);                          \
126       }                                                                 \
127       asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
128       asm("":"=A" (n):"a" (__low),"d" (__high));                        \
129       __mod;                                                            \
130     })
131
132
133
134 /* This divides two 64bit unsigned ints
135  * The previous version only allows 32 bit bases(?)...
136  * 
137  * NOTE: This absolutely sucks... there has to be a better way....
138  */
139 #define do_divll(n, base) ({                            \
140       ullong_t __rem = 0;                               \
141       ullong_t __num = 0;                               \
142       while (n > base) {                                \
143         __num++;                                        \
144         n -= base;                                      \
145       }                                                 \
146       __rem = n;                                        \
147       n = __num;                                        \
148       __rem;                                            \
149     })                                          
150
151 #endif
152
153
154
155
156
157 #endif // ! __V3VEE__
158
159 #endif