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.


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