Statistics
| Branch: | Revision:

root / hw / s390-virtio-bus.c @ 6d3b6d3d

History | View | Annotate | Download (14.6 kB)

1 f3304eea Alexander Graf
/*
2 f3304eea Alexander Graf
 * QEMU S390 virtio target
3 f3304eea Alexander Graf
 *
4 f3304eea Alexander Graf
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
5 f3304eea Alexander Graf
 *
6 f3304eea Alexander Graf
 * This library is free software; you can redistribute it and/or
7 f3304eea Alexander Graf
 * modify it under the terms of the GNU Lesser General Public
8 f3304eea Alexander Graf
 * License as published by the Free Software Foundation; either
9 f3304eea Alexander Graf
 * version 2 of the License, or (at your option) any later version.
10 f3304eea Alexander Graf
 *
11 f3304eea Alexander Graf
 * This library is distributed in the hope that it will be useful,
12 f3304eea Alexander Graf
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 f3304eea Alexander Graf
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 f3304eea Alexander Graf
 * Lesser General Public License for more details.
15 f3304eea Alexander Graf
 *
16 f3304eea Alexander Graf
 * You should have received a copy of the GNU Lesser General Public
17 f3304eea Alexander Graf
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 f3304eea Alexander Graf
 */
19 f3304eea Alexander Graf
20 f3304eea Alexander Graf
#include "hw.h"
21 f3304eea Alexander Graf
#include "block.h"
22 f3304eea Alexander Graf
#include "sysemu.h"
23 f3304eea Alexander Graf
#include "net.h"
24 f3304eea Alexander Graf
#include "boards.h"
25 f3304eea Alexander Graf
#include "monitor.h"
26 f3304eea Alexander Graf
#include "loader.h"
27 f3304eea Alexander Graf
#include "elf.h"
28 f3304eea Alexander Graf
#include "hw/virtio.h"
29 98b19252 Amit Shah
#include "hw/virtio-serial.h"
30 f0c07c7c Alex Williamson
#include "hw/virtio-net.h"
31 f3304eea Alexander Graf
#include "hw/sysbus.h"
32 f3304eea Alexander Graf
#include "kvm.h"
33 f3304eea Alexander Graf
34 f3304eea Alexander Graf
#include "hw/s390-virtio-bus.h"
35 f3304eea Alexander Graf
36 f3304eea Alexander Graf
/* #define DEBUG_S390 */
37 f3304eea Alexander Graf
38 f3304eea Alexander Graf
#ifdef DEBUG_S390
39 f3304eea Alexander Graf
#define dprintf(fmt, ...) \
40 f3304eea Alexander Graf
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
41 f3304eea Alexander Graf
#else
42 f3304eea Alexander Graf
#define dprintf(fmt, ...) \
43 f3304eea Alexander Graf
    do { } while (0)
44 f3304eea Alexander Graf
#endif
45 f3304eea Alexander Graf
46 8103b4d1 Alexander Graf
#define VIRTIO_EXT_CODE   0x2603
47 8103b4d1 Alexander Graf
48 0d936928 Anthony Liguori
static const TypeInfo s390_virtio_bus_info = {
49 0d936928 Anthony Liguori
    .name = TYPE_S390_VIRTIO_BUS,
50 0d936928 Anthony Liguori
    .parent = TYPE_BUS,
51 0d936928 Anthony Liguori
    .instance_size = sizeof(VirtIOS390Bus),
52 f3304eea Alexander Graf
};
53 f3304eea Alexander Graf
54 f3304eea Alexander Graf
static const VirtIOBindings virtio_s390_bindings;
55 f3304eea Alexander Graf
56 f3304eea Alexander Graf
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
57 f3304eea Alexander Graf
58 d1ff903c Alexander Graf
/* length of VirtIO device pages */
59 d1ff903c Alexander Graf
const target_phys_addr_t virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
60 d1ff903c Alexander Graf
61 eb3caa44 Jens Freimann
static void s390_virtio_bus_reset(void *opaque)
62 eb3caa44 Jens Freimann
{
63 eb3caa44 Jens Freimann
    VirtIOS390Bus *bus = opaque;
64 eb3caa44 Jens Freimann
    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
65 eb3caa44 Jens Freimann
}
66 eb3caa44 Jens Freimann
67 4170aea1 Jens Freimann
void s390_virtio_reset_idx(VirtIOS390Device *dev)
68 4170aea1 Jens Freimann
{
69 4170aea1 Jens Freimann
    int i;
70 4170aea1 Jens Freimann
    target_phys_addr_t idx_addr;
71 4170aea1 Jens Freimann
    uint8_t num_vq;
72 4170aea1 Jens Freimann
73 4170aea1 Jens Freimann
    num_vq = s390_virtio_device_num_vq(dev);
74 4170aea1 Jens Freimann
    for (i = 0; i < num_vq; i++) {
75 4170aea1 Jens Freimann
        idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) +
76 4170aea1 Jens Freimann
            VIRTIO_VRING_AVAIL_IDX_OFFS;
77 4170aea1 Jens Freimann
        stw_phys(idx_addr, 0);
78 4170aea1 Jens Freimann
        idx_addr = virtio_queue_get_used_addr(dev->vdev, i) +
79 4170aea1 Jens Freimann
            VIRTIO_VRING_USED_IDX_OFFS;
80 4170aea1 Jens Freimann
        stw_phys(idx_addr, 0);
81 4170aea1 Jens Freimann
    }
