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.


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