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.


ea6cdc7387f6d295d35df350d9c540b8673ae721
[palacios.git] / linux_usr / v3_user_host_dev_example.c
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <sys/select.h>
7 #include <malloc.h>
8
9 #include "v3_user_host_dev.h"
10
11 void usage()
12 {
13     fprintf(stderr,"v3_host_dev_example /dev/v3-vm0 user:mydev busywait|select\n");
14 }
15
16
17 int do_work(struct palacios_host_dev_host_request_response *req, 
18             struct palacios_host_dev_host_request_response **resp)
19 {
20     uint64_t datasize;
21     
22     //
23     //
24     // Process request here, perhaps calling these functions:
25     //
26     // uint64_t v3_user_host_dev_read_guest_mem(int devfd, void *gpa, void *dest, uint64_t len);
27     // uint64_t v3_user_host_dev_write_guest_mem(int devfd, void *gpa, void *src, uint64_t len);
28     // int      v3_user_host_dev_raise_irq(int devfd, uint8_t irq);
29     // int      v3_user_host_dev_lower_irq(int devfd, uint8_t irq);
30     //
31     // determine datasize - # bytes to include in response
32     //
33     // now built a response
34     *resp = malloc(sizeof(struct palacios_host_dev_host_request_response) + datasize);
35     if (!*resp) {
36         fprintf(stderr, "ERROR: could not allocate memory for response\n");
37         return -1;
38     }
39     (*resp)->data_len = sizeof(struct palacios_host_dev_host_request_response) + datasize;
40
41     //
42     // Fill out the fields of the response - notice that there are six kinds of things to response to:
43     //   - read/write device port
44     //   - read/write device mem
45     //   - read/write device configuration space
46
47     return 0;
48 }
49
50 int main(int argc, char *argv[])
51 {
52     int devfd;
53     int mode=0;
54     char *vm, *url;
55
56     if (argc!=4) { 
57         usage();
58         exit(-1);
59     }
60     
61     vm=argv[1];
62     url=argv[2];
63     mode = argv[3][0]=='s';
64
65     fprintf(stderr,"Attempting to rendezvous with host device %s on vm %s\n", url, vm);
66     
67     if ((devfd = v3_user_host_dev_rendezvous(vm,url))<0) { 
68         perror("failed to rendezvous");
69         exit(-1);
70     }
71     
72     fprintf(stderr,"Rendezvous succeeded, I will now operate in %s mode\n", mode==0 ? "busywait" : "select");
73     
74     if (mode==0) { 
75         //busywait
76
77         struct palacios_host_dev_host_request_response *req;
78         struct palacios_host_dev_host_request_response *resp;
79         uint64_t datasize;
80
81         while (1) { 
82             while (!(v3_user_host_dev_have_request(devfd))) { 
83             }
84             v3_user_host_dev_pull_request(devfd, &req);
85
86             do_work(req, &resp);
87             
88             v3_user_host_dev_push_response(devfd, resp);
89
90             free(resp);
91             free(req);
92         }
93     } else {
94
95         struct palacios_host_dev_host_request_response *req;
96         struct palacios_host_dev_host_request_response *resp;
97         uint64_t datasize;
98         fd_set   readset;
99         int rc;
100
101         // select-based operation so that you can wait for multiple things
102         
103         while (1) { 
104             FD_ZERO(&readset);
105             FD_SET(devfd,&readset);
106
107             rc = select(devfd+1, &readset, 0, 0, 0);  // pick whatever you want to select on, just include devfd
108
109             if (rc>0) { 
110                 if (FD_ISSET(devfd,&readset)) { 
111                     // a request is read for us!
112                     v3_user_host_dev_pull_request(devfd, &req);
113
114                     do_work(req, &resp);
115                     
116                     v3_user_host_dev_push_response(devfd, resp);
117                     
118                     free(resp);
119                     free(req);
120                 }
121             }
122         }
123     }
124
125     v3_user_host_dev_depart(devfd);
126
127     return 0;
128                     
129 }