82 4170aea1 Jens Freimann
}
83 4170aea1 Jens Freimann
84 f3304eea Alexander Graf
VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
85 f3304eea Alexander Graf
{
86 f3304eea Alexander Graf
    VirtIOS390Bus *bus;
87 f3304eea Alexander Graf
    BusState *_bus;
88 f3304eea Alexander Graf
    DeviceState *dev;
89 f3304eea Alexander Graf
90 f3304eea Alexander Graf
    /* Create bridge device */
91 f3304eea Alexander Graf
    dev = qdev_create(NULL, "s390-virtio-bridge");
92 f3304eea Alexander Graf
    qdev_init_nofail(dev);
93 f3304eea Alexander Graf
94 f3304eea Alexander Graf
    /* Create bus on bridge device */
95 f3304eea Alexander Graf
96 0d936928 Anthony Liguori
    _bus = qbus_create(TYPE_S390_VIRTIO_BUS, dev, "s390-virtio");
97 f3304eea Alexander Graf
    bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);
98 f3304eea Alexander Graf
99 f3304eea Alexander Graf
    bus->dev_page = *ram_size;
100 f3304eea Alexander Graf
    bus->dev_offs = bus->dev_page;
101 f3304eea Alexander Graf
    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
102 f3304eea Alexander Graf
103 7fa41e53 Alexander Graf
    /* Enable hotplugging */
104 7fa41e53 Alexander Graf
    _bus->allow_hotplug = 1;
105 7fa41e53 Alexander Graf
106 f3304eea Alexander Graf
    /* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
107 f3304eea Alexander Graf
    *ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
108 f3304eea Alexander Graf
109 eb3caa44 Jens Freimann
    qemu_register_reset(s390_virtio_bus_reset, bus);
110 f3304eea Alexander Graf
    return bus;
111 f3304eea Alexander Graf
}
112 f3304eea Alexander Graf
113 0e4213a7 Andreas Färber
static void s390_virtio_irq(CPUS390XState *env, int config_change, uint64_t token)
114 7fa41e53 Alexander Graf
{
115 7fa41e53 Alexander Graf
    if (kvm_enabled()) {
116 7fa41e53 Alexander Graf
        kvm_s390_virtio_irq(env, config_change, token);
117 7fa41e53 Alexander Graf
    } else {
118 7fa41e53 Alexander Graf
        cpu_inject_ext(env, VIRTIO_EXT_CODE, config_change, token);
119 7fa41e53 Alexander Graf
    }
120 7fa41e53 Alexander Graf
}
121 7fa41e53 Alexander Graf
122 f3304eea Alexander Graf
static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
123 f3304eea Alexander Graf
{
124 f3304eea Alexander Graf
    VirtIOS390Bus *bus;
125 f3304eea Alexander Graf
    int dev_len;
126 f3304eea Alexander Graf
127 f3304eea Alexander Graf
    bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
128 f3304eea Alexander Graf
    dev->vdev = vdev;
129 f3304eea Alexander Graf
    dev->dev_offs = bus->dev_offs;
130 f3304eea Alexander Graf
    dev->feat_len = sizeof(uint32_t); /* always keep 32 bits features */
