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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
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.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
25 #include <palacios/vmm_types.h>
26 #include <palacios/vmm_list.h>
27 #include <palacios/vmm_string.h>
28 #include <palacios/vmm_hashtable.h>
29 #include <palacios/vmm_msr.h>
30 #include <palacios/vmm_config.h>
32 #ifdef V3_CONFIG_CHECKPOINT
33 #include <palacios/vmm_checkpoint.h>
40 typedef void * v3_dev_data_t;
49 struct v3_device_ops * ops;
51 struct v3_vm_info * vm;
53 struct list_head dev_link;
56 struct list_head res_hooks;
62 struct list_head dev_list;
63 struct hashtable * dev_table;
65 struct list_head blk_list;
66 struct hashtable * blk_table;
68 struct list_head net_list;
69 struct hashtable * net_table;
71 struct list_head char_list;
72 struct hashtable * char_table;
74 struct list_head cons_list;
75 struct hashtable * cons_table;
79 int v3_create_device(struct v3_vm_info * vm, const char * dev_name, v3_cfg_tree_t * cfg);
81 struct vm_device * v3_find_dev(struct v3_vm_info * info, const char * dev_name);
84 // Registration of devices
87 // The following device manager functions should only be called
88 // when the guest is stopped
93 int v3_init_dev_mgr(struct v3_vm_info * vm);
94 int v3_deinit_dev_mgr(struct v3_vm_info * vm);
96 int v3_free_vm_devices(struct v3_vm_info * vm);
98 #ifdef V3_CONFIG_CHECKPOINT
99 int v3_save_vm_devices(struct v3_vm_info * vm, struct v3_chkpt * chkpt);
100 int v3_load_vm_devices(struct v3_vm_info * vm, struct v3_chkpt * chkpt);
105 int V3_init_devices();
106 int V3_deinit_devices();
109 struct v3_device_ops {
110 int (*free)(void * private_data);
112 #ifdef V3_CONFIG_CHECKPOINT
114 Both the base and extended save/load functions are optional.
115 If save_extended is defined, then it will be called in
116 preference to save. The idea is that with "save", the caller
117 opens the context using the name of the device, and expects
118 the callee to write it and then return. With "save_extended"
119 the caller passes the checkpoint store and the device name
120 to the callee. The callee is then expected to open
121 contexts as desired, write to them, and then close them
122 before returning. Load and load/extended are symmetric.
125 int (*save)(struct v3_chkpt_ctx * ctx, void * private_data);
126 int (*load)(struct v3_chkpt_ctx * ctx, void * privata_data);
127 int (*save_extended)(struct v3_chkpt * chkpt, char * id, void * private_data);
128 int (*load_extended)(struct v3_chkpt * chkpt, char * id, void * privata_data);
137 int v3_dev_hook_io(struct vm_device * dev,
139 int (*read)(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data),
140 int (*write)(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data));
142 int v3_dev_unhook_io(struct vm_device * dev,
146 int v3_dev_hook_msr(struct vm_device * dev,
148 int (*read)(struct guest_info * core, uint32_t msr, struct v3_msr * dst, void * priv_data),
149 int (*write)(struct guest_info * core, uint32_t msr, struct v3_msr src, void * priv_data));
151 int v3_dev_unhook_msr(struct vm_device * dev,
157 struct vm_device * v3_add_device(struct v3_vm_info * vm, char * name,
158 struct v3_device_ops * ops, void * private_data);
159 int v3_remove_device(struct vm_device * dev);
162 int v3_attach_device(struct v3_vm_info * vm, struct vm_device * dev);
163 int v3_detach_device(struct vm_device * dev);
164 struct vm_device * v3_allocate_device(char * name, struct v3_device_ops * ops, void * private_data);
167 struct v3_device_info {
169 int (*init)(struct v3_vm_info * info, v3_cfg_tree_t * cfg);
173 #define device_register(name, init_dev_fn) \
174 static char _v3_device_name[] = name; \
175 static struct v3_device_info _v3_device \
176 __attribute__((__used__)) \
177 __attribute__((unused, __section__ ("_v3_devices"), \
178 aligned(sizeof(addr_t)))) \
179 = {_v3_device_name , init_dev_fn};
184 void v3_print_dev_mgr(struct v3_vm_info * vm);
187 struct v3_dev_blk_ops {
188 uint64_t (*get_capacity)(void * private_data);
189 // Reads always operate on 2048 byte blocks
191 // how does this signal bytes_read < requested but not error?
193 int (*read)(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data);
194 int (*write)(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data);
198 struct v3_dev_net_ops_cfg{
199 void * frontend_data;
202 int poll; /* need poll? */
205 struct v3_dev_net_ops {
206 /* Backend implemented functions */
207 int (*send)(uint8_t * buf, uint32_t len, void * private_data);
209 /* Frontend implemented functions */
210 int (*recv)(uint8_t * buf, uint32_t len, void * frnt_data);
211 int (*poll)(int quote, void * frnt_data);
213 /* This is ugly... */
214 struct v3_dev_net_ops_cfg config;
217 struct v3_dev_console_ops {
218 int (*update_screen)(uint_t x, uint_t y, uint_t length, uint8_t * fb_data, void * private_data);
219 int (*update_cursor)(uint_t x, uint_t y, void * private_data);
220 int (*scroll)(int rows, void * private_data);
221 int (*set_text_resolution)(int cols, int rows, void * private_data);
223 /* frontend implemented functions */
224 int (*get_screen)(uint_t x, uint_t y, uint_t length, void * frontend_data);
228 struct v3_dev_char_ops {
229 /* Backend implemented functions */
230 sint64_t (*output)(uint8_t * buf, sint64_t len, void * private_data);
231 // int (*read)(uint8_t * buf, uint64_t len, void * private_data);
233 /* Frontend Implemented functions */
234 sint64_t (*input)(struct v3_vm_info * vm, uint8_t * buf, sint64_t len, void * private_data);
238 int v3_dev_add_blk_frontend(struct v3_vm_info * vm,
240 int (*connect)(struct v3_vm_info * vm,
241 void * frontend_data,
242 struct v3_dev_blk_ops * ops,
244 void * private_data),
247 int v3_dev_connect_blk(struct v3_vm_info * vm,
248 char * frontend_name,
249 struct v3_dev_blk_ops * ops,
251 void * private_data);
253 int v3_dev_add_net_frontend(struct v3_vm_info * vm,
255 int (*connect)(struct v3_vm_info * vm,
256 void * frontend_data,
257 struct v3_dev_net_ops * ops,
259 void * private_data),
262 int v3_dev_connect_net(struct v3_vm_info * vm,
263 char * frontend_name,
264 struct v3_dev_net_ops * ops,
266 void * private_data);
271 int v3_dev_add_console_frontend(struct v3_vm_info * vm,
273 int (*connect)(struct v3_vm_info * vm,
274 void * frontend_data,
275 struct v3_dev_console_ops * ops,
277 void * private_data),
280 int v3_dev_connect_console(struct v3_vm_info * vm,
281 char * frontend_name,
282 struct v3_dev_console_ops * ops,
284 void * private_data);
288 int v3_dev_add_char_frontend(struct v3_vm_info * vm,
290 int (*connect)(struct v3_vm_info * vm,
291 void * frontend_data,
292 struct v3_dev_char_ops * ops,
295 void ** push_fn_arg),
298 int v3_dev_connect_char(struct v3_vm_info * vm,
299 char * frontend_name,
300 struct v3_dev_char_ops * ops,
303 void ** push_fn_arg);
306 #endif // ! __V3VEE__