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.


timer fixes
[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
70
71 #define rdtscll(val)                                                    \
72   do {                                                                  \
73     uint64_t tsc;                                                       \
74     uint32_t a, d;                                                      \
75     asm volatile("rdtsc" : "=a" (a), "=d" (d));                         \
76     *(uint32_t *)&(tsc) = a;                                            \
77     *(uint32_t *)(((uchar_t *)&tsc) + 4) = d;                           \
78     val = tsc;                                                          \
79   } while (0)                                   
80
81 /*
82 #if __V3_32BIT__
83
84 #define rdtscll(val)                            \
85      __asm__ __volatile__("rdtsc" : "=A" (val))
86
87 #elif __V3_64BIT__
88
89 #define rdtscll(val) do {                                   \
90     unsigned int a,d;                                       \
91     asm volatile("rdtsc" : "=a" (a), "=d" (d));             \
92     (val) = ((unsigned long)a) | (((unsigned long)d)<<32);  \
93   } while(0)
94
95 #endif
96 */
97
98
99
100
101
102 #ifdef __V3_64BIT__
103
104
105 #define do_divll(n, base) ({                            \
106       uint64_t __rem = 0;                               \
107       uint64_t __num = 0;                               \
108       while (n > base) {                                \
109         __num++;                                        \
110         n -= base;                                      \
111       }                                                 \
112       __rem = n;                                        \
113       n = __num;                                        \
114       __rem;                                            \
115     })                                          
116
117 //#define do_divll do_div
118
119
120 /*
121   #define do_div(n,base) ({                                     \
122   uint32_t __base = (base);                                     \
123   uint32_t __rem;                                               \
124   __rem = ((uint64_t)(n)) % __base;                             \
125   (n) = ((uint64_t)(n)) / __base;                               \
126   __rem;                                                        \
127   })
128 */
129
130 #else
131
132 /*
133  * do_div() is NOT a C function. It wants to return
134  * two values (the quotient and the remainder), but
135  * since that doesn't work very well in C, what it
136  * does is:
137  *
138  * - modifies the 64-bit dividend _in_place_
139  * - returns the 32-bit remainder
140  *
141  * This ends up being the most efficient "calling
142  * convention" on x86.
143  */
144 #define do_div(n,base) ({                                    \
145       unsigned long __upper, __low, __high, __mod, __base;   \
146       __base = (base);                                       \
147       asm("":"=a" (__low), "=d" (__high):"A" (n));           \
148       __upper = __high;                                      \
149       if (__high) {                                          \
150         __upper = __high % (__base);                         \
151         __high = __high / (__base);                          \
152       }                                                                 \
153       asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
154       asm("":"=A" (n):"a" (__low),"d" (__high));                        \
155       __mod;                                                            \
156     })
157
158
159
160 /* This divides two 64bit unsigned ints
161  * The previous version only allows 32 bit bases(?)...
162  * 
163  * NOTE: This absolutely sucks... there has to be a better way....
164  */
165 #define do_divll(n, base) ({                            \
166       ullong_t __rem = 0;                               \
167       ullong_t __num = 0;                               \
168       while (n > base) {                                \
169         __num++;                                        \
170         n -= base;                                      \
171       }                                                 \
172       __rem = n;                                        \
173       n = __num;                                        \
174       __rem;                                            \
175     })                                          
176
177 #endif
178
179
180
181
182
183 #endif // ! __V3VEE__
184
185 #endif