blob: 44344a4993f4af5cc299f7239303f96f40db7cf1 [file] [log] [blame]
Gerd Hoffmann69f65a42020-03-06 14:34:18 +01001#include "config.h" // CONFIG_DEBUG_LEVEL
2#include "malloc.h" // free
3#include "output.h" // dprintf
4#include "stacks.h" // run_thread
5#include "string.h" // memset
Gerd Hoffmann665dce12020-03-31 15:11:46 +02006#include "util.h" // acpi_dsdt_*
Gerd Hoffmann69f65a42020-03-06 14:34:18 +01007#include "virtio-pci.h"
Gerd Hoffmannc12a1dc2020-03-09 08:05:21 +01008#include "virtio-blk.h"
Gerd Hoffmannf82e82a2020-03-09 07:43:50 +01009#include "virtio-scsi.h"
Gerd Hoffmann69f65a42020-03-06 14:34:18 +010010#include "virtio-ring.h"
11#include "virtio-mmio.h"
12
Gerd Hoffmann665dce12020-03-31 15:11:46 +020013void virtio_mmio_setup_acpi(void)
14{
15 static const char *virtio_hid = "LNRO0005";
16 struct acpi_device *dev;
17 u64 mem, irq, unused;
18
19 for (dev = acpi_dsdt_find_string(NULL, virtio_hid);
20 dev != NULL;
21 dev = acpi_dsdt_find_string(dev, virtio_hid)) {
22 if (acpi_dsdt_find_mem(dev, &mem, &unused) < 0)
23 continue;
24 if (acpi_dsdt_find_irq(dev, &irq) < 0)
25 continue;
26 dprintf(1, "ACPI: virtio-mmio device %s at 0x%llx, irq %lld\n",
27 acpi_dsdt_name(dev), mem, irq);
28 virtio_mmio_setup_one(mem);
29 }
30}
31
Gerd Hoffmann69f65a42020-03-06 14:34:18 +010032void virtio_mmio_setup_one(u64 addr)
33{
Gerd Hoffmann63565242020-04-03 09:33:34 +020034 static const char *names[] = {
35 [ 1 ] = "net",
36 [ 2 ] = "blk",
37 [ 3 ] = "console",
38 [ 4 ] = "rng",
39 [ 8 ] = "scsi",
40 [ 9 ] = "9p",
41 [ 16 ] = "gpu",
42 [ 19 ] = "vsock",
43 [ 18 ] = "input",
44 [ 26 ] = "fs",
45 };
46 const char *name;
Gerd Hoffmann69f65a42020-03-06 14:34:18 +010047 u32 magic, version, devid;
48 void *mmio;
49
50 if (addr >= 0x100000000) {
51 dprintf(1, "virtio-mmio: %llx: above 4G\n", addr);
52 return;
53 }
54
55 mmio = (void*)(u32)(addr);
56 magic = readl(mmio);
57 if (magic != 0x74726976) {
58 dprintf(1, "virtio-mmio: %llx: magic mismatch\n", addr);
59 return;
60 }
61 version = readl(mmio+4);
62 if (version != 1 /* legacy */ &&
63 version != 2 /* 1.0 */) {
64 dprintf(1, "virtio-mmio: %llx: unknown version %d\n", addr, version);
65 return;
66 }
67 devid = readl(mmio+8);
Gerd Hoffmann63565242020-04-03 09:33:34 +020068
69 name = (devid < ARRAY_SIZE(names) && names[devid] != NULL)
70 ? names[devid] : "unknown";
71 dprintf(1, "virtio-mmio: %llx: device id %x (%s%s)\n",
72 addr, devid, name, version == 1 ? ", legacy" : "");
73
Gerd Hoffmann69f65a42020-03-06 14:34:18 +010074 switch (devid) {
75 case 2: /* blk */
Gerd Hoffmannc12a1dc2020-03-09 08:05:21 +010076 run_thread(init_virtio_blk_mmio, mmio);
Gerd Hoffmann69f65a42020-03-06 14:34:18 +010077 break;
78 case 8: /* scsi */
Gerd Hoffmannf82e82a2020-03-09 07:43:50 +010079 run_thread(init_virtio_scsi_mmio, mmio);
Gerd Hoffmann69f65a42020-03-06 14:34:18 +010080 break;
81 default:
82 break;
83 }
84}
85
86void vp_init_mmio(struct vp_device *vp, void *mmio)
87{
88 memset(vp, 0, sizeof(*vp));
89 vp->use_mmio = 1;
90 vp->common.mode = VP_ACCESS_MMIO;
91 vp->common.memaddr = mmio;
92 vp->device.mode = VP_ACCESS_MMIO;
93 vp->device.memaddr = mmio + 0x100;
94 vp_reset(vp);
95 vp_set_status(vp, VIRTIO_CONFIG_S_ACKNOWLEDGE |
96 VIRTIO_CONFIG_S_DRIVER);
97}