131 f3304eea Alexander Graf
132 f3304eea Alexander Graf
    dev_len = VIRTIO_DEV_OFFS_CONFIG;
133 f3304eea Alexander Graf
    dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN;
134 f3304eea Alexander Graf
    dev_len += dev->feat_len * 2;
135 f3304eea Alexander Graf
    dev_len += vdev->config_len;
136 f3304eea Alexander Graf
137 f3304eea Alexander Graf
    bus->dev_offs += dev_len;
138 f3304eea Alexander Graf
139 f3304eea Alexander Graf
    virtio_bind_device(vdev, &virtio_s390_bindings, dev);
140 8172539d Michael S. Tsirkin
    dev->host_features = vdev->get_features(vdev, dev->host_features);
141 f3304eea Alexander Graf
    s390_virtio_device_sync(dev);
142 4170aea1 Jens Freimann
    s390_virtio_reset_idx(dev);
143 7fa41e53 Alexander Graf
    if (dev->qdev.hotplugged) {
144 45fa769b Andreas Färber
        S390CPU *cpu = s390_cpu_addr2state(0);
145 45fa769b Andreas Färber
        CPUS390XState *env = &cpu->env;
146 7fa41e53 Alexander Graf
        s390_virtio_irq(env, VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
147 7fa41e53 Alexander Graf
    }
148 7fa41e53 Alexander Graf
149 f3304eea Alexander Graf
    return 0;
150 f3304eea Alexander Graf
}
151 f3304eea Alexander Graf
152 f3304eea Alexander Graf
static int s390_virtio_net_init(VirtIOS390Device *dev)
153 f3304eea Alexander Graf
{
154 f3304eea Alexander Graf
    VirtIODevice *vdev;
155 f3304eea Alexander Graf
156 f0c07c7c Alex Williamson
    vdev = virtio_net_init((DeviceState *)dev, &dev->nic, &dev->net);
157 f3304eea Alexander Graf
    if (!vdev) {
158 f3304eea Alexander Graf
        return -1;
159 f3304eea Alexander Graf
    }
160 f3304eea Alexander Graf
161 f3304eea Alexander Graf
    return s390_virtio_device_init(dev, vdev);
162 f3304eea Alexander Graf
}
163 f3304eea Alexander Graf
164 f3304eea Alexander Graf
static int s390_virtio_blk_init(VirtIOS390Device *dev)
165 f3304eea Alexander Graf
{
166 f3304eea Alexander Graf
    VirtIODevice *vdev;
167 f3304eea Alexander Graf
168 12c5674b Paolo Bonzini
    vdev = virtio_blk_init((DeviceState *)dev, &dev->blk);
169 f3304eea Alexander Graf
    if (!vdev) {
170 f3304eea Alexander Graf
        return -1;
171 f3304eea Alexander Graf
    }
172 f3304eea Alexander Graf
173 f3304eea Alexander Graf
    return s390_virtio_device_init(dev, vdev);
174 f3304eea Alexander Graf
}
175 f3304eea Alexander Graf
176 98b19252 Amit Shah
static int s390_virtio_serial_init(VirtIOS390Device *dev)
177 f3304eea Alexander Graf
{
178 f3304eea Alexander Graf
    VirtIOS390Bus *bus;
179 f3304eea Alexander Graf
    VirtIODevice *vdev;
180 f3304eea Alexander Graf
    int r;
181 f3304eea Alexander Graf
182 f3304eea Alexander Graf
    bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
183 f3304eea Alexander Graf
184 6be9b414 Alexander Graf
    vdev = virtio_serial_init((DeviceState *)dev, &dev->serial);
185 f3304eea Alexander Graf
    if (!vdev) {
186 f3304eea Alexander Graf
        return -1;
187 f3304eea Alexander Graf
    }
188 f3304eea Alexander Graf
189 f3304eea Alexander Graf
    r = s390_virtio_device_init(dev, vdev);
190 f3304eea Alexander Graf
    if (!r) {
191 f3304eea Alexander Graf
        bus->console = dev;
192 f3304eea Alexander Graf
    }
193 f3304eea Alexander Graf
194 f3304eea Alexander Graf
    return r;
195 f3304eea Alexander Graf
}
196 f3304eea Alexander Graf
197 973abc7f Stefan Hajnoczi
static int s390_virtio_scsi_init(VirtIOS390Device *dev)
198 973abc7f Stefan Hajnoczi
{
199 973abc7f Stefan Hajnoczi
    VirtIODevice *vdev;
200 973abc7f Stefan Hajnoczi
201 973abc7f Stefan Hajnoczi
    vdev = virtio_scsi_init((DeviceState *)dev, &dev->scsi);
202 973abc7f Stefan Hajnoczi
    if (!vdev) {
203 973abc7f Stefan Hajnoczi
        return -1;
204 973abc7f Stefan Hajnoczi
    }
205 973abc7f Stefan Hajnoczi
206 973abc7f Stefan Hajnoczi
    return s390_virtio_device_init(dev, vdev);
207 973abc7f Stefan Hajnoczi
}
208 973abc7f Stefan Hajnoczi
209 f3304eea Alexander Graf
static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
210 f3304eea Alexander Graf
{
211 f3304eea Alexander Graf
    ram_addr_t token_off;
212 f3304eea Alexander Graf
213 f3304eea Alexander Graf
    token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
214 f3304eea Alexander Graf
                (vq * VIRTIO_VQCONFIG_LEN) +
215 f3304eea Alexander Graf
                VIRTIO_VQCONFIG_OFFS_TOKEN;
216 f3304eea Alexander Graf
217 04bc74ed Alexander Graf
    return ldq_be_phys(token_off);
218 f3304eea Alexander Graf
}
219 f3304eea Alexander Graf
220 f3304eea Alexander Graf
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
221 f3304eea Alexander Graf
{
222 f3304eea Alexander Graf
    VirtIODevice *vdev = dev->vdev;
223 f3304eea Alexander Graf
    int num_vq;
224 f3304eea Alexander Graf
225 f3304eea Alexander Graf
    for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) {
226 f3304eea Alexander Graf
        if (!virtio_queue_get_num(vdev, num_vq)) {
227 f3304eea Alexander Graf
            break;
228 f3304eea Alexander Graf
        }
229 f3304eea Alexander Graf
    }
