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 irq initial setup
[palacios.git] / palacios / src / palacios / vmm_dev_mgr.c
1 #include <palacios/vm_dev.h>
2 #include <palacios/vmm_dev_mgr.h>
3 #include <palacios/vm_guest.h>
4 #include <palacios/vmm.h>
5 #include <palacios/vmm_irq.h>
6
7 extern struct vmm_os_hooks *os_hooks;
8
9 #ifndef NULL
10 #define NULL 0
11 #endif
12
13 int dev_mgr_init(struct vmm_dev_mgr * mgr) {
14
15   INIT_LIST_HEAD(&(mgr->dev_list));
16   mgr->num_devs = 0;
17
18   INIT_LIST_HEAD(&(mgr->io_hooks));
19   mgr->num_io_hooks = 0;
20   return 0;
21 }
22
23
24 int dev_mgr_deinit(struct vmm_dev_mgr * mgr) {
25   struct vm_device * dev;
26
27   list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
28     unattach_device(dev);
29     free_device(dev);
30   }
31
32   return 0;
33 }
34
35
36
37
38 int dev_mgr_add_device(struct vmm_dev_mgr * mgr, struct vm_device * dev) {
39   list_add(&(dev->dev_link), &(mgr->dev_list));
40   mgr->num_devs++;
41
42   return 0;
43 }
44
45 int dev_mgr_remove_device(struct vmm_dev_mgr * mgr, struct vm_device * dev) {
46   list_del(&(dev->dev_link));
47   mgr->num_devs--;
48
49   return 0;
50 }
51
52
53
54 /* IO HOOKS */
55 int dev_mgr_add_io_hook(struct vmm_dev_mgr * mgr, struct dev_io_hook * hook) {
56   list_add(&(hook->mgr_list), &(mgr->io_hooks));
57   mgr->num_io_hooks++;
58   return 0;
59 }
60
61
62 int dev_mgr_remove_io_hook(struct vmm_dev_mgr * mgr, struct dev_io_hook * hook) {
63   list_del(&(hook->mgr_list));
64   mgr->num_io_hooks--;
65
66   return 0;
67 }
68
69
70 int dev_add_io_hook(struct vm_device * dev, struct dev_io_hook * hook) {
71   list_add(&(hook->dev_list), &(dev->io_hooks));
72   dev->num_io_hooks++;
73   return 0;
74 }
75
76
77 int dev_remove_io_hook(struct vm_device * dev, struct dev_io_hook * hook) {
78   list_del(&(hook->dev_list));
79   dev->num_io_hooks--;
80
81   return 0;
82 }
83
84
85
86
87
88 struct dev_io_hook * dev_mgr_find_io_hook(struct vmm_dev_mgr * mgr, ushort_t port) {
89   struct dev_io_hook * tmp;
90
91   list_for_each_entry(tmp, &(mgr->io_hooks), mgr_list) {
92     if (tmp->port == port) {
93       return tmp;
94     }
95   }
96   return NULL;
97 }
98
99 struct dev_io_hook * dev_find_io_hook(struct vm_device * dev, ushort_t port) {
100   struct dev_io_hook * tmp;
101
102   list_for_each_entry(tmp, &(dev->io_hooks), dev_list) {
103     if (tmp->port == port) {
104       return tmp;
105     }
106   }
107   return NULL;
108 }
109
110
111
112
113 int dev_hook_io(struct vm_device   *dev,
114                 ushort_t            port,
115                 int (*read)(ushort_t port, void * dst, uint_t length, struct vm_device * dev),
116                 int (*write)(ushort_t port, void * src, uint_t length, struct vm_device * dev)) {
117
118   struct dev_io_hook *hook = os_hooks->malloc(sizeof(struct dev_io_hook));
119   
120   if (!hook) { 
121     return -1;
122   }
123
124
125   if (hook_io_port(&(dev->vm->io_map), port, 
126                    (int (*)(ushort_t, void *, uint_t, void *))read, 
127                    (int (*)(ushort_t, void *, uint_t, void *))write, 
128                    (void *)dev) == 0) {
129
130     hook->dev = dev;
131     hook->port = port;
132     hook->read = read;
133     hook->write = write;
134     
135     dev_mgr_add_io_hook(&(dev->vm->dev_mgr), hook);
136     dev_add_io_hook(dev, hook);
137   } else {
138     return -1;
139   }
140
141   return 0;
142 }
143
144
145 int dev_unhook_io(struct vm_device   *dev,
146                   ushort_t            port) {
147
148   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
149   struct dev_io_hook * hook = dev_mgr_find_io_hook(mgr, port);
150
151   if (!hook) { 
152     return -1;
153   }
154
155   dev_mgr_remove_io_hook(mgr, hook);
156   dev_remove_io_hook(dev, hook);
157
158   return unhook_io_port(&(dev->vm->io_map), port);
159 }
160
161
162
163
164 /* IRQ HOOKS */
165 /*
166 int dev_mgr_add_irq_hook(struct vmm_dev_mgr * mgr, struct dev_irq_hook * hook) {
167   list_add(&(hook->mgr_list), &(mgr->irq_hooks));
168   mgr->num_irq_hooks++;
169   return 0;
170 }
171
172
173 int dev_mgr_remove_irq_hook(struct vmm_dev_mgr * mgr, struct dev_irq_hook * hook) {
174   list_del(&(hook->mgr_list));
175   mgr->num_irq_hooks--;
176
177   return 0;
178 }
179
180
181 int dev_add_irq_hook(struct vm_device * dev, struct dev_irq_hook * hook) {
182   list_add(&(hook->dev_list), &(dev->irq_hooks));
183   dev->num_irq_hooks++;
184   return 0;
185 }
186
187
188 int dev_remove_irq_hook(struct vm_device * dev, struct dev_irq_hook * hook) {
189   list_del(&(hook->dev_list));
190   dev->num_irq_hooks--;
191
192   return 0;
193 }
194
195
196
197
198
199 struct dev_irq_hook * dev_mgr_find_irq_hook(struct vmm_dev_mgr * mgr, uint_t irq) {
200   struct dev_irq_hook * tmp;
201
202   list_for_each_entry(tmp, &(mgr->irq_hooks), mgr_list) {
203     if (tmp->irq == irq) {
204       return tmp;
205     }
206   }
207   return NULL;
208 }
209
210 struct dev_irq_hook * dev_find_irq_hook(struct vm_device * dev, uint_t irq) {
211   struct dev_irq_hook * tmp;
212
213   list_for_each_entry(tmp, &(dev->irq_hooks), dev_list) {
214     if (tmp->irq == irq) {
215       return tmp;
216     }
217   }
218   return NULL;
219 }
220
221
222
223
224 int dev_hook_irq(struct vm_device   *dev,
225                  uint_t irq,
226                  int (*handler)(uint_t irq, struct vm_device * dev)) {
227
228   struct dev_irq_hook *hook = os_hooks->malloc(sizeof(struct dev_irq_hook));
229   
230   if (!hook) { 
231     return -1;
232   }
233
234
235   if (hook_irq(&(dev->vm->irq_map), irq, 
236                (int (*)(uint_t, void *))handler, 
237                (void *)dev) == 0) {
238
239     hook->dev = dev;
240     hook->irq = irq;
241     hook->handler = handler;
242     
243     dev_mgr_add_irq_hook(&(dev->vm->dev_mgr), hook);
244     dev_add_irq_hook(dev, hook);
245   } else {
246     return -1;
247   }
248
249   return 0;
250 }
251
252
253 int dev_unhook_irq(struct vm_device * dev,
254                    uint_t irq) {
255
256   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
257   struct dev_irq_hook * hook = dev_mgr_find_irq_hook(mgr, irq);
258
259   if (!hook) { 
260     return -1;
261   }
262
263   dev_mgr_remove_irq_hook(mgr, hook);
264   dev_remove_irq_hook(dev, hook);
265
266   return unhook_irq(&(dev->vm->irq_map), irq);
267 }
268
269
270 */
271
272
273
274
275
276 int attach_device(struct guest_info * vm, struct vm_device * dev) {
277   struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
278   
279   dev->vm = vm;
280   dev_mgr_add_device(mgr, dev);
281   dev->ops->init(dev);
282
283   return 0;
284 }
285
286 int unattach_device(struct vm_device * dev) {
287   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
288
289   dev->ops->deinit(dev);
290   dev_mgr_remove_device(mgr, dev);
291   dev->vm = NULL;
292
293   return 0;
294 }
295
296
297
298
299
300 int dev_mgr_hook_mem(struct guest_info    *vm,
301                      struct vm_device   *device,
302                      void               *start,
303                      void               *end)
304 {
305
306   struct dev_mem_hook *hook;
307   VMMMalloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
308   
309   if (!hook) { 
310     return -1;
311   }
312
313
314     
315
316   /* not implemented yet
317   hook_memory(vm->mem_map, 
318               guest_physical_address_start, 
319               guest_physical_address_end, 
320               read,
321               write,
322               device);
323
324   */
325
326   return -1;   // remove when hook_memory works
327
328
329   hook->addr_start = start;
330   hook->addr_end = end;
331
332   return 0;
333   
334 }
335
336
337 int dev_mgr_unhook_mem(struct vm_device   *dev,
338                        addr_t start,
339                        addr_t end)  {
340   /*
341   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
342   struct dev_mem_hook *hook = dev_mgr_find_mem_hook(mgr, start, end);
343   
344   if (!hook) { 
345     // Very bad - unhooking something that doesn't exist!
346     return -1;
347   }
348   */
349
350   /* not implemented yet
351   return unhook_mem_port(vm->mem_map,
352                          guest_physical_start,
353                          guest_physical_end) ;
354
355   */
356   return -1;
357 }
358
359
360
361
362 void PrintDebugDevMgr(struct vmm_dev_mgr * mgr) {
363   struct vm_device * dev;
364   PrintDebug("%d devices registered with manager\n", mgr->num_devs);
365
366   list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
367     PrintDebugDev(dev);
368     PrintDebug("next..\n");
369   }
370
371   return;
372 }
373
374
375 void PrintDebugDev(struct vm_device * dev) {
376   
377   PrintDebug("Device: %s\n", dev->name);
378   PrintDebugDevIO(dev);
379 }
380
381 void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {
382
383 }
384
385 void PrintDebugDevIO(struct vm_device * dev) {
386   struct dev_io_hook * hook;
387
388   PrintDebug("IO Hooks(%d)  for Device: %s\n", dev->num_io_hooks,  dev->name);
389
390   list_for_each_entry(hook, &(dev->io_hooks), dev_list) {
391     PrintDebug("\tPort: 0x%x (read=0x%x), (write=0x%x)\n", hook->port, hook->read, hook->write);
392   }
393
394   return;
395 }