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.


code clean up
[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
9 #ifndef NULL
10 #define NULL 0
11 #endif
12
13 int dev_mgr_init(struct guest_info * info) {
14   struct vmm_dev_mgr * mgr = &(info->dev_mgr);
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
21   return 0;
22 }
23
24
25 int dev_mgr_deinit(struct guest_info * info) {
26   struct vm_device * dev;
27   struct vmm_dev_mgr * mgr = &(info->dev_mgr);
28
29   list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
30     v3_unattach_device(dev);
31     free_device(dev);
32   }
33
34   return 0;
35 }
36
37
38
39
40 static 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 static 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 = (struct dev_io_hook *)V3_Malloc(sizeof(struct dev_io_hook));
121   
122   if (!hook) { 
123     return -1;
124   }
125
126
127   if (v3_hook_io_port(dev->vm, 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 v3_unhook_io_port(dev->vm, port);
162 }
163
164
165 int v3_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 v3_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 guest_info * info) {
249   struct vmm_dev_mgr * mgr = &(info->dev_mgr);
250   struct vm_device * dev;
251   PrintDebug("%d devices registered with manager\n", mgr->num_devs);
252
253   list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
254     PrintDebugDev(dev);
255     PrintDebug("next..\n");
256   }
257
258   return;
259 }
260
261
262 void PrintDebugDev(struct vm_device * dev) {
263   
264   PrintDebug("Device: %s\n", dev->name);
265   PrintDebugDevIO(dev);
266 }
267
268 void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {
269
270 }
271
272 void PrintDebugDevIO(struct vm_device * dev) {
273   struct dev_io_hook * hook;
274
275   PrintDebug("IO Hooks(%d)  for Device: %s\n", dev->num_io_hooks,  dev->name);
276
277   list_for_each_entry(hook, &(dev->io_hooks), dev_list) {
278     PrintDebug("\tPort: 0x%x (read=0x%x), (write=0x%x)\n", hook->port, hook->read, hook->write);
279   }
280
281   return;
282 }