230 f3304eea Alexander Graf
231 f3304eea Alexander Graf
    return num_vq;
232 f3304eea Alexander Graf
}
233 f3304eea Alexander Graf
234 f3304eea Alexander Graf
static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
235 f3304eea Alexander Graf
{
236 f3304eea Alexander Graf
    ram_addr_t r = bus->next_ring;
237 f3304eea Alexander Graf
238 f3304eea Alexander Graf
    bus->next_ring += VIRTIO_RING_LEN;
239 f3304eea Alexander Graf
    return r;
240 f3304eea Alexander Graf
}
241 f3304eea Alexander Graf
242 baf0b55a Alexander Graf
void s390_virtio_device_sync(VirtIOS390Device *dev)
243 f3304eea Alexander Graf
{
244 f3304eea Alexander Graf
    VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
245 f3304eea Alexander Graf
    ram_addr_t cur_offs;
246 f3304eea Alexander Graf
    uint8_t num_vq;
247 f3304eea Alexander Graf
    int i;
248 f3304eea Alexander Graf
249 f3304eea Alexander Graf
    virtio_reset(dev->vdev);
250 f3304eea Alexander Graf
251 f3304eea Alexander Graf
    /* Sync dev space */
252 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, dev->vdev->device_id);
253 f3304eea Alexander Graf
254 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, s390_virtio_device_num_vq(dev));
255 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, dev->feat_len);
256 f3304eea Alexander Graf
257 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, dev->vdev->config_len);
258 f3304eea Alexander Graf
259 f3304eea Alexander Graf
    num_vq = s390_virtio_device_num_vq(dev);
260 f3304eea Alexander Graf
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq);
261 f3304eea Alexander Graf
262 f3304eea Alexander Graf
    /* Sync virtqueues */
263 f3304eea Alexander Graf
    for (i = 0; i < num_vq; i++) {
264 f3304eea Alexander Graf
        ram_addr_t vq = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
265 f3304eea Alexander Graf
                        (i * VIRTIO_VQCONFIG_LEN);
266 f3304eea Alexander Graf
        ram_addr_t vring;
267 f3304eea Alexander Graf
268 f3304eea Alexander Graf
        vring = s390_virtio_next_ring(bus);
269 f3304eea Alexander Graf
        virtio_queue_set_addr(dev->vdev, i, vring);
270 f3304eea Alexander Graf
        virtio_queue_set_vector(dev->vdev, i, i);
271 04bc74ed Alexander Graf
        stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
272 04bc74ed Alexander Graf
        stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
273 f3304eea Alexander Graf
    }
274 f3304eea Alexander Graf
275 f3304eea Alexander Graf
    cur_offs = dev->dev_offs;
276 f3304eea Alexander Graf
    cur_offs += VIRTIO_DEV_OFFS_CONFIG;
277 f3304eea Alexander Graf
    cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
278 f3304eea Alexander Graf
279 f3304eea Alexander Graf
    /* Sync feature bitmap */
280 04bc74ed Alexander Graf
    stl_le_phys(cur_offs, dev->host_features);
281 f3304eea Alexander Graf
282 f3304eea Alexander Graf
    dev->feat_offs = cur_offs + dev->feat_len;
283 f3304eea Alexander Graf
    cur_offs += dev->feat_len * 2;
284 f3304eea Alexander Graf
285 f3304eea Alexander Graf
    /* Sync config space */
286 f3304eea Alexander Graf
    if (dev->vdev->get_config) {
287 f3304eea Alexander Graf
        dev->vdev->get_config(dev->vdev, dev->vdev->config);
288 f3304eea Alexander Graf
    }
289 f3304eea Alexander Graf
290 54f7b4a3 Stefan Weil
    cpu_physical_memory_write(cur_offs,
291 54f7b4a3 Stefan Weil
                              dev->vdev->config, dev->vdev->config_len);
292 f3304eea Alexander Graf
    cur_offs += dev->vdev->config_len;
293 f3304eea Alexander Graf
}
294 f3304eea Alexander Graf
295 f3304eea Alexander Graf
void s390_virtio_device_update_status(VirtIOS390Device *dev)
296 f3304eea Alexander Graf
{
297 f3304eea Alexander Graf
    VirtIODevice *vdev = dev->vdev;
298 f3304eea Alexander Graf
    uint32_t features;
299 f3304eea Alexander Graf
300 3e607cb5 Michael S. Tsirkin
    virtio_set_status(vdev, ldub_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS));
301 f3304eea Alexander Graf
302 f3304eea Alexander Graf
    /* Update guest supported feature bitmap */
303 f3304eea Alexander Graf
304 04bc74ed Alexander Graf
    features = bswap32(ldl_be_phys(dev->feat_offs));
305 ad0c9332 Paolo Bonzini
    virtio_set_features(vdev, features);
306 f3304eea Alexander Graf
}
307 f3304eea Alexander Graf
308 f3304eea Alexander Graf
VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
309 f3304eea Alexander Graf
{
310 f3304eea Alexander Graf
    return bus->console;
311 f3304eea Alexander Graf
}
312 f3304eea Alexander Graf
313 f3304eea Alexander Graf
/* Find a device by vring address */
314 f3304eea Alexander Graf
VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
315 f3304eea Alexander Graf
                                             ram_addr_t mem,
316 f3304eea Alexander Graf
                                             int *vq_num)
317 f3304eea Alexander Graf
{
318 0866aca1 Anthony Liguori
    BusChild *kid;
319 f3304eea Alexander Graf
    int i;
320 f3304eea Alexander Graf
321 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
322 0866aca1 Anthony Liguori
        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
323 0866aca1 Anthony Liguori
324 f3304eea Alexander Graf
        for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
325 0866aca1 Anthony Liguori
            if (!virtio_queue_get_addr(dev->vdev, i))
326 f3304eea Alexander Graf
                break;
327 0866aca1 Anthony Liguori
            if (virtio_queue_get_addr(dev->vdev, i) == mem) {
328 f3304eea Alexander Graf
                if (vq_num) {
329 f3304eea Alexander Graf
                    *vq_num = i;
330 f3304eea Alexander Graf
                }
331 0866aca1 Anthony Liguori
                return dev;
332 f3304eea Alexander Graf
            }
333 f3304eea Alexander Graf
        }
334 f3304eea Alexander Graf
    }
335 f3304eea Alexander Graf
336 f3304eea Alexander Graf
    return NULL;
337 f3304eea Alexander Graf
}
338 f3304eea Alexander Graf
339 f3304eea Alexander Graf
/* Find a device by device descriptor location */
340 f3304eea Alexander Graf
VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
341 f3304eea Alexander Graf
{
342 0866aca1 Anthony Liguori
    BusChild *kid;
343 f3304eea Alexander Graf
344 0866aca1 Anthony Liguori
    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
345 0866aca1 Anthony Liguori
        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
346 0866aca1 Anthony Liguori
        if (dev->dev_offs == mem) {
347 0866aca1 Anthony Liguori
            return dev;
348 f3304eea Alexander Graf
        }
349 f3304eea Alexander Graf
    }
350 f3304eea Alexander Graf
351 f3304eea Alexander Graf
    return NULL;
352 f3304eea Alexander Graf
}
353 f3304eea Alexander Graf
354 f3304eea Alexander Graf
static void virtio_s390_notify(void *opaque, uint16_t vector)
355 f3304eea Alexander Graf
{
356 f3304eea Alexander Graf
    VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
357 f3304eea Alexander Graf
    uint64_t token = s390_virtio_device_vq_token(dev, vector);
358 45fa769b Andreas Färber
    S390CPU *cpu = s390_cpu_addr2state(0);
359 45fa769b Andreas Färber
    CPUS390XState *env = &cpu->env;
360 f3304eea Alexander Graf
361 7fa41e53 Alexander Graf
    s390_virtio_irq(env, 0, token);
362 f3304eea Alexander Graf
}
363 f3304eea Alexander Graf
364 8172539d Michael S. Tsirkin
static unsigned virtio_s390_get_features(void *opaque)
365 8172539d Michael S. Tsirkin
{
366 8172539d Michael S. Tsirkin
    VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
367 8172539d Michael S. Tsirkin
    return dev->host_features;
368 8172539d Michael S. Tsirkin
}
369 8172539d Michael S. Tsirkin
370 f3304eea Alexander Graf
/**************** S390 Virtio Bus Device Descriptions *******************/
371 f3304eea Alexander Graf
372 f3304eea Alexander Graf
static const VirtIOBindings virtio_s390_bindings = {
373 f3304eea Alexander Graf
    .notify = virtio_s390_notify,
374 8172539d Michael S. Tsirkin
    .get_features = virtio_s390_get_features,
375 f3304eea Alexander Graf
};
376 f3304eea Alexander Graf
377 39bffca2 Anthony Liguori
static Property s390_virtio_net_properties[] = {
378 39bffca2 Anthony Liguori
    DEFINE_NIC_PROPERTIES(VirtIOS390Device, nic),
379 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("x-txtimer", VirtIOS390Device,
380 39bffca2 Anthony Liguori
                       net.txtimer, TX_TIMER_INTERVAL),
381 39bffca2 Anthony Liguori
    DEFINE_PROP_INT32("x-txburst", VirtIOS390Device,
382 39bffca2 Anthony Liguori
                      net.txburst, TX_BURST),
383 39bffca2 Anthony Liguori
    DEFINE_PROP_STRING("tx", VirtIOS390Device, net.tx),
384 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
385 39bffca2 Anthony Liguori
};
386 39bffca2 Anthony Liguori
387 19b6914a Anthony Liguori
static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
388 19b6914a Anthony Liguori
{
389 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
390 39bffca2 Anthony Liguori
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
391 19b6914a Anthony Liguori
392 39bffca2 Anthony Liguori
    k->init = s390_virtio_net_init;
393 39bffca2 Anthony Liguori
    dc->props = s390_virtio_net_properties;
394 19b6914a Anthony Liguori
}
395 19b6914a Anthony Liguori
396 39bffca2 Anthony Liguori
static TypeInfo s390_virtio_net = {
397 39bffca2 Anthony Liguori
    .name          = "virtio-net-s390",
398 39bffca2 Anthony Liguori
    .parent        = TYPE_VIRTIO_S390_DEVICE,
399 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOS390Device),
400 39bffca2 Anthony Liguori
    .class_init    = s390_virtio_net_class_init,
401 39bffca2 Anthony Liguori
};
402 39bffca2 Anthony Liguori
403 39bffca2 Anthony Liguori
static Property s390_virtio_blk_properties[] = {
404 12c5674b Paolo Bonzini
    DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, blk.conf),
405 e63e7fde Markus Armbruster
    DEFINE_BLOCK_CHS_PROPERTIES(VirtIOS390Device, blk.conf),
406 12c5674b Paolo Bonzini
    DEFINE_PROP_STRING("serial", VirtIOS390Device, blk.serial),
407 a6c5c84a Paolo Bonzini
#ifdef __linux__
408 a6c5c84a Paolo Bonzini
    DEFINE_PROP_BIT("scsi", VirtIOS390Device, blk.scsi, 0, true),
409 a6c5c84a Paolo Bonzini
#endif
410 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
411 f3304eea Alexander Graf
};
412 f3304eea Alexander Graf
413 19b6914a Anthony Liguori
static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
414 19b6914a Anthony Liguori
{
415 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
416 39bffca2 Anthony Liguori
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
417 19b6914a Anthony Liguori
418 39bffca2 Anthony Liguori
    k->init = s390_virtio_blk_init;
419 39bffca2 Anthony Liguori
    dc->props = s390_virtio_blk_properties;
420 19b6914a Anthony Liguori
}
421 19b6914a Anthony Liguori
422 39bffca2 Anthony Liguori
static TypeInfo s390_virtio_blk = {
423 39bffca2 Anthony Liguori
    .name          = "virtio-blk-s390",
424 39bffca2 Anthony Liguori
    .parent        = TYPE_VIRTIO_S390_DEVICE,
425 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOS390Device),
426 39bffca2 Anthony Liguori
    .class_init    = s390_virtio_blk_class_init,
427 39bffca2 Anthony Liguori
};
428 39bffca2 Anthony Liguori
429 39bffca2 Anthony Liguori
static Property s390_virtio_serial_properties[] = {
430 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("max_ports", VirtIOS390Device,
431 39bffca2 Anthony Liguori
                       serial.max_virtserial_ports, 31),
432 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
433 f3304eea Alexander Graf
};
434 f3304eea Alexander Graf
435 19b6914a Anthony Liguori
static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
436 19b6914a Anthony Liguori
{
437 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
438 39bffca2 Anthony Liguori
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
439 19b6914a Anthony Liguori
440 39bffca2 Anthony Liguori
    k->init = s390_virtio_serial_init;
441 39bffca2 Anthony Liguori
    dc->props = s390_virtio_serial_properties;
442 19b6914a Anthony Liguori
}
443 19b6914a Anthony Liguori
444 39bffca2 Anthony Liguori
static TypeInfo s390_virtio_serial = {
445 39bffca2 Anthony Liguori
    .name          = "virtio-serial-s390",
446 39bffca2 Anthony Liguori
    .parent        = TYPE_VIRTIO_S390_DEVICE,
447 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOS390Device),
448 39bffca2 Anthony Liguori
    .class_init    = s390_virtio_serial_class_init,
449 f3304eea Alexander Graf
};
450 f3304eea Alexander Graf
451 d307af79 Anthony Liguori
static int s390_virtio_busdev_init(DeviceState *dev)
452 f3304eea Alexander Graf
{
453 f3304eea Alexander Graf
    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
454 19b6914a Anthony Liguori
    VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
455 f3304eea Alexander Graf
456 f3304eea Alexander Graf
    return _info->init(_dev);
457 f3304eea Alexander Graf
}
458 f3304eea Alexander Graf
459 39bffca2 Anthony Liguori
static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
460 f3304eea Alexander Graf
{
461 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
462 f3304eea Alexander Graf
463 39bffca2 Anthony Liguori
    dc->init = s390_virtio_busdev_init;
464 0d936928 Anthony Liguori
    dc->bus_type = TYPE_S390_VIRTIO_BUS;
465 39bffca2 Anthony Liguori
    dc->unplug = qdev_simple_unplug_cb;
466 f3304eea Alexander Graf
}
467 f3304eea Alexander Graf
468 19b6914a Anthony Liguori
static TypeInfo virtio_s390_device_info = {
469 19b6914a Anthony Liguori
    .name = TYPE_VIRTIO_S390_DEVICE,
470 19b6914a Anthony Liguori
    .parent = TYPE_DEVICE,
471 19b6914a Anthony Liguori
    .instance_size = sizeof(VirtIOS390Device),
472 39bffca2 Anthony Liguori
    .class_init = virtio_s390_device_class_init,
473 e87f7fc6 Anthony Liguori
    .class_size = sizeof(VirtIOS390DeviceClass),
474 19b6914a Anthony Liguori
    .abstract = true,
475 19b6914a Anthony Liguori
};
476 19b6914a Anthony Liguori
477 973abc7f Stefan Hajnoczi
static Property s390_virtio_scsi_properties[] = {
478 973abc7f Stefan Hajnoczi
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOS390Device, host_features, scsi),
479 973abc7f Stefan Hajnoczi
    DEFINE_PROP_END_OF_LIST(),
480 973abc7f Stefan Hajnoczi
};
481 973abc7f Stefan Hajnoczi
482 973abc7f Stefan Hajnoczi
static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
483 973abc7f Stefan Hajnoczi
{
484 973abc7f Stefan Hajnoczi
    DeviceClass *dc = DEVICE_CLASS(klass);
485 973abc7f Stefan Hajnoczi
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
486 973abc7f Stefan Hajnoczi
487 973abc7f Stefan Hajnoczi
    k->init = s390_virtio_scsi_init;
488 973abc7f Stefan Hajnoczi
    dc->props = s390_virtio_scsi_properties;
489 973abc7f Stefan Hajnoczi
}
490 973abc7f Stefan Hajnoczi
491 973abc7f Stefan Hajnoczi
static TypeInfo s390_virtio_scsi = {
492 973abc7f Stefan Hajnoczi
    .name          = "virtio-scsi-s390",
493 973abc7f Stefan Hajnoczi
    .parent        = TYPE_VIRTIO_S390_DEVICE,
494 973abc7f Stefan Hajnoczi
    .instance_size = sizeof(VirtIOS390Device),
495 973abc7f Stefan Hajnoczi
    .class_init    = s390_virtio_scsi_class_init,
496 973abc7f Stefan Hajnoczi
};
497 f3304eea Alexander Graf
498 f3304eea Alexander Graf
/***************** S390 Virtio Bus Bridge Device *******************/
499 f3304eea Alexander Graf
/* Only required to have the virtio bus as child in the system bus */
500 f3304eea Alexander Graf
501 f3304eea Alexander Graf
static int s390_virtio_bridge_init(SysBusDevice *dev)
502 f3304eea Alexander Graf
{
503 f3304eea Alexander Graf
    /* nothing */
504 f3304eea Alexander Graf
    return 0;
505 f3304eea Alexander Graf
}
506 f3304eea Alexander Graf
507 999e12bb Anthony Liguori
static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
508 999e12bb Anthony Liguori
{
509 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
510 999e12bb Anthony Liguori
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
511 999e12bb Anthony Liguori
512 999e12bb Anthony Liguori
    k->init = s390_virtio_bridge_init;
513 39bffca2 Anthony Liguori
    dc->no_user = 1;
514 999e12bb Anthony Liguori
}
515 999e12bb Anthony Liguori
516 39bffca2 Anthony Liguori
static TypeInfo s390_virtio_bridge_info = {
517 39bffca2 Anthony Liguori
    .name          = "s390-virtio-bridge",
518 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
519 39bffca2 Anthony Liguori
    .instance_size = sizeof(SysBusDevice),
520 39bffca2 Anthony Liguori
    .class_init    = s390_virtio_bridge_class_init,
521 f3304eea Alexander Graf
};
522 f3304eea Alexander Graf
523 83f7d43a Andreas Färber
static void s390_virtio_register_types(void)
524 f3304eea Alexander Graf
{
525 0d936928 Anthony Liguori
    type_register_static(&s390_virtio_bus_info);
526 83f7d43a Andreas Färber
    type_register_static(&virtio_s390_device_info);
527 83f7d43a Andreas Färber
    type_register_static(&s390_virtio_serial);
528 83f7d43a Andreas Färber
    type_register_static(&s390_virtio_blk);
529 83f7d43a Andreas Färber
    type_register_static(&s390_virtio_net);
530 973abc7f Stefan Hajnoczi
    type_register_static(&s390_virtio_scsi);
531 39bffca2 Anthony Liguori
    type_register_static(&s390_virtio_bridge_info);
532 f3304eea Alexander Graf
}
533 f3304eea Alexander Graf
534 83f7d43a Andreas Färber
type_init(s390_virtio_register_types)