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.


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