2 #include <palacios/vmm_dev.h>
3 #include <palacios/vmm_dev_mgr.h>
4 #include <palacios/vm_guest.h>
5 #include <palacios/vmm.h>
7 extern struct vmm_os_hooks *os_hooks;
13 int dev_mgr_init(struct vmm_dev_mgr *mgr, struct guest_info *vm)
22 int dev_mgr_deinit(struct vmm_dev_mgr *mgr)
26 while (mgr->dev_list) {
27 rc=dev_mgr_detach_device(mgr->vm,mgr->dev_list);
35 int dev_mgr_attach_device(struct guest_info *vm, struct vm_device *device)
37 struct vmm_dev_mgr *mgr= &(vm->dev_mgr);
39 if (device->io_hooks || device->mem_hooks) {
43 device->next = mgr->dev_list;
46 device->next->prev = device;
48 mgr->dev_list = device;
55 int dev_mgr_detach_device(struct guest_info *vm, struct vm_device *device)
57 if (device->prev==0) {
58 vm->dev_mgr.dev_list = device->next;
60 device->prev->next = device->next;
63 device->next->prev=device->prev;
66 // avoid interrupts here
68 device->deinit_device(device);
75 #define INSERT_FRONT(listhead,item) \
83 (item)->next=(listhead); \
84 if ((listhead)->next) { \
85 (listhead)->next->prev=(item); \
91 #define DELETE(listhead,item) \
94 (item)->prev->next=(item)->next; \
96 (listhead)=(item)->next; \
99 (item)->next->prev=(item)->prev; \
106 int dev_mgr_hook_io(struct guest_info *vm,
107 struct vm_device *device,
109 enum access_control control,
110 enum access_type atype)
112 struct vm_device_io_hook *hook = os_hooks->malloc(sizeof(struct vm_device_io_hook));
118 int (*read)(ushort_t, void *, uint_t, void *) = NULL;
119 int (*write)(ushort_t, void *, uint_t, void *) = NULL;
122 case DEVICE_EMULATED:
125 read = (int (*)(ushort_t, void *,uint_t, void *)) (device->read_io_port);
128 write = (int (*)(ushort_t, void *, uint_t, void *)) (device->write_io_port);
130 case DEVICE_READWRITE:
131 read = (int (*)(ushort_t, void *, uint_t, void *)) (device->read_io_port);
132 write = (int (*)(ushort_t, void *, uint_t, void *)) (device->write_io_port);
136 case DEVICE_PASSTHROUGH:
141 hook_io_port(&(vm->io_map),
147 hook->control=control;
149 hook->guest_port = portno;
151 INSERT_FRONT(device->io_hooks,hook);
157 int dev_mgr_unhook_io(struct guest_info *vm,
158 struct vm_device *device,
161 struct vm_device_io_hook *hook = device->io_hooks;
164 if (hook->guest_port==portno) {
165 DELETE(device->io_hooks,hook);
171 // Very bad - unhooking something that doesn't exist!
175 return unhook_io_port(&(vm->io_map),
181 int dev_mgr_hook_mem(struct guest_info *vm,
182 struct vm_device *device,
183 void *guest_physical_address_start,
184 void *guest_physical_address_end,
185 enum access_control control,
186 enum access_type atype)
189 struct vm_device_mem_hook *hook = os_hooks->malloc(sizeof(struct vm_device_mem_hook));
195 int (*read)(ushort_t, void *, uint_t, void *) = NULL;
196 int (*write)(ushort_t, void *, uint_t, void *) = NULL;
199 case DEVICE_EMULATED:
202 read = (int (*)(ushort_t, void *, uint_t, void *))(device->read_mapped_memory);
205 write = (int (*)(ushort_t, void *, uint_t, void *))(device->write_mapped_memory);
207 case DEVICE_READWRITE:
208 read = (int (*)(ushort_t, void *, uint_t, void *))(device->read_mapped_memory);
209 write = (int (*)(ushort_t, void *, uint_t, void *))(device->write_mapped_memory);
213 case DEVICE_PASSTHROUGH:
219 /* not implemented yet
220 hook_memory(vm->mem_map,
221 guest_physical_address_start,
222 guest_physical_address_end,
229 return -1; // remove when hook_memory works
231 hook->control=control;
233 hook->guest_physical_start = guest_physical_address_start;
234 hook->guest_physical_end = guest_physical_address_end;
237 INSERT_FRONT(device->mem_hooks,hook);
244 int dev_mgr_unhook_mem(struct guest_info *vm,
245 struct vm_device *device,
246 void *guest_physical_start,
247 void *guest_physical_end)
249 struct vm_device_mem_hook *hook = device->mem_hooks;
252 if (hook->guest_physical_start==guest_physical_start &&
253 hook->guest_physical_end==guest_physical_end) {
254 DELETE(device->mem_hooks,hook);
260 // Very bad - unhooking something that doesn't exist!
265 /* not implemented yet
266 return unhook_mem_port(vm->mem_map,
267 guest_physical_start,
268 guest_physical_end) ;
275 int dev_mgr_unhook_device(struct guest_info *vm,
276 struct vm_device *device)
278 struct vm_device_io_hook *iohook=device->io_hooks;
279 struct vm_device_mem_hook *memhook=device->mem_hooks;
282 if (dev_mgr_unhook_io(vm,device,iohook->guest_port)) {
288 if (dev_mgr_unhook_mem(vm,device,memhook->guest_physical_start, memhook->guest_physical_end)) {