Fix up DEVICE_FEATURES usage
[akaros.git] / user / vmm / virtio-mmio.c
1 /*
2  * Virtio MMIO bindings
3  *
4  * Copyright (c) 2011 Linaro Limited
5  *
6  * Author:
7  *  Peter Maydell <peter.maydell@linaro.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <pthread.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <parlib/arch/arch.h>
28 #include <parlib/ros_debug.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/uio.h>
34 #include <stdint.h>
35 #include <err.h>
36 #include <sys/mman.h>
37 #include <ros/vmm.h>
38 #include <vmm/virtio.h>
39 #include <vmm/virtio_mmio.h>
40 #include <vmm/virtio_ids.h>
41 #include <vmm/virtio_config.h>
42
43 int debug_virtio_mmio = 1;
44 #define DPRINTF(fmt, ...) \
45         if (debug_virtio_mmio) { printf("virtio_mmio: " fmt , ## __VA_ARGS__); }
46
47
48 #define VIRT_MAGIC 0x74726976 /* 'virt' */
49 #define VIRT_VERSION 2
50 #define VIRT_VENDOR 0x554D4551 /* 'QEMU' */
51
52
53 typedef struct {
54         int state; // not used yet. */
55         uint64_t bar;
56         uint32_t status;
57         int qsel; // queue we are on.
58         int pagesize;
59         int page_shift;
60         int device_features_word; // if this is 1, use the high 32 bits. 
61         int guest_features_sel;
62         struct vqdev *vqdev;
63 } mmiostate;
64
65 static mmiostate mmio;
66
67 void register_virtio_mmio(struct vqdev *vqdev, uint64_t virtio_base)
68 {
69         mmio.bar = virtio_base;
70         mmio.vqdev = vqdev;
71 }
72
73 static uint32_t virtio_mmio_read(uint64_t gpa);
74 char *virtio_names[] = {
75         [VIRTIO_MMIO_MAGIC_VALUE] "VIRTIO_MMIO_MAGIC_VALUE",
76         [VIRTIO_MMIO_VERSION] "VIRTIO_MMIO_VERSION",
77         [VIRTIO_MMIO_DEVICE_ID] "VIRTIO_MMIO_DEVICE_ID",
78         [VIRTIO_MMIO_VENDOR_ID] "VIRTIO_MMIO_VENDOR_ID",
79         [VIRTIO_MMIO_DEVICE_FEATURES] "VIRTIO_MMIO_DEVICE_FEATURES",
80         [VIRTIO_MMIO_DEVICE_FEATURES_SEL] "VIRTIO_MMIO_DEVICE_FEATURES_SEL",
81         [VIRTIO_MMIO_DRIVER_FEATURES] "VIRTIO_MMIO_DRIVER_FEATURES",
82         [VIRTIO_MMIO_DRIVER_FEATURES_SEL] "VIRTIO_MMIO_DRIVER_FEATURES_SEL",
83         [VIRTIO_MMIO_GUEST_PAGE_SIZE] "VIRTIO_MMIO_GUEST_PAGE_SIZE",
84         [VIRTIO_MMIO_QUEUE_SEL] "VIRTIO_MMIO_QUEUE_SEL",
85         [VIRTIO_MMIO_QUEUE_NUM_MAX] "VIRTIO_MMIO_QUEUE_NUM_MAX",
86         [VIRTIO_MMIO_QUEUE_NUM] "VIRTIO_MMIO_QUEUE_NUM",
87         [VIRTIO_MMIO_QUEUE_ALIGN] "VIRTIO_MMIO_QUEUE_ALIGN",
88         [VIRTIO_MMIO_QUEUE_PFN] "VIRTIO_MMIO_QUEUE_PFN",
89         [VIRTIO_MMIO_QUEUE_READY] "VIRTIO_MMIO_QUEUE_READY",
90         [VIRTIO_MMIO_QUEUE_NOTIFY] "VIRTIO_MMIO_QUEUE_NOTIFY",
91         [VIRTIO_MMIO_INTERRUPT_STATUS] "VIRTIO_MMIO_INTERRUPT_STATUS",
92         [VIRTIO_MMIO_INTERRUPT_ACK] "VIRTIO_MMIO_INTERRUPT_ACK",
93         [VIRTIO_MMIO_STATUS] "VIRTIO_MMIO_STATUS",
94         [VIRTIO_MMIO_QUEUE_DESC_LOW] "VIRTIO_MMIO_QUEUE_DESC_LOW",
95         [VIRTIO_MMIO_QUEUE_DESC_HIGH] "VIRTIO_MMIO_QUEUE_DESC_HIGH",
96         [VIRTIO_MMIO_QUEUE_AVAIL_LOW] "VIRTIO_MMIO_QUEUE_AVAIL_LOW",
97         [VIRTIO_MMIO_QUEUE_AVAIL_HIGH] "VIRTIO_MMIO_QUEUE_AVAIL_HIGH",
98         [VIRTIO_MMIO_QUEUE_USED_LOW] "VIRTIO_MMIO_QUEUE_USED_LOW",
99         [VIRTIO_MMIO_QUEUE_USED_HIGH] "VIRTIO_MMIO_QUEUE_USED_HIGH",
100         [VIRTIO_MMIO_CONFIG_GENERATION] "VIRTIO_MMIO_CONFIG_GENERATION",
101 };
102
103 /* We're going to attempt to make mmio stateless, since the real machine is in
104  * the guest kernel. From what we know so far, all IO to the mmio space is 32 bits.
105  */
106 static uint32_t virtio_mmio_read(uint64_t gpa)
107 {
108
109         unsigned int offset = gpa - mmio.bar;
110         
111         DPRINTF("virtio_mmio_read offset %s 0x%x\n", virtio_names[offset],(int)offset);
112
113         /* If no backend is present, we treat most registers as
114          * read-as-zero, except for the magic number, version and
115          * vendor ID. This is not strictly sanctioned by the virtio
116          * spec, but it allows us to provide transports with no backend
117          * plugged in which don't confuse Linux's virtio code: the
118          * probe won't complain about the bad magic number, but the
119          * device ID of zero means no backend will claim it.
120          */
121         if (mmio.vqdev->numvqs == 0) {
122                 switch (offset) {
123                 case VIRTIO_MMIO_MAGIC_VALUE:
124                         return VIRT_MAGIC;
125                 case VIRTIO_MMIO_VERSION:
126                         return VIRT_VERSION;
127                 case VIRTIO_MMIO_VENDOR_ID:
128                         return VIRT_VENDOR;
129                 default:
130                         return 0;
131                 }
132         }
133
134
135     // WTF? Does this happen? 
136     if (offset >= VIRTIO_MMIO_CONFIG) {
137             fprintf(stderr, "Whoa. Reading past mmio config space? What gives?\n");
138             return -1;
139 #if 0
140             offset -= VIRTIO_MMIO_CONFIG;
141             switch (size) {
142             case 1:
143                     return virtio_config_readb(vdev, offset);
144             case 2:
145                     return virtio_config_readw(vdev, offset);
146             case 4:
147                     return virtio_config_readl(vdev, offset);
148             default:
149                     abort();
150             }
151 #endif
152     }
153
154 #if 0
155     if (size != 4) {
156         DPRINTF("wrong size access to register!\n");
157         return 0;
158     }
159 #endif
160 DPRINTF("FUCK 0x%x\n", offset);
161 fprintf(stderr, "FUCK2 0x%x\n", offset);
162     switch (offset) {
163     case VIRTIO_MMIO_MAGIC_VALUE:
164             return VIRT_MAGIC;
165     case VIRTIO_MMIO_VERSION:
166             return VIRT_VERSION;
167     case VIRTIO_MMIO_DEVICE_ID:
168             return mmio.vqdev->dev;
169     case VIRTIO_MMIO_VENDOR_ID:
170             return VIRT_VENDOR;
171     case VIRTIO_MMIO_DEVICE_FEATURES:
172         DPRINTF("RETURN 0x%x \n", mmio.vqdev->features);
173             return mmio.vqdev->features >> (mmio.device_features_word) ? 32 : 0;
174     case VIRTIO_MMIO_QUEUE_NUM_MAX:
175             DPRINTF("For q %d, qnum is %d\n", mmio.qsel, mmio.vqdev->vqs[mmio.qsel].qnum);
176             return mmio.vqdev->vqs[mmio.qsel].maxqnum;
177     case VIRTIO_MMIO_QUEUE_PFN:
178             return mmio.vqdev->vqs[mmio.qsel].pfn;
179     case VIRTIO_MMIO_INTERRUPT_STATUS:
180             return mmio.vqdev->vqs[mmio.qsel].isr;
181     case VIRTIO_MMIO_STATUS:
182             return mmio.vqdev->vqs[mmio.qsel].status;
183     case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
184     case VIRTIO_MMIO_DRIVER_FEATURES:
185     case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
186     case VIRTIO_MMIO_GUEST_PAGE_SIZE:
187     case VIRTIO_MMIO_QUEUE_SEL:
188     case VIRTIO_MMIO_QUEUE_NUM:
189     case VIRTIO_MMIO_QUEUE_ALIGN:
190     case VIRTIO_MMIO_QUEUE_READY:
191     case VIRTIO_MMIO_INTERRUPT_ACK:
192             fprintf(stderr, "read of write-only register@%p\n", (void *)gpa);
193         return 0;
194     default:
195             fprintf(stderr, "bad register offset@%p\n", (void *)gpa);
196         return 0;
197     }
198     return 0;
199 }
200
201 static void virtio_mmio_write(uint64_t gpa, uint32_t value)
202 {
203         uint64_t val64;
204         uint32_t low, high;
205         unsigned int offset = gpa - mmio.bar;
206         
207         DPRINTF("virtio_mmio_write offset %s 0x%x value 0x%x\n", virtio_names[offset], (int)offset, value);
208
209     if (offset >= VIRTIO_MMIO_CONFIG) {
210             fprintf(stderr, "Whoa. Writing past mmio config space? What gives?\n");
211 #if 0
212         offset -= VIRTIO_MMIO_CONFIG;
213         switch (size) {
214         case 1:
215             virtio_config_writeb(vdev, offset, value);
216             break;
217         case 2:
218             virtio_config_writew(vdev, offset, value);
219             break;
220         case 4:
221             virtio_config_writel(vdev, offset, value);
222             break;
223         default:
224             abort();
225         }
226 #endif
227         return;
228     }
229 #if 0
230     if (size != 4) {
231         DPRINTF("wrong size access to register!\n");
232         return;
233     }
234 #endif
235     switch (offset) {
236     case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
237         mmio.device_features_word = value;
238         break;
239     case VIRTIO_MMIO_DEVICE_FEATURES:
240         if (mmio.device_features_word) {
241             /* changing the high word. */
242             low = mmio.vqdev->features;
243             high = value;
244         } else {
245             /* changing the low word. */
246             high = (mmio.vqdev->features >> 32);
247             low = value;
248         }
249         mmio.vqdev->features = ((uint64_t)high << 32) | low;
250         DPRINTF("Set VIRTIO_MMIO_DEVICE_FEATURES to %p\n", mmio.vqdev->features);
251         break;
252         /* what's the difference here? Maybe FEATURES is the one you offer. */
253     case VIRTIO_MMIO_DRIVER_FEATURES:
254         if (!mmio.guest_features_sel) {
255             mmio.guest_features_sel = value;
256         }
257         break;
258     case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
259             mmio.guest_features_sel = value;
260         break;
261
262     case VIRTIO_MMIO_GUEST_PAGE_SIZE:
263             mmio.pagesize = value;
264             DPRINTF("guest page size %d bytes\n", mmio.pagesize);
265         break;
266     case VIRTIO_MMIO_QUEUE_SEL:
267             /* don't check it here. Check it on use. Or maybe check it here. Who knows. */
268             if (value < mmio.vqdev->numvqs)
269                     mmio.qsel = value;
270             else
271                     mmio.qsel = -1;
272             break;
273     case VIRTIO_MMIO_QUEUE_NUM:
274         mmio.vqdev->vqs[mmio.qsel].qnum = value;
275         break;
276     case VIRTIO_MMIO_QUEUE_ALIGN:
277         mmio.vqdev->vqs[mmio.qsel].qalign = value;
278         break;
279     case VIRTIO_MMIO_QUEUE_PFN:
280         // failure of vision: they used 32 bit numbers. Geez.
281         // v2 is better, we'll do v1 for now.
282         mmio.vqdev->vqs[mmio.qsel].pfn = value;
283                     // let's kick off the thread and see how it goes?
284                     struct virtio_threadarg *va = malloc(sizeof(*va));
285                     va->arg = &mmio.vqdev->vqs[mmio.qsel];
286                     va->arg->virtio = (void *)(va->arg->pfn * mmio.pagesize);
287                     fprintf(stderr, "START THE THREAD. pfn is 0x%x, virtio is %p\n", mmio.pagesize, va->arg->virtio);
288                     if (pthread_create(&va->arg->thread, NULL, va->arg->f, va)) {
289                             fprintf(stderr, "pth_create failed for vq %s", va->arg->name);
290                             perror("pth_create");
291                     }
292         break;
293     case VIRTIO_MMIO_QUEUE_NOTIFY:
294             if (value < mmio.vqdev->numvqs) {
295                     mmio.qsel = value;
296             }
297         break;
298     case VIRTIO_MMIO_INTERRUPT_ACK:
299         //vdev->isr &= ~value;
300         //virtio_update_irq(vdev);
301         break;
302     case VIRTIO_MMIO_STATUS:
303         if (!(value & VIRTIO_CONFIG_S_DRIVER_OK)) {
304             printf("VIRTIO_MMIO_STATUS write: NOT OK! 0x%x\n", value);
305         }
306
307         mmio.status |= value & 0xff;
308
309         if (value & VIRTIO_CONFIG_S_DRIVER_OK) {
310             printf("VIRTIO_MMIO_STATUS write: OK! 0x%x\n", value);
311         }
312
313         break;
314     case VIRTIO_MMIO_QUEUE_DESC_LOW:
315             val64 = mmio.vqdev->vqs[mmio.qsel].qdesc;
316             val64 = val64 >> 32;
317             val64 = (val64 <<32) | value;
318             mmio.vqdev->vqs[mmio.qsel].qdesc = val64;
319             DPRINTF("qdesc set low result 0xx%x\n", val64);
320             break;
321             
322     case VIRTIO_MMIO_QUEUE_DESC_HIGH:
323             val64 = (uint32_t) mmio.vqdev->vqs[mmio.qsel].qdesc;
324             mmio.vqdev->vqs[mmio.qsel].qdesc = (((uint64_t) value) <<32) | val64;
325             DPRINTF("qdesc set high result 0xx%x\n", mmio.vqdev->vqs[mmio.qsel].qdesc);
326             break;
327             
328 /* Selected queue's Available Ring address, 64 bits in two halves */
329     case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
330             val64 = mmio.vqdev->vqs[mmio.qsel].qavail;
331             val64 = val64 >> 32;
332             val64 = (val64 <<32) | value;
333             mmio.vqdev->vqs[mmio.qsel].qavail = val64;
334             DPRINTF("qavail set low result 0xx%x\n", val64);
335             break;
336     case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
337             val64 = (uint32_t) mmio.vqdev->vqs[mmio.qsel].qavail;
338             mmio.vqdev->vqs[mmio.qsel].qavail = (((uint64_t) value) <<32) | val64;
339             DPRINTF("qavail set high result 0xx%x\n", mmio.vqdev->vqs[mmio.qsel].qavail);
340             break;
341             
342 /* Selected queue's Used Ring address, 64 bits in two halves */
343     case VIRTIO_MMIO_QUEUE_USED_LOW:
344             val64 = mmio.vqdev->vqs[mmio.qsel].qused;
345             val64 = val64 >> 32;
346             val64 = (val64 <<32) | value;
347             mmio.vqdev->vqs[mmio.qsel].qused = val64;
348             DPRINTF("qused set low result 0xx%x\n", val64);
349             break;
350     case VIRTIO_MMIO_QUEUE_USED_HIGH:
351             val64 = (uint32_t) mmio.vqdev->vqs[mmio.qsel].qused;
352             mmio.vqdev->vqs[mmio.qsel].qused = (((uint64_t) value) <<32) | val64;
353             DPRINTF("qused set used result 0xx%x\n", mmio.vqdev->vqs[mmio.qsel].qused);
354             break;
355             
356         // for v2. 
357     case VIRTIO_MMIO_QUEUE_READY:
358             if (value) {
359                     // let's kick off the thread and see how it goes?
360                     struct virtio_threadarg *va = malloc(sizeof(*va));
361                     va->arg = &mmio.vqdev->vqs[mmio.qsel];
362                     va->arg->virtio = (void *)(va->arg->pfn * mmio.pagesize);
363                     fprintf(stderr, "START THE THREAD. pfn is 0x%x, virtio is %p\n", mmio.pagesize, va->arg->virtio);
364                     if (pthread_create(&va->arg->thread, NULL, va->arg->f, va)) {
365                             fprintf(stderr, "pth_create failed for vq %s", va->arg->name);
366                             perror("pth_create");
367                     }
368             }
369             break;
370
371     case VIRTIO_MMIO_MAGIC_VALUE:
372     case VIRTIO_MMIO_VERSION:
373     case VIRTIO_MMIO_DEVICE_ID:
374     case VIRTIO_MMIO_VENDOR_ID:
375 //    case VIRTIO_MMIO_HOSTFEATURES:
376     case VIRTIO_MMIO_QUEUE_NUM_MAX:
377     case VIRTIO_MMIO_INTERRUPT_STATUS:
378         DPRINTF("write to readonly register\n");
379         break;
380
381     default:
382         DPRINTF("bad register offset 0x%x\n", offset);
383     }
384
385 }
386
387 static char *modrmreg[] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"};
388
389 void virtio_mmio(struct vmctl *v)
390 {
391         int advance = 3; /* how much to move the IP forward at the end. 3 is a good default. */
392         // All virtio accesses seem to be 32 bits.
393         // valp points to a place to get or put the value. 
394         uint32_t *valp;
395         //DPRINTF("v is %p\n", v);
396         // regp points to the register in hw_trapframe from which
397         // to load or store a result.
398         uint64_t *regp;
399
400         // Duh, which way did he go George? Which way did he go? 
401         // First hit on Google gets you there!
402         // This is the guest physical address of the access.
403         // This is nice, because if we ever go with more complete
404         // instruction decode, knowing this gpa reduces our work:
405         // we don't have to find the source address in registers,
406         // only the register holding or receiving the value.
407         uint64_t gpa = v->gpa;
408         //DPRINTF("gpa is %p\n", gpa);
409
410         // To find out what to do, we have to look at
411         // RIP. Technically, we should read RIP, walk the page tables
412         // to find the PA, and read that. But we're in the kernel, so
413         // we take a shortcut for now: read the low 30 bits and use
414         // that as the kernel PA, or our VA, and see what's
415         // there. Hokey. Works.
416         uint8_t *kva = (void *)(v->regs.tf_rip & 0x3fffffff);
417         //DPRINTF("kva is %p\n", kva);
418
419         if ((kva[0] != 0x8b) && (kva[0] != 0x89)) {
420                 fprintf(stderr, "%s: can't handle instruction 0x%x\n", kva[0]);
421                 return;
422         }
423
424         uint16_t ins = *(uint16_t *)kva;
425         //DPRINTF("ins is %04x\n", ins);
426         
427         int write = (kva[0] == 0x8b) ? 0 : 1;
428         if (write)
429                 valp = (uint32_t *)gpa;
430
431         int mod = kva[1]>>6;
432         switch (mod) {
433                 case 0: 
434                 case 3:
435                         advance = 2;
436                         break;
437                 case 1:
438                         advance = 3;
439                         break;
440                 case 2: 
441                         advance = 6;
442                         break;
443         }
444         /* the dreaded mod/rm byte. */
445         int destreg = (ins>>11) & 7;
446         // Our primitive approach wins big here.
447         // We don't have to decode the register or the offset used
448         // in the computation; that was done by the CPU and is the gpa.
449         // All we need to know is which destination or source register it is.
450         switch (destreg) {
451         case 0:
452                 regp = &v->regs.tf_rax;
453                 break;
454         case 1:
455                 regp = &v->regs.tf_rcx;
456                 break;
457         case 2:
458                 regp = &v->regs.tf_rdx;
459                 break;
460         case 3:
461                 regp = &v->regs.tf_rbx;
462                 break;
463         case 4:
464                 regp = &v->regs.tf_rsp; // uh, right.
465                 break;
466         case 5:
467                 regp = &v->regs.tf_rbp;
468                 break;
469         case 6:
470                 regp = &v->regs.tf_rsi;
471                 break;
472         case 7:
473                 regp = &v->regs.tf_rdi;
474                 break;
475         }
476
477         if (write) {
478                 virtio_mmio_write(gpa, *regp);
479                 DPRINTF("Write: mov %s to %s @%p val %p\n", modrmreg[destreg], virtio_names[(uint8_t)gpa], gpa, *regp);
480         } else {
481                 *regp = virtio_mmio_read(gpa);
482                 DPRINTF("Read: Set %s from %s @%p to %p\n", modrmreg[destreg], virtio_names[(uint8_t)gpa], gpa, *regp);
483         }
484
485         DPRINTF("Advance rip by %d bytes to %p\n", advance, v->regs.tf_rip);
486         v->regs.tf_rip += advance;
487 }