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>
21 #include "qemu-common.h"
23 #include "block_int.h"
26 //#define trace() printf("QEMU-VIO: %s-%s: %s(%d)\n",__TIME__, __FILE__,__func__, __LINE__)
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
);
42 target_phys_addr_t data_buffaddr
;
44 static inline void printHexa(void *buff
,unsigned int len
) {
45 __u8
*buf
= (__u8
*)buff
;
48 for (cur
=buf
; (cur
- buf
) < len
; cur
++)
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");
69 static void vv_get_config_hdr(struct swap_buff
*vreq
) {
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
));
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
) {
97 memcpy(devdata
, vreq
->data
, sizeof(struct vv_device_header
));
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
));
111 memcpy(blkcfg
,vreq
->data
,sizeof(struct virtio_blk_config
));
114 vreq
->function
= VV_REFRESH_CONFIG_SPACE_RESPONSE
;
117 static unsigned int get_features(void) {
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
);
131 flags
|= (1 << VIRTIO_BLK_F_SCSI
);
134 if (bdrv_is_read_only(bs
))
135 flags
|= 1 << VIRTIO_BLK_F_RO
;
141 static int gather_device_configs(void) {
143 struct vv_device_header
*hdr
;
144 struct virtio_blk_config
*blkcfg
;
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
;
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
);
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
);
175 vv_get_config_space(vreq
);
177 case VV_REFRESH_CONFIG_HDR
:
178 vv_refresh_config_hdr(vreq
);
180 case VV_REFRESH_CONFIG_SPACE
:
181 vv_refresh_config_space(vreq
);
186 static int open_image(char *name
) {
187 unsigned int flags
= BDRV_O_RDWR
;
190 fprintf(stderr
, "qemu-vio: file open already, try 'help close'\n");
194 bs
= bdrv_new("hda");
198 if (bdrv_open(bs
, name
, flags
, NULL
) == -1) {
199 fprintf(stderr
, "qemu-vio: can't open file %s\n", name
);
211 int main(int argc
, char **argv
) {
214 char *sh_buff
, imgfname
[30], devname
[30];
216 struct swap_buff
*vreq
;
219 printf("qemu-vio: usage: %s [ virtio device ] [ imagefile ]\n",argv
[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");
232 if (open_image(imgfname
)) {
233 printf("qemu-vio: could not open file %s\n", argv
[1]);
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
);
243 perror("qemu-vio: open");
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");
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
;
264 printf("qemu-vio: checking/waiting for data...");
269 nbytes
= poll(&pfd1
, 1, -1);
273 process_swap_buff(vreq
);
275 //TODO: Find apropriate ioctl number
276 ioctl(fd
, DATAREADY
,0);