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.


reformatting of the source files
[palacios.git] / palacios / src / palacios / vmm_dev_mgr.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vm_dev.h>
21 #include <palacios/vmm_dev_mgr.h>
22 #include <palacios/vm_guest.h>
23 #include <palacios/vmm.h>
24 #include <palacios/vmm_decoder.h>
25
26
27 #ifndef DEBUG_DEV_MGR
28 #undef PrintDebug
29 #define PrintDebug(fmt, args...)
30 #endif
31
32
33
34 int v3_init_dev_mgr(struct guest_info * info) {
35     struct vmm_dev_mgr * mgr = &(info->dev_mgr);
36     INIT_LIST_HEAD(&(mgr->dev_list));
37     mgr->num_devs = 0;
38
39     INIT_LIST_HEAD(&(mgr->io_hooks));
40     mgr->num_io_hooks = 0;
41
42     INIT_LIST_HEAD(&(mgr->mem_hooks));
43     mgr->num_mem_hooks = 0;
44
45     INIT_LIST_HEAD(&(mgr->msr_hooks));
46     mgr->num_msr_hook = 0;
47
48     return 0;
49 }
50
51
52 int v3_dev_mgr_deinit(struct guest_info * info) {
53     struct vm_device * dev;
54     struct vmm_dev_mgr * mgr = &(info->dev_mgr);
55     struct vm_device * tmp;
56
57     list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
58         v3_unattach_device(dev);
59         v3_free_device(dev);
60     }
61
62     return 0;
63 }
64
65
66
67 int v3_attach_device(struct guest_info * vm, struct vm_device * dev) {
68     struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
69   
70     dev->vm = vm;
71
72     list_add(&(dev->dev_link), &(mgr->dev_list));
73     mgr->num_devs++;
74
75     dev->ops->init(dev);
76
77     return 0;
78 }
79
80 int v3_unattach_device(struct vm_device * dev) {
81     struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
82
83     dev->ops->deinit(dev);
84
85     list_del(&(dev->dev_link));
86     mgr->num_devs--;
87
88     dev->vm = NULL;
89
90     return 0;
91 }
92
93
94
95
96
97 /* IO HOOKS */
98 static struct dev_io_hook * dev_mgr_find_io_hook(struct vmm_dev_mgr * mgr, ushort_t port) {
99     struct dev_io_hook * tmp = NULL;
100
101     list_for_each_entry(tmp, &(mgr->io_hooks), mgr_list) {
102         if (tmp->port == port) {
103             return tmp;
104         }
105     }
106     return NULL;
107 }
108
109
110
111
112
113 int v3_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 = (struct dev_io_hook *)V3_Malloc(sizeof(struct dev_io_hook));
119     struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
120
121     if (!hook) { 
122         return -1;
123     }
124
125
126     if (v3_hook_io_port(dev->vm, 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         list_add(&(hook->mgr_list), &(mgr->io_hooks));
137         mgr->num_io_hooks++;
138     
139         list_add(&(hook->dev_list), &(dev->io_hooks));
140         dev->num_io_hooks++;
141     } else {
142
143         return -1;
144     }
145
146     return 0;
147 }
148
149
150 int v3_dev_unhook_io(struct vm_device   *dev,
151                      ushort_t            port) {
152     struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr);
153     struct dev_io_hook * hook = dev_mgr_find_io_hook(mgr, port);
154
155     if (!hook) { 
156         return -1;
157     }
158
159     list_del(&(hook->mgr_list));
160     mgr->num_io_hooks--;
161
162     list_del(&(hook->dev_list));
163     dev->num_io_hooks--;
164
165
166     return v3_unhook_io_port(dev->vm, port);
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186 #if 0
187 static 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 static 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 #endif
243
244
245
246
247
248 #ifdef DEBUG_DEV_MGR
249
250 void PrintDebugDevMgr(struct guest_info * info) {
251     struct vmm_dev_mgr * mgr = &(info->dev_mgr);
252     struct vm_device * dev;
253     PrintDebug("%d devices registered with manager\n", mgr->num_devs);
254
255     list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
256         PrintDebugDev(dev);
257         PrintDebug("next..\n");
258     }
259
260     return;
261 }
262
263
264 void PrintDebugDev(struct vm_device * dev) {
265   
266     PrintDebug("Device: %s\n", dev->name);
267     PrintDebugDevIO(dev);
268 }
269
270 void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {
271
272 }
273
274 void PrintDebugDevIO(struct vm_device * dev) {
275     struct dev_io_hook * hook;
276
277     PrintDebug("IO Hooks(%d)  for Device: %s\n", dev->num_io_hooks,  dev->name);
278
279     list_for_each_entry(hook, &(dev->io_hooks), dev_list) {
280         PrintDebug("\tPort: 0x%x (read=0x%p), (write=0x%p)\n", hook->port, 
281                    (void *)(addr_t)(hook->read), 
282                    (void *)(addr_t)(hook->write));
283     }
284
285     return;
286 }
287
288 #else 
289 void PrintDebugDevMgr(struct guest_info * info) {}
290 void PrintDebugDev(struct vm_device * dev) {}
291 void PrintDebugDevMgrIO(struct vmm_dev_mgr * mgr) {}
292 void PrintDebugDevIO(struct vm_device * dev) {}
293 #endif