aboutsummaryrefslogtreecommitdiffstats
path: root/src/hw/virtio-mmio.c
blob: daca8a098a0bca513b5bc9f39ecfab40e5a70461 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "config.h" // CONFIG_DEBUG_LEVEL
#include "malloc.h" // free
#include "output.h" // dprintf
#include "stacks.h" // run_thread
#include "string.h" // memset
#include "virtio-pci.h"
#include "virtio-scsi.h"
#include "virtio-ring.h"
#include "virtio-mmio.h"

void virtio_mmio_setup_one(u64 addr)
{
    u32 magic, version, devid;
    void *mmio;

    if (addr >= 0x100000000) {
        dprintf(1, "virtio-mmio: %llx: above 4G\n", addr);
        return;
    }

    mmio = (void*)(u32)(addr);
    magic = readl(mmio);
    if (magic != 0x74726976) {
        dprintf(1, "virtio-mmio: %llx: magic mismatch\n", addr);
        return;
    }
    version = readl(mmio+4);
    if (version != 1 /* legacy */ &&
        version != 2 /* 1.0 */) {
        dprintf(1, "virtio-mmio: %llx: unknown version %d\n", addr, version);
        return;
    }
    devid = readl(mmio+8);
    dprintf(1, "virtio-mmio: %llx: device id %x%s\n",
            addr, devid, version == 1 ? " (legacy)" : "");
    switch (devid) {
    case 2: /* blk */
        /* TODO */
        break;
    case 8: /* scsi */
        run_thread(init_virtio_scsi_mmio, mmio);
        break;
    default:
        break;
    }
}

void vp_init_mmio(struct vp_device *vp, void *mmio)
{
    memset(vp, 0, sizeof(*vp));
    vp->use_mmio = 1;
    vp->common.mode = VP_ACCESS_MMIO;
    vp->common.memaddr = mmio;
    vp->device.mode = VP_ACCESS_MMIO;
    vp->device.memaddr = mmio + 0x100;
    vp_reset(vp);
    vp_set_status(vp, VIRTIO_CONFIG_S_ACKNOWLEDGE |
                  VIRTIO_CONFIG_S_DRIVER);
}