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.


added more selective debugging directives
[palacios.git] / palacios / src / palacios / vmm_dev_mgr.c
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 #include <palacios/vm_dev.h>
21 #include <palacios/vmm_dev_mgr.h>
22 #include <palacios/vm_guest.h>
23 #include <palacios/vmm.h>
24 #include <palacios/vmm_decoder.h>
25
26
27 #ifndef DEBUG_DEV_MGR
28 #undef PrintDebug
29 #define PrintDebug(fmt, args...)
30 #endif
31
32
33
34 int dev_mgr_init(struct guest_info * info) {
35   struct vmm_dev_mgr * mgr = &(info->dev_mgr);
36   INIT_LIST_HEAD(&(mgr->dev_list));
37   mgr->num_devs = 0;
38
39   INIT_LIST_HEAD(&(mgr->io_hooks));
40   mgr->num_io_hooks = 0;
41
42   return 0;
43 }
44
45
46 int dev_mgr_deinit(struct guest_info * info) {
47   struct vm_device * dev;
48   struct vmm_dev_mgr * mgr = &(info->dev_mgr);
49   struct vm_device * tmp;
50
51   list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
52     v3_unattach_device(dev);
53     free_device(dev);
54   }
55
56   return 0;
57 }
58
59
60
61
62 static int dev_mgr_add_device(struct vmm_dev_mgr * mgr, struct vm_device * dev) {
63   list_add(&(dev->dev_link), &(mgr->dev_list));
64   mgr->num_devs++;
65
66   return 0;
67 }
68
69 static int dev_mgr_remove_device(struct vmm_dev_mgr * mgr, struct vm_device * dev) {
70   list_del(&(dev->dev_link));
71   mgr->num_devs--;
72
73   return 0;
74 }
75
76
77
78 /* IO HOOKS */
79 int dev_mgr_add_io_hook(struct vmm_dev_mgr * mgr, struct dev_io_hook * hook) {
80   list_add(&(hook->mgr_list), &(mgr->io_hooks));
81   mgr->num_io_hooks++;
82   return 0;
83 }
84
85
86 int dev_mgr_remove_io_hook(struct vmm_dev_mgr * mgr, struct dev_io_hook * hook) {
87   list_del(&(hook->mgr_list));
88   mgr->num_io_hooks--;
89
90   return 0;
91 }
92
93
94 int dev_add_io_hook(struct vm_device * dev, struct dev_io_hook * hook) {
95   list_add(&(hook->dev_list), &(dev->io_hooks));
96   dev->num_io_hooks++;
97   return 0;
98 }
99
100
101 int dev_remove_io_hook(struct vm_device * dev, struct dev_io_hook * hook) {
102   list_del(&(hook->dev_list));
103   dev->num_io_hooks--;
104
105   return 0;
106 }
107
108
109
110
111
112 struct dev_io_hook * dev_mgr_find_io_hook(struct vmm_dev_mgr * mgr, ushort_t port) {
113   struct dev_io_hook * tmp = NULL;
114
115   list_for_each_entry(tmp, &(mgr->io_hooks), mgr_list) {
116     if (tmp->port == port) {
117       return tmp;
118     }
119   }
120   return NULL;
121 }
122
123 struct dev_io_hook * dev_find_io_hook(struct vm_device * dev, ushort_t port) {
124   struct dev_io_hook * tmp = NULL;
125
126   list_for_each_entry(tmp, &(dev->io_hooks), dev_list) {
127     if (tmp->port == port) {
128       return tmp;
129     }
130   }
131   return NULL;
132 }
133
134
135
136
137 int dev_hook_io(struct vm_device   *dev,
138                 ushort_t            port,
139                 int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev),
140                 int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev)) {
141
142   struct dev_io_hook *hook = (struct dev_io_hook *)V3_Malloc(sizeof(struct dev_io_hook));
143   
144   if (!hook) { 
145     return -1;
146   }
147
148
149   if (v3_hook_io_port(dev->vm, port, 
150                       (int (*)(ushort_t, void *, uint_t, void *))read, 
151                       (int (*)(ushort_t, void *, uint_t, void *))write, 
152                       (void *)dev) == 0) {
153
154     hook->dev = dev;
155     hook->port = port;
156     hook->read = read;
157     hook->write = write;
158     
159     dev_mgr_add_io_hook(&(dev->vm->dev_mgr), hook);
160     dev_add_io_hook(dev, hook);
161   } else {
162
163     return -1;
164   }
165
166   return 0;
167 }
168
169
170 int dev_unhook_io(struct vm_device   *dev,
171                   ushort_t            port) {
172
173   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
174   struct dev_io_hook * hook = dev_mgr_find_io_hook(mgr, port);
175
176   if (!hook) { 
177     return -1;
178   }
179
180   dev_mgr_remove_io_hook(mgr, hook);
181   dev_remove_io_hook(dev, hook);
182
183   return v3_unhook_io_port(dev->vm, port);
184 }
185
186
187 int v3_attach_device(struct guest_info * vm, struct vm_device * dev) {
188   struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
189   
190   dev->vm = vm;
191   dev_mgr_add_device(mgr, dev);
192   dev->ops->init(dev);
193
194   return 0;
195 }
196
197 int v3_unattach_device(struct vm_device * dev) {
198   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
199
200   dev->ops->deinit(dev);
201   dev_mgr_remove_device(mgr, dev);
202   dev->vm = NULL;
203
204   return 0;
205 }
206
207
208
209
210
211 int dev_mgr_hook_mem(struct guest_info    *vm,
212                      struct vm_device   *device,
213                      void               *start,
214                      void               *end)
215 {
216
217   struct dev_mem_hook * hook = (struct dev_mem_hook*)V3_Malloc(sizeof(struct dev_mem_hook));
218   //  V3_Malloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
219
220   if (!hook) { 
221     return -1;
222   }
223
224   /* not implemented yet
225   hook_memory(vm->mem_map, 
226               guest_physical_address_start, 
227               guest_physical_address_end, 
228               read,
229               write,
230               device);
231
232   */
233
234   return -1;   // remove when hook_memory works
235
236
237   hook->addr_start = start;
238   hook->addr_end = end;
239
240   return 0;
241   
242 }
243
244
245 int dev_mgr_unhook_mem(struct vm_device   *dev,
246                        addr_t start,
247                        addr_t end)  {
248   /*
249   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
250   struct dev_mem_hook *hook = dev_mgr_find_mem_hook(mgr, start, end);
251   
252   if (!hook) { 
253     // Very bad - unhooking something that doesn't exist!
254     return -1;
255   }
256   */
257
258   /* not implemented yet
259   return unhook_mem_port(vm->mem_map,
260                          guest_physical_start,
261                          guest_physical_end) ;
262
263   */
264   return -1;
265 }
266
267
268
269 #ifdef DEBUG_DEV_MGR
270
271 void PrintDebugDevMgr(struct guest_info * info) {
272   struct vmm_dev_mgr * mgr = &(info->dev_mgr);
273   struct vm_device * dev;
274   PrintDebug("%d devices registered with manager\n", mgr->num_devs);
275
276   list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
277     PrintDebugDev(dev);
278     PrintDebug("next..\n");
279   }
280
281   return;
282 }
283
284
285 void PrintDebugDev(struct vm_device * dev) {
286   
287   PrintDebug("Device: %s\n", dev->name);
288   PrintDebugDevIO(dev);
289 }
290
291 void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {
292
293 }
294
295 void PrintDebugDevIO(struct vm_device * dev) {
296   struct dev_io_hook * hook;
297
298   PrintDebug("IO Hooks(%d)  for Device: %s\n", dev->num_io_hooks,  dev->name);
299
300   list_for_each_entry(hook, &(dev->io_hooks), dev_list) {
301     PrintDebug("\tPort: 0x%x (read=0x%x), (write=0x%x)\n", hook->port, hook->read, hook->write);
302   }
303
304   return;
305 }
306
307 #else 
308 void PrintDebugDevMgr(struct guest_info * info) {}
309 void PrintDebugDev(struct vm_device * dev) {}
310 void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {}
311 void PrintDebugDevIO(struct vm_device * dev) {}
312 #endif