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.


lot of changes
[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
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 int attach_device(struct guest_info * vm, struct vm_device * dev) {
164   struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
165   
166   dev->vm = vm;
167   dev_mgr_add_device(mgr, dev);
168   dev->ops->init(dev);
169
170   return 0;
171 }
172
173 int unattach_device(struct vm_device * dev) {
174   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
175
176   dev->ops->deinit(dev);
177   dev_mgr_remove_device(mgr, dev);
178   dev->vm = NULL;
179
180   return 0;
181 }
182
183
184
185
186
187 int dev_mgr_hook_mem(struct guest_info    *vm,
188                      struct vm_device   *device,
189                      void               *start,
190                      void               *end)
191 {
192
193   struct dev_mem_hook * hook = (struct dev_mem_hook*)V3_Malloc(sizeof(struct dev_mem_hook));
194   //  V3_Malloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
195
196   if (!hook) { 
197     return -1;
198   }
199
200   /* not implemented yet
201   hook_memory(vm->mem_map, 
202               guest_physical_address_start, 
203               guest_physical_address_end, 
204               read,
205               write,
206               device);
207
208   */
209
210   return -1;   // remove when hook_memory works
211
212
213   hook->addr_start = start;
214   hook->addr_end = end;
215
216   return 0;
217   
218 }
219
220
221 int dev_mgr_unhook_mem(struct vm_device   *dev,
222                        addr_t start,
223                        addr_t end)  {
224   /*
225   struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
226   struct dev_mem_hook *hook = dev_mgr_find_mem_hook(mgr, start, end);
227   
228   if (!hook) { 
229     // Very bad - unhooking something that doesn't exist!
230     return -1;
231   }
232   */
233
234   /* not implemented yet
235   return unhook_mem_port(vm->mem_map,
236                          guest_physical_start,
237                          guest_physical_end) ;
238
239   */
240   return -1;
241 }
242
243
244
245
246 void PrintDebugDevMgr(struct vmm_dev_mgr * mgr) {
247   struct vm_device * dev;
248   PrintDebug("%d devices registered with manager\n", mgr->num_devs);
249
250   list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
251     PrintDebugDev(dev);
252     PrintDebug("next..\n");
253   }
254
255   return;
256 }
257
258
259 void PrintDebugDev(struct vm_device * dev) {
260   
261   PrintDebug("Device: %s\n", dev->name);
262   PrintDebugDevIO(dev);
263 }
264
265 void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {
266
267 }
268
269 void PrintDebugDevIO(struct vm_device * dev) {
270   struct dev_io_hook * hook;
271
272   PrintDebug("IO Hooks(%d)  for Device: %s\n", dev->num_io_hooks,  dev->name);
273
274   list_for_each_entry(hook, &(dev->io_hooks), dev_list) {
275     PrintDebug("\tPort: 0x%x (read=0x%x), (write=0x%x)\n", hook->port, hook->read, hook->write);
276   }
277
278   return;
279 }