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.


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