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.


First cut at a keyboard device (partially done)
[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
139     return -1;
140   }
141
142   return 0;
143 }
144
145
146 int dev_unhook_io(struct vm_device   *dev,
147                   ushort_t            port) {
148
149   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
150   struct dev_io_hook * hook = dev_mgr_find_io_hook(mgr, port);
151
152   if (!hook) { 
153     return -1;
154   }
155
156   dev_mgr_remove_io_hook(mgr, hook);
157   dev_remove_io_hook(dev, hook);
158
159   return unhook_io_port(&(dev->vm->io_map), port);
160 }
161
162
163
164
165 /* IRQ HOOKS */
166 /*
167 int dev_mgr_add_irq_hook(struct vmm_dev_mgr * mgr, struct dev_irq_hook * hook) {
168   list_add(&(hook->mgr_list), &(mgr->irq_hooks));
169   mgr->num_irq_hooks++;
170   return 0;
171 }
172
173
174 int dev_mgr_remove_irq_hook(struct vmm_dev_mgr * mgr, struct dev_irq_hook * hook) {
175   list_del(&(hook->mgr_list));
176   mgr->num_irq_hooks--;
177
178   return 0;
179 }
180
181
182 int dev_add_irq_hook(struct vm_device * dev, struct dev_irq_hook * hook) {
183   list_add(&(hook->dev_list), &(dev->irq_hooks));
184   dev->num_irq_hooks++;
185   return 0;
186 }
187
188
189 int dev_remove_irq_hook(struct vm_device * dev, struct dev_irq_hook * hook) {
190   list_del(&(hook->dev_list));
191   dev->num_irq_hooks--;
192
193   return 0;
194 }
195
196
197
198
199
200 struct dev_irq_hook * dev_mgr_find_irq_hook(struct vmm_dev_mgr * mgr, uint_t irq) {
201   struct dev_irq_hook * tmp;
202
203   list_for_each_entry(tmp, &(mgr->irq_hooks), mgr_list) {
204     if (tmp->irq == irq) {
205       return tmp;
206     }
207   }
208   return NULL;
209 }
210
211 struct dev_irq_hook * dev_find_irq_hook(struct vm_device * dev, uint_t irq) {
212   struct dev_irq_hook * tmp;
213
214   list_for_each_entry(tmp, &(dev->irq_hooks), dev_list) {
215     if (tmp->irq == irq) {
216       return tmp;
217     }
218   }
219   return NULL;
220 }
221
222
223
224
225 int dev_hook_irq(struct vm_device   *dev,
226                  uint_t irq,
227                  int (*handler)(uint_t irq, struct vm_device * dev)) {
228
229   struct dev_irq_hook *hook = os_hooks->malloc(sizeof(struct dev_irq_hook));
230   
231   if (!hook) { 
232     return -1;
233   }
234
235
236   if (hook_irq(&(dev->vm->irq_map), irq, 
237                (int (*)(uint_t, void *))handler, 
238                (void *)dev) == 0) {
239
240     hook->dev = dev;
241     hook->irq = irq;
242     hook->handler = handler;
243     
244     dev_mgr_add_irq_hook(&(dev->vm->dev_mgr), hook);
245     dev_add_irq_hook(dev, hook);
246   } else {
247     return -1;
248   }
249
250   return 0;
251 }
252
253
254 int dev_unhook_irq(struct vm_device * dev,
255                    uint_t irq) {
256
257   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
258   struct dev_irq_hook * hook = dev_mgr_find_irq_hook(mgr, irq);
259
260   if (!hook) { 
261     return -1;
262   }
263
264   dev_mgr_remove_irq_hook(mgr, hook);
265   dev_remove_irq_hook(dev, hook);
266
267   return unhook_irq(&(dev->vm->irq_map), irq);
268 }
269
270
271 */
272
273
274
275
276
277 int attach_device(struct guest_info * vm, struct vm_device * dev) {
278   struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
279   
280   dev->vm = vm;
281   dev_mgr_add_device(mgr, dev);
282   dev->ops->init(dev);
283
284   return 0;
285 }
286
287 int unattach_device(struct vm_device * dev) {
288   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
289
290   dev->ops->deinit(dev);
291   dev_mgr_remove_device(mgr, dev);
292   dev->vm = NULL;
293
294   return 0;
295 }
296
297
298
299
300
301 int dev_mgr_hook_mem(struct guest_info    *vm,
302                      struct vm_device   *device,
303                      void               *start,
304                      void               *end)
305 {
306
307   struct dev_mem_hook *hook;
308   V3_Malloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
309   
310   if (!hook) { 
311     return -1;
312   }
313
314
315     
316
317   /* not implemented yet
318   hook_memory(vm->mem_map, 
319               guest_physical_address_start, 
320               guest_physical_address_end, 
321               read,
322               write,
323               device);
324
325   */
326
327   return -1;   // remove when hook_memory works
328
329
330   hook->addr_start = start;
331   hook->addr_end = end;
332
333   return 0;
334   
335 }
336
337
338 int dev_mgr_unhook_mem(struct vm_device   *dev,
339                        addr_t start,
340                        addr_t end)  {
341   /*
342   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
343   struct dev_mem_hook *hook = dev_mgr_find_mem_hook(mgr, start, end);
344   
345   if (!hook) { 
346     // Very bad - unhooking something that doesn't exist!
347     return -1;
348   }
349   */
350
351   /* not implemented yet
352   return unhook_mem_port(vm->mem_map,
353                          guest_physical_start,
354                          guest_physical_end) ;
355
356   */
357   return -1;
358 }
359
360
361
362
363 void PrintDebugDevMgr(struct vmm_dev_mgr * mgr) {
364   struct vm_device * dev;
365   PrintDebug("%d devices registered with manager\n", mgr->num_devs);
366
367   list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
368     PrintDebugDev(dev);
369     PrintDebug("next..\n");
370   }
371
372   return;
373 }
374
375
376 void PrintDebugDev(struct vm_device * dev) {
377   
378   PrintDebug("Device: %s\n", dev->name);
379   PrintDebugDevIO(dev);
380 }
381
382 void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {
383
384 }
385
386 void PrintDebugDevIO(struct vm_device * dev) {
387   struct dev_io_hook * hook;
388
389   PrintDebug("IO Hooks(%d)  for Device: %s\n", dev->num_io_hooks,  dev->name);
390
391   list_for_each_entry(hook, &(dev->io_hooks), dev_list) {
392     PrintDebug("\tPort: 0x%x (read=0x%x), (write=0x%x)\n", hook->port, hook->read, hook->write);
393   }
394
395   return;
396 }