Added server side config functions
[qemu/ovp.git] / qemu-vio.c
blob6aaf9e4f3c23a8d422550b9425cc84290e466099
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <libgen.h>
5 #include <sys/ioctl.h>
6 #include <sys/mman.h>
7 #include <sys/poll.h>
8 #include <sys/time.h>
9 #include <sys/types.h>
10 #include <signal.h>
11 #include <unistd.h>
13 #include <linux/virtio_blk.h>
14 #include <linux/virtio_config.h>
15 #include <linux/virtio_ids.h>
16 #include <linux/virtio_net.h>
17 #include <linux/virtio_pci.h>
18 #include <linux/virtio_vio.h>
20 #include "cmd.h"
21 #include "qemu-common.h"
22 #include "targphys.h"
23 #include "block_int.h"
25 #define VERSION "1.0"
26 //#define trace() printf("QEMU-VIO: %s-%s: %s(%d)\n",__TIME__, __FILE__,__func__, __LINE__)
27 #define trace() ;
29 char *progname;
30 void *devdata;
31 BlockDriverState *bs;
32 int fd;
34 long long unsigned int num_reads;
35 long long unsigned int num_writes;
36 long long unsigned int num_scsi_cmds;
37 long long unsigned int num_flushs;
39 void vv_exit(int param);
41 struct tlbmap *tlb;
42 target_phys_addr_t data_buffaddr;
44 static inline void printHexa(void *buff,unsigned int len) {
45 __u8 *buf = (__u8 *)buff;
46 __u8 *cur;
48 for (cur=buf; (cur - buf) < len; cur++)
49 printf("%02X",*cur);
53 /**
54 * Qemu-vio functions
55 * */
57 void vv_exit(int param) {
59 printf("\nqemu-vio: ");
60 printf("num_reads: %llu, num_writes: %llu, num_scsi_cmds: %llu,num_flushs: %llu\n",
61 num_reads, num_writes,num_scsi_cmds, num_flushs );
62 printf("qemu-vio: total requests processed: %llu\n",num_reads+num_writes+num_scsi_cmds+num_flushs);
63 printf("qemu-vio: bye.\n");
64 // free(devdata);
65 // qemu_vio_exit(bs);
66 exit(0);
69 static void vv_get_config_hdr(struct swap_buff *vreq) {
71 trace();
72 vreq->param = 0;
73 vreq->len = sizeof(struct vv_device_header);
74 vreq->function = VV_GET_CONFIG_HDR_RESPONSE;
75 memcpy(vreq->data, devdata, sizeof(struct vv_device_header));
78 static void vv_get_config_space(struct swap_buff *vreq) {
80 struct virtio_blk_config *blkcfg;
82 blkcfg = (struct virtio_blk_config *)(((char *)devdata) + sizeof(struct vv_device_header));
84 trace();
86 vreq->param = 0;
87 vreq->len = sizeof(struct virtio_blk_config);
88 vreq->function = VV_GET_CONFIGS_RESPONSE;
90 memcpy(vreq->data,blkcfg,vreq->len);
93 static void vv_refresh_config_hdr(struct swap_buff *vreq) {
96 trace();
97 memcpy(devdata, vreq->data, sizeof(struct vv_device_header));
99 vreq->param = 0;
100 vreq->len = 0;
101 vreq->function = VV_REFRESH_CONFIG_HDR_RESPONSE;
104 static void vv_refresh_config_space(struct swap_buff *vreq) {
106 struct virtio_blk_config *blkcfg;
107 blkcfg = (struct virtio_blk_config *)(((char *)devdata) + sizeof(struct vv_device_header));
109 trace();
111 memcpy(blkcfg,vreq->data,sizeof(struct virtio_blk_config));
112 vreq->param = 0;
113 vreq->len = 0;
114 vreq->function = VV_REFRESH_CONFIG_SPACE_RESPONSE;
117 static unsigned int get_features(void) {
119 unsigned int flags;
121 flags = 0;
123 flags |= (1 << VIRTIO_BLK_F_SEG_MAX);
124 flags |= VIRTIO_BLK_F_BLK_SIZE;
125 flags |= VIRTIO_BLK_F_SIZE_MAX;
127 if (bdrv_enable_write_cache(bs))
128 flags |= (1 << VIRTIO_BLK_F_WCACHE);
130 #ifdef __linux__
131 flags |= (1 << VIRTIO_BLK_F_SCSI);
132 #endif
134 if (bdrv_is_read_only(bs))
135 flags |= 1 << VIRTIO_BLK_F_RO;
137 return flags;
141 static int gather_device_configs(void) {
143 struct vv_device_header *hdr;
144 struct virtio_blk_config *blkcfg;
145 int cfg_data_len;
147 cfg_data_len = sizeof(struct vv_device_header) +
148 sizeof(struct virtio_blk_config);
149 memset(devdata, 0x00, cfg_data_len);
150 hdr = (struct vv_device_header *)devdata;
151 blkcfg = (struct virtio_blk_config *)(((char *)devdata) + sizeof(struct vv_device_header));
153 hdr->type = VIRTIO_ID_BLOCK;
154 hdr->num_vqs = 1;
155 hdr->vqs_size = VRING_ELEMENTS;
156 hdr->device_features = get_features();
157 hdr->guest_features = 0;
158 hdr->config_len = sizeof(struct virtio_blk_config);
159 hdr->device_status = 0;
161 blkcfg->size_max = 4096;
162 blkcfg->blk_size = 512;
163 blkcfg->seg_max = VRING_ELEMENTS - 2;
165 printf("qemu-vio: total sectors: %llu\n", (long long)blkcfg->capacity);
166 return 0;
169 static void process_swap_buff(struct swap_buff *vreq) {
170 switch (vreq->function) {
171 case VV_GET_CONFIG_HDR:
172 vv_get_config_hdr(vreq);
173 break;
174 case VV_GET_CONFIGS:
175 vv_get_config_space(vreq);
176 break;
177 case VV_REFRESH_CONFIG_HDR:
178 vv_refresh_config_hdr(vreq);
179 break;
180 case VV_REFRESH_CONFIG_SPACE:
181 vv_refresh_config_space(vreq);
182 break;
186 static int open_image(char *name) {
187 unsigned int flags = BDRV_O_RDWR;
189 if (bs) {
190 fprintf(stderr, "qemu-vio: file open already, try 'help close'\n");
191 return 1;
194 bs = bdrv_new("hda");
195 if (!bs)
196 return 1;
198 if (bdrv_open(bs, name, flags, NULL) == -1) {
199 fprintf(stderr, "qemu-vio: can't open file %s\n", name);
200 bs = NULL;
201 return 1;
205 return 0;
209 * Main loop
210 * */
211 int main(int argc, char **argv) {
213 int nbytes;
214 char *sh_buff, imgfname[30], devname[30];
215 struct pollfd pfd1;
216 struct swap_buff *vreq;
218 if (argc<3) {
219 printf("qemu-vio: usage: %s [ virtio device ] [ imagefile ]\n",argv[0]);
220 exit(0);
222 strcpy(devname,argv[1]);
223 strcpy(imgfname,argv[2]);
225 if (signal(SIGINT, vv_exit)==SIG_ERR) {
226 perror("qemu-vio: error capturing signal");
227 return(1);
231 bdrv_init();
232 if (open_image(imgfname)) {
233 printf("qemu-vio: could not open file %s\n", argv[1]);
234 return 0;
237 devdata = malloc(sizeof(struct vv_device_header)+sizeof(struct virtio_blk_config));
239 gather_device_configs();
241 fd = open(devname, O_RDWR | O_SYNC);
242 if ( fd == -1) {
243 perror("qemu-vio: open");
244 exit(0);
247 sh_buff = mmap(0,SWAP_SIZE, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0);
248 if (sh_buff == MAP_FAILED) {
249 printf("qemu-vio: mmap() failed\n");
250 exit(1);
252 pfd1.fd = fd;
253 pfd1.events = POLLIN;
255 tlb = (struct tlbmap *)((char *)sh_buff + TLB_OFFSET);
256 data_buffaddr =(target_phys_addr_t)((char *)tlb + TLB_LEN);
257 vreq = (struct swap_buff *)sh_buff;
259 num_reads = 0;
260 num_writes = 0;
261 num_scsi_cmds = 0;
262 num_flushs = 0;
264 printf("qemu-vio: checking/waiting for data...");
265 fflush(stdout);
266 while (1) {
267 vreq->function = 0;
269 nbytes = poll(&pfd1, 1, -1);
271 printf(".");
272 fflush(stdout);
273 process_swap_buff(vreq);
275 //TODO: Find apropriate ioctl number
276 ioctl(fd, DATAREADY